VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c@ 34310

Last change on this file since 34310 was 33988, checked in by vboxsync, 14 years ago

crOpenGL/wddm: more multithreading fixes, vista expirience index works now

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.1 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_packfunctions.h"
8#include "packspu.h"
9#include "packspu_proto.h"
10#include "cr_mem.h"
11
12void PACKSPU_APIENTRY packspu_ChromiumParametervCR(GLenum target, GLenum type, GLsizei count, const GLvoid *values)
13{
14
15 CRMessage msg;
16 int len;
17
18 GET_THREAD(thread);
19
20
21 switch(target)
22 {
23 case GL_GATHER_PACK_CR:
24 /* flush the current pack buffer */
25 packspuFlush( (void *) thread );
26
27 /* the connection is thread->server.conn */
28 msg.header.type = CR_MESSAGE_GATHER;
29 msg.gather.offset = 69;
30 len = sizeof(CRMessageGather);
31 crNetSend(thread->netServer.conn, NULL, &msg, len);
32 break;
33
34 default:
35 if (pack_spu.swap)
36 crPackChromiumParametervCRSWAP(target, type, count, values);
37 else
38 crPackChromiumParametervCR(target, type, count, values);
39 }
40
41
42}
43
44GLboolean packspuSyncOnFlushes()
45{
46 GLint buffer;
47
48 /*Seems to still cause issues, always sync for now*/
49 return 1;
50
51 crStateGetIntegerv(GL_DRAW_BUFFER, &buffer);
52 /*Usually buffer==GL_BACK, so put this extra check to simplify boolean eval on runtime*/
53 return (buffer != GL_BACK)
54 && (buffer == GL_FRONT_LEFT
55 || buffer == GL_FRONT_RIGHT
56 || buffer == GL_FRONT
57 || buffer == GL_FRONT_AND_BACK
58 || buffer == GL_LEFT
59 || buffer == GL_RIGHT);
60}
61
62void PACKSPU_APIENTRY packspu_DrawBuffer(GLenum mode)
63{
64 GLboolean hadtoflush;
65
66 hadtoflush = packspuSyncOnFlushes();
67
68 crStateDrawBuffer(mode);
69 crPackDrawBuffer(mode);
70
71 if (hadtoflush && !packspuSyncOnFlushes())
72 packspu_Flush();
73}
74
75void PACKSPU_APIENTRY packspu_Finish( void )
76{
77 GET_THREAD(thread);
78 GLint writeback = pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
79
80 if (pack_spu.swap)
81 {
82 crPackFinishSWAP();
83 }
84 else
85 {
86 crPackFinish();
87 }
88
89 if (packspuSyncOnFlushes())
90 {
91 if (writeback)
92 {
93 if (pack_spu.swap)
94 crPackWritebackSWAP(&writeback);
95 else
96 crPackWriteback(&writeback);
97
98 packspuFlush( (void *) thread );
99
100 while (writeback)
101 crNetRecv();
102 }
103 }
104}
105
106void PACKSPU_APIENTRY packspu_Flush( void )
107{
108 GET_THREAD(thread);
109 int writeback = 1;
110
111 if (!thread->bInjectThread)
112 {
113 crPackFlush();
114 if (packspuSyncOnFlushes())
115 {
116 crPackWriteback(&writeback);
117 packspuFlush( (void *) thread );
118 while (writeback)
119 crNetRecv();
120 }
121 }
122 else
123 {
124 int i;
125
126 crLockMutex(&_PackMutex);
127 /*Make sure we process commands in order they should appear, so flush thread being injected first*/
128 for (i=0; i<MAX_THREADS; ++i)
129 {
130 if (pack_spu.thread[i].inUse
131 && (thread != &pack_spu.thread[i]) && pack_spu.thread[i].netServer.conn
132 && (pack_spu.thread[i].netServer.conn->u32ClientID == thread->netServer.conn->u32InjectClientID)
133 && pack_spu.thread[i].packer && pack_spu.thread[i].packer->currentBuffer)
134 {
135 packspuFlush((void *) &pack_spu.thread[i]);
136 break;
137 }
138 }
139 if (i>=MAX_THREADS)
140 {
141 crWarning("packspu: inject for invalid client id");
142 }
143 crUnlockMutex(&_PackMutex);
144
145 packspuFlush((void *) thread);
146 }
147}
148
149GLint PACKSPU_APIENTRY packspu_WindowCreate( const char *dpyName, GLint visBits )
150{
151 GET_THREAD(thread);
152 static int num_calls = 0;
153 int writeback = pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
154 GLint return_val = (GLint) 0;
155
156 if (!thread) {
157 thread = packspuNewThread( crThreadID() );
158 }
159 CRASSERT(thread);
160 CRASSERT(thread->packer);
161
162 crPackSetContext(thread->packer);
163
164 if (pack_spu.swap)
165 {
166 crPackWindowCreateSWAP( dpyName, visBits, &return_val, &writeback );
167 }
168 else
169 {
170 crPackWindowCreate( dpyName, visBits, &return_val, &writeback );
171 }
172 packspuFlush(thread);
173 if (!(thread->netServer.conn->actual_network))
174 {
175 return num_calls++;
176 }
177 else
178 {
179 while (writeback)
180 crNetRecv();
181 if (pack_spu.swap)
182 {
183 return_val = (GLint) SWAP32(return_val);
184 }
185 return return_val;
186 }
187}
188
189
190
191GLboolean PACKSPU_APIENTRY
192packspu_AreTexturesResident( GLsizei n, const GLuint * textures,
193 GLboolean * residences )
194{
195 GET_THREAD(thread);
196 int writeback = 1;
197 GLboolean return_val = GL_TRUE;
198 GLsizei i;
199
200 if (!(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
201 {
202 crError( "packspu_AreTexturesResident doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
203 }
204
205 if (pack_spu.swap)
206 {
207 crPackAreTexturesResidentSWAP( n, textures, residences, &return_val, &writeback );
208 }
209 else
210 {
211 crPackAreTexturesResident( n, textures, residences, &return_val, &writeback );
212 }
213 packspuFlush( (void *) thread );
214
215 while (writeback)
216 crNetRecv();
217
218 /* Since the Chromium packer/unpacker can't return both 'residences'
219 * and the function's return value, compute the return value here.
220 */
221 for (i = 0; i < n; i++) {
222 if (!residences[i]) {
223 return_val = GL_FALSE;
224 break;
225 }
226 }
227
228 return return_val;
229}
230
231
232GLboolean PACKSPU_APIENTRY
233packspu_AreProgramsResidentNV( GLsizei n, const GLuint * ids,
234 GLboolean * residences )
235{
236 GET_THREAD(thread);
237 int writeback = 1;
238 GLboolean return_val = GL_TRUE;
239 GLsizei i;
240
241 if (!(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
242 {
243 crError( "packspu_AreProgramsResidentNV doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
244 }
245 if (pack_spu.swap)
246 {
247 crPackAreProgramsResidentNVSWAP( n, ids, residences, &return_val, &writeback );
248 }
249 else
250 {
251 crPackAreProgramsResidentNV( n, ids, residences, &return_val, &writeback );
252 }
253 packspuFlush( (void *) thread );
254
255 while (writeback)
256 crNetRecv();
257
258 /* Since the Chromium packer/unpacker can't return both 'residences'
259 * and the function's return value, compute the return value here.
260 */
261 for (i = 0; i < n; i++) {
262 if (!residences[i]) {
263 return_val = GL_FALSE;
264 break;
265 }
266 }
267
268 return return_val;
269}
270
271void PACKSPU_APIENTRY packspu_GetPolygonStipple( GLubyte * mask )
272{
273 GET_THREAD(thread);
274 int writeback = 1;
275
276 if (pack_spu.swap)
277 {
278 crPackGetPolygonStippleSWAP( mask, &writeback );
279 }
280 else
281 {
282 crPackGetPolygonStipple( mask, &writeback );
283 }
284
285#ifdef CR_ARB_pixel_buffer_object
286 if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
287#endif
288 {
289 packspuFlush( (void *) thread );
290 while (writeback)
291 crNetRecv();
292 }
293}
294
295void PACKSPU_APIENTRY packspu_GetPixelMapfv( GLenum map, GLfloat * values )
296{
297 GET_THREAD(thread);
298 int writeback = 1;
299
300 if (pack_spu.swap)
301 {
302 crPackGetPixelMapfvSWAP( map, values, &writeback );
303 }
304 else
305 {
306 crPackGetPixelMapfv( map, values, &writeback );
307 }
308
309#ifdef CR_ARB_pixel_buffer_object
310 if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
311#endif
312 {
313 packspuFlush( (void *) thread );
314 while (writeback)
315 crNetRecv();
316 }
317}
318
319void PACKSPU_APIENTRY packspu_GetPixelMapuiv( GLenum map, GLuint * values )
320{
321 GET_THREAD(thread);
322 int writeback = 1;
323
324 if (pack_spu.swap)
325 {
326 crPackGetPixelMapuivSWAP( map, values, &writeback );
327 }
328 else
329 {
330 crPackGetPixelMapuiv( map, values, &writeback );
331 }
332
333#ifdef CR_ARB_pixel_buffer_object
334 if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
335#endif
336 {
337 packspuFlush( (void *) thread );
338 while (writeback)
339 crNetRecv();
340 }
341}
342
343void PACKSPU_APIENTRY packspu_GetPixelMapusv( GLenum map, GLushort * values )
344{
345 GET_THREAD(thread);
346 int writeback = 1;
347
348 if (pack_spu.swap)
349 {
350 crPackGetPixelMapusvSWAP( map, values, &writeback );
351 }
352 else
353 {
354 crPackGetPixelMapusv( map, values, &writeback );
355 }
356
357#ifdef CR_ARB_pixel_buffer_object
358 if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
359#endif
360 {
361 packspuFlush( (void *) thread );
362 while (writeback)
363 crNetRecv();
364 }
365}
366
367#ifdef CHROMIUM_THREADSAFE
368void PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(void)
369{
370 crLockMutex(&_PackMutex);
371 {
372 int i;
373 GET_THREAD(thread);
374 CRASSERT(!thread);
375 CRASSERT((pack_spu.numThreads>0) && (pack_spu.numThreads<MAX_THREADS));
376
377 for (i=0; i<MAX_THREADS; ++i)
378 {
379 if (!pack_spu.thread[i].inUse)
380 {
381 thread = &pack_spu.thread[i];
382 break;
383 }
384 }
385 CRASSERT(thread);
386
387 thread->inUse = GL_TRUE;
388 thread->id = crThreadID();
389 thread->currentContext = NULL;
390 thread->bInjectThread = GL_TRUE;
391
392 thread->netServer.name = crStrdup(pack_spu.name);
393 thread->netServer.buffer_size = 64 * 1024;
394
395 crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer));
396 CRASSERT(thread->netServer.conn);
397
398 CRASSERT(thread->packer == NULL);
399 thread->packer = crPackNewContext( pack_spu.swap );
400 CRASSERT(thread->packer);
401 crPackInitBuffer(&(thread->buffer), crNetAlloc(thread->netServer.conn),
402 thread->netServer.conn->buffer_size, thread->netServer.conn->mtu);
403 thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
404
405 crPackSetBuffer( thread->packer, &thread->buffer );
406 crPackFlushFunc( thread->packer, packspuFlush );
407 crPackFlushArg( thread->packer, (void *) thread );
408 crPackSendHugeFunc( thread->packer, packspuHuge );
409 crPackSetContext( thread->packer );
410
411 crSetTSD(&_PackTSD, thread);
412
413 pack_spu.numThreads++;
414 }
415 crUnlockMutex(&_PackMutex);
416}
417
418GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(void)
419{
420 GLuint ret;
421
422 crLockMutex(&_PackMutex);
423 {
424 GET_THREAD(thread);
425 CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM);
426 ret = thread->netServer.conn->u32ClientID;
427 }
428 crUnlockMutex(&_PackMutex);
429
430 return ret;
431}
432
433void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id)
434{
435 crLockMutex(&_PackMutex);
436 {
437 GET_THREAD(thread);
438 CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM);
439 thread->netServer.conn->u32InjectClientID = id;
440 }
441 crUnlockMutex(&_PackMutex);
442}
443
444void PACKSPU_APIENTRY packspu_VBoxPackAttachThread()
445{
446#if 0
447 int i;
448 GET_THREAD(thread);
449
450 for (i=0; i<MAX_THREADS; ++i)
451 {
452 if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i] && thread->id==crThreadID())
453 {
454 crError("2nd attach to same thread");
455 }
456 }
457#endif
458
459 crSetTSD(&_PackTSD, NULL);
460}
461
462void PACKSPU_APIENTRY packspu_VBoxPackDetachThread()
463{
464 int i;
465 GET_THREAD(thread);
466
467 if (thread)
468 {
469 crLockMutex(&_PackMutex);
470
471 for (i=0; i<MAX_THREADS; ++i)
472 {
473 if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i]
474 && thread->id==crThreadID() && thread->netServer.conn)
475 {
476 CRASSERT(pack_spu.numThreads>0);
477
478 packspuFlush((void *) thread);
479
480 if (pack_spu.thread[i].packer)
481 {
482 CR_LOCK_PACKER_CONTEXT(thread->packer);
483 crPackSetContext(NULL);
484 CR_UNLOCK_PACKER_CONTEXT(thread->packer);
485 crPackDeleteContext(pack_spu.thread[i].packer);
486 }
487 crNetFreeConnection(pack_spu.thread[i].netServer.conn);
488
489 pack_spu.numThreads--;
490 /*note can't shift the array here, because other threads have TLS references to array elements*/
491 crMemZero(&pack_spu.thread[i], sizeof(ThreadInfo));
492
493 crSetTSD(&_PackTSD, NULL);
494
495 if (i==pack_spu.idxThreadInUse)
496 {
497 for (i=0; i<MAX_THREADS; ++i)
498 {
499 if (pack_spu.thread[i].inUse)
500 {
501 pack_spu.idxThreadInUse=i;
502 break;
503 }
504 }
505 }
506
507 break;
508 }
509 }
510
511 crUnlockMutex(&_PackMutex);
512 }
513}
514
515#ifdef WINDOWS
516#define WIN32_LEAN_AND_MEAN
517#include <windows.h>
518BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
519{
520 (void) lpvReserved;
521
522 switch (fdwReason)
523 {
524 case DLL_PROCESS_ATTACH:
525 {
526 crInitMutex(&_PackMutex);
527 break;
528 }
529
530 case DLL_PROCESS_DETACH:
531 {
532 crFreeMutex(&_PackMutex);
533 break;
534 }
535
536 case DLL_THREAD_ATTACH:
537 {
538 packspu_VBoxPackAttachThread();
539 break;
540 }
541
542 case DLL_THREAD_DETACH:
543 {
544 packspu_VBoxPackDetachThread();
545 break;
546 }
547
548 default:
549 break;
550 }
551
552 return TRUE;
553}
554#endif
555
556#else /*ifdef CHROMIUM_THREADSAFE*/
557void PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(void)
558{
559}
560
561GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(void)
562{
563 return 0;
564}
565
566void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id)
567{
568 (void) id;
569}
570
571void PACKSPU_APIENTRY packspu_VBoxPackAttachThread()
572{
573}
574
575void PACKSPU_APIENTRY packspu_VBoxPackDetachThread()
576{
577}
578#endif /*CHROMIUM_THREADSAFE*/
Note: See TracBrowser for help on using the repository browser.

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