VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_lists.c@ 44444

Last change on this file since 44444 was 40691, checked in by vboxsync, 13 years ago

crOpenGL: basics for using multiple contexts on host

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.2 KB
Line 
1/* Copyright (c) 2001-2003, Stanford University
2 All rights reserved.
3
4 See the file LICENSE.txt for information on redistributing this software. */
5
6#include "server_dispatch.h"
7#include "server.h"
8#include "cr_mem.h"
9
10
11/*
12 * Notes on ID translation:
13 *
14 * If a server has multiple clients (in the case of parallel applications)
15 * and N of the clients all create a display list with ID K, does K name
16 * one display list or N different display lists?
17 *
18 * By default, there is one display list named K. If the clients put
19 * identical commands into list K, then this is fine. But if the clients
20 * each put something different into list K when they created it, then this
21 * is a serious problem.
22 *
23 * By zeroing the 'shared_display_lists' configuration option, we can tell
24 * the server to make list K be unique for all N clients. We do this by
25 * translating K into a new, unique ID dependent on which client we're
26 * talking to (curClient->number).
27 *
28 * Same story for texture objects, vertex programs, etc.
29 *
30 * The application can also dynamically switch between shared and private
31 * display lists with:
32 * glChromiumParameteri(GL_SHARED_DISPLAY_LISTS_CR, GL_TRUE)
33 * and
34 * glChromiumParameteri(GL_SHARED_DISPLAY_LISTS_CR, GL_FALSE)
35 *
36 */
37
38
39
40static GLuint TranslateListID( GLuint id )
41{
42 if (!cr_server.sharedDisplayLists) {
43 int client = cr_server.curClient->number;
44 return id + client * 100000;
45 }
46 return id;
47}
48
49/* XXXX Note: shared/separate Program ID numbers aren't totally implemented! */
50GLuint crServerTranslateProgramID( GLuint id )
51{
52 if (!cr_server.sharedPrograms && id) {
53 int client = cr_server.curClient->number;
54 return id + client * 100000;
55 }
56 return id;
57}
58
59
60void SERVER_DISPATCH_APIENTRY
61crServerDispatchNewList( GLuint list, GLenum mode )
62{
63 if (mode == GL_COMPILE_AND_EXECUTE)
64 crWarning("using glNewList(GL_COMPILE_AND_EXECUTE) can confuse the crserver");
65
66 list = TranslateListID( list );
67 crStateNewList( list, mode );
68 cr_server.head_spu->dispatch_table.NewList( list, mode );
69}
70
71void SERVER_DISPATCH_APIENTRY crServerDispatchEndList(void)
72{
73 cr_server.head_spu->dispatch_table.EndList();
74 crStateEndList();
75}
76
77void SERVER_DISPATCH_APIENTRY
78crServerDispatchCallList( GLuint list )
79{
80 list = TranslateListID( list );
81
82 if (cr_server.curClient->currentCtxInfo->pContext->lists.mode == 0) {
83 /* we're not compiling, so execute the list now */
84 /* Issue the list as-is */
85 cr_server.head_spu->dispatch_table.CallList( list );
86 crStateQueryHWState();
87 }
88 else {
89 /* we're compiling glCallList into another list - just pass it through */
90 cr_server.head_spu->dispatch_table.CallList( list );
91 }
92}
93
94
95/**
96 * Translate an array of display list IDs from various datatypes to GLuint
97 * IDs while adding the per-client offset.
98 */
99static void
100TranslateListIDs(GLsizei n, GLenum type, const GLvoid *lists, GLuint *newLists)
101{
102 int offset = cr_server.curClient->number * 100000;
103 GLsizei i;
104 switch (type) {
105 case GL_UNSIGNED_BYTE:
106 {
107 const GLubyte *src = (const GLubyte *) lists;
108 for (i = 0; i < n; i++) {
109 newLists[i] = src[i] + offset;
110 }
111 }
112 break;
113 case GL_BYTE:
114 {
115 const GLbyte *src = (const GLbyte *) lists;
116 for (i = 0; i < n; i++) {
117 newLists[i] = src[i] + offset;
118 }
119 }
120 break;
121 case GL_UNSIGNED_SHORT:
122 {
123 const GLushort *src = (const GLushort *) lists;
124 for (i = 0; i < n; i++) {
125 newLists[i] = src[i] + offset;
126 }
127 }
128 break;
129 case GL_SHORT:
130 {
131 const GLshort *src = (const GLshort *) lists;
132 for (i = 0; i < n; i++) {
133 newLists[i] = src[i] + offset;
134 }
135 }
136 break;
137 case GL_UNSIGNED_INT:
138 {
139 const GLuint *src = (const GLuint *) lists;
140 for (i = 0; i < n; i++) {
141 newLists[i] = src[i] + offset;
142 }
143 }
144 break;
145 case GL_INT:
146 {
147 const GLint *src = (const GLint *) lists;
148 for (i = 0; i < n; i++) {
149 newLists[i] = src[i] + offset;
150 }
151 }
152 break;
153 case GL_FLOAT:
154 {
155 const GLfloat *src = (const GLfloat *) lists;
156 for (i = 0; i < n; i++) {
157 newLists[i] = (GLuint) src[i] + offset;
158 }
159 }
160 break;
161 case GL_2_BYTES:
162 {
163 const GLubyte *src = (const GLubyte *) lists;
164 for (i = 0; i < n; i++) {
165 newLists[i] = (src[i*2+0] * 256 +
166 src[i*2+1]) + offset;
167 }
168 }
169 break;
170 case GL_3_BYTES:
171 {
172 const GLubyte *src = (const GLubyte *) lists;
173 for (i = 0; i < n; i++) {
174 newLists[i] = (src[i*3+0] * 256 * 256 +
175 src[i*3+1] * 256 +
176 src[i*3+2]) + offset;
177 }
178 }
179 break;
180 case GL_4_BYTES:
181 {
182 const GLubyte *src = (const GLubyte *) lists;
183 for (i = 0; i < n; i++) {
184 newLists[i] = (src[i*4+0] * 256 * 256 * 256 +
185 src[i*4+1] * 256 * 256 +
186 src[i*4+2] * 256 +
187 src[i*4+3]) + offset;
188 }
189 }
190 break;
191 default:
192 crWarning("CRServer: invalid display list datatype 0x%x", type);
193 }
194}
195
196
197void SERVER_DISPATCH_APIENTRY
198crServerDispatchCallLists( GLsizei n, GLenum type, const GLvoid *lists )
199{
200 if (!cr_server.sharedDisplayLists) {
201 /* need to translate IDs */
202 GLuint *newLists = (GLuint *) crAlloc(n * sizeof(GLuint));
203 if (newLists) {
204 TranslateListIDs(n, type, lists, newLists);
205 }
206 lists = newLists;
207 type = GL_UNSIGNED_INT;
208 }
209
210 if (cr_server.curClient->currentCtxInfo->pContext->lists.mode == 0) {
211 /* we're not compiling, so execute the list now */
212 /* Issue the list as-is */
213 cr_server.head_spu->dispatch_table.CallLists( n, type, lists );
214 crStateQueryHWState();
215 }
216 else {
217 /* we're compiling glCallList into another list - just pass it through */
218 cr_server.head_spu->dispatch_table.CallLists( n, type, lists );
219 }
220
221 if (!cr_server.sharedDisplayLists) {
222 crFree((void *) lists); /* malloc'd above */
223 }
224}
225
226
227GLboolean SERVER_DISPATCH_APIENTRY crServerDispatchIsList( GLuint list )
228{
229 GLboolean retval;
230 list = TranslateListID( list );
231 retval = cr_server.head_spu->dispatch_table.IsList( list );
232 crServerReturnValue( &retval, sizeof(retval) );
233 return retval;
234}
235
236
237void SERVER_DISPATCH_APIENTRY crServerDispatchDeleteLists( GLuint list, GLsizei range )
238{
239 list = TranslateListID( list );
240 crStateDeleteLists( list, range );
241 cr_server.head_spu->dispatch_table.DeleteLists( list, range );
242}
243
244
245void SERVER_DISPATCH_APIENTRY crServerDispatchBindTexture( GLenum target, GLuint texture )
246{
247 crStateBindTexture( target, texture );
248 cr_server.head_spu->dispatch_table.BindTexture(target, crStateGetTextureHWID(texture));
249}
250
251void SERVER_DISPATCH_APIENTRY crServerDispatchDeleteTextures( GLsizei n, const GLuint *textures)
252{
253 GLuint *newTextures = (GLuint *) crAlloc(n * sizeof(GLuint));
254 GLint i;
255
256 if (!newTextures)
257 {
258 crError("crServerDispatchDeleteTextures: out of memory");
259 return;
260 }
261
262 for (i = 0; i < n; i++)
263 {
264 newTextures[i] = crStateGetTextureHWID(textures[i]);
265 }
266
267 crStateDeleteTextures(n, textures);
268 cr_server.head_spu->dispatch_table.DeleteTextures(n, newTextures);
269 crFree(newTextures);
270}
271
272void SERVER_DISPATCH_APIENTRY crServerDispatchPrioritizeTextures( GLsizei n, const GLuint * textures, const GLclampf * priorities )
273{
274 GLuint *newTextures = (GLuint *) crAlloc(n * sizeof(GLuint));
275 GLint i;
276
277 if (!newTextures)
278 {
279 crError("crServerDispatchDeleteTextures: out of memory");
280 return;
281 }
282
283 for (i = 0; i < n; i++)
284 {
285 newTextures[i] = crStateGetTextureHWID(textures[i]);
286 }
287
288 crStatePrioritizeTextures(n, textures, priorities);
289 cr_server.head_spu->dispatch_table.PrioritizeTextures(n, newTextures, priorities);
290 crFree(newTextures);
291}
292
293void SERVER_DISPATCH_APIENTRY crServerDispatchDeleteProgramsARB(GLsizei n, const GLuint * programs)
294{
295 GLuint *pLocalProgs = (GLuint *) crAlloc(n * sizeof(GLuint));
296 GLint i;
297 if (!pLocalProgs) {
298 crError("crServerDispatchDeleteProgramsARB: out of memory");
299 return;
300 }
301 for (i = 0; i < n; i++) {
302 pLocalProgs[i] = crServerTranslateProgramID(programs[i]);
303 }
304 crStateDeleteProgramsARB(n, pLocalProgs);
305 cr_server.head_spu->dispatch_table.DeleteProgramsARB(n, pLocalProgs);
306 crFree(pLocalProgs);
307}
308
309/*@todo will fail for textures loaded from snapshot */
310GLboolean SERVER_DISPATCH_APIENTRY crServerDispatchIsTexture( GLuint texture )
311{
312 GLboolean retval;
313 retval = cr_server.head_spu->dispatch_table.IsTexture(crStateGetTextureHWID(texture));
314 crServerReturnValue( &retval, sizeof(retval) );
315 return retval; /* WILL PROBABLY BE IGNORED */
316}
317
318/*@todo will fail for progs loaded from snapshot */
319GLboolean SERVER_DISPATCH_APIENTRY crServerDispatchIsProgramARB( GLuint program )
320{
321 GLboolean retval;
322 program = crServerTranslateProgramID(program);
323 retval = cr_server.head_spu->dispatch_table.IsProgramARB( program );
324 crServerReturnValue( &retval, sizeof(retval) );
325 return retval; /* WILL PROBABLY BE IGNORED */
326}
327
328GLboolean SERVER_DISPATCH_APIENTRY
329crServerDispatchAreTexturesResident(GLsizei n, const GLuint *textures,
330 GLboolean *residences)
331{
332 GLboolean retval;
333 GLsizei i;
334 GLboolean *res = (GLboolean *) crAlloc(n * sizeof(GLboolean));
335 GLuint *textures2 = (GLuint *) crAlloc(n * sizeof(GLuint));
336
337 (void) residences;
338
339 for (i = 0; i < n; i++)
340 {
341 textures2[i] = crStateGetTextureHWID(textures[i]);
342 }
343 retval = cr_server.head_spu->dispatch_table.AreTexturesResident(n, textures2, res);
344
345 crFree(textures2);
346
347 crServerReturnValue(res, n * sizeof(GLboolean));
348
349 crFree(res);
350
351 return retval; /* WILL PROBABLY BE IGNORED */
352}
353
354
355GLboolean SERVER_DISPATCH_APIENTRY
356crServerDispatchAreProgramsResidentNV(GLsizei n, const GLuint *programs,
357 GLboolean *residences)
358{
359 GLboolean retval;
360 GLboolean *res = (GLboolean *) crAlloc(n * sizeof(GLboolean));
361 GLsizei i;
362
363 (void) residences;
364
365 if (!cr_server.sharedTextureObjects) {
366 GLuint *programs2 = (GLuint *) crAlloc(n * sizeof(GLuint));
367 for (i = 0; i < n; i++)
368 programs2[i] = crServerTranslateProgramID(programs[i]);
369 retval = cr_server.head_spu->dispatch_table.AreProgramsResidentNV(n, programs2, res);
370 crFree(programs2);
371 }
372 else {
373 retval = cr_server.head_spu->dispatch_table.AreProgramsResidentNV(n, programs, res);
374 }
375
376 crServerReturnValue(res, n * sizeof(GLboolean));
377 crFree(res);
378
379 return retval; /* WILL PROBABLY BE IGNORED */
380}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette