VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/glx.c@ 51490

最後變更 在這個檔案從51490是 49308,由 vboxsync 提交於 11 年 前

crOpenGL 24bpp depth

  • 屬性 svn:eol-style 設為 native
檔案大小: 82.9 KB
 
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/* opengl_stub/glx.c */
8#include "chromium.h"
9#include "cr_error.h"
10#include "cr_spu.h"
11#include "cr_mem.h"
12#include "cr_string.h"
13#include "stub.h"
14#include "dri_glx.h"
15#include "GL/internal/glcore.h"
16#include "cr_glstate.h"
17
18#include <X11/Xregion.h>
19
20//#define VBOX_NO_NATIVEGL
21
22/* Force full pixmap update if there're more damaged regions than this number*/
23#define CR_MAX_DAMAGE_REGIONS_TRACKED 50
24
25/* Force "bigger" update (full or clip) if it's reducing number of regions updated
26 * but doesn't increase updated area more than given number
27 */
28#define CR_MIN_DAMAGE_PROFIT_SIZE 64*64
29
30/*@todo combine it in some other place*/
31/* Size of pack spu buffer - some delta for commands packing, see pack/packspu_config.c*/
32
33/** Ramshankar: Solaris compiz fix */
34#ifdef RT_OS_SOLARIS
35# define CR_MAX_TRANSFER_SIZE 20*1024*1024
36#else
37# define CR_MAX_TRANSFER_SIZE 4*1024*1024
38#endif
39
40/** For optimizing glXMakeCurrent */
41static Display *currentDisplay = NULL;
42static GLXDrawable currentDrawable = 0;
43static GLXDrawable currentReadDrawable = 0;
44
45/**
46 * Keep a list of structures which associates X visual IDs with
47 * Chromium visual bitmasks.
48 */
49struct VisualInfo {
50 Display *dpy;
51 int screen;
52 VisualID visualid;
53 int visBits;
54 struct VisualInfo *next;
55};
56
57static struct VisualInfo *VisualInfoList = NULL;
58
59static void stubXshmUpdateImageRect(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap, XRectangle *pRect);
60static void stubQueryXDamageExtension(Display *dpy, ContextInfo *pContext);
61
62static void
63AddVisualInfo(Display *dpy, int screen, VisualID visualid, int visBits)
64{
65 struct VisualInfo *v;
66 for (v = VisualInfoList; v; v = v->next) {
67 if (v->dpy == dpy && v->screen == screen && v->visualid == visualid) {
68 v->visBits |= visBits;
69 return;
70 }
71 }
72 v = (struct VisualInfo *) crAlloc(sizeof(struct VisualInfo));
73 v->dpy = dpy;
74 v->screen = screen;
75 v->visualid = visualid;
76 v->visBits = visBits;
77 v->next = VisualInfoList;
78 VisualInfoList = v;
79}
80
81static struct VisualInfo *
82FindVisualInfo(Display *dpy, int screen, VisualID visualid)
83{
84 struct VisualInfo *v;
85 for (v = VisualInfoList; v; v = v->next) {
86 if (v->dpy == dpy && v->screen == screen && v->visualid == visualid)
87 return v;
88 }
89 return NULL;
90}
91
92/**
93 * Return string for a GLX error code
94 */
95static const char *glx_error_string(int err)
96{
97 static const char *glxErrors[] = {
98 "none",
99 "GLX_BAD_SCREEN",
100 "GLX_BAD_ATTRIBUTE",
101 "GLX_NO_EXTENSION",
102 "GLX_BAD_VISUAL",
103 "GLX_BAD_CONTEXT",
104 "GLX_BAD_VALUE",
105 "GLX_BAD_ENUM"
106 };
107 if (err > 0 && err < 8) {
108 return glxErrors[err];
109 }
110 else {
111 static char tmp[100];
112 sprintf(tmp, "0x%x", err);
113 return tmp;
114 }
115}
116
117/* Given an XVisualInfo structure, try to figure out what its
118 * OpenGL capabilities are, if we have a native OpenGL.
119 * Returns 0 if no information is available.
120 */
121static struct {
122 int gl_attrib;
123 char *attrib_name;
124 enum {TEST_TRUE, TEST_GREATER_0} test;
125 int match_vis_bits;
126} attrib_map[] = {
127 {GLX_RGBA, "GLX_RGBA", TEST_TRUE, CR_RGB_BIT},
128 {GLX_DOUBLEBUFFER, "GLX_DOUBLEBUFFER", TEST_TRUE, CR_DOUBLE_BIT},
129 {GLX_STEREO, "GLX_STEREO", TEST_TRUE, CR_STEREO_BIT},
130 {GLX_LEVEL, "GLX_LEVEL", TEST_GREATER_0, CR_OVERLAY_BIT},
131 {GLX_ALPHA_SIZE, "GLX_ALPHA_SIZE", TEST_GREATER_0, CR_ALPHA_BIT},
132 {GLX_DEPTH_SIZE, "GLX_DEPTH_SIZE", TEST_GREATER_0, CR_DEPTH_BIT},
133 {GLX_STENCIL_SIZE, "GLX_STENCIL_SIZE", TEST_GREATER_0, CR_STENCIL_BIT},
134 {GLX_ACCUM_RED_SIZE, "GLX_ACCUM_RED_SIZE", TEST_GREATER_0, CR_ACCUM_BIT},
135 {GLX_SAMPLE_BUFFERS_SGIS, "GLX_SAMPLE_BUFFERS_SGIS", TEST_GREATER_0, CR_MULTISAMPLE_BIT},
136};
137#ifndef VBOX_NO_NATIVEGL /* Currently not used */
138static int QueryVisBits(Display *dpy, XVisualInfo *vis)
139{
140 int visBits = 0;
141 int foo, bar, return_val, value;
142 unsigned int i;
143
144 /* We can only query the OpenGL capabilities if we actually
145 * have a native OpenGL underneath us. Without it, we can't
146 * get at all the actual OpenGL characteristics.
147 */
148 if (!stub.haveNativeOpenGL) return 0;
149
150 if (!stub.wsInterface.glXQueryExtension(dpy, &foo, &bar)) return 0;
151
152 /* If we don't have the GLX_USE_GL attribute, we've failed. */
153 return_val = stub.wsInterface.glXGetConfig(dpy, vis, GLX_USE_GL, &value);
154 if (return_val) {
155 crDebug("native glXGetConfig returned %d (%s) at %s line %d",
156 return_val, glx_error_string(return_val), __FILE__, __LINE__);
157 return 0;
158 }
159 if (value == 0) {
160 crDebug("visual ID 0x%x doesn't support OpenGL at %s line %d",
161 (int) vis->visual->visualid, __FILE__, __LINE__);
162 return 0;
163 }
164
165 for (i = 0; i < sizeof(attrib_map)/sizeof(attrib_map[0]); i++) {
166 return_val = stub.wsInterface.glXGetConfig(dpy, vis, attrib_map[i].gl_attrib, &value);
167 if (return_val) {
168 crDebug("native glXGetConfig(%s) returned %d (%s) at %s line %d",
169 attrib_map[i].attrib_name, return_val, glx_error_string(return_val), __FILE__, __LINE__);
170 return 0;
171 }
172
173 switch(attrib_map[i].test) {
174 case TEST_TRUE:
175 if (value)
176 visBits |= attrib_map[i].match_vis_bits;
177 break;
178
179 case TEST_GREATER_0:
180 if (value > 0)
181 visBits |= attrib_map[i].match_vis_bits;
182 break;
183
184 default:
185 crWarning("illegal attribute map test for %s at %s line %d",
186 attrib_map[i].attrib_name, __FILE__, __LINE__);
187 return 0;
188 }
189 }
190
191 return visBits;
192}
193#endif /* not 0 */
194
195
196
197#ifndef VBOX_NO_NATIVEGL /* Old code */
198DECLEXPORT(XVisualInfo *)
199VBOXGLXTAG(glXChooseVisual)( Display *dpy, int screen, int *attribList )
200{
201 XVisualInfo *vis;
202 int *attrib;
203 int visBits = 0;
204
205 stubInit();
206
207 for (attrib = attribList; *attrib != None; attrib++)
208 {
209 switch (*attrib)
210 {
211 case GLX_USE_GL:
212 /* ignored, this is mandatory */
213 break;
214
215 case GLX_BUFFER_SIZE:
216 /* this is for color-index visuals, which we don't support */
217 attrib++;
218 break;
219
220 case GLX_LEVEL:
221 if (attrib[1] > 0)
222 visBits |= CR_OVERLAY_BIT;
223 attrib++;
224 break;
225
226 case GLX_RGBA:
227 visBits |= CR_RGB_BIT;
228 break;
229
230 case GLX_DOUBLEBUFFER:
231 visBits |= CR_DOUBLE_BIT;
232 break;
233
234 case GLX_STEREO:
235 visBits |= CR_STEREO_BIT;
236 /*
237 crWarning( "glXChooseVisual: stereo unsupported" );
238 return NULL;
239 */
240 break;
241
242 case GLX_AUX_BUFFERS:
243 {
244 int aux_buffers = attrib[1];
245 if (aux_buffers != 0)
246 {
247 crWarning("glXChooseVisual: aux_buffers=%d unsupported",
248 aux_buffers);
249 return NULL;
250 }
251 }
252 attrib++;
253 break;
254
255 case GLX_RED_SIZE:
256 case GLX_GREEN_SIZE:
257 case GLX_BLUE_SIZE:
258 if (attrib[1] > 0)
259 visBits |= CR_RGB_BIT;
260 attrib++;
261 break;
262
263 case GLX_ALPHA_SIZE:
264 if (attrib[1] > 0)
265 visBits |= CR_ALPHA_BIT;
266 attrib++;
267 break;
268
269 case GLX_DEPTH_SIZE:
270 if (attrib[1] > 0)
271 visBits |= CR_DEPTH_BIT;
272 attrib++;
273 break;
274
275 case GLX_STENCIL_SIZE:
276 if (attrib[1] > 0)
277 visBits |= CR_STENCIL_BIT;
278 attrib++;
279 break;
280
281 case GLX_ACCUM_RED_SIZE:
282 case GLX_ACCUM_GREEN_SIZE:
283 case GLX_ACCUM_BLUE_SIZE:
284 case GLX_ACCUM_ALPHA_SIZE:
285 if (attrib[1] > 0)
286 visBits |= CR_ACCUM_BIT;
287 attrib++;
288 break;
289
290 case GLX_SAMPLE_BUFFERS_SGIS: /* aka GLX_SAMPLES_ARB */
291 if (attrib[1] > 0)
292 visBits |= CR_MULTISAMPLE_BIT;
293 attrib++;
294 break;
295 case GLX_SAMPLES_SGIS: /* aka GLX_SAMPLES_ARB */
296 /* just ignore value for now, we'll try to get 4 samples/pixel */
297 if (attrib[1] > 4)
298 return NULL;
299 visBits |= CR_MULTISAMPLE_BIT;
300 attrib++;
301 break;
302
303#ifdef GLX_VERSION_1_3
304 case GLX_X_VISUAL_TYPE:
305 case GLX_TRANSPARENT_TYPE_EXT:
306 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
307 case GLX_TRANSPARENT_RED_VALUE_EXT:
308 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
309 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
310 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
311 /* ignore */
312 crWarning("glXChooseVisual: ignoring attribute 0x%x", *attrib);
313 attrib++;
314 break;
315#endif
316
317 default:
318 crWarning( "glXChooseVisual: bad attrib=0x%x", *attrib );
319 return NULL;
320 }
321 }
322
323 if ((visBits & CR_RGB_BIT) == 0 && (visBits & CR_OVERLAY_BIT) == 0)
324 {
325 /* normal layer, color index mode not supported */
326 crWarning( "glXChooseVisual: didn't request RGB visual?" );
327 return NULL;
328 }
329
330 vis = crChooseVisual(&stub.wsInterface, dpy, screen, GL_FALSE, visBits);
331 if (!vis && (visBits & CR_STEREO_BIT)) {
332 /* try non-stereo */
333 visBits &= ~CR_STEREO_BIT;
334 vis = crChooseVisual(&stub.wsInterface, dpy, screen, GL_FALSE, visBits);
335 }
336
337 if (vis) {
338 AddVisualInfo(dpy, screen, vis->visual->visualid, visBits);
339 }
340 return vis;
341}
342#else /* not 0 */
343DECLEXPORT(XVisualInfo *)
344VBOXGLXTAG(glXChooseVisual)( Display *dpy, int screen, int *attribList )
345{
346 bool useRGBA = false;
347 int *attrib;
348 XVisualInfo searchvis, *pret;
349 int nvisuals;
350 stubInit();
351
352 for (attrib = attribList; *attrib != None; attrib++)
353 {
354 switch (*attrib)
355 {
356 case GLX_USE_GL:
357 /* ignored, this is mandatory */
358 break;
359
360 case GLX_BUFFER_SIZE:
361 /* this is for color-index visuals, which we don't support */
362 attrib++;
363 break;
364
365 case GLX_LEVEL:
366 if (attrib[1] != 0)
367 goto err_exit;
368 attrib++;
369 break;
370
371 case GLX_RGBA:
372 useRGBA = true;
373 break;
374
375 case GLX_STEREO:
376 goto err_exit;
377 /*
378 crWarning( "glXChooseVisual: stereo unsupported" );
379 return NULL;
380 */
381 break;
382
383 case GLX_AUX_BUFFERS:
384 if (attrib[1] != 0)
385 goto err_exit;
386 attrib++;
387 break;
388
389 case GLX_RED_SIZE:
390 case GLX_GREEN_SIZE:
391 case GLX_BLUE_SIZE:
392 if (attrib[1] > 8)
393 goto err_exit;
394 attrib++;
395 break;
396
397 case GLX_ALPHA_SIZE:
398 if (attrib[1] > 8)
399 goto err_exit;
400 attrib++;
401 break;
402
403 case GLX_DEPTH_SIZE:
404 if (attrib[1] > 24)
405 goto err_exit;
406 attrib++;
407 break;
408
409 case GLX_STENCIL_SIZE:
410 if (attrib[1] > 8)
411 goto err_exit;
412 attrib++;
413 break;
414
415 case GLX_ACCUM_RED_SIZE:
416 case GLX_ACCUM_GREEN_SIZE:
417 case GLX_ACCUM_BLUE_SIZE:
418 case GLX_ACCUM_ALPHA_SIZE:
419 if (attrib[1] > 16)
420 goto err_exit;
421 attrib++;
422 break;
423
424 case GLX_SAMPLE_BUFFERS_SGIS: /* aka GLX_SAMPLES_ARB */
425 if (attrib[1] > 0)
426 goto err_exit;
427 attrib++;
428 break;
429 case GLX_SAMPLES_SGIS: /* aka GLX_SAMPLES_ARB */
430 if (attrib[1] > 0)
431 goto err_exit;
432 attrib++;
433 break;
434
435 case GLX_DOUBLEBUFFER: /* @todo, check if we support it */
436 break;
437
438#ifdef GLX_VERSION_1_3
439 case GLX_X_VISUAL_TYPE:
440 case GLX_TRANSPARENT_TYPE_EXT:
441 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
442 case GLX_TRANSPARENT_RED_VALUE_EXT:
443 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
444 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
445 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
446 /* ignore */
447 crWarning("glXChooseVisual: ignoring attribute 0x%x", *attrib);
448 attrib++;
449 break;
450#endif
451
452 default:
453 crWarning( "glXChooseVisual: bad attrib=0x%x, ignoring", *attrib );
454 attrib++;
455 //return NULL;
456 }
457 }
458
459 if (!useRGBA)
460 return NULL;
461
462 XLOCK(dpy);
463 searchvis.visualid = XVisualIDFromVisual(DefaultVisual(dpy, screen));
464 pret = XGetVisualInfo(dpy, VisualIDMask, &searchvis, &nvisuals);
465 XUNLOCK(dpy);
466
467 if (nvisuals!=1) crWarning("glXChooseVisual: XGetVisualInfo returned %i visuals for %x", nvisuals, (unsigned int) searchvis.visualid);
468 if (pret)
469 crDebug("glXChooseVisual returned %x depth=%i", (unsigned int)pret->visualid, pret->depth);
470 return pret;
471
472err_exit:
473 crDebug("glXChooseVisual returning NULL, due to attrib=0x%x, next=0x%x", attrib[0], attrib[1]);
474 return NULL;
475}
476#endif
477
478/**
479 ** There is a problem with glXCopyContext.
480 ** IRIX and Mesa both define glXCopyContext
481 ** to have the mask argument being a
482 ** GLuint. XFree 4 and oss.sgi.com
483 ** define it to be an unsigned long.
484 ** Solution: We don't support
485 ** glXCopyContext anyway so we'll just
486 ** #ifdef out the code.
487 */
488DECLEXPORT(void)
489VBOXGLXTAG(glXCopyContext)( Display *dpy, GLXContext src, GLXContext dst,
490#if defined(AIX) || defined(PLAYSTATION2)
491GLuint mask )
492#elif defined(SunOS)
493unsigned long mask )
494#else
495unsigned long mask )
496#endif
497{
498 (void) dpy;
499 (void) src;
500 (void) dst;
501 (void) mask;
502 crWarning( "Unsupported GLX Call: glXCopyContext()" );
503}
504
505
506/**
507 * Get the display string for the given display pointer.
508 * Never return just ":0.0". In that case, prefix with our host name.
509 */
510static void
511stubGetDisplayString( Display *dpy, char *nameResult, int maxResult )
512{
513 const char *dpyName = DisplayString(dpy);
514 char host[1000];
515#ifndef VBOX_NO_NATIVEGL
516 if (dpyName[0] == ':')
517 {
518 crGetHostname(host, 1000);
519 }
520 else
521#endif
522 {
523 host[0] = 0;
524 }
525 if (crStrlen(host) + crStrlen(dpyName) >= maxResult - 1)
526 {
527 /* return null string */
528 crWarning("Very long host / display name string in stubDisplayString!");
529 nameResult[0] = 0;
530 }
531 else
532 {
533 /* return host concatenated with dpyName */
534 crStrcpy(nameResult, host);
535 crStrcat(nameResult, dpyName);
536 }
537}
538
539
540
541DECLEXPORT(GLXContext)
542VBOXGLXTAG(glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext share, Bool direct)
543{
544 char dpyName[MAX_DPY_NAME];
545 ContextInfo *context;
546 int visBits = CR_RGB_BIT | CR_DOUBLE_BIT | CR_DEPTH_BIT; /* default vis */
547 int i, numExt;
548
549 stubInit();
550
551 CRASSERT(stub.contextTable);
552
553 /*
554 {
555 char **list;
556
557 list = XListExtensions(dpy, &numExt);
558 crDebug("X extensions [%i]:", numExt);
559 for (i=0; i<numExt; ++i)
560 {
561 crDebug("%s", list[i]);
562 }
563 XFreeExtensionList(list);
564 }
565 */
566
567 stubGetDisplayString(dpy, dpyName, MAX_DPY_NAME);
568#ifndef VBOX_NO_NATIVEGL /* We only care about the host capabilities, not the guest. */
569 if (stub.haveNativeOpenGL) {
570 int foo, bar;
571 if (stub.wsInterface.glXQueryExtension(dpy, &foo, &bar)) {
572 /* If we have real GLX, compute the Chromium visual bitmask now.
573 * otherwise, we'll use the default desiredVisual bitmask.
574 */
575 struct VisualInfo *v = FindVisualInfo(dpy, DefaultScreen(dpy),
576 vis->visual->visualid);
577 if (v) {
578 visBits = v->visBits;
579 /*crDebug("%s visBits=0x%x", __FUNCTION__, visBits);*/
580 }
581 else {
582 /* For some reason, we haven't tested this visual
583 * before. This could be because the visual was found
584 * through a different display connection to the same
585 * display (as happens in GeoProbe), or through a
586 * connection to an external daemon that queries
587 * visuals. If we can query it directly, we can still
588 * find the proper visBits.
589 */
590 int newVisBits = QueryVisBits(dpy, vis);
591 if (newVisBits > 0) {
592 AddVisualInfo(dpy, DefaultScreen(dpy), vis->visual->visualid, newVisBits);
593 crDebug("Application used unexpected but queryable visual id 0x%x", (int) vis->visual->visualid);
594 visBits = newVisBits;
595 }
596 else {
597 crWarning("Application used unexpected and unqueryable visual id 0x%x; using default visbits", (int) vis->visual->visualid);
598 }
599 }
600
601 /*crDebug("ComputeVisBits(0x%x) = 0x%x", (int)vis->visual->visualid, visBits);*/
602 if (stub.force_pbuffers) {
603 crDebug("App faker: Forcing use of Pbuffers");
604 visBits |= CR_PBUFFER_BIT;
605 }
606
607 if (!v) {
608 AddVisualInfo(dpy, DefaultScreen(dpy),
609 vis->visual->visualid, visBits);
610 }
611
612 }
613 }
614 else {
615 crDebug("No native OpenGL; cannot compute visbits");
616 }
617#endif
618
619 context = stubNewContext(dpyName, visBits, UNDECIDED, (unsigned long) share);
620 if (!context)
621 return 0;
622
623 context->dpy = dpy;
624 context->visual = vis;
625 context->direct = direct;
626
627 stubQueryXDamageExtension(dpy, context);
628
629 return (GLXContext) context->id;
630}
631
632
633DECLEXPORT(void) VBOXGLXTAG(glXDestroyContext)( Display *dpy, GLXContext ctx )
634{
635 (void) dpy;
636 stubDestroyContext( (unsigned long) ctx );
637}
638
639typedef struct _stubFindPixmapParms_t {
640 ContextInfo *pCtx;
641 GLX_Pixmap_t *pGlxPixmap;
642 GLXDrawable draw;
643} stubFindPixmapParms_t;
644
645static void stubFindPixmapCB(unsigned long key, void *data1, void *data2)
646{
647 ContextInfo *pCtx = (ContextInfo *) data1;
648 stubFindPixmapParms_t *pParms = (stubFindPixmapParms_t *) data2;
649 GLX_Pixmap_t *pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(pCtx->pGLXPixmapsHash, (unsigned int) pParms->draw);
650
651 if (pGlxPixmap)
652 {
653 pParms->pCtx = pCtx;
654 pParms->pGlxPixmap = pGlxPixmap;
655 }
656}
657
658DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx )
659{
660 ContextInfo *context;
661 WindowInfo *window;
662 Bool retVal;
663
664 /*crDebug("glXMakeCurrent(%p, 0x%x, 0x%x)", (void *) dpy, (int) drawable, (int) ctx);*/
665
666 /*check if passed drawable is GLXPixmap and not X Window*/
667 if (drawable)
668 {
669 GLX_Pixmap_t *pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) drawable);
670
671 if (!pGlxPixmap)
672 {
673 stubFindPixmapParms_t parms;
674 parms.pGlxPixmap = NULL;
675 parms.draw = drawable;
676 crHashtableWalk(stub.contextTable, stubFindPixmapCB, &parms);
677 pGlxPixmap = parms.pGlxPixmap;
678 }
679
680 if (pGlxPixmap)
681 {
682 /*@todo*/
683 crWarning("Unimplemented glxMakeCurrent call with GLXPixmap passed, unexpected things might happen.");
684 }
685 }
686
687 if (ctx && drawable)
688 {
689 crHashtableLock(stub.windowTable);
690 crHashtableLock(stub.contextTable);
691
692 context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) ctx);
693 window = stubGetWindowInfo(dpy, drawable);
694
695 if (context && context->type == UNDECIDED) {
696 XLOCK(dpy);
697 XSync(dpy, 0); /* sync to force window creation on the server */
698 XUNLOCK(dpy);
699 }
700 }
701 else
702 {
703 dpy = NULL;
704 window = NULL;
705 context = NULL;
706 }
707
708 currentDisplay = dpy;
709 currentDrawable = drawable;
710
711 retVal = stubMakeCurrent(window, context);
712
713 if (ctx && drawable)
714 {
715 crHashtableUnlock(stub.contextTable);
716 crHashtableUnlock(stub.windowTable);
717 }
718
719 return retVal;
720}
721
722
723DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmap)( Display *dpy, XVisualInfo *vis, Pixmap pixmap )
724{
725 stubInit();
726 return VBOXGLXTAG(glXCreatePixmap)(dpy, (GLXFBConfig)vis->visualid, pixmap, NULL);
727}
728
729DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPixmap)( Display *dpy, GLXPixmap pix )
730{
731 VBOXGLXTAG(glXDestroyPixmap)(dpy, pix);
732}
733
734#ifndef VBOX_NO_NATIVEGL /* old code */
735DECLEXPORT(int) VBOXGLXTAG(glXGetConfig)( Display *dpy, XVisualInfo *vis, int attrib, int *value )
736{
737 struct VisualInfo *v;
738 int visBits;
739
740 if (!vis) {
741 /* SGI OpenGL Performer hits this */
742 crWarning("glXGetConfig called with NULL XVisualInfo");
743 return GLX_BAD_VISUAL;
744 }
745
746 v = FindVisualInfo(dpy, DefaultScreen(dpy), vis->visual->visualid);
747 if (v) {
748 visBits = v->visBits;
749 }
750 else {
751 visBits = 0;
752 }
753
754 stubInit();
755
756 /* try to satisfy this request with the native glXGetConfig() */
757 if (stub.haveNativeOpenGL)
758 {
759 int foo, bar;
760 int return_val;
761
762 if (stub.wsInterface.glXQueryExtension(dpy, &foo, &bar))
763 {
764 return_val = stub.wsInterface.glXGetConfig( dpy, vis, attrib, value );
765 if (return_val)
766 {
767 crDebug("faker native glXGetConfig returned %s",
768 glx_error_string(return_val));
769 }
770 return return_val;
771 }
772 }
773
774 /*
775 * If the GLX application chooses its visual via a bunch of calls to
776 * glXGetConfig, instead of by calling glXChooseVisual, we need to keep
777 * track of which attributes are queried to help satisfy context creation
778 * later.
779 */
780 switch ( attrib ) {
781
782 case GLX_USE_GL:
783 *value = 1;
784 break;
785
786 case GLX_BUFFER_SIZE:
787 *value = 32;
788 break;
789
790 case GLX_LEVEL:
791 visBits |= CR_OVERLAY_BIT;
792 *value = (visBits & CR_OVERLAY_BIT) ? 1 : 0;
793 break;
794
795 case GLX_RGBA:
796 visBits |= CR_RGB_BIT;
797 *value = 1;
798 break;
799
800 case GLX_DOUBLEBUFFER:
801 *value = 1;
802 break;
803
804 case GLX_STEREO:
805 *value = 1;
806 break;
807
808 case GLX_AUX_BUFFERS:
809 *value = 0;
810 break;
811
812 case GLX_RED_SIZE:
813 *value = 8;
814 break;
815
816 case GLX_GREEN_SIZE:
817 *value = 8;
818 break;
819
820 case GLX_BLUE_SIZE:
821 *value = 8;
822 break;
823
824 case GLX_ALPHA_SIZE:
825 visBits |= CR_ALPHA_BIT;
826 *value = (visBits & CR_ALPHA_BIT) ? 8 : 0;
827 break;
828
829 case GLX_DEPTH_SIZE:
830 visBits |= CR_DEPTH_BIT;
831 *value = 24;
832 break;
833
834 case GLX_STENCIL_SIZE:
835 visBits |= CR_STENCIL_BIT;
836 *value = 8;
837 break;
838
839 case GLX_ACCUM_RED_SIZE:
840 visBits |= CR_ACCUM_BIT;
841 *value = 16;
842 break;
843
844 case GLX_ACCUM_GREEN_SIZE:
845 visBits |= CR_ACCUM_BIT;
846 *value = 16;
847 break;
848
849 case GLX_ACCUM_BLUE_SIZE:
850 visBits |= CR_ACCUM_BIT;
851 *value = 16;
852 break;
853
854 case GLX_ACCUM_ALPHA_SIZE:
855 visBits |= CR_ACCUM_BIT;
856 *value = 16;
857 break;
858
859 case GLX_SAMPLE_BUFFERS_SGIS:
860 visBits |= CR_MULTISAMPLE_BIT;
861 *value = 0; /* fix someday */
862 break;
863
864 case GLX_SAMPLES_SGIS:
865 visBits |= CR_MULTISAMPLE_BIT;
866 *value = 0; /* fix someday */
867 break;
868
869 case GLX_VISUAL_CAVEAT_EXT:
870 *value = GLX_NONE_EXT;
871 break;
872#if defined(SunOS)
873 /*
874 I don't think this is even a valid attribute for glxGetConfig.
875 No idea why this gets called under SunOS but we simply ignore it
876 -- jw
877 */
878 case GLX_X_VISUAL_TYPE:
879 crWarning ("Ignoring Unsupported GLX Call: glxGetConfig with attrib 0x%x", attrib);
880 break;
881#endif
882
883 case GLX_TRANSPARENT_TYPE:
884 *value = GLX_NONE_EXT;
885 break;
886 case GLX_TRANSPARENT_INDEX_VALUE:
887 *value = 0;
888 break;
889 case GLX_TRANSPARENT_RED_VALUE:
890 *value = 0;
891 break;
892 case GLX_TRANSPARENT_GREEN_VALUE:
893 *value = 0;
894 break;
895 case GLX_TRANSPARENT_BLUE_VALUE:
896 *value = 0;
897 break;
898 case GLX_TRANSPARENT_ALPHA_VALUE:
899 *value = 0;
900 break;
901 default:
902 crWarning( "Unsupported GLX Call: glXGetConfig with attrib 0x%x", attrib );
903 return GLX_BAD_ATTRIBUTE;
904 }
905
906 AddVisualInfo(dpy, DefaultScreen(dpy), vis->visual->visualid, visBits);
907
908 return 0;
909}
910#else /* not 0 */
911DECLEXPORT(int) VBOXGLXTAG(glXGetConfig)( Display *dpy, XVisualInfo *vis, int attrib, int *value )
912{
913 if (!vis) {
914 /* SGI OpenGL Performer hits this */
915 crWarning("glXGetConfig called with NULL XVisualInfo");
916 return GLX_BAD_VISUAL;
917 }
918
919 stubInit();
920
921 *value = 0; /* For sanity */
922
923 switch ( attrib ) {
924
925 case GLX_USE_GL:
926 *value = 1;
927 break;
928
929 case GLX_BUFFER_SIZE:
930 *value = 32;
931 break;
932
933 case GLX_LEVEL:
934 *value = 0; /* for now */
935 break;
936
937 case GLX_RGBA:
938 *value = 1;
939 break;
940
941 case GLX_DOUBLEBUFFER:
942 *value = 1;
943 break;
944
945 case GLX_STEREO:
946 *value = 1;
947 break;
948
949 case GLX_AUX_BUFFERS:
950 *value = 0;
951 break;
952
953 case GLX_RED_SIZE:
954 *value = 8;
955 break;
956
957 case GLX_GREEN_SIZE:
958 *value = 8;
959 break;
960
961 case GLX_BLUE_SIZE:
962 *value = 8;
963 break;
964
965 case GLX_ALPHA_SIZE:
966 *value = 8;
967 break;
968
969 case GLX_DEPTH_SIZE:
970 *value = 24;
971 break;
972
973 case GLX_STENCIL_SIZE:
974 *value = 8;
975 break;
976
977 case GLX_ACCUM_RED_SIZE:
978 *value = 16;
979 break;
980
981 case GLX_ACCUM_GREEN_SIZE:
982 *value = 16;
983 break;
984
985 case GLX_ACCUM_BLUE_SIZE:
986 *value = 16;
987 break;
988
989 case GLX_ACCUM_ALPHA_SIZE:
990 *value = 16;
991 break;
992
993 case GLX_SAMPLE_BUFFERS_SGIS:
994 *value = 0; /* fix someday */
995 break;
996
997 case GLX_SAMPLES_SGIS:
998 *value = 0; /* fix someday */
999 break;
1000
1001 case GLX_VISUAL_CAVEAT_EXT:
1002 *value = GLX_NONE_EXT;
1003 break;
1004#if defined(SunOS) || 1
1005 /*
1006 I don't think this is even a valid attribute for glxGetConfig.
1007 No idea why this gets called under SunOS but we simply ignore it
1008 -- jw
1009 */
1010 case GLX_X_VISUAL_TYPE:
1011 crWarning ("Ignoring Unsupported GLX Call: glxGetConfig with attrib 0x%x", attrib);
1012 break;
1013#endif
1014
1015 case GLX_TRANSPARENT_TYPE:
1016 *value = GLX_NONE_EXT;
1017 break;
1018 case GLX_TRANSPARENT_INDEX_VALUE:
1019 *value = 0;
1020 break;
1021 case GLX_TRANSPARENT_RED_VALUE:
1022 *value = 0;
1023 break;
1024 case GLX_TRANSPARENT_GREEN_VALUE:
1025 *value = 0;
1026 break;
1027 case GLX_TRANSPARENT_BLUE_VALUE:
1028 *value = 0;
1029 break;
1030 case GLX_TRANSPARENT_ALPHA_VALUE:
1031 *value = 0;
1032 break;
1033 case GLX_DRAWABLE_TYPE:
1034 *value = GLX_WINDOW_BIT;
1035 break;
1036 default:
1037 crWarning( "Unsupported GLX Call: glXGetConfig with attrib 0x%x, ignoring...", attrib );
1038 //return GLX_BAD_ATTRIBUTE;
1039 *value = 0;
1040 }
1041
1042 return 0;
1043}
1044#endif
1045
1046DECLEXPORT(GLXContext) VBOXGLXTAG(glXGetCurrentContext)( void )
1047{
1048 ContextInfo *context = stubGetCurrentContext();
1049 if (context)
1050 return (GLXContext) context->id;
1051 else
1052 return (GLXContext) NULL;
1053}
1054
1055DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentDrawable)(void)
1056{
1057 return currentDrawable;
1058}
1059
1060DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplay)(void)
1061{
1062 return currentDisplay;
1063}
1064
1065DECLEXPORT(Bool) VBOXGLXTAG(glXIsDirect)(Display *dpy, GLXContext ctx)
1066{
1067 (void) dpy;
1068 (void) ctx;
1069 crDebug("->glXIsDirect");
1070 return True;
1071}
1072
1073DECLEXPORT(Bool) VBOXGLXTAG(glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase)
1074{
1075 (void) dpy;
1076 (void) errorBase;
1077 (void) eventBase;
1078 return 1; /* You BET we do... */
1079}
1080
1081DECLEXPORT(Bool) VBOXGLXTAG(glXQueryVersion)( Display *dpy, int *major, int *minor )
1082{
1083 (void) dpy;
1084 *major = 1;
1085 *minor = 3;
1086 return 1;
1087}
1088
1089static XErrorHandler oldErrorHandler;
1090static unsigned char lastXError = Success;
1091
1092static int
1093errorHandler (Display *dpy, XErrorEvent *e)
1094{
1095 lastXError = e->error_code;
1096 return 0;
1097}
1098
1099DECLEXPORT(void) VBOXGLXTAG(glXSwapBuffers)( Display *dpy, GLXDrawable drawable )
1100{
1101 WindowInfo *window = stubGetWindowInfo(dpy, drawable);
1102 stubSwapBuffers( window, 0 );
1103
1104#ifdef VBOX_TEST_MEGOO
1105 if (!stub.bXExtensionsChecked)
1106 {
1107 stubCheckXExtensions(window);
1108 }
1109
1110 if (!stub.bHaveXComposite)
1111 {
1112 return;
1113 }
1114
1115 {
1116 Pixmap p;
1117 XWindowAttributes attr;
1118
1119 XLOCK(dpy);
1120 XGetWindowAttributes(dpy, window->drawable, &attr);
1121 if (attr.override_redirect)
1122 {
1123 XUNLOCK(dpy);
1124 return;
1125 }
1126
1127 crLockMutex(&stub.mutex);
1128
1129 XSync(dpy, false);
1130 oldErrorHandler = XSetErrorHandler(errorHandler);
1131 /*@todo this creates new pixmap for window every call*/
1132 /*p = XCompositeNameWindowPixmap(dpy, window->drawable);*/
1133 XSync(dpy, false);
1134 XSetErrorHandler(oldErrorHandler);
1135 XUNLOCK(dpy);
1136
1137 if (lastXError==Success)
1138 {
1139 char *data, *imgdata;
1140 GC gc;
1141 XImage *image;
1142 XVisualInfo searchvis, *pret;
1143 int nvisuals;
1144 XGCValues gcValues;
1145 int i, rowsize;
1146
1147 XLOCK(dpy);
1148
1149 searchvis.visualid = attr.visual->visualid;
1150 pret = XGetVisualInfo(dpy, VisualIDMask, &searchvis, &nvisuals);
1151 if (nvisuals!=1) crWarning("XGetVisualInfo returned %i visuals for %x", nvisuals, (unsigned int) searchvis.visualid);
1152 CRASSERT(pret);
1153
1154 gc = XCreateGC(dpy, window->drawable, 0, &gcValues);
1155 if (!gc) crWarning("Failed to create gc!");
1156
1157 data = crCalloc(window->width * window->height * 4);
1158 imgdata = crCalloc(window->width * window->height * 4);
1159 CRASSERT(data && imgdata);
1160 stub.spu->dispatch_table.ReadPixels(0, 0, window->width, window->height, GL_RGBA, GL_UNSIGNED_BYTE, data);
1161 /*y-invert image*/
1162 rowsize = 4*window->width;
1163 for (i=0; i<window->height; ++i)
1164 {
1165 crMemcpy(imgdata+rowsize*i, data+rowsize*(window->height-i-1), rowsize);
1166 }
1167 crFree(data);
1168
1169 XSync(dpy, false);
1170 image = XCreateImage(dpy, attr.visual, pret->depth, ZPixmap, 0, imgdata, window->width, window->height, 32, 0);
1171 XPutImage(dpy, window->drawable, gc, image, 0, 0, 0, 0, window->width, window->height);
1172
1173 XFree(pret);
1174 /*XFreePixmap(dpy, p);*/
1175 XFreeGC(dpy, gc);
1176 XDestroyImage(image);
1177 XUNLOCK(dpy);
1178 }
1179 lastXError=Success;
1180 crUnlockMutex(&stub.mutex);
1181 }
1182#endif
1183}
1184
1185#ifndef VBOX_NO_NATIVEGL
1186DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)( Font font, int first, int count, int listBase )
1187{
1188 ContextInfo *context = stubGetCurrentContext();
1189 if (context->type == CHROMIUM)
1190 {
1191 Display *dpy = stub.wsInterface.glXGetCurrentDisplay();
1192 if (dpy) {
1193 stubUseXFont( dpy, font, first, count, listBase );
1194 }
1195 else {
1196 dpy = XOpenDisplay(NULL);
1197 if (!dpy)
1198 return;
1199 stubUseXFont( dpy, font, first, count, listBase );
1200 XCloseDisplay(dpy);
1201 }
1202 } else
1203 stub.wsInterface.glXUseXFont( font, first, count, listBase );
1204}
1205#else /* not 0 */
1206DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)( Font font, int first, int count, int listBase )
1207{
1208 ContextInfo *context = stubGetCurrentContext();
1209 Display *dpy = context->dpy;
1210 if (dpy) {
1211 stubUseXFont( dpy, font, first, count, listBase );
1212 }
1213 else {
1214 dpy = XOpenDisplay(NULL);
1215 if (!dpy)
1216 return;
1217 stubUseXFont( dpy, font, first, count, listBase );
1218 XCloseDisplay(dpy);
1219 }
1220}
1221#endif
1222
1223DECLEXPORT(void) VBOXGLXTAG(glXWaitGL)( void )
1224{
1225 static int first_call = 1;
1226
1227 if ( first_call )
1228 {
1229 crDebug( "Ignoring unsupported GLX call: glXWaitGL()" );
1230 first_call = 0;
1231 }
1232}
1233
1234DECLEXPORT(void) VBOXGLXTAG(glXWaitX)( void )
1235{
1236 static int first_call = 1;
1237
1238 if ( first_call )
1239 {
1240 crDebug( "Ignoring unsupported GLX call: glXWaitX()" );
1241 first_call = 0;
1242 }
1243}
1244
1245DECLEXPORT(const char *) VBOXGLXTAG(glXQueryExtensionsString)( Display *dpy, int screen )
1246{
1247 /* XXX maybe also advertise GLX_SGIS_multisample? */
1248
1249 static const char *retval = "GLX_ARB_multisample GLX_EXT_texture_from_pixmap GLX_SGIX_fbconfig GLX_ARB_get_proc_address";
1250
1251 (void) dpy;
1252 (void) screen;
1253
1254 crDebug("->glXQueryExtensionsString");
1255 return retval;
1256}
1257
1258DECLEXPORT(const char *) VBOXGLXTAG(glXGetClientString)( Display *dpy, int name )
1259{
1260 const char *retval;
1261 (void) dpy;
1262 (void) name;
1263
1264 switch ( name ) {
1265
1266 case GLX_VENDOR:
1267 retval = "Chromium";
1268 break;
1269
1270 case GLX_VERSION:
1271 retval = "1.3 Chromium";
1272 break;
1273
1274 case GLX_EXTENSIONS:
1275 /*@todo should be a screen not a name...but it's not used anyway*/
1276 retval = glXQueryExtensionsString(dpy, name);
1277 break;
1278
1279 default:
1280 retval = NULL;
1281 }
1282
1283 return retval;
1284}
1285
1286DECLEXPORT(const char *) VBOXGLXTAG(glXQueryServerString)( Display *dpy, int screen, int name )
1287{
1288 const char *retval;
1289 (void) dpy;
1290 (void) screen;
1291
1292 switch ( name ) {
1293
1294 case GLX_VENDOR:
1295 retval = "Chromium";
1296 break;
1297
1298 case GLX_VERSION:
1299 retval = "1.3 Chromium";
1300 break;
1301
1302 case GLX_EXTENSIONS:
1303 retval = glXQueryExtensionsString(dpy, screen);
1304 break;
1305
1306 default:
1307 retval = NULL;
1308 }
1309
1310 return retval;
1311}
1312
1313DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddressARB)( const GLubyte *name )
1314{
1315 return (CR_GLXFuncPtr) crGetProcAddress( (const char *) name );
1316}
1317
1318DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddress)( const GLubyte *name )
1319{
1320 return (CR_GLXFuncPtr) crGetProcAddress( (const char *) name );
1321}
1322
1323
1324#if GLX_EXTRAS
1325
1326DECLEXPORT(GLXPbufferSGIX)
1327VBOXGLXTAG(glXCreateGLXPbufferSGIX)(Display *dpy, GLXFBConfigSGIX config,
1328 unsigned int width, unsigned int height,
1329 int *attrib_list)
1330{
1331 (void) dpy;
1332 (void) config;
1333 (void) width;
1334 (void) height;
1335 (void) attrib_list;
1336 crWarning("glXCreateGLXPbufferSGIX not implemented by Chromium");
1337 return 0;
1338}
1339
1340DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf)
1341{
1342 (void) dpy;
1343 (void) pbuf;
1344 crWarning("glXDestroyGLXPbufferSGIX not implemented by Chromium");
1345}
1346
1347DECLEXPORT(void) VBOXGLXTAG(glXSelectEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long mask)
1348{
1349 (void) dpy;
1350 (void) drawable;
1351 (void) mask;
1352}
1353
1354DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long *mask)
1355{
1356 (void) dpy;
1357 (void) drawable;
1358 (void) mask;
1359}
1360
1361DECLEXPORT(int) VBOXGLXTAG(glXQueryGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf,
1362 int attribute, unsigned int *value)
1363{
1364 (void) dpy;
1365 (void) pbuf;
1366 (void) attribute;
1367 (void) value;
1368 crWarning("glXQueryGLXPbufferSGIX not implemented by Chromium");
1369 return 0;
1370}
1371
1372DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttribSGIX)(Display *dpy, GLXFBConfig config,
1373 int attribute, int *value)
1374{
1375 return VBOXGLXTAG(glXGetFBConfigAttrib)(dpy, config, attribute, value);
1376}
1377
1378DECLEXPORT(GLXFBConfigSGIX *)
1379VBOXGLXTAG(glXChooseFBConfigSGIX)(Display *dpy, int screen,
1380 int *attrib_list, int *nelements)
1381{
1382 return VBOXGLXTAG(glXChooseFBConfig)(dpy, screen, attrib_list, nelements);
1383}
1384
1385DECLEXPORT(GLXPixmap)
1386VBOXGLXTAG(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy,
1387 GLXFBConfig config,
1388 Pixmap pixmap)
1389{
1390 return VBOXGLXTAG(glXCreatePixmap)(dpy, config, pixmap, NULL);
1391}
1392
1393DECLEXPORT(GLXContext)
1394VBOXGLXTAG(glXCreateContextWithConfigSGIX)(Display *dpy, GLXFBConfig config,
1395 int render_type,
1396 GLXContext share_list,
1397 Bool direct)
1398{
1399 if (render_type!=GLX_RGBA_TYPE_SGIX)
1400 {
1401 crWarning("glXCreateContextWithConfigSGIX: Unsupported render type %i", render_type);
1402 return NULL;
1403 }
1404 else
1405 {
1406 XVisualInfo *vis;
1407 GLXContext ret;
1408
1409 vis = VBOXGLXTAG(glXGetVisualFromFBConfigSGIX)(dpy, config);
1410 if (!vis)
1411 {
1412 crWarning("glXCreateContextWithConfigSGIX: no visuals for %p", config);
1413 return NULL;
1414 }
1415 ret = VBOXGLXTAG(glXCreateContext)(dpy, vis, share_list, direct);
1416 XFree(vis);
1417 return ret;
1418 }
1419}
1420
1421DECLEXPORT(XVisualInfo *)
1422VBOXGLXTAG(glXGetVisualFromFBConfigSGIX)(Display *dpy,
1423 GLXFBConfig config)
1424{
1425 return VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1426}
1427
1428DECLEXPORT(GLXFBConfigSGIX)
1429VBOXGLXTAG(glXGetFBConfigFromVisualSGIX)(Display *dpy, XVisualInfo *vis)
1430{
1431 if (!vis)
1432 {
1433 return NULL;
1434 }
1435 /*Note: Caller is supposed to call XFree on returned value, so can't just return (GLXFBConfig)vis->visualid*/
1436 return (GLXFBConfigSGIX) VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, (GLXFBConfig)vis->visualid);
1437}
1438
1439/*
1440 * GLX 1.3 functions
1441 */
1442DECLEXPORT(GLXFBConfig *)
1443VBOXGLXTAG(glXChooseFBConfig)(Display *dpy, int screen, ATTRIB_TYPE *attrib_list, int *nelements)
1444{
1445 ATTRIB_TYPE *attrib;
1446 intptr_t fbconfig = 0;
1447
1448 stubInit();
1449
1450 if (!attrib_list)
1451 {
1452 return VBOXGLXTAG(glXGetFBConfigs)(dpy, screen, nelements);
1453 }
1454
1455 for (attrib = attrib_list; *attrib != None; attrib++)
1456 {
1457 switch (*attrib)
1458 {
1459 case GLX_FBCONFIG_ID:
1460 fbconfig = attrib[1];
1461 attrib++;
1462 break;
1463
1464 case GLX_BUFFER_SIZE:
1465 /* this is for color-index visuals, which we don't support */
1466 goto err_exit;
1467 attrib++;
1468 break;
1469
1470 case GLX_LEVEL:
1471 if (attrib[1] != 0)
1472 goto err_exit;
1473 attrib++;
1474 break;
1475
1476 case GLX_AUX_BUFFERS:
1477 if (attrib[1] != 0)
1478 goto err_exit;
1479 attrib++;
1480 break;
1481
1482 case GLX_DOUBLEBUFFER: /* @todo, check if we support it */
1483 attrib++;
1484 break;
1485
1486 case GLX_STEREO:
1487 if (attrib[1] != 0)
1488 goto err_exit;
1489 attrib++;
1490 break;
1491
1492 case GLX_RED_SIZE:
1493 case GLX_GREEN_SIZE:
1494 case GLX_BLUE_SIZE:
1495 case GLX_ALPHA_SIZE:
1496 if (attrib[1] > 8)
1497 goto err_exit;
1498 attrib++;
1499 break;
1500
1501 case GLX_DEPTH_SIZE:
1502 if (attrib[1] > 24)
1503 goto err_exit;
1504 attrib++;
1505 break;
1506
1507 case GLX_STENCIL_SIZE:
1508 if (attrib[1] > 8)
1509 goto err_exit;
1510 attrib++;
1511 break;
1512
1513 case GLX_ACCUM_RED_SIZE:
1514 case GLX_ACCUM_GREEN_SIZE:
1515 case GLX_ACCUM_BLUE_SIZE:
1516 case GLX_ACCUM_ALPHA_SIZE:
1517 if (attrib[1] > 16)
1518 goto err_exit;
1519 attrib++;
1520 break;
1521
1522 case GLX_X_RENDERABLE:
1523 case GLX_CONFIG_CAVEAT:
1524 attrib++;
1525 break;
1526
1527 case GLX_RENDER_TYPE:
1528 if (attrib[1]!=GLX_RGBA_BIT)
1529 goto err_exit;
1530 attrib++;
1531 break;
1532
1533 case GLX_DRAWABLE_TYPE:
1534 if ( !(attrib[1] & GLX_WINDOW_BIT)
1535 && !(attrib[1] & GLX_PIXMAP_BIT))
1536 goto err_exit;
1537 attrib++;
1538 break;
1539
1540 case GLX_X_VISUAL_TYPE:
1541 case GLX_TRANSPARENT_TYPE_EXT:
1542 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
1543 case GLX_TRANSPARENT_RED_VALUE_EXT:
1544 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
1545 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
1546 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
1547 /* ignore */
1548 crWarning("glXChooseVisual: ignoring attribute 0x%x", *attrib);
1549 attrib++;
1550 break;
1551
1552 break;
1553 default:
1554 crWarning( "glXChooseVisual: bad attrib=0x%x, ignoring", *attrib );
1555 attrib++;
1556 break;
1557 }
1558 }
1559
1560 if (fbconfig)
1561 {
1562 GLXFBConfig *pGLXFBConfigs;
1563
1564 *nelements = 1;
1565 pGLXFBConfigs = (GLXFBConfig *) crAlloc(*nelements * sizeof(GLXFBConfig));
1566 pGLXFBConfigs[0] = (GLXFBConfig)fbconfig;
1567 return pGLXFBConfigs;
1568 }
1569 else
1570 {
1571 return VBOXGLXTAG(glXGetFBConfigs)(dpy, screen, nelements);
1572 }
1573
1574err_exit:
1575 crWarning("glXChooseFBConfig returning NULL, due to attrib=0x%x, next=0x%x", attrib[0], attrib[1]);
1576 return NULL;
1577}
1578
1579DECLEXPORT(GLXContext)
1580VBOXGLXTAG(glXCreateNewContext)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
1581{
1582 XVisualInfo *vis;
1583
1584 (void) dpy;
1585 (void) config;
1586 (void) render_type;
1587 (void) share_list;
1588 (void) direct;
1589
1590 if (render_type != GLX_RGBA_TYPE)
1591 {
1592 crWarning("glXCreateNewContext, unsupported render_type %x", render_type);
1593 return NULL;
1594 }
1595
1596 vis = VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1597 return VBOXGLXTAG(glXCreateContext)(dpy, vis, share_list, direct);
1598}
1599
1600DECLEXPORT(GLXPbuffer)
1601VBOXGLXTAG(glXCreatePbuffer)(Display *dpy, GLXFBConfig config, ATTRIB_TYPE *attrib_list)
1602{
1603 (void) dpy;
1604 (void) config;
1605 (void) attrib_list;
1606 crWarning("glXCreatePbuffer not implemented by Chromium");
1607 return 0;
1608}
1609
1610/* Note: there're examples where glxpixmaps are created without current context, so can't do much of the work here.
1611 * Instead we'd do necessary initialization on first use of those pixmaps.
1612 */
1613DECLEXPORT(GLXPixmap)
1614VBOXGLXTAG(glXCreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const ATTRIB_TYPE *attrib_list)
1615{
1616 ATTRIB_TYPE *attrib;
1617 XVisualInfo *pVis;
1618 GLX_Pixmap_t *pGlxPixmap;
1619 (void) dpy;
1620 (void) config;
1621
1622#if 0
1623 {
1624 int x, y;
1625 unsigned int w, h;
1626 unsigned int border;
1627 unsigned int depth;
1628 Window root;
1629
1630 crDebug("glXCreatePixmap called for %lu", pixmap);
1631
1632 XLOCK(dpy);
1633 if (!XGetGeometry(dpy, pixmap, &root, &x, &y, &w, &h, &border, &depth))
1634 {
1635 XSync(dpy, False);
1636 if (!XGetGeometry(dpy, pixmap, &root, &x, &y, &w, &h, &border, &depth))
1637 {
1638 crDebug("fail");
1639 }
1640 }
1641 crDebug("root: %lu, [%i,%i %u,%u]", root, x, y, w, h);
1642 XUNLOCK(dpy);
1643 }
1644#endif
1645
1646 pGlxPixmap = crCalloc(sizeof(GLX_Pixmap_t));
1647 if (!pGlxPixmap)
1648 {
1649 crWarning("glXCreatePixmap failed to allocate memory");
1650 return 0;
1651 }
1652
1653 pVis = VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1654 if (!pVis)
1655 {
1656 crWarning("Unknown config %p in glXCreatePixmap", config);
1657 return 0;
1658 }
1659
1660 pGlxPixmap->format = pVis->depth==24 ? GL_RGB:GL_RGBA;
1661 pGlxPixmap->target = GL_TEXTURE_2D;
1662
1663 if (attrib_list)
1664 {
1665 for (attrib = attrib_list; *attrib != None; attrib++)
1666 {
1667 switch (*attrib)
1668 {
1669 case GLX_TEXTURE_FORMAT_EXT:
1670 attrib++;
1671 switch (*attrib)
1672 {
1673 case GLX_TEXTURE_FORMAT_RGBA_EXT:
1674 pGlxPixmap->format = GL_RGBA;
1675 break;
1676 case GLX_TEXTURE_FORMAT_RGB_EXT:
1677 pGlxPixmap->format = GL_RGB;
1678 break;
1679 default:
1680 crDebug("Unexpected GLX_TEXTURE_FORMAT_EXT 0x%x", (unsigned int) *attrib);
1681 }
1682 break;
1683 case GLX_TEXTURE_TARGET_EXT:
1684 attrib++;
1685 switch (*attrib)
1686 {
1687 case GLX_TEXTURE_2D_EXT:
1688 pGlxPixmap->target = GL_TEXTURE_2D;
1689 break;
1690 case GLX_TEXTURE_RECTANGLE_EXT:
1691 pGlxPixmap->target = GL_TEXTURE_RECTANGLE_NV;
1692 break;
1693 default:
1694 crDebug("Unexpected GLX_TEXTURE_TARGET_EXT 0x%x", (unsigned int) *attrib);
1695 }
1696 break;
1697 default: attrib++;
1698 }
1699 }
1700 }
1701
1702 crHashtableAdd(stub.pGLXPixmapsHash, (unsigned int) pixmap, pGlxPixmap);
1703 return (GLXPixmap) pixmap;
1704}
1705
1706DECLEXPORT(GLXWindow)
1707VBOXGLXTAG(glXCreateWindow)(Display *dpy, GLXFBConfig config, Window win, ATTRIB_TYPE *attrib_list)
1708{
1709 GLXFBConfig *realcfg;
1710 int nconfigs;
1711 (void) config;
1712
1713 if (stub.wsInterface.glXGetFBConfigs)
1714 {
1715 realcfg = stub.wsInterface.glXGetFBConfigs(dpy, 0, &nconfigs);
1716 if (!realcfg || nconfigs<1)
1717 {
1718 crWarning("glXCreateWindow !realcfg || nconfigs<1");
1719 return 0;
1720 }
1721 else
1722 {
1723 return stub.wsInterface.glXCreateWindow(dpy, realcfg[0], win, attrib_list);
1724 }
1725 }
1726 else
1727 {
1728 if (attrib_list && *attrib_list!=None)
1729 {
1730 crWarning("Non empty attrib list in glXCreateWindow");
1731 return 0;
1732 }
1733 return (GLXWindow)win;
1734 }
1735}
1736
1737DECLEXPORT(void) VBOXGLXTAG(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf)
1738{
1739 (void) dpy;
1740 (void) pbuf;
1741 crWarning("glXDestroyPbuffer not implemented by Chromium");
1742}
1743
1744DECLEXPORT(void) VBOXGLXTAG(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap)
1745{
1746 stubFindPixmapParms_t parms;
1747
1748 if (crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) pixmap))
1749 {
1750 /*it's valid but never used glxpixmap, so simple free stored ptr*/
1751 crHashtableDelete(stub.pGLXPixmapsHash, (unsigned int) pixmap, crFree);
1752 return;
1753 }
1754 else
1755 {
1756 /*it's either invalid glxpixmap or one which was already initialized, so it's stored in appropriate ctx hash*/
1757 parms.pCtx = NULL;
1758 parms.pGlxPixmap = NULL;
1759 parms.draw = pixmap;
1760 crHashtableWalk(stub.contextTable, stubFindPixmapCB, &parms);
1761 }
1762
1763 if (!parms.pGlxPixmap)
1764 {
1765 crWarning("glXDestroyPixmap called for unknown glxpixmap 0x%x", (unsigned int) pixmap);
1766 return;
1767 }
1768
1769 XLOCK(dpy);
1770 if (parms.pGlxPixmap->gc)
1771 {
1772 XFreeGC(dpy, parms.pGlxPixmap->gc);
1773 }
1774
1775 if (parms.pGlxPixmap->hShmPixmap>0)
1776 {
1777 XFreePixmap(dpy, parms.pGlxPixmap->hShmPixmap);
1778 }
1779 XUNLOCK(dpy);
1780
1781 if (parms.pGlxPixmap->hDamage>0)
1782 {
1783 //crDebug("Destroy: Damage for drawable 0x%x, handle 0x%x", (unsigned int) pixmap, (unsigned int) parms.pGlxPixmap->damage);
1784 XDamageDestroy(dpy, parms.pGlxPixmap->hDamage);
1785 }
1786
1787 if (parms.pGlxPixmap->pDamageRegion)
1788 {
1789 XDestroyRegion(parms.pGlxPixmap->pDamageRegion);
1790 }
1791
1792 crHashtableDelete(parms.pCtx->pGLXPixmapsHash, (unsigned int) pixmap, crFree);
1793}
1794
1795DECLEXPORT(void) VBOXGLXTAG(glXDestroyWindow)(Display *dpy, GLXWindow win)
1796{
1797 (void) dpy;
1798 (void) win;
1799 /*crWarning("glXDestroyWindow not implemented by Chromium");*/
1800}
1801
1802DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentReadDrawable)(void)
1803{
1804 return currentReadDrawable;
1805}
1806
1807DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value)
1808{
1809 XVisualInfo * pVisual;
1810 const char * pExt;
1811
1812 pVisual = VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1813 if (!pVisual)
1814 {
1815 crWarning("glXGetFBConfigAttrib for %p, failed to get XVisualInfo", config);
1816 return GLX_BAD_ATTRIBUTE;
1817 }
1818 //crDebug("glXGetFBConfigAttrib 0x%x for 0x%x, visualid=0x%x, depth=%i", attribute, (int)config, (int)pVisual->visualid, pVisual->depth);
1819
1820
1821 switch (attribute)
1822 {
1823 case GLX_DRAWABLE_TYPE:
1824 *value = GLX_PIXMAP_BIT | GLX_WINDOW_BIT;
1825 break;
1826 case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
1827 *value = GLX_TEXTURE_2D_BIT_EXT;
1828 pExt = (const char *) stub.spu->dispatch_table.GetString(GL_EXTENSIONS);
1829 if (crStrstr(pExt, "GL_NV_texture_rectangle")
1830 || crStrstr(pExt, "GL_ARB_texture_rectangle")
1831 || crStrstr(pExt, "GL_EXT_texture_rectangle"))
1832 {
1833 *value |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
1834 }
1835 break;
1836 case GLX_BIND_TO_TEXTURE_RGBA_EXT:
1837 *value = pVisual->depth==32;
1838 break;
1839 case GLX_BIND_TO_TEXTURE_RGB_EXT:
1840 *value = True;
1841 break;
1842 case GLX_DOUBLEBUFFER:
1843 //crDebug("attribute=GLX_DOUBLEBUFFER");
1844 *value = True;
1845 break;
1846 case GLX_Y_INVERTED_EXT:
1847 *value = True;
1848 break;
1849 case GLX_ALPHA_SIZE:
1850 //crDebug("attribute=GLX_ALPHA_SIZE");
1851 *value = pVisual->depth==32 ? 8:0;
1852 break;
1853 case GLX_BUFFER_SIZE:
1854 //crDebug("attribute=GLX_BUFFER_SIZE");
1855 *value = pVisual->depth;
1856 break;
1857 case GLX_STENCIL_SIZE:
1858 //crDebug("attribute=GLX_STENCIL_SIZE");
1859 *value = 8;
1860 break;
1861 case GLX_DEPTH_SIZE:
1862 *value = 24;
1863 //crDebug("attribute=GLX_DEPTH_SIZE");
1864 break;
1865 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
1866 *value = 0;
1867 break;
1868 case GLX_RENDER_TYPE:
1869 //crDebug("attribute=GLX_RENDER_TYPE");
1870 *value = GLX_RGBA_BIT;
1871 break;
1872 case GLX_CONFIG_CAVEAT:
1873 //crDebug("attribute=GLX_CONFIG_CAVEAT");
1874 *value = GLX_NONE;
1875 break;
1876 case GLX_VISUAL_ID:
1877 //crDebug("attribute=GLX_VISUAL_ID");
1878 *value = pVisual->visualid;
1879 break;
1880 case GLX_FBCONFIG_ID:
1881 *value = pVisual->visualid; /*or config, though those are the same at the moment but this could change one day?*/
1882 break;
1883 case GLX_RED_SIZE:
1884 case GLX_GREEN_SIZE:
1885 case GLX_BLUE_SIZE:
1886 *value = 8;
1887 break;
1888 case GLX_LEVEL:
1889 *value = 0;
1890 break;
1891 case GLX_STEREO:
1892 *value = false;
1893 break;
1894 case GLX_AUX_BUFFERS:
1895 *value = 0;
1896 break;
1897 case GLX_ACCUM_RED_SIZE:
1898 case GLX_ACCUM_GREEN_SIZE:
1899 case GLX_ACCUM_BLUE_SIZE:
1900 case GLX_ACCUM_ALPHA_SIZE:
1901 *value = 0;
1902 break;
1903 case GLX_X_VISUAL_TYPE:
1904 *value = GLX_TRUE_COLOR;
1905 break;
1906 case GLX_TRANSPARENT_TYPE:
1907 *value = GLX_NONE;
1908 break;
1909 case GLX_SAMPLE_BUFFERS:
1910 case GLX_SAMPLES:
1911 *value = 1;
1912 break;
1913 case GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:
1914 *value = 0;
1915 break;
1916 default:
1917 crDebug("glXGetFBConfigAttrib: unknown attribute=0x%x", attribute);
1918 XFree(pVisual);
1919 return GLX_BAD_ATTRIBUTE;
1920 }
1921
1922 XFree(pVisual);
1923 return Success;
1924}
1925
1926#if !defined(VBOX_NO_NATIVEGL) || 1 /* need fbconfigs atleast for depths 24 and 32 */
1927DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
1928{
1929 GLXFBConfig *pGLXFBConfigs = NULL;
1930 struct VisualInfo *v;
1931 int i=0, cVisuals;
1932 XVisualInfo searchvis, *pVisuals;
1933
1934 *nelements = 0;
1935
1936 /*
1937 for (v = VisualInfoList; v; v = v->next) {
1938 if (v->dpy == dpy && v->screen == screen)
1939 ++*nelements;
1940 }
1941
1942 if (*nelements)
1943 pGLXFBConfigs = crAlloc(*nelements * sizeof(GLXFBConfig));
1944
1945 for (v = VisualInfoList; v && i<*nelements; v = v->next) {
1946 if (v->dpy == dpy && v->screen == screen)
1947 pGLXFBConfigs[i++] = (GLXFBConfig) v->visualid;
1948 }
1949 */
1950
1951 /*@todo doesn't really list all the common visuals, have to use some static list*/
1952 searchvis.screen = screen;
1953 XLOCK(dpy);
1954 pVisuals = XGetVisualInfo(dpy, VisualScreenMask, &searchvis, nelements);
1955 XUNLOCK(dpy);
1956
1957 if (*nelements)
1958 pGLXFBConfigs = crAlloc(*nelements * sizeof(GLXFBConfig));
1959
1960 for (i=0; i<*nelements; ++i)
1961 {
1962 pGLXFBConfigs[i] = (GLXFBConfig) pVisuals[i].visualid;
1963 }
1964
1965 XFree(pVisuals);
1966
1967 crDebug("glXGetFBConfigs returned %i configs", *nelements);
1968 for (i=0; i<*nelements; ++i)
1969 {
1970 crDebug("glXGetFBConfigs[%i]=%p", i, pGLXFBConfigs[i]);
1971 }
1972 return pGLXFBConfigs;
1973}
1974#else /* not 0 */
1975DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
1976{
1977 int i;
1978
1979 GLXFBConfig *pGLXFBConfigs = crAlloc(sizeof(GLXFBConfig));
1980
1981 *nelements = 1;
1982 XLOCK(dpy);
1983 *pGLXFBConfigs = (GLXFBConfig) XVisualIDFromVisual(DefaultVisual(dpy, screen));
1984 XUNLOCK(dpy);
1985
1986 crDebug("glXGetFBConfigs returned %i configs", *nelements);
1987 for (i=0; i<*nelements; ++i)
1988 {
1989 crDebug("glXGetFBConfigs[%i]=0x%x", i, (unsigned int) pGLXFBConfigs[i]);
1990 }
1991 return pGLXFBConfigs;
1992}
1993#endif
1994
1995DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEvent)(Display *dpy, GLXDrawable draw, unsigned long *event_mask)
1996{
1997 (void) dpy;
1998 (void) draw;
1999 (void) event_mask;
2000 crWarning("glXGetSelectedEvent not implemented by Chromium");
2001}
2002
2003DECLEXPORT(XVisualInfo *) VBOXGLXTAG(glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config)
2004{
2005 (void) dpy;
2006 (void) config;
2007
2008 struct VisualInfo *v;
2009
2010 /*
2011 for (v = VisualInfoList; v; v = v->next) {
2012 if (v->dpy == dpy && v->visualid == (VisualID)config)
2013 {
2014 XVisualInfo temp, *pret;
2015 int nret;
2016
2017 temp.visualid = v->visualid;
2018 pret = XGetVisualInfo(dpy, VisualIDMask, &temp, &nret);
2019
2020 if (nret!=1) crWarning("XGetVisualInfo returned %i visuals", nret);
2021 crDebug("glXGetVisualFromFBConfig(cfg/visid==0x%x): depth=%i", (int) config, pret->depth);
2022 return pret;
2023 }
2024 }
2025 */
2026 {
2027 XVisualInfo temp, *pret;
2028 int nret;
2029
2030 temp.visualid = (VisualID)config;
2031 XLOCK(dpy);
2032 pret = XGetVisualInfo(dpy, VisualIDMask, &temp, &nret);
2033 XUNLOCK(dpy);
2034
2035 if (nret!=1)
2036 {
2037 crWarning("XGetVisualInfo returned %i visuals for %p", nret, config);
2038 /* Hack for glut based apps.
2039 We fail to patch first call to glXChooseFBConfigSGIX, which ends up in the mesa's fbconfigs being passed to this function later.
2040 */
2041 if (!nret && config)
2042 {
2043 temp.visualid = (VisualID) ((__GLcontextModes*)config)->visualID;
2044 XLOCK(dpy);
2045 pret = XGetVisualInfo(dpy, VisualIDMask, &temp, &nret);
2046 XUNLOCK(dpy);
2047 crWarning("Retry with %#x returned %i visuals", ((__GLcontextModes*)config)->visualID, nret);
2048 }
2049 }
2050 //crDebug("glXGetVisualFromFBConfig(cfg/visid==0x%x): depth=%i", (int) config, pret->depth);
2051//crDebug("here");
2052 return pret;
2053 }
2054
2055 crDebug("glXGetVisualFromFBConfig unknown fbconfig %p", config);
2056 return NULL;
2057}
2058
2059DECLEXPORT(Bool) VBOXGLXTAG(glXMakeContextCurrent)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
2060{
2061 currentReadDrawable = read;
2062 return VBOXGLXTAG(glXMakeCurrent)(display, draw, ctx);
2063}
2064
2065DECLEXPORT(int) VBOXGLXTAG(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value)
2066{
2067 (void) dpy;
2068 (void) ctx;
2069 (void) attribute;
2070 (void) value;
2071 crWarning("glXQueryContext not implemented by Chromium");
2072 return 0;
2073}
2074
2075DECLEXPORT(void) VBOXGLXTAG(glXQueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
2076{
2077 (void) dpy;
2078 (void) draw;
2079 (void) attribute;
2080 (void) value;
2081 crWarning("glXQueryDrawable not implemented by Chromium");
2082}
2083
2084DECLEXPORT(void) VBOXGLXTAG(glXSelectEvent)(Display *dpy, GLXDrawable draw, unsigned long event_mask)
2085{
2086 (void) dpy;
2087 (void) draw;
2088 (void) event_mask;
2089 crWarning("glXSelectEvent not implemented by Chromium");
2090}
2091
2092#ifdef CR_EXT_texture_from_pixmap
2093/*typedef struct
2094{
2095 int x, y;
2096 unsigned int w, h, border, depth;
2097 Window root;
2098 void *data;
2099} pminfo;*/
2100
2101static void stubInitXSharedMemory(Display *dpy)
2102{
2103 int vma, vmi;
2104 Bool pixmaps;
2105
2106 if (stub.bShmInitFailed || stub.xshmSI.shmid>=0)
2107 return;
2108
2109 stub.bShmInitFailed = GL_TRUE;
2110
2111 /* Check for extension and pixmaps format */
2112 XLOCK(dpy);
2113 if (!XShmQueryExtension(dpy))
2114 {
2115 crWarning("No XSHM extension");
2116 XUNLOCK(dpy);
2117 return;
2118 }
2119
2120 if (!XShmQueryVersion(dpy, &vma, &vmi, &pixmaps) || !pixmaps)
2121 {
2122 crWarning("XSHM extension doesn't support pixmaps");
2123 XUNLOCK(dpy);
2124 return;
2125 }
2126
2127 if (XShmPixmapFormat(dpy)!=ZPixmap)
2128 {
2129 crWarning("XSHM extension doesn't support ZPixmap format");
2130 XUNLOCK(dpy);
2131 return;
2132 }
2133 XUNLOCK(dpy);
2134
2135 /* Alloc shared memory, so far using hardcoded value...could fail for bigger displays one day */
2136 stub.xshmSI.readOnly = false;
2137 stub.xshmSI.shmid = shmget(IPC_PRIVATE, 4*4096*2048, IPC_CREAT | 0600);
2138 if (stub.xshmSI.shmid<0)
2139 {
2140 crWarning("XSHM Failed to create shared segment");
2141 return;
2142 }
2143
2144 stub.xshmSI.shmaddr = (char*) shmat(stub.xshmSI.shmid, NULL, 0);
2145 if (stub.xshmSI.shmaddr==(void*)-1)
2146 {
2147 crWarning("XSHM Failed to attach shared segment");
2148 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
2149 return;
2150 }
2151
2152 XLOCK(dpy);
2153 if (!XShmAttach(dpy, &stub.xshmSI))
2154 {
2155 crWarning("XSHM Failed to attach shared segment to XServer");
2156 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
2157 shmdt(stub.xshmSI.shmaddr);
2158 XUNLOCK(dpy);
2159 return;
2160 }
2161 XUNLOCK(dpy);
2162
2163 stub.bShmInitFailed = GL_FALSE;
2164 crInfo("Using XSHM for GLX_EXT_texture_from_pixmap");
2165
2166 /*Anyway mark to be deleted when our process detaches it, in case of segfault etc*/
2167
2168/* Ramshankar: Solaris compiz fix */
2169#ifndef RT_OS_SOLARIS
2170 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
2171#endif
2172}
2173
2174void stubQueryXDamageExtension(Display *dpy, ContextInfo *pContext)
2175{
2176 int erb, vma, vmi;
2177
2178 CRASSERT(pContext);
2179
2180 if (pContext->damageQueryFailed)
2181 return;
2182
2183 pContext->damageQueryFailed = True;
2184
2185 if (!XDamageQueryExtension(dpy, &pContext->damageEventsBase, &erb)
2186 || !XDamageQueryVersion(dpy, &vma, &vmi))
2187 {
2188 crWarning("XDamage not found or old version (%i.%i), going to run *very* slow", vma, vmi);
2189 return;
2190 }
2191
2192 crDebug("XDamage %i.%i", vma, vmi);
2193 pContext->damageQueryFailed = False;
2194}
2195
2196static void stubFetchDamageOnDrawable(Display *dpy, GLX_Pixmap_t *pGlxPixmap)
2197{
2198 Damage damage = pGlxPixmap->hDamage;
2199
2200 if (damage)
2201 {
2202 XRectangle *returnRects;
2203 int nReturnRects;
2204
2205 /* Get the damage region as a server region */
2206 XserverRegion serverDamageRegion = XFixesCreateRegion (dpy, NULL, 0);
2207
2208 /* Unite damage region with server region and clear damage region */
2209 XDamageSubtract (dpy,
2210 damage,
2211 None, /* subtract all damage from this region */
2212 serverDamageRegion /* save in serverDamageRegion */);
2213
2214 /* Fetch damage rectangles */
2215 returnRects = XFixesFetchRegion (dpy, serverDamageRegion, &nReturnRects);
2216
2217 /* Delete region */
2218 XFixesDestroyRegion (dpy, serverDamageRegion);
2219
2220 if (pGlxPixmap->pDamageRegion)
2221 {
2222 /* If it's dirty and regions are empty, it marked for full update, so do nothing.*/
2223 if (!pGlxPixmap->bPixmapImageDirty || !XEmptyRegion(pGlxPixmap->pDamageRegion))
2224 {
2225 int i = 0;
2226 for (; i < nReturnRects; ++i)
2227 {
2228 if (CR_MAX_DAMAGE_REGIONS_TRACKED <= pGlxPixmap->pDamageRegion->numRects)
2229 {
2230 /* Mark for full update */
2231 EMPTY_REGION(pGlxPixmap->pDamageRegion);
2232 }
2233 else
2234 {
2235 /* Add to damage regions */
2236 XUnionRectWithRegion(&returnRects[i], pGlxPixmap->pDamageRegion, pGlxPixmap->pDamageRegion);
2237 }
2238 }
2239 }
2240 }
2241
2242 XFree(returnRects);
2243
2244 pGlxPixmap->bPixmapImageDirty = True;
2245 }
2246}
2247
2248static const CRPixelPackState defaultPacking =
2249{
2250 0, /*rowLength*/
2251 0, /*skipRows*/
2252 0, /*skipPixels*/
2253 1, /*alignment*/
2254 0, /*imageHeight*/
2255 0, /*skipImages*/
2256 GL_FALSE, /*swapBytes*/
2257 GL_FALSE /*lsbFirst*/
2258};
2259
2260static void stubGetUnpackState(CRPixelPackState *pUnpackState)
2261{
2262 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_ROW_LENGTH, &pUnpackState->rowLength);
2263 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_SKIP_ROWS, &pUnpackState->skipRows);
2264 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_SKIP_PIXELS, &pUnpackState->skipPixels);
2265 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_ALIGNMENT, &pUnpackState->alignment);
2266 stub.spu->dispatch_table.GetBooleanv(GL_UNPACK_SWAP_BYTES, &pUnpackState->swapBytes);
2267 stub.spu->dispatch_table.GetBooleanv(GL_UNPACK_LSB_FIRST, &pUnpackState->psLSBFirst);
2268}
2269
2270static void stubSetUnpackState(const CRPixelPackState *pUnpackState)
2271{
2272 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, pUnpackState->rowLength);
2273 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_SKIP_ROWS, pUnpackState->skipRows);
2274 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_SKIP_PIXELS, pUnpackState->skipPixels);
2275 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ALIGNMENT, pUnpackState->alignment);
2276 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_SWAP_BYTES, pUnpackState->swapBytes);
2277 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_LSB_FIRST, pUnpackState->psLSBFirst);
2278}
2279
2280static GLX_Pixmap_t* stubInitGlxPixmap(GLX_Pixmap_t* pCreateInfoPixmap, Display *dpy, GLXDrawable draw, ContextInfo *pContext)
2281{
2282 int x, y;
2283 unsigned int w, h;
2284 unsigned int border;
2285 unsigned int depth;
2286 Window root;
2287 GLX_Pixmap_t *pGlxPixmap;
2288
2289 CRASSERT(pContext && pCreateInfoPixmap);
2290
2291 XLOCK(dpy);
2292 if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
2293 {
2294 XSync(dpy, False);
2295 if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
2296 {
2297 crWarning("stubInitGlxPixmap failed in call to XGetGeometry for 0x%x", (int) draw);
2298 XUNLOCK(dpy);
2299 return NULL;
2300 }
2301 }
2302
2303 pGlxPixmap = crAlloc(sizeof(GLX_Pixmap_t));
2304 if (!pGlxPixmap)
2305 {
2306 crWarning("stubInitGlxPixmap failed to allocate memory");
2307 XUNLOCK(dpy);
2308 return NULL;
2309 }
2310
2311 pGlxPixmap->x = x;
2312 pGlxPixmap->y = y;
2313 pGlxPixmap->w = w;
2314 pGlxPixmap->h = h;
2315 pGlxPixmap->border = border;
2316 pGlxPixmap->depth = depth;
2317 pGlxPixmap->root = root;
2318 pGlxPixmap->format = pCreateInfoPixmap->format;
2319 pGlxPixmap->target = pCreateInfoPixmap->target;
2320
2321 /* Try to allocate shared memory
2322 * As we're allocating huge chunk of memory, do it in this function, only if this extension is really used
2323 */
2324 if (!stub.bShmInitFailed && stub.xshmSI.shmid<0)
2325 {
2326 stubInitXSharedMemory(dpy);
2327 }
2328
2329 if (stub.xshmSI.shmid>=0)
2330 {
2331 XGCValues xgcv;
2332 xgcv.graphics_exposures = False;
2333 xgcv.subwindow_mode = IncludeInferiors;
2334 pGlxPixmap->gc = XCreateGC(dpy, (Pixmap)draw, GCGraphicsExposures|GCSubwindowMode, &xgcv);
2335
2336 pGlxPixmap->hShmPixmap = XShmCreatePixmap(dpy, pGlxPixmap->root, stub.xshmSI.shmaddr, &stub.xshmSI,
2337 pGlxPixmap->w, pGlxPixmap->h, pGlxPixmap->depth);
2338 }
2339 else
2340 {
2341 pGlxPixmap->gc = NULL;
2342 pGlxPixmap->hShmPixmap = 0;
2343 }
2344 XUNLOCK(dpy);
2345
2346 /* If there's damage extension, then get handle for damage events related to this pixmap */
2347 if (!pContext->damageQueryFailed)
2348 {
2349 pGlxPixmap->hDamage = XDamageCreate(dpy, (Pixmap)draw, XDamageReportNonEmpty);
2350 /*crDebug("Create: Damage for drawable 0x%x, handle 0x%x (level=%i)",
2351 (unsigned int) draw, (unsigned int) pGlxPixmap->damage, (int) XDamageReportRawRectangles);*/
2352 pGlxPixmap->pDamageRegion = XCreateRegion();
2353 if (!pGlxPixmap->pDamageRegion)
2354 {
2355 crWarning("stubInitGlxPixmap failed to create empty damage region for drawable 0x%x", (unsigned int) draw);
2356 }
2357
2358 /*We have never seen this pixmap before, so mark it as dirty for first use*/
2359 pGlxPixmap->bPixmapImageDirty = True;
2360 }
2361 else
2362 {
2363 pGlxPixmap->hDamage = 0;
2364 pGlxPixmap->pDamageRegion = NULL;
2365 }
2366
2367 /* glTexSubImage2D generates GL_INVALID_OP if texture array hasn't been defined by a call to glTexImage2D first.
2368 * It's fine for small textures which would be updated in stubXshmUpdateWholeImage, but we'd never call glTexImage2D for big ones.
2369 * Note that we're making empty texture by passing NULL as pixels pointer, so there's no overhead transferring data to host.*/
2370 if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
2371 {
2372 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pGlxPixmap->w, pGlxPixmap->h, 0,
2373 GL_BGRA, GL_UNSIGNED_BYTE, NULL);
2374 }
2375
2376 crHashtableAdd(pContext->pGLXPixmapsHash, (unsigned int) draw, pGlxPixmap);
2377 crHashtableDelete(stub.pGLXPixmapsHash, (unsigned int) draw, crFree);
2378
2379 return pGlxPixmap;
2380}
2381
2382static void stubXshmUpdateWholeImage(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap)
2383{
2384 /* To limit the size of transferring buffer, split bigger texture into regions
2385 * which fit into connection buffer. Could be done in hgcm or packspu but implementation in this place allows to avoid
2386 * unnecessary memcpy.
2387 * This also workarounds guest driver failures when sending 6+mb texture buffers on linux.
2388 */
2389 if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
2390 {
2391 XRectangle rect;
2392
2393 rect.x = pGlxPixmap->x;
2394 rect.y = pGlxPixmap->y;
2395 rect.width = pGlxPixmap->w;
2396 rect.height = CR_MAX_TRANSFER_SIZE/(4*pGlxPixmap->w);
2397
2398 /*crDebug("Texture size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
2399 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, rect.height);*/
2400
2401 for (; (rect.y+rect.height)<=(pGlxPixmap->y+pGlxPixmap->h); rect.y+=rect.height)
2402 {
2403 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2404 }
2405
2406 if (rect.y!=(pGlxPixmap->y+pGlxPixmap->h))
2407 {
2408 rect.height=pGlxPixmap->h-rect.y;
2409 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2410 }
2411 }
2412 else
2413 {
2414 CRPixelPackState unpackState;
2415
2416 XLOCK(dpy);
2417 XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
2418 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, 0, 0);
2419 /* Have to make sure XCopyArea is processed */
2420 XSync(dpy, False);
2421 XUNLOCK(dpy);
2422
2423 stubGetUnpackState(&unpackState);
2424 stubSetUnpackState(&defaultPacking);
2425 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pGlxPixmap->w, pGlxPixmap->h, 0,
2426 GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
2427 stubSetUnpackState(&unpackState);
2428 /*crDebug("Sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
2429 (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
2430 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);*/
2431 }
2432}
2433
2434static void stubXshmUpdateImageRect(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap, XRectangle *pRect)
2435{
2436 /* See comment in stubXshmUpdateWholeImage */
2437 if (CR_MAX_TRANSFER_SIZE < 4*pRect->width*pRect->height)
2438 {
2439 XRectangle rect;
2440
2441 rect.x = pRect->x;
2442 rect.y = pRect->y;
2443 rect.width = pRect->width;
2444 rect.height = CR_MAX_TRANSFER_SIZE/(4*pRect->width);
2445
2446 /*crDebug("Region size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
2447 pRect->x, pRect->y, pRect->width, pRect->height, rect.height);*/
2448
2449 for (; (rect.y+rect.height)<=(pRect->y+pRect->height); rect.y+=rect.height)
2450 {
2451 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2452 }
2453
2454 if (rect.y!=(pRect->y+pRect->height))
2455 {
2456 rect.height=pRect->y+pRect->height-rect.y;
2457 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2458 }
2459 }
2460 else
2461 {
2462 CRPixelPackState unpackState;
2463
2464 XLOCK(dpy);
2465 XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
2466 pRect->x, pRect->y, pRect->width, pRect->height, 0, 0);
2467 /* Have to make sure XCopyArea is processed */
2468 XSync(dpy, False);
2469 XUNLOCK(dpy);
2470
2471 stubGetUnpackState(&unpackState);
2472 stubSetUnpackState(&defaultPacking);
2473 if (pRect->width!=pGlxPixmap->w)
2474 {
2475 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, pGlxPixmap->w);
2476 }
2477 stub.spu->dispatch_table.TexSubImage2D(pGlxPixmap->target, 0, pRect->x, pRect->y, pRect->width, pRect->height,
2478 GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
2479 stubSetUnpackState(&unpackState);
2480
2481 /*crDebug("Region sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
2482 (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
2483 pRect->x, pRect->y, pRect->width, pRect->height);*/
2484 }
2485}
2486
2487#if 0
2488Bool checkevents(Display *display, XEvent *event, XPointer arg)
2489{
2490 //crDebug("got type: 0x%x", event->type);
2491 if (event->type==damage_evb+XDamageNotify)
2492 {
2493 ContextInfo *context = stubGetCurrentContext();
2494 XDamageNotifyEvent *e = (XDamageNotifyEvent *) event;
2495 /* we're interested in pixmaps only...and those have e->drawable set to 0 or other strange value for some odd reason
2496 * so have to walk glxpixmaps hashtable to find if we have damage event handle assigned to some pixmap
2497 */
2498 /*crDebug("Event: Damage for drawable 0x%x, handle 0x%x (level=%i) [%i,%i,%i,%i]",
2499 (unsigned int) e->drawable, (unsigned int) e->damage, (int) e->level,
2500 e->area.x, e->area.y, e->area.width, e->area.height);*/
2501 CRASSERT(context);
2502 crHashtableWalk(context->pGLXPixmapsHash, checkdamageCB, e);
2503 }
2504 return False;
2505}
2506#endif
2507
2508/*@todo check what error codes could we throw for failures here*/
2509DECLEXPORT(void) VBOXGLXTAG(glXBindTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer, const int *attrib_list)
2510{
2511 static int cnt=0;
2512 XImage dummyimg;
2513 ContextInfo *context = stubGetCurrentContext();
2514
2515 GLX_Pixmap_t *pGlxPixmap;
2516
2517 if (!context)
2518 {
2519 crWarning("glXBindTexImageEXT called without current context");
2520 return;
2521 }
2522
2523 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(context->pGLXPixmapsHash, (unsigned int) draw);
2524 if (!pGlxPixmap)
2525 {
2526 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) draw);
2527 if (!pGlxPixmap)
2528 {
2529 crDebug("Unknown drawable 0x%x in glXBindTexImageEXT!", (unsigned int) draw);
2530 return;
2531 }
2532 pGlxPixmap = stubInitGlxPixmap(pGlxPixmap, dpy, draw, context);
2533 if (!pGlxPixmap)
2534 {
2535 crDebug("glXBindTexImageEXT failed to get pGlxPixmap");
2536 return;
2537 }
2538 }
2539
2540 /* If there's damage extension, then process incoming events as we need the information right now */
2541 if (!context->damageQueryFailed)
2542 {
2543 /* Sync connection */
2544 XLOCK(dpy);
2545 XSync(dpy, False);
2546 XUNLOCK(dpy);
2547
2548 stubFetchDamageOnDrawable(dpy, pGlxPixmap);
2549 }
2550
2551 /* No shared memory? Rollback to use slow x protocol then */
2552 if (stub.xshmSI.shmid<0)
2553 {
2554 /*@todo add damage support here too*/
2555 XImage *pxim;
2556 CRPixelPackState unpackState;
2557
2558 XLOCK(dpy);
2559 pxim = XGetImage(dpy, (Pixmap)draw, pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, AllPlanes, ZPixmap);
2560 XUNLOCK(dpy);
2561 /*if (pxim)
2562 {
2563 if (!ptextable)
2564 {
2565 ptextable = crAllocHashtable();
2566 }
2567 pm = crHashtableSearch(ptextable, (unsigned int) draw);
2568 if (!pm)
2569 {
2570 pm = crCalloc(sizeof(pminfo));
2571 crHashtableAdd(ptextable, (unsigned int) draw, pm);
2572 }
2573 pm->w = w;
2574 pm->h = h;
2575 if (pm->data) crFree(pm->data);
2576 pm->data = crAlloc(4*w*h);
2577 crMemcpy(pm->data, (void*)(&(pxim->data[0])), 4*w*h);
2578 }*/
2579
2580 if (NULL==pxim)
2581 {
2582 crWarning("Failed, to get pixmap data for 0x%x", (unsigned int) draw);
2583 return;
2584 }
2585
2586 stubGetUnpackState(&unpackState);
2587 stubSetUnpackState(&defaultPacking);
2588 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pxim->width, pxim->height, 0,
2589 GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(pxim->data[0])));
2590 stubSetUnpackState(&unpackState);
2591 XDestroyImage(pxim);
2592 }
2593 else /* Use shm to get pixmap data */
2594 {
2595 /* Check if we have damage extension */
2596 if (!context->damageQueryFailed)
2597 {
2598 if (pGlxPixmap->bPixmapImageDirty)
2599 {
2600 /* Either we failed to allocate damage region or this pixmap is marked for full update */
2601 if (!pGlxPixmap->pDamageRegion || XEmptyRegion(pGlxPixmap->pDamageRegion))
2602 {
2603 /*crDebug("**FULL** update for 0x%x", (unsigned int)draw);*/
2604 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2605 }
2606 else
2607 {
2608 long fullArea, damageArea=0, clipdamageArea, i;
2609 XRectangle damageClipBox;
2610
2611 fullArea = pGlxPixmap->w * pGlxPixmap->h;
2612 XClipBox(pGlxPixmap->pDamageRegion, &damageClipBox);
2613 clipdamageArea = damageClipBox.width * damageClipBox.height;
2614
2615 //crDebug("FullSize [%i,%i,%i,%i]", pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);
2616 //crDebug("Clip [%i,%i,%i,%i]", damageClipBox.x, damageClipBox.y, damageClipBox.width, damageClipBox.height);
2617
2618 for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
2619 {
2620 BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
2621 damageArea += (pBox->x2-pBox->x1)*(pBox->y2-pBox->y1);
2622 //crDebug("Damage rect [%i,%i,%i,%i]", pBox->x1, pBox->y1, pBox->x2, pBox->y2);
2623 }
2624
2625 if (damageArea>clipdamageArea || clipdamageArea>fullArea)
2626 {
2627 crWarning("glXBindTexImageEXT, damage regions seems to be broken, forcing full update");
2628 /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
2629 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2630 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2631 }
2632 else /*We have corect damage info*/
2633 {
2634 if (CR_MIN_DAMAGE_PROFIT_SIZE > (fullArea-damageArea))
2635 {
2636 /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
2637 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2638 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2639 }
2640 else if (CR_MIN_DAMAGE_PROFIT_SIZE > (clipdamageArea-damageArea))
2641 {
2642 /*crDebug("**PARTIAL** update for 0x%x, numRect=%li, FS=%li, *CS*=%li, DS=%li",
2643 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2644 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &damageClipBox);
2645 }
2646 else
2647 {
2648 /*crDebug("**PARTIAL** update for 0x%x, numRect=*%li*, FS=%li, CS=%li, *DS*=%li",
2649 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2650 for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
2651 {
2652 XRectangle rect;
2653 BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
2654
2655 rect.x = pBox->x1;
2656 rect.y = pBox->y1;
2657 rect.width = pBox->x2-pBox->x1;
2658 rect.height = pBox->y2-pBox->y1;
2659
2660 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2661 }
2662 }
2663 }
2664 }
2665
2666 /* Clean dirty flag and damage region */
2667 pGlxPixmap->bPixmapImageDirty = False;
2668 if (pGlxPixmap->pDamageRegion)
2669 EMPTY_REGION(pGlxPixmap->pDamageRegion);
2670 }
2671 }
2672 else
2673 {
2674 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2675 }
2676 }
2677}
2678
2679DECLEXPORT(void) VBOXGLXTAG(glXReleaseTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer)
2680{
2681 (void) dpy;
2682 (void) draw;
2683 (void) buffer;
2684 //crDebug("glXReleaseTexImageEXT 0x%x", (unsigned int)draw);
2685}
2686#endif
2687
2688#endif /* GLX_EXTRAS */
2689
2690
2691#ifdef GLX_SGIX_video_resize
2692/* more dummy funcs. These help when linking with older GLUTs */
2693
2694DECLEXPORT(int) VBOXGLXTAG(glXBindChannelToWindowSGIX)(Display *dpy, int scrn, int chan, Window w)
2695{
2696 (void) dpy;
2697 (void) scrn;
2698 (void) chan;
2699 (void) w;
2700 crDebug("glXBindChannelToWindowSGIX");
2701 return 0;
2702}
2703
2704DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSGIX)(Display *dpy, int scrn, int chan, int x , int y, int w, int h)
2705{
2706 (void) dpy;
2707 (void) scrn;
2708 (void) chan;
2709 (void) x;
2710 (void) y;
2711 (void) w;
2712 (void) h;
2713 crDebug("glXChannelRectSGIX");
2714 return 0;
2715}
2716
2717DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelRectSGIX)(Display *dpy, int scrn, int chan, int *x, int *y, int *w, int *h)
2718{
2719 (void) dpy;
2720 (void) scrn;
2721 (void) chan;
2722 (void) x;
2723 (void) y;
2724 (void) w;
2725 (void) h;
2726 crDebug("glXQueryChannelRectSGIX");
2727 return 0;
2728}
2729
2730DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelDeltasSGIX)(Display *dpy, int scrn, int chan, int *dx, int *dy, int *dw, int *dh)
2731{
2732 (void) dpy;
2733 (void) scrn;
2734 (void) chan;
2735 (void) dx;
2736 (void) dy;
2737 (void) dw;
2738 (void) dh;
2739 crDebug("glXQueryChannelDeltasSGIX");
2740 return 0;
2741}
2742
2743DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSyncSGIX)(Display *dpy, int scrn, int chan, GLenum synctype)
2744{
2745 (void) dpy;
2746 (void) scrn;
2747 (void) chan;
2748 (void) synctype;
2749 crDebug("glXChannelRectSyncSGIX");
2750 return 0;
2751}
2752
2753#endif /* GLX_SGIX_video_resize */
2754
2755#ifdef VBOXOGL_FAKEDRI
2756DECLEXPORT(const char *) VBOXGLXTAG(glXGetDriverConfig)(const char *driverName)
2757{
2758 return NULL;
2759}
2760
2761DECLEXPORT(void) VBOXGLXTAG(glXFreeMemoryMESA)(Display *dpy, int scrn, void *pointer)
2762{
2763 (void) dpy;
2764 (void) scrn;
2765 (void) pointer;
2766}
2767
2768DECLEXPORT(GLXContext) VBOXGLXTAG(glXImportContextEXT)(Display *dpy, GLXContextID contextID)
2769{
2770 (void) dpy;
2771 (void) contextID;
2772 return NULL;
2773}
2774
2775DECLEXPORT(GLXContextID) VBOXGLXTAG(glXGetContextIDEXT)(const GLXContext ctx)
2776{
2777 (void) ctx;
2778 return 0;
2779}
2780
2781DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrentReadSGI)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
2782{
2783 return VBOXGLXTAG(glXMakeContextCurrent)(display, draw, read, ctx);
2784}
2785
2786DECLEXPORT(const char *) VBOXGLXTAG(glXGetScreenDriver)(Display *dpy, int scrNum)
2787{
2788 static char *screendriver = "vboxvideo";
2789 return screendriver;
2790}
2791
2792DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplayEXT)(void)
2793{
2794 return VBOXGLXTAG(glXGetCurrentDisplay());
2795}
2796
2797DECLEXPORT(void) VBOXGLXTAG(glXFreeContextEXT)(Display *dpy, GLXContext ctx)
2798{
2799 VBOXGLXTAG(glXDestroyContext(dpy, ctx));
2800}
2801
2802/*Mesa internal*/
2803DECLEXPORT(int) VBOXGLXTAG(glXQueryContextInfoEXT)(Display *dpy, GLXContext ctx)
2804{
2805 (void) dpy;
2806 (void) ctx;
2807 return 0;
2808}
2809
2810DECLEXPORT(void *) VBOXGLXTAG(glXAllocateMemoryMESA)(Display *dpy, int scrn,
2811 size_t size, float readFreq,
2812 float writeFreq, float priority)
2813{
2814 (void) dpy;
2815 (void) scrn;
2816 (void) size;
2817 (void) readFreq;
2818 (void) writeFreq;
2819 (void) priority;
2820 return NULL;
2821}
2822
2823DECLEXPORT(GLuint) VBOXGLXTAG(glXGetMemoryOffsetMESA)(Display *dpy, int scrn, const void *pointer)
2824{
2825 (void) dpy;
2826 (void) scrn;
2827 (void) pointer;
2828 return 0;
2829}
2830
2831DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap)
2832{
2833 (void) dpy;
2834 (void) visual;
2835 (void) pixmap;
2836 (void) cmap;
2837 return 0;
2838}
2839
2840#endif /*VBOXOGL_FAKEDRI*/
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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