VirtualBox

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

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

crOpenGL: more fixes for glx functions

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

© 2023 Oracle
ContactPrivacy policyTerms of Use