VirtualBox

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

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

WDDM/3D: fix windows expirience index crashed on win7 with ati cards

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.5 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
128 /*Make sure we process commands in order they should appear, so flush thread being injected first*/
129 for (i=0; i<MAX_THREADS; ++i)
130 {
131 if (pack_spu.thread[i].inUse
132 && (thread != &pack_spu.thread[i]) && pack_spu.thread[i].netServer.conn
133 && (pack_spu.thread[i].netServer.conn->u32ClientID == thread->netServer.conn->u32InjectClientID)
134 && pack_spu.thread[i].packer && pack_spu.thread[i].packer->currentBuffer)
135 {
136 packspuFlush((void *) &pack_spu.thread[i]);
137 break;
138 }
139 }
140
141 if (i>=MAX_THREADS)
142 {
143 /*Thread we're supposed to inject commands for has been detached,
144 so there's nothing to sync with and we should just pass commands through our own connection.
145 */
146 thread->netServer.conn->u32InjectClientID=0;
147 }
148
149 crUnlockMutex(&_PackMutex);
150
151 packspuFlush((void *) thread);
152 }
153}
154
155GLint PACKSPU_APIENTRY packspu_WindowCreate( const char *dpyName, GLint visBits )
156{
157 GET_THREAD(thread);
158 static int num_calls = 0;
159 int writeback = pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
160 GLint return_val = (GLint) 0;
161
162 if (!thread) {
163 thread = packspuNewThread( crThreadID() );
164 }
165 CRASSERT(thread);
166 CRASSERT(thread->packer);
167
168 crPackSetContext(thread->packer);
169
170 if (pack_spu.swap)
171 {
172 crPackWindowCreateSWAP( dpyName, visBits, &return_val, &writeback );
173 }
174 else
175 {
176 crPackWindowCreate( dpyName, visBits, &return_val, &writeback );
177 }
178 packspuFlush(thread);
179 if (!(thread->netServer.conn->actual_network))
180 {
181 return num_calls++;
182 }
183 else
184 {
185 while (writeback)
186 crNetRecv();
187 if (pack_spu.swap)
188 {
189 return_val = (GLint) SWAP32(return_val);
190 }
191 return return_val;
192 }
193}
194
195
196
197GLboolean PACKSPU_APIENTRY
198packspu_AreTexturesResident( GLsizei n, const GLuint * textures,
199 GLboolean * residences )
200{
201 GET_THREAD(thread);
202 int writeback = 1;
203 GLboolean return_val = GL_TRUE;
204 GLsizei i;
205
206 if (!(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
207 {
208 crError( "packspu_AreTexturesResident doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
209 }
210
211 if (pack_spu.swap)
212 {
213 crPackAreTexturesResidentSWAP( n, textures, residences, &return_val, &writeback );
214 }
215 else
216 {
217 crPackAreTexturesResident( n, textures, residences, &return_val, &writeback );
218 }
219 packspuFlush( (void *) thread );
220
221 while (writeback)
222 crNetRecv();
223
224 /* Since the Chromium packer/unpacker can't return both 'residences'
225 * and the function's return value, compute the return value here.
226 */
227 for (i = 0; i < n; i++) {
228 if (!residences[i]) {
229 return_val = GL_FALSE;
230 break;
231 }
232 }
233
234 return return_val;
235}
236
237
238GLboolean PACKSPU_APIENTRY
239packspu_AreProgramsResidentNV( GLsizei n, const GLuint * ids,
240 GLboolean * residences )
241{
242 GET_THREAD(thread);
243 int writeback = 1;
244 GLboolean return_val = GL_TRUE;
245 GLsizei i;
246
247 if (!(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
248 {
249 crError( "packspu_AreProgramsResidentNV doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
250 }
251 if (pack_spu.swap)
252 {
253 crPackAreProgramsResidentNVSWAP( n, ids, residences, &return_val, &writeback );
254 }
255 else
256 {
257 crPackAreProgramsResidentNV( n, ids, residences, &return_val, &writeback );
258 }
259 packspuFlush( (void *) thread );
260
261 while (writeback)
262 crNetRecv();
263
264 /* Since the Chromium packer/unpacker can't return both 'residences'
265 * and the function's return value, compute the return value here.
266 */
267 for (i = 0; i < n; i++) {
268 if (!residences[i]) {
269 return_val = GL_FALSE;
270 break;
271 }
272 }
273
274 return return_val;
275}
276
277void PACKSPU_APIENTRY packspu_GetPolygonStipple( GLubyte * mask )
278{
279 GET_THREAD(thread);
280 int writeback = 1;
281
282 if (pack_spu.swap)
283 {
284 crPackGetPolygonStippleSWAP( mask, &writeback );
285 }
286 else
287 {
288 crPackGetPolygonStipple( mask, &writeback );
289 }
290
291#ifdef CR_ARB_pixel_buffer_object
292 if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
293#endif
294 {
295 packspuFlush( (void *) thread );
296 while (writeback)
297 crNetRecv();
298 }
299}
300
301void PACKSPU_APIENTRY packspu_GetPixelMapfv( GLenum map, GLfloat * values )
302{
303 GET_THREAD(thread);
304 int writeback = 1;
305
306 if (pack_spu.swap)
307 {
308 crPackGetPixelMapfvSWAP( map, values, &writeback );
309 }
310 else
311 {
312 crPackGetPixelMapfv( map, values, &writeback );
313 }
314
315#ifdef CR_ARB_pixel_buffer_object
316 if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
317#endif
318 {
319 packspuFlush( (void *) thread );
320 while (writeback)
321 crNetRecv();
322 }
323}
324
325void PACKSPU_APIENTRY packspu_GetPixelMapuiv( GLenum map, GLuint * values )
326{
327 GET_THREAD(thread);
328 int writeback = 1;
329
330 if (pack_spu.swap)
331 {
332 crPackGetPixelMapuivSWAP( map, values, &writeback );
333 }
334 else
335 {
336 crPackGetPixelMapuiv( map, values, &writeback );
337 }
338
339#ifdef CR_ARB_pixel_buffer_object
340 if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
341#endif
342 {
343 packspuFlush( (void *) thread );
344 while (writeback)
345 crNetRecv();
346 }
347}
348
349void PACKSPU_APIENTRY packspu_GetPixelMapusv( GLenum map, GLushort * values )
350{
351 GET_THREAD(thread);
352 int writeback = 1;
353
354 if (pack_spu.swap)
355 {
356 crPackGetPixelMapusvSWAP( map, values, &writeback );
357 }
358 else
359 {
360 crPackGetPixelMapusv( map, values, &writeback );
361 }
362
363#ifdef CR_ARB_pixel_buffer_object
364 if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
365#endif
366 {
367 packspuFlush( (void *) thread );
368 while (writeback)
369 crNetRecv();
370 }
371}
372
373void PACKSPU_APIENTRY packspu_ChromiumParameteriCR(GLenum target, GLint value)
374{
375 if (GL_SHARE_CONTEXT_RESOURCES_CR==target)
376 {
377 crStateShareContext(value);
378 }
379 crPackChromiumParameteriCR(target, value);
380}
381
382#ifdef CHROMIUM_THREADSAFE
383void PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(void)
384{
385 crLockMutex(&_PackMutex);
386 {
387 int i;
388 GET_THREAD(thread);
389 CRASSERT(!thread);
390 CRASSERT((pack_spu.numThreads>0) && (pack_spu.numThreads<MAX_THREADS));
391
392 for (i=0; i<MAX_THREADS; ++i)
393 {
394 if (!pack_spu.thread[i].inUse)
395 {
396 thread = &pack_spu.thread[i];
397 break;
398 }
399 }
400 CRASSERT(thread);
401
402 thread->inUse = GL_TRUE;
403 thread->id = crThreadID();
404 thread->currentContext = NULL;
405 thread->bInjectThread = GL_TRUE;
406
407 thread->netServer.name = crStrdup(pack_spu.name);
408 thread->netServer.buffer_size = 64 * 1024;
409
410 crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer));
411 CRASSERT(thread->netServer.conn);
412
413 CRASSERT(thread->packer == NULL);
414 thread->packer = crPackNewContext( pack_spu.swap );
415 CRASSERT(thread->packer);
416 crPackInitBuffer(&(thread->buffer), crNetAlloc(thread->netServer.conn),
417 thread->netServer.conn->buffer_size, thread->netServer.conn->mtu);
418 thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
419
420 crPackSetBuffer( thread->packer, &thread->buffer );
421 crPackFlushFunc( thread->packer, packspuFlush );
422 crPackFlushArg( thread->packer, (void *) thread );
423 crPackSendHugeFunc( thread->packer, packspuHuge );
424 crPackSetContext( thread->packer );
425
426 crSetTSD(&_PackTSD, thread);
427
428 pack_spu.numThreads++;
429 }
430 crUnlockMutex(&_PackMutex);
431}
432
433GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(void)
434{
435 GLuint ret;
436
437 crLockMutex(&_PackMutex);
438 {
439 GET_THREAD(thread);
440 CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM);
441 ret = thread->netServer.conn->u32ClientID;
442 }
443 crUnlockMutex(&_PackMutex);
444
445 return ret;
446}
447
448void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id)
449{
450 crLockMutex(&_PackMutex);
451 {
452 GET_THREAD(thread);
453
454 CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM && thread->bInjectThread);
455 thread->netServer.conn->u32InjectClientID = id;
456 }
457 crUnlockMutex(&_PackMutex);
458}
459
460void PACKSPU_APIENTRY packspu_VBoxPackAttachThread()
461{
462#if 0
463 int i;
464 GET_THREAD(thread);
465
466 for (i=0; i<MAX_THREADS; ++i)
467 {
468 if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i] && thread->id==crThreadID())
469 {
470 crError("2nd attach to same thread");
471 }
472 }
473#endif
474
475 crSetTSD(&_PackTSD, NULL);
476}
477
478void PACKSPU_APIENTRY packspu_VBoxPackDetachThread()
479{
480 int i;
481 GET_THREAD(thread);
482
483 if (thread)
484 {
485 crLockMutex(&_PackMutex);
486
487 for (i=0; i<MAX_THREADS; ++i)
488 {
489 if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i]
490 && thread->id==crThreadID() && thread->netServer.conn)
491 {
492 CRASSERT(pack_spu.numThreads>0);
493
494 packspuFlush((void *) thread);
495
496 if (pack_spu.thread[i].packer)
497 {
498 CR_LOCK_PACKER_CONTEXT(thread->packer);
499 crPackSetContext(NULL);
500 CR_UNLOCK_PACKER_CONTEXT(thread->packer);
501 crPackDeleteContext(pack_spu.thread[i].packer);
502 }
503 crNetFreeConnection(pack_spu.thread[i].netServer.conn);
504
505 pack_spu.numThreads--;
506 /*note can't shift the array here, because other threads have TLS references to array elements*/
507 crMemZero(&pack_spu.thread[i], sizeof(ThreadInfo));
508
509 crSetTSD(&_PackTSD, NULL);
510
511 if (i==pack_spu.idxThreadInUse)
512 {
513 for (i=0; i<MAX_THREADS; ++i)
514 {
515 if (pack_spu.thread[i].inUse)
516 {
517 pack_spu.idxThreadInUse=i;
518 break;
519 }
520 }
521 }
522
523 break;
524 }
525 }
526
527 crUnlockMutex(&_PackMutex);
528 }
529}
530
531#ifdef WINDOWS
532#define WIN32_LEAN_AND_MEAN
533#include <windows.h>
534BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
535{
536 (void) lpvReserved;
537
538 switch (fdwReason)
539 {
540 case DLL_PROCESS_ATTACH:
541 {
542 crInitMutex(&_PackMutex);
543 break;
544 }
545
546 case DLL_PROCESS_DETACH:
547 {
548 crFreeMutex(&_PackMutex);
549 crNetTearDown();
550 break;
551 }
552
553 case DLL_THREAD_ATTACH:
554 {
555 packspu_VBoxPackAttachThread();
556 break;
557 }
558
559 case DLL_THREAD_DETACH:
560 {
561 packspu_VBoxPackDetachThread();
562 break;
563 }
564
565 default:
566 break;
567 }
568
569 return TRUE;
570}
571#endif
572
573#else /*ifdef CHROMIUM_THREADSAFE*/
574void PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(void)
575{
576}
577
578GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(void)
579{
580 return 0;
581}
582
583void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id)
584{
585 (void) id;
586}
587
588void PACKSPU_APIENTRY packspu_VBoxPackAttachThread()
589{
590}
591
592void PACKSPU_APIENTRY packspu_VBoxPackDetachThread()
593{
594}
595#endif /*CHROMIUM_THREADSAFE*/
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