VirtualBox

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

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

crOpenGL,wined3d,wddm: second part of fixing resource leakage, basics for cr commands submission from r0 miniport driver (for r0 visible region reporting, WPF 3D rendering fixes w/o Aero, etc.)

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