VirtualBox

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

最後變更 在這個檔案從34233是 34138,由 vboxsync 提交於 14 年 前

crOpenGL: add missing glx 1.3 functions, partially working ogre based demos

  • 屬性 svn:eol-style 設為 native
檔案大小: 80.1 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
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
635
636DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx )
637{
638 ContextInfo *context;
639 WindowInfo *window;
640 Bool retVal;
641
642 /*crDebug("glXMakeCurrent(%p, 0x%x, 0x%x)", (void *) dpy, (int) drawable, (int) ctx);*/
643
644 if (ctx && drawable) {
645 context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) ctx);
646 window = stubGetWindowInfo(dpy, drawable);
647
648 if (context && context->type == UNDECIDED) {
649 XLOCK(dpy);
650 XSync(dpy, 0); /* sync to force window creation on the server */
651 XUNLOCK(dpy);
652 }
653 }
654 else {
655 dpy = NULL;
656 window = NULL;
657 context = NULL;
658 }
659
660 currentDisplay = dpy;
661 currentDrawable = drawable;
662
663 retVal = stubMakeCurrent(window, context);
664 return retVal;
665}
666
667
668DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmap)( Display *dpy, XVisualInfo *vis, Pixmap pixmap )
669{
670 stubInit();
671 return VBOXGLXTAG(glXCreatePixmap)(dpy, (GLXFBConfig)vis->visualid, pixmap, NULL);
672}
673
674DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPixmap)( Display *dpy, GLXPixmap pix )
675{
676 VBOXGLXTAG(glXDestroyPixmap)(dpy, pix);
677}
678
679#ifndef VBOX_NO_NATIVEGL /* old code */
680DECLEXPORT(int) VBOXGLXTAG(glXGetConfig)( Display *dpy, XVisualInfo *vis, int attrib, int *value )
681{
682 struct VisualInfo *v;
683 int visBits;
684
685 if (!vis) {
686 /* SGI OpenGL Performer hits this */
687 crWarning("glXGetConfig called with NULL XVisualInfo");
688 return GLX_BAD_VISUAL;
689 }
690
691 v = FindVisualInfo(dpy, DefaultScreen(dpy), vis->visual->visualid);
692 if (v) {
693 visBits = v->visBits;
694 }
695 else {
696 visBits = 0;
697 }
698
699 stubInit();
700
701 /* try to satisfy this request with the native glXGetConfig() */
702 if (stub.haveNativeOpenGL)
703 {
704 int foo, bar;
705 int return_val;
706
707 if (stub.wsInterface.glXQueryExtension(dpy, &foo, &bar))
708 {
709 return_val = stub.wsInterface.glXGetConfig( dpy, vis, attrib, value );
710 if (return_val)
711 {
712 crDebug("faker native glXGetConfig returned %s",
713 glx_error_string(return_val));
714 }
715 return return_val;
716 }
717 }
718
719 /*
720 * If the GLX application chooses its visual via a bunch of calls to
721 * glXGetConfig, instead of by calling glXChooseVisual, we need to keep
722 * track of which attributes are queried to help satisfy context creation
723 * later.
724 */
725 switch ( attrib ) {
726
727 case GLX_USE_GL:
728 *value = 1;
729 break;
730
731 case GLX_BUFFER_SIZE:
732 *value = 32;
733 break;
734
735 case GLX_LEVEL:
736 visBits |= CR_OVERLAY_BIT;
737 *value = (visBits & CR_OVERLAY_BIT) ? 1 : 0;
738 break;
739
740 case GLX_RGBA:
741 visBits |= CR_RGB_BIT;
742 *value = 1;
743 break;
744
745 case GLX_DOUBLEBUFFER:
746 *value = 1;
747 break;
748
749 case GLX_STEREO:
750 *value = 1;
751 break;
752
753 case GLX_AUX_BUFFERS:
754 *value = 0;
755 break;
756
757 case GLX_RED_SIZE:
758 *value = 8;
759 break;
760
761 case GLX_GREEN_SIZE:
762 *value = 8;
763 break;
764
765 case GLX_BLUE_SIZE:
766 *value = 8;
767 break;
768
769 case GLX_ALPHA_SIZE:
770 visBits |= CR_ALPHA_BIT;
771 *value = (visBits & CR_ALPHA_BIT) ? 8 : 0;
772 break;
773
774 case GLX_DEPTH_SIZE:
775 visBits |= CR_DEPTH_BIT;
776 *value = 16;
777 break;
778
779 case GLX_STENCIL_SIZE:
780 visBits |= CR_STENCIL_BIT;
781 *value = 8;
782 break;
783
784 case GLX_ACCUM_RED_SIZE:
785 visBits |= CR_ACCUM_BIT;
786 *value = 16;
787 break;
788
789 case GLX_ACCUM_GREEN_SIZE:
790 visBits |= CR_ACCUM_BIT;
791 *value = 16;
792 break;
793
794 case GLX_ACCUM_BLUE_SIZE:
795 visBits |= CR_ACCUM_BIT;
796 *value = 16;
797 break;
798
799 case GLX_ACCUM_ALPHA_SIZE:
800 visBits |= CR_ACCUM_BIT;
801 *value = 16;
802 break;
803
804 case GLX_SAMPLE_BUFFERS_SGIS:
805 visBits |= CR_MULTISAMPLE_BIT;
806 *value = 0; /* fix someday */
807 break;
808
809 case GLX_SAMPLES_SGIS:
810 visBits |= CR_MULTISAMPLE_BIT;
811 *value = 0; /* fix someday */
812 break;
813
814 case GLX_VISUAL_CAVEAT_EXT:
815 *value = GLX_NONE_EXT;
816 break;
817#if defined(SunOS)
818 /*
819 I don't think this is even a valid attribute for glxGetConfig.
820 No idea why this gets called under SunOS but we simply ignore it
821 -- jw
822 */
823 case GLX_X_VISUAL_TYPE:
824 crWarning ("Ignoring Unsupported GLX Call: glxGetConfig with attrib 0x%x", attrib);
825 break;
826#endif
827
828 case GLX_TRANSPARENT_TYPE:
829 *value = GLX_NONE_EXT;
830 break;
831 case GLX_TRANSPARENT_INDEX_VALUE:
832 *value = 0;
833 break;
834 case GLX_TRANSPARENT_RED_VALUE:
835 *value = 0;
836 break;
837 case GLX_TRANSPARENT_GREEN_VALUE:
838 *value = 0;
839 break;
840 case GLX_TRANSPARENT_BLUE_VALUE:
841 *value = 0;
842 break;
843 case GLX_TRANSPARENT_ALPHA_VALUE:
844 *value = 0;
845 break;
846 default:
847 crWarning( "Unsupported GLX Call: glXGetConfig with attrib 0x%x", attrib );
848 return GLX_BAD_ATTRIBUTE;
849 }
850
851 AddVisualInfo(dpy, DefaultScreen(dpy), vis->visual->visualid, visBits);
852
853 return 0;
854}
855#else /* not 0 */
856DECLEXPORT(int) VBOXGLXTAG(glXGetConfig)( Display *dpy, XVisualInfo *vis, int attrib, int *value )
857{
858 if (!vis) {
859 /* SGI OpenGL Performer hits this */
860 crWarning("glXGetConfig called with NULL XVisualInfo");
861 return GLX_BAD_VISUAL;
862 }
863
864 stubInit();
865
866 *value = 0; /* For sanity */
867
868 switch ( attrib ) {
869
870 case GLX_USE_GL:
871 *value = 1;
872 break;
873
874 case GLX_BUFFER_SIZE:
875 *value = 32;
876 break;
877
878 case GLX_LEVEL:
879 *value = 0; /* for now */
880 break;
881
882 case GLX_RGBA:
883 *value = 1;
884 break;
885
886 case GLX_DOUBLEBUFFER:
887 *value = 1;
888 break;
889
890 case GLX_STEREO:
891 *value = 1;
892 break;
893
894 case GLX_AUX_BUFFERS:
895 *value = 0;
896 break;
897
898 case GLX_RED_SIZE:
899 *value = 8;
900 break;
901
902 case GLX_GREEN_SIZE:
903 *value = 8;
904 break;
905
906 case GLX_BLUE_SIZE:
907 *value = 8;
908 break;
909
910 case GLX_ALPHA_SIZE:
911 *value = 8;
912 break;
913
914 case GLX_DEPTH_SIZE:
915 *value = 16;
916 break;
917
918 case GLX_STENCIL_SIZE:
919 *value = 8;
920 break;
921
922 case GLX_ACCUM_RED_SIZE:
923 *value = 16;
924 break;
925
926 case GLX_ACCUM_GREEN_SIZE:
927 *value = 16;
928 break;
929
930 case GLX_ACCUM_BLUE_SIZE:
931 *value = 16;
932 break;
933
934 case GLX_ACCUM_ALPHA_SIZE:
935 *value = 16;
936 break;
937
938 case GLX_SAMPLE_BUFFERS_SGIS:
939 *value = 0; /* fix someday */
940 break;
941
942 case GLX_SAMPLES_SGIS:
943 *value = 0; /* fix someday */
944 break;
945
946 case GLX_VISUAL_CAVEAT_EXT:
947 *value = GLX_NONE_EXT;
948 break;
949#if defined(SunOS) || 1
950 /*
951 I don't think this is even a valid attribute for glxGetConfig.
952 No idea why this gets called under SunOS but we simply ignore it
953 -- jw
954 */
955 case GLX_X_VISUAL_TYPE:
956 crWarning ("Ignoring Unsupported GLX Call: glxGetConfig with attrib 0x%x", attrib);
957 break;
958#endif
959
960 case GLX_TRANSPARENT_TYPE:
961 *value = GLX_NONE_EXT;
962 break;
963 case GLX_TRANSPARENT_INDEX_VALUE:
964 *value = 0;
965 break;
966 case GLX_TRANSPARENT_RED_VALUE:
967 *value = 0;
968 break;
969 case GLX_TRANSPARENT_GREEN_VALUE:
970 *value = 0;
971 break;
972 case GLX_TRANSPARENT_BLUE_VALUE:
973 *value = 0;
974 break;
975 case GLX_TRANSPARENT_ALPHA_VALUE:
976 *value = 0;
977 break;
978 default:
979 crWarning( "Unsupported GLX Call: glXGetConfig with attrib 0x%x, ignoring...", attrib );
980 //return GLX_BAD_ATTRIBUTE;
981 *value = 0;
982 }
983
984 return 0;
985}
986#endif
987
988DECLEXPORT(GLXContext) VBOXGLXTAG(glXGetCurrentContext)( void )
989{
990 if (stub.currentContext)
991 return (GLXContext) stub.currentContext->id;
992 else
993 return (GLXContext) NULL;
994}
995
996DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentDrawable)(void)
997{
998 return currentDrawable;
999}
1000
1001DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplay)(void)
1002{
1003 return currentDisplay;
1004}
1005
1006DECLEXPORT(Bool) VBOXGLXTAG(glXIsDirect)(Display *dpy, GLXContext ctx)
1007{
1008 (void) dpy;
1009 (void) ctx;
1010 crDebug("->glXIsDirect");
1011 return True;
1012}
1013
1014DECLEXPORT(Bool) VBOXGLXTAG(glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase)
1015{
1016 (void) dpy;
1017 (void) errorBase;
1018 (void) eventBase;
1019 return 1; /* You BET we do... */
1020}
1021
1022DECLEXPORT(Bool) VBOXGLXTAG(glXQueryVersion)( Display *dpy, int *major, int *minor )
1023{
1024 (void) dpy;
1025 *major = 1;
1026 *minor = 3;
1027 return 1;
1028}
1029
1030static XErrorHandler oldErrorHandler;
1031static unsigned char lastXError = Success;
1032
1033static int
1034errorHandler (Display *dpy, XErrorEvent *e)
1035{
1036 lastXError = e->error_code;
1037 return 0;
1038}
1039
1040DECLEXPORT(void) VBOXGLXTAG(glXSwapBuffers)( Display *dpy, GLXDrawable drawable )
1041{
1042 WindowInfo *window = stubGetWindowInfo(dpy, drawable);
1043 stubSwapBuffers( window, 0 );
1044
1045#ifdef VBOX_TEST_MEGOO
1046 if (!stub.bXExtensionsChecked)
1047 {
1048 stubCheckXExtensions(window);
1049 }
1050
1051 if (!stub.bHaveXComposite)
1052 {
1053 return;
1054 }
1055
1056 {
1057 Pixmap p;
1058 XWindowAttributes attr;
1059
1060 XLOCK(dpy);
1061 XGetWindowAttributes(dpy, window->drawable, &attr);
1062 if (attr.override_redirect)
1063 {
1064 XUNLOCK(dpy);
1065 return;
1066 }
1067
1068 crLockMutex(&stub.mutex);
1069
1070 XSync(dpy, false);
1071 oldErrorHandler = XSetErrorHandler(errorHandler);
1072 /*@todo this creates new pixmap for window every call*/
1073 /*p = XCompositeNameWindowPixmap(dpy, window->drawable);*/
1074 XSync(dpy, false);
1075 XSetErrorHandler(oldErrorHandler);
1076 XUNLOCK(dpy);
1077
1078 if (lastXError==Success)
1079 {
1080 char *data, *imgdata;
1081 GC gc;
1082 XImage *image;
1083 XVisualInfo searchvis, *pret;
1084 int nvisuals;
1085 XGCValues gcValues;
1086 int i, rowsize;
1087
1088 XLOCK(dpy);
1089
1090 searchvis.visualid = attr.visual->visualid;
1091 pret = XGetVisualInfo(dpy, VisualIDMask, &searchvis, &nvisuals);
1092 if (nvisuals!=1) crWarning("XGetVisualInfo returned %i visuals for %x", nvisuals, (unsigned int) searchvis.visualid);
1093 CRASSERT(pret);
1094
1095 gc = XCreateGC(dpy, window->drawable, 0, &gcValues);
1096 if (!gc) crWarning("Failed to create gc!");
1097
1098 data = crCalloc(window->width * window->height * 4);
1099 imgdata = crCalloc(window->width * window->height * 4);
1100 CRASSERT(data && imgdata);
1101 stub.spu->dispatch_table.ReadPixels(0, 0, window->width, window->height, GL_RGBA, GL_UNSIGNED_BYTE, data);
1102 /*y-invert image*/
1103 rowsize = 4*window->width;
1104 for (i=0; i<window->height; ++i)
1105 {
1106 crMemcpy(imgdata+rowsize*i, data+rowsize*(window->height-i-1), rowsize);
1107 }
1108 crFree(data);
1109
1110 XSync(dpy, false);
1111 image = XCreateImage(dpy, attr.visual, pret->depth, ZPixmap, 0, imgdata, window->width, window->height, 32, 0);
1112 XPutImage(dpy, window->drawable, gc, image, 0, 0, 0, 0, window->width, window->height);
1113
1114 XFree(pret);
1115 /*XFreePixmap(dpy, p);*/
1116 XFreeGC(dpy, gc);
1117 XDestroyImage(image);
1118 XUNLOCK(dpy);
1119 }
1120 lastXError=Success;
1121 crUnlockMutex(&stub.mutex);
1122 }
1123#endif
1124}
1125
1126#ifndef VBOX_NO_NATIVEGL
1127DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)( Font font, int first, int count, int listBase )
1128{
1129 if (stub.currentContext->type == CHROMIUM)
1130 {
1131 Display *dpy = stub.wsInterface.glXGetCurrentDisplay();
1132 if (dpy) {
1133 stubUseXFont( dpy, font, first, count, listBase );
1134 }
1135 else {
1136 dpy = XOpenDisplay(NULL);
1137 if (!dpy)
1138 return;
1139 stubUseXFont( dpy, font, first, count, listBase );
1140 XCloseDisplay(dpy);
1141 }
1142 } else
1143 stub.wsInterface.glXUseXFont( font, first, count, listBase );
1144}
1145#else /* not 0 */
1146DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)( Font font, int first, int count, int listBase )
1147{
1148 Display *dpy = stub.currentContext->dpy;
1149 if (dpy) {
1150 stubUseXFont( dpy, font, first, count, listBase );
1151 }
1152 else {
1153 dpy = XOpenDisplay(NULL);
1154 if (!dpy)
1155 return;
1156 stubUseXFont( dpy, font, first, count, listBase );
1157 XCloseDisplay(dpy);
1158 }
1159}
1160#endif
1161
1162DECLEXPORT(void) VBOXGLXTAG(glXWaitGL)( void )
1163{
1164 static int first_call = 1;
1165
1166 if ( first_call )
1167 {
1168 crDebug( "Ignoring unsupported GLX call: glXWaitGL()" );
1169 first_call = 0;
1170 }
1171}
1172
1173DECLEXPORT(void) VBOXGLXTAG(glXWaitX)( void )
1174{
1175 static int first_call = 1;
1176
1177 if ( first_call )
1178 {
1179 crDebug( "Ignoring unsupported GLX call: glXWaitX()" );
1180 first_call = 0;
1181 }
1182}
1183
1184DECLEXPORT(const char *) VBOXGLXTAG(glXQueryExtensionsString)( Display *dpy, int screen )
1185{
1186 /* XXX maybe also advertise GLX_SGIS_multisample? */
1187
1188 static const char *retval = "GLX_ARB_multisample GLX_EXT_texture_from_pixmap GLX_SGIX_fbconfig GLX_ARB_get_proc_address";
1189
1190 (void) dpy;
1191 (void) screen;
1192
1193 crDebug("->glXQueryExtensionsString");
1194 return retval;
1195}
1196
1197DECLEXPORT(const char *) VBOXGLXTAG(glXGetClientString)( Display *dpy, int name )
1198{
1199 const char *retval;
1200 (void) dpy;
1201 (void) name;
1202
1203 switch ( name ) {
1204
1205 case GLX_VENDOR:
1206 retval = "Chromium";
1207 break;
1208
1209 case GLX_VERSION:
1210 retval = "1.3 Chromium";
1211 break;
1212
1213 case GLX_EXTENSIONS:
1214 /*@todo should be a screen not a name...but it's not used anyway*/
1215 retval = glXQueryExtensionsString(dpy, name);
1216 break;
1217
1218 default:
1219 retval = NULL;
1220 }
1221
1222 return retval;
1223}
1224
1225DECLEXPORT(const char *) VBOXGLXTAG(glXQueryServerString)( Display *dpy, int screen, int name )
1226{
1227 const char *retval;
1228 (void) dpy;
1229 (void) screen;
1230
1231 switch ( name ) {
1232
1233 case GLX_VENDOR:
1234 retval = "Chromium";
1235 break;
1236
1237 case GLX_VERSION:
1238 retval = "1.3 Chromium";
1239 break;
1240
1241 case GLX_EXTENSIONS:
1242 retval = glXQueryExtensionsString(dpy, screen);
1243 break;
1244
1245 default:
1246 retval = NULL;
1247 }
1248
1249 return retval;
1250}
1251
1252DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddressARB)( const GLubyte *name )
1253{
1254 return (CR_GLXFuncPtr) crGetProcAddress( (const char *) name );
1255}
1256
1257DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddress)( const GLubyte *name )
1258{
1259 return (CR_GLXFuncPtr) crGetProcAddress( (const char *) name );
1260}
1261
1262
1263#if GLX_EXTRAS
1264
1265DECLEXPORT(GLXPbufferSGIX)
1266VBOXGLXTAG(glXCreateGLXPbufferSGIX)(Display *dpy, GLXFBConfigSGIX config,
1267 unsigned int width, unsigned int height,
1268 int *attrib_list)
1269{
1270 (void) dpy;
1271 (void) config;
1272 (void) width;
1273 (void) height;
1274 (void) attrib_list;
1275 crWarning("glXCreateGLXPbufferSGIX not implemented by Chromium");
1276 return 0;
1277}
1278
1279DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf)
1280{
1281 (void) dpy;
1282 (void) pbuf;
1283 crWarning("glXDestroyGLXPbufferSGIX not implemented by Chromium");
1284}
1285
1286DECLEXPORT(void) VBOXGLXTAG(glXSelectEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long mask)
1287{
1288 (void) dpy;
1289 (void) drawable;
1290 (void) mask;
1291}
1292
1293DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long *mask)
1294{
1295 (void) dpy;
1296 (void) drawable;
1297 (void) mask;
1298}
1299
1300DECLEXPORT(int) VBOXGLXTAG(glXQueryGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf,
1301 int attribute, unsigned int *value)
1302{
1303 (void) dpy;
1304 (void) pbuf;
1305 (void) attribute;
1306 (void) value;
1307 crWarning("glXQueryGLXPbufferSGIX not implemented by Chromium");
1308 return 0;
1309}
1310
1311DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttribSGIX)(Display *dpy, GLXFBConfig config,
1312 int attribute, int *value)
1313{
1314 return VBOXGLXTAG(glXGetFBConfigAttrib)(dpy, config, attribute, value);
1315}
1316
1317DECLEXPORT(GLXFBConfigSGIX *)
1318VBOXGLXTAG(glXChooseFBConfigSGIX)(Display *dpy, int screen,
1319 int *attrib_list, int *nelements)
1320{
1321 return VBOXGLXTAG(glXChooseFBConfig)(dpy, screen, attrib_list, nelements);
1322}
1323
1324DECLEXPORT(GLXPixmap)
1325VBOXGLXTAG(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy,
1326 GLXFBConfig config,
1327 Pixmap pixmap)
1328{
1329 return VBOXGLXTAG(glXCreatePixmap)(dpy, config, pixmap, NULL);
1330}
1331
1332DECLEXPORT(GLXContext)
1333VBOXGLXTAG(glXCreateContextWithConfigSGIX)(Display *dpy, GLXFBConfig config,
1334 int render_type,
1335 GLXContext share_list,
1336 Bool direct)
1337{
1338 if (render_type!=GLX_RGBA_TYPE_SGIX)
1339 {
1340 crWarning("glXCreateContextWithConfigSGIX: Unsupported render type %i", render_type);
1341 return NULL;
1342 }
1343 else
1344 {
1345 XVisualInfo *vis;
1346 GLXContext ret;
1347
1348 vis = VBOXGLXTAG(glXGetVisualFromFBConfigSGIX)(dpy, config);
1349 if (!vis)
1350 {
1351 crWarning("glXCreateContextWithConfigSGIX: no visuals for %p", config);
1352 return NULL;
1353 }
1354 ret = VBOXGLXTAG(glXCreateContext)(dpy, vis, share_list, direct);
1355 XFree(vis);
1356 return ret;
1357 }
1358}
1359
1360DECLEXPORT(XVisualInfo *)
1361VBOXGLXTAG(glXGetVisualFromFBConfigSGIX)(Display *dpy,
1362 GLXFBConfig config)
1363{
1364 return VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1365}
1366
1367DECLEXPORT(GLXFBConfigSGIX)
1368VBOXGLXTAG(glXGetFBConfigFromVisualSGIX)(Display *dpy, XVisualInfo *vis)
1369{
1370 if (!vis)
1371 {
1372 return NULL;
1373 }
1374 /*Note: Caller is supposed to call XFree on returned value, so can't just return (GLXFBConfig)vis->visualid*/
1375 return (GLXFBConfigSGIX) VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, (GLXFBConfig)vis->visualid);
1376}
1377
1378/*
1379 * GLX 1.3 functions
1380 */
1381DECLEXPORT(GLXFBConfig *)
1382VBOXGLXTAG(glXChooseFBConfig)(Display *dpy, int screen, ATTRIB_TYPE *attrib_list, int *nelements)
1383{
1384 ATTRIB_TYPE *attrib;
1385 intptr_t fbconfig = 0;
1386
1387 stubInit();
1388
1389 if (!attrib_list)
1390 {
1391 return VBOXGLXTAG(glXGetFBConfigs)(dpy, screen, nelements);
1392 }
1393
1394 for (attrib = attrib_list; *attrib != None; attrib++)
1395 {
1396 switch (*attrib)
1397 {
1398 case GLX_FBCONFIG_ID:
1399 fbconfig = attrib[1];
1400 attrib++;
1401 break;
1402
1403 case GLX_BUFFER_SIZE:
1404 /* this is for color-index visuals, which we don't support */
1405 goto err_exit;
1406 attrib++;
1407 break;
1408
1409 case GLX_LEVEL:
1410 if (attrib[1] != 0)
1411 goto err_exit;
1412 attrib++;
1413 break;
1414
1415 case GLX_AUX_BUFFERS:
1416 if (attrib[1] != 0)
1417 goto err_exit;
1418 attrib++;
1419 break;
1420
1421 case GLX_DOUBLEBUFFER: /* @todo, check if we support it */
1422 attrib++;
1423 break;
1424
1425 case GLX_STEREO:
1426 if (attrib[1] != 0)
1427 goto err_exit;
1428 attrib++;
1429 break;
1430
1431 case GLX_RED_SIZE:
1432 case GLX_GREEN_SIZE:
1433 case GLX_BLUE_SIZE:
1434 case GLX_ALPHA_SIZE:
1435 if (attrib[1] > 8)
1436 goto err_exit;
1437 attrib++;
1438 break;
1439
1440 case GLX_DEPTH_SIZE:
1441 if (attrib[1] > 16)
1442 goto err_exit;
1443 attrib++;
1444 break;
1445
1446 case GLX_STENCIL_SIZE:
1447 if (attrib[1] > 8)
1448 goto err_exit;
1449 attrib++;
1450 break;
1451
1452 case GLX_ACCUM_RED_SIZE:
1453 case GLX_ACCUM_GREEN_SIZE:
1454 case GLX_ACCUM_BLUE_SIZE:
1455 case GLX_ACCUM_ALPHA_SIZE:
1456 if (attrib[1] > 16)
1457 goto err_exit;
1458 attrib++;
1459 break;
1460
1461 case GLX_X_RENDERABLE:
1462 case GLX_CONFIG_CAVEAT:
1463 attrib++;
1464 break;
1465
1466 case GLX_RENDER_TYPE:
1467 if (attrib[1]!=GLX_RGBA_BIT)
1468 goto err_exit;
1469 attrib++;
1470 break;
1471
1472 case GLX_DRAWABLE_TYPE:
1473 if (attrib[1]!=GLX_WINDOW_BIT)
1474 goto err_exit;
1475 attrib++;
1476 break;
1477
1478 case GLX_X_VISUAL_TYPE:
1479 case GLX_TRANSPARENT_TYPE_EXT:
1480 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
1481 case GLX_TRANSPARENT_RED_VALUE_EXT:
1482 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
1483 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
1484 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
1485 /* ignore */
1486 crWarning("glXChooseVisual: ignoring attribute 0x%x", *attrib);
1487 attrib++;
1488 break;
1489
1490 break;
1491 default:
1492 crWarning( "glXChooseVisual: bad attrib=0x%x, ignoring", *attrib );
1493 attrib++;
1494 break;
1495 }
1496 }
1497
1498 if (fbconfig)
1499 {
1500 GLXFBConfig *pGLXFBConfigs;
1501
1502 *nelements = 1;
1503 pGLXFBConfigs = (GLXFBConfig *) crAlloc(*nelements * sizeof(GLXFBConfig));
1504 pGLXFBConfigs[0] = (GLXFBConfig)fbconfig;
1505 return pGLXFBConfigs;
1506 }
1507 else
1508 {
1509 return VBOXGLXTAG(glXGetFBConfigs)(dpy, screen, nelements);
1510 }
1511
1512err_exit:
1513 crWarning("glXChooseFBConfig returning NULL, due to attrib=0x%x, next=0x%x", attrib[0], attrib[1]);
1514 return NULL;
1515}
1516
1517DECLEXPORT(GLXContext)
1518VBOXGLXTAG(glXCreateNewContext)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
1519{
1520 XVisualInfo *vis;
1521
1522 (void) dpy;
1523 (void) config;
1524 (void) render_type;
1525 (void) share_list;
1526 (void) direct;
1527
1528 if (render_type != GLX_RGBA_TYPE)
1529 {
1530 crWarning("glXCreateNewContext, unsupported render_type %x", render_type);
1531 return NULL;
1532 }
1533
1534 vis = VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1535 return VBOXGLXTAG(glXCreateContext)(dpy, vis, share_list, direct);
1536}
1537
1538DECLEXPORT(GLXPbuffer)
1539VBOXGLXTAG(glXCreatePbuffer)(Display *dpy, GLXFBConfig config, ATTRIB_TYPE *attrib_list)
1540{
1541 (void) dpy;
1542 (void) config;
1543 (void) attrib_list;
1544 crWarning("glXCreatePbuffer not implemented by Chromium");
1545 return 0;
1546}
1547
1548/* Note: there're examples where glxpixmaps are created without current context, so can't do much of the work here.
1549 * Instead we'd do necessary initialization on first use of those pixmaps.
1550 */
1551DECLEXPORT(GLXPixmap)
1552VBOXGLXTAG(glXCreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const ATTRIB_TYPE *attrib_list)
1553{
1554 ATTRIB_TYPE *attrib;
1555 XVisualInfo *pVis;
1556 GLX_Pixmap_t *pGlxPixmap;
1557 (void) dpy;
1558 (void) config;
1559
1560#if 0
1561 {
1562 int x, y;
1563 unsigned int w, h;
1564 unsigned int border;
1565 unsigned int depth;
1566 Window root;
1567
1568 crDebug("glXCreatePixmap called for %lu", pixmap);
1569
1570 XLOCK(dpy);
1571 if (!XGetGeometry(dpy, pixmap, &root, &x, &y, &w, &h, &border, &depth))
1572 {
1573 XSync(dpy, False);
1574 if (!XGetGeometry(dpy, pixmap, &root, &x, &y, &w, &h, &border, &depth))
1575 {
1576 crDebug("fail");
1577 }
1578 }
1579 crDebug("root: %lu, [%i,%i %u,%u]", root, x, y, w, h);
1580 XUNLOCK(dpy);
1581 }
1582#endif
1583
1584 pGlxPixmap = crCalloc(sizeof(GLX_Pixmap_t));
1585 if (!pGlxPixmap)
1586 {
1587 crWarning("glXCreatePixmap failed to allocate memory");
1588 return 0;
1589 }
1590
1591 pVis = VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1592 if (!pVis)
1593 {
1594 crWarning("Unknown config %p in glXCreatePixmap", config);
1595 return 0;
1596 }
1597
1598 pGlxPixmap->format = pVis->depth==24 ? GL_RGB:GL_RGBA;
1599 pGlxPixmap->target = GL_TEXTURE_2D;
1600
1601 if (attrib_list)
1602 {
1603 for (attrib = attrib_list; *attrib != None; attrib++)
1604 {
1605 switch (*attrib)
1606 {
1607 case GLX_TEXTURE_FORMAT_EXT:
1608 attrib++;
1609 switch (*attrib)
1610 {
1611 case GLX_TEXTURE_FORMAT_RGBA_EXT:
1612 pGlxPixmap->format = GL_RGBA;
1613 break;
1614 case GLX_TEXTURE_FORMAT_RGB_EXT:
1615 pGlxPixmap->format = GL_RGB;
1616 break;
1617 default:
1618 crDebug("Unexpected GLX_TEXTURE_FORMAT_EXT 0x%x", (unsigned int) *attrib);
1619 }
1620 break;
1621 case GLX_TEXTURE_TARGET_EXT:
1622 attrib++;
1623 switch (*attrib)
1624 {
1625 case GLX_TEXTURE_2D_EXT:
1626 pGlxPixmap->target = GL_TEXTURE_2D;
1627 break;
1628 case GLX_TEXTURE_RECTANGLE_EXT:
1629 pGlxPixmap->target = GL_TEXTURE_RECTANGLE_NV;
1630 break;
1631 default:
1632 crDebug("Unexpected GLX_TEXTURE_TARGET_EXT 0x%x", (unsigned int) *attrib);
1633 }
1634 break;
1635 default: attrib++;
1636 }
1637 }
1638 }
1639
1640 crHashtableAdd(stub.pGLXPixmapsHash, (unsigned int) pixmap, pGlxPixmap);
1641 return (GLXPixmap) pixmap;
1642}
1643
1644DECLEXPORT(GLXWindow)
1645VBOXGLXTAG(glXCreateWindow)(Display *dpy, GLXFBConfig config, Window win, ATTRIB_TYPE *attrib_list)
1646{
1647 GLXFBConfig *realcfg;
1648 int nconfigs;
1649 //XVisualInfo *vis;
1650 (void) dpy;
1651 (void) config;
1652 (void) win;
1653 (void) attrib_list;
1654 //crWarning("glXCreateWindow not implemented by Chromium");
1655 //vis = VBOXGLXTAG(glXGetVisualFromFBConfig)(config);
1656 if (stub.wsInterface.glXGetFBConfigs)
1657 {
1658 realcfg = stub.wsInterface.glXGetFBConfigs(dpy, 0, &nconfigs);
1659 if (!realcfg || nconfigs<1)
1660 {
1661 crWarning("glXCreateWindow !realcfg || nconfigs<1");
1662 return 0;
1663 }
1664 else
1665 {
1666 return stub.wsInterface.glXCreateWindow(dpy, realcfg[0], win, attrib_list);
1667 }
1668 }
1669 else
1670 {
1671 crWarning("glXCreateWindow stub.wsInterface.glXChooseFBConfig==NULL");
1672 return 0;
1673 }
1674}
1675
1676DECLEXPORT(void) VBOXGLXTAG(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf)
1677{
1678 (void) dpy;
1679 (void) pbuf;
1680 crWarning("glXDestroyPbuffer not implemented by Chromium");
1681}
1682
1683DECLEXPORT(void) VBOXGLXTAG(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap)
1684{
1685 GLX_Pixmap_t *pGlxPixmap;
1686
1687 if (!stub.currentContext)
1688 {
1689 crWarning("glXDestroyPixmap failed, no current context");
1690 return;
1691 }
1692
1693 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.currentContext->pGLXPixmapsHash, (unsigned int) pixmap);
1694
1695 if (pGlxPixmap)
1696 {
1697 XLOCK(dpy);
1698 if (pGlxPixmap->gc)
1699 {
1700 XFreeGC(dpy, pGlxPixmap->gc);
1701 }
1702
1703 if (pGlxPixmap->hShmPixmap>0)
1704 {
1705 XFreePixmap(dpy, pGlxPixmap->hShmPixmap);
1706 }
1707 XUNLOCK(dpy);
1708
1709 if (pGlxPixmap->hDamage>0)
1710 {
1711 //crDebug("Destroy: Damage for drawable 0x%x, handle 0x%x", (unsigned int) pixmap, (unsigned int) pGlxPixmap->damage);
1712 XDamageDestroy(stub.currentContext->damageDpy, pGlxPixmap->hDamage);
1713 }
1714
1715 if (pGlxPixmap->pDamageRegion)
1716 {
1717 XDestroyRegion(pGlxPixmap->pDamageRegion);
1718 }
1719
1720 crHashtableDelete(stub.currentContext->pGLXPixmapsHash, (unsigned int) pixmap, crFree);
1721 }
1722 /*else
1723 {
1724 crWarning("glXDestroyPixmap called for unknown glxpixmap 0x%x", (unsigned int) pixmap);
1725 }*/
1726}
1727
1728DECLEXPORT(void) VBOXGLXTAG(glXDestroyWindow)(Display *dpy, GLXWindow win)
1729{
1730 (void) dpy;
1731 (void) win;
1732 crWarning("glXDestroyWindow not implemented by Chromium");
1733}
1734
1735DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentReadDrawable)(void)
1736{
1737 //crWarning("glXGetCurrentReadDrawable not implemented by Chromium");
1738 return currentReadDrawable;
1739}
1740
1741DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value)
1742{
1743 XVisualInfo * pVisual;
1744 const char * pExt;
1745
1746 pVisual = VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1747 if (!pVisual)
1748 {
1749 crWarning("glXGetFBConfigAttrib for %p, failed to get XVisualInfo", config);
1750 return GLX_BAD_ATTRIBUTE;
1751 }
1752 //crDebug("glXGetFBConfigAttrib 0x%x for 0x%x, visualid=0x%x, depth=%i", attribute, (int)config, (int)pVisual->visualid, pVisual->depth);
1753
1754
1755 switch (attribute)
1756 {
1757 case GLX_DRAWABLE_TYPE:
1758 *value = GLX_PIXMAP_BIT;
1759 break;
1760 case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
1761 *value = GLX_TEXTURE_2D_BIT_EXT;
1762 pExt = (const char *) stub.spu->dispatch_table.GetString(GL_EXTENSIONS);
1763 if (crStrstr(pExt, "GL_NV_texture_rectangle")
1764 || crStrstr(pExt, "GL_ARB_texture_rectangle")
1765 || crStrstr(pExt, "GL_EXT_texture_rectangle"))
1766 {
1767 *value |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
1768 }
1769 break;
1770 case GLX_BIND_TO_TEXTURE_RGBA_EXT:
1771 *value = pVisual->depth==32;
1772 break;
1773 case GLX_BIND_TO_TEXTURE_RGB_EXT:
1774 *value = True;
1775 break;
1776 case GLX_DOUBLEBUFFER:
1777 //crDebug("attribute=GLX_DOUBLEBUFFER");
1778 *value = True;
1779 break;
1780 case GLX_Y_INVERTED_EXT:
1781 *value = True;
1782 break;
1783 case GLX_ALPHA_SIZE:
1784 //crDebug("attribute=GLX_ALPHA_SIZE");
1785 *value = pVisual->depth==32 ? 8:0;
1786 break;
1787 case GLX_BUFFER_SIZE:
1788 //crDebug("attribute=GLX_BUFFER_SIZE");
1789 *value = pVisual->depth;
1790 break;
1791 case GLX_STENCIL_SIZE:
1792 //crDebug("attribute=GLX_STENCIL_SIZE");
1793 *value = 8;
1794 break;
1795 case GLX_DEPTH_SIZE:
1796 *value = 16;
1797 //crDebug("attribute=GLX_DEPTH_SIZE");
1798 break;
1799 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
1800 *value = 0;
1801 break;
1802 case GLX_RENDER_TYPE:
1803 //crDebug("attribute=GLX_RENDER_TYPE");
1804 *value = GLX_RGBA_BIT;
1805 break;
1806 case GLX_CONFIG_CAVEAT:
1807 //crDebug("attribute=GLX_CONFIG_CAVEAT");
1808 *value = GLX_NONE;
1809 break;
1810 case GLX_VISUAL_ID:
1811 //crDebug("attribute=GLX_VISUAL_ID");
1812 *value = pVisual->visualid;
1813 break;
1814 case GLX_FBCONFIG_ID:
1815 *value = pVisual->visualid; /*or config, though those are the same at the moment but this could change one day?*/
1816 break;
1817 case GLX_RED_SIZE:
1818 case GLX_GREEN_SIZE:
1819 case GLX_BLUE_SIZE:
1820 *value = 8;
1821 break;
1822 case GLX_LEVEL:
1823 *value = 0;
1824 break;
1825 case GLX_STEREO:
1826 *value = false;
1827 break;
1828 case GLX_AUX_BUFFERS:
1829 *value = 0;
1830 break;
1831 case GLX_ACCUM_RED_SIZE:
1832 case GLX_ACCUM_GREEN_SIZE:
1833 case GLX_ACCUM_BLUE_SIZE:
1834 case GLX_ACCUM_ALPHA_SIZE:
1835 *value = 0;
1836 break;
1837 case GLX_X_VISUAL_TYPE:
1838 *value = GLX_TRUE_COLOR;
1839 break;
1840 case GLX_TRANSPARENT_TYPE:
1841 *value = GLX_NONE;
1842 break;
1843 case GLX_SAMPLE_BUFFERS:
1844 case GLX_SAMPLES:
1845 *value = 1;
1846 break;
1847 case GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:
1848 *value = 0;
1849 break;
1850 default:
1851 crDebug("glXGetFBConfigAttrib: unknown attribute=0x%x", attribute);
1852 XFree(pVisual);
1853 return GLX_BAD_ATTRIBUTE;
1854 }
1855
1856 XFree(pVisual);
1857 return Success;
1858}
1859
1860#if !defined(VBOX_NO_NATIVEGL) || 1 /* need fbconfigs atleast for depths 24 and 32 */
1861DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
1862{
1863 GLXFBConfig *pGLXFBConfigs = NULL;
1864 struct VisualInfo *v;
1865 int i=0, cVisuals;
1866 XVisualInfo searchvis, *pVisuals;
1867
1868 *nelements = 0;
1869
1870 /*
1871 for (v = VisualInfoList; v; v = v->next) {
1872 if (v->dpy == dpy && v->screen == screen)
1873 ++*nelements;
1874 }
1875
1876 if (*nelements)
1877 pGLXFBConfigs = crAlloc(*nelements * sizeof(GLXFBConfig));
1878
1879 for (v = VisualInfoList; v && i<*nelements; v = v->next) {
1880 if (v->dpy == dpy && v->screen == screen)
1881 pGLXFBConfigs[i++] = (GLXFBConfig) v->visualid;
1882 }
1883 */
1884
1885 /*@todo doesn't really list all the common visuals, have to use some static list*/
1886 searchvis.screen = screen;
1887 XLOCK(dpy);
1888 pVisuals = XGetVisualInfo(dpy, VisualScreenMask, &searchvis, nelements);
1889 XUNLOCK(dpy);
1890
1891 if (*nelements)
1892 pGLXFBConfigs = crAlloc(*nelements * sizeof(GLXFBConfig));
1893
1894 for (i=0; i<*nelements; ++i)
1895 {
1896 pGLXFBConfigs[i] = (GLXFBConfig) pVisuals[i].visualid;
1897 }
1898
1899 XFree(pVisuals);
1900
1901 crDebug("glXGetFBConfigs returned %i configs", *nelements);
1902 for (i=0; i<*nelements; ++i)
1903 {
1904 crDebug("glXGetFBConfigs[%i]=%p", i, pGLXFBConfigs[i]);
1905 }
1906 return pGLXFBConfigs;
1907}
1908#else /* not 0 */
1909DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
1910{
1911 int i;
1912
1913 GLXFBConfig *pGLXFBConfigs = crAlloc(sizeof(GLXFBConfig));
1914
1915 *nelements = 1;
1916 XLOCK(dpy);
1917 *pGLXFBConfigs = (GLXFBConfig) XVisualIDFromVisual(DefaultVisual(dpy, screen));
1918 XUNLOCK(dpy);
1919
1920 crDebug("glXGetFBConfigs returned %i configs", *nelements);
1921 for (i=0; i<*nelements; ++i)
1922 {
1923 crDebug("glXGetFBConfigs[%i]=0x%x", i, (unsigned int) pGLXFBConfigs[i]);
1924 }
1925 return pGLXFBConfigs;
1926}
1927#endif
1928
1929DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEvent)(Display *dpy, GLXDrawable draw, unsigned long *event_mask)
1930{
1931 (void) dpy;
1932 (void) draw;
1933 (void) event_mask;
1934 crWarning("glXGetSelectedEvent not implemented by Chromium");
1935}
1936
1937DECLEXPORT(XVisualInfo *) VBOXGLXTAG(glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config)
1938{
1939 (void) dpy;
1940 (void) config;
1941
1942 struct VisualInfo *v;
1943
1944 /*
1945 for (v = VisualInfoList; v; v = v->next) {
1946 if (v->dpy == dpy && v->visualid == (VisualID)config)
1947 {
1948 XVisualInfo temp, *pret;
1949 int nret;
1950
1951 temp.visualid = v->visualid;
1952 pret = XGetVisualInfo(dpy, VisualIDMask, &temp, &nret);
1953
1954 if (nret!=1) crWarning("XGetVisualInfo returned %i visuals", nret);
1955 crDebug("glXGetVisualFromFBConfig(cfg/visid==0x%x): depth=%i", (int) config, pret->depth);
1956 return pret;
1957 }
1958 }
1959 */
1960 {
1961 XVisualInfo temp, *pret;
1962 int nret;
1963
1964 temp.visualid = (VisualID)config;
1965 XLOCK(dpy);
1966 pret = XGetVisualInfo(dpy, VisualIDMask, &temp, &nret);
1967 XUNLOCK(dpy);
1968
1969 if (nret!=1)
1970 {
1971 crWarning("XGetVisualInfo returned %i visuals for %p", nret, config);
1972 /* Hack for glut based apps.
1973 We fail to patch first call to glXChooseFBConfigSGIX, which ends up in the mesa's fbconfigs being passed to this function later.
1974 */
1975 if (!nret && config)
1976 {
1977 temp.visualid = (VisualID) ((__GLcontextModes*)config)->visualID;
1978 XLOCK(dpy);
1979 pret = XGetVisualInfo(dpy, VisualIDMask, &temp, &nret);
1980 XUNLOCK(dpy);
1981 crWarning("Retry with %#x returned %i visuals", ((__GLcontextModes*)config)->visualID, nret);
1982 }
1983 }
1984 //crDebug("glXGetVisualFromFBConfig(cfg/visid==0x%x): depth=%i", (int) config, pret->depth);
1985//crDebug("here");
1986 return pret;
1987 }
1988
1989 crDebug("glXGetVisualFromFBConfig unknown fbconfig %p", config);
1990 return NULL;
1991}
1992
1993DECLEXPORT(Bool) VBOXGLXTAG(glXMakeContextCurrent)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
1994{
1995 (void) display;
1996 (void) draw;
1997 (void) read;
1998 (void) ctx;
1999 //crWarning("glXMakeContextCurrent not implemented by Chromium");
2000 currentReadDrawable = read;
2001 return VBOXGLXTAG(glXMakeCurrent)(display, draw, ctx);
2002}
2003
2004DECLEXPORT(int) VBOXGLXTAG(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value)
2005{
2006 (void) dpy;
2007 (void) ctx;
2008 (void) attribute;
2009 (void) value;
2010 crWarning("glXQueryContext not implemented by Chromium");
2011 return 0;
2012}
2013
2014DECLEXPORT(void) VBOXGLXTAG(glXQueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
2015{
2016 (void) dpy;
2017 (void) draw;
2018 (void) attribute;
2019 (void) value;
2020 crWarning("glXQueryDrawable not implemented by Chromium");
2021}
2022
2023DECLEXPORT(void) VBOXGLXTAG(glXSelectEvent)(Display *dpy, GLXDrawable draw, unsigned long event_mask)
2024{
2025 (void) dpy;
2026 (void) draw;
2027 (void) event_mask;
2028 crWarning("glXSelectEvent not implemented by Chromium");
2029}
2030
2031#ifdef CR_EXT_texture_from_pixmap
2032/*typedef struct
2033{
2034 int x, y;
2035 unsigned int w, h, border, depth;
2036 Window root;
2037 void *data;
2038} pminfo;*/
2039
2040static void stubInitXSharedMemory(Display *dpy)
2041{
2042 int vma, vmi;
2043 Bool pixmaps;
2044
2045 if (stub.bShmInitFailed || stub.xshmSI.shmid>=0)
2046 return;
2047
2048 stub.bShmInitFailed = GL_TRUE;
2049
2050 /* Check for extension and pixmaps format */
2051 XLOCK(dpy);
2052 if (!XShmQueryExtension(dpy))
2053 {
2054 crWarning("No XSHM extension");
2055 XUNLOCK(dpy);
2056 return;
2057 }
2058
2059 if (!XShmQueryVersion(dpy, &vma, &vmi, &pixmaps) || !pixmaps)
2060 {
2061 crWarning("XSHM extension doesn't support pixmaps");
2062 XUNLOCK(dpy);
2063 return;
2064 }
2065
2066 if (XShmPixmapFormat(dpy)!=ZPixmap)
2067 {
2068 crWarning("XSHM extension doesn't support ZPixmap format");
2069 XUNLOCK(dpy);
2070 return;
2071 }
2072 XUNLOCK(dpy);
2073
2074 /* Alloc shared memory, so far using hardcoded value...could fail for bigger displays one day */
2075 stub.xshmSI.readOnly = false;
2076 stub.xshmSI.shmid = shmget(IPC_PRIVATE, 4*4096*2048, IPC_CREAT | 0600);
2077 if (stub.xshmSI.shmid<0)
2078 {
2079 crWarning("XSHM Failed to create shared segment");
2080 return;
2081 }
2082
2083 stub.xshmSI.shmaddr = (char*) shmat(stub.xshmSI.shmid, NULL, 0);
2084 if (stub.xshmSI.shmaddr==(void*)-1)
2085 {
2086 crWarning("XSHM Failed to attach shared segment");
2087 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
2088 return;
2089 }
2090
2091 XLOCK(dpy);
2092 if (!XShmAttach(dpy, &stub.xshmSI))
2093 {
2094 crWarning("XSHM Failed to attach shared segment to XServer");
2095 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
2096 shmdt(stub.xshmSI.shmaddr);
2097 XUNLOCK(dpy);
2098 return;
2099 }
2100 XUNLOCK(dpy);
2101
2102 stub.bShmInitFailed = GL_FALSE;
2103 crInfo("Using XSHM for GLX_EXT_texture_from_pixmap");
2104
2105 /*Anyway mark to be deleted when our process detaches it, in case of segfault etc*/
2106
2107/* Ramshankar: Solaris compiz fix */
2108#ifndef RT_OS_SOLARIS
2109 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
2110#endif
2111}
2112
2113static void stubInitXDamageExtension(ContextInfo *pContext)
2114{
2115 int erb, vma, vmi;
2116
2117 CRASSERT(pContext);
2118
2119 if (pContext->damageInitFailed || pContext->damageDpy)
2120 return;
2121
2122 pContext->damageInitFailed = True;
2123
2124 /* Open second xserver connection to make sure we'd receive all the xdamage messages
2125 * and those wouldn't be eaten by application even queue */
2126 pContext->damageDpy = XOpenDisplay(DisplayString(pContext->dpy));
2127
2128 if (!pContext->damageDpy)
2129 {
2130 crWarning("XDamage: Can't connect to display %s", DisplayString(pContext->dpy));
2131 return;
2132 }
2133
2134 if (!XDamageQueryExtension(pContext->damageDpy, &pContext->damageEventsBase, &erb)
2135 || !XDamageQueryVersion(pContext->damageDpy, &vma, &vmi))
2136 {
2137 crWarning("XDamage not found or old version (%i.%i), going to run *very* slow", vma, vmi);
2138 XCloseDisplay(pContext->damageDpy);
2139 pContext->damageDpy = NULL;
2140 return;
2141 }
2142
2143 crDebug("XDamage %i.%i", vma, vmi);
2144 pContext->damageInitFailed = False;
2145}
2146
2147static void stubCheckXDamageCB(unsigned long key, void *data1, void *data2)
2148{
2149 GLX_Pixmap_t *pGlxPixmap = (GLX_Pixmap_t *) data1;
2150 XDamageNotifyEvent *e = (XDamageNotifyEvent *) data2;
2151
2152 if (pGlxPixmap->hDamage==e->damage)
2153 {
2154 /*crDebug("Event: Damage for pixmap 0x%lx(drawable 0x%x), handle 0x%x (level=%i) [%i,%i,%i,%i]",
2155 key, (unsigned int) e->drawable, (unsigned int) e->damage, (int) e->level,
2156 e->area.x, e->area.y, e->area.width, e->area.height);*/
2157
2158 if (pGlxPixmap->pDamageRegion)
2159 {
2160 /* If it's dirty and regions are empty, it marked for full update, so do nothing.*/
2161 if (!pGlxPixmap->bPixmapImageDirty || !XEmptyRegion(pGlxPixmap->pDamageRegion))
2162 {
2163 if (CR_MAX_DAMAGE_REGIONS_TRACKED <= pGlxPixmap->pDamageRegion->numRects)
2164 {
2165 /* Mark for full update */
2166 EMPTY_REGION(pGlxPixmap->pDamageRegion);
2167 }
2168 else
2169 {
2170 /* Add to damage regions */
2171 XUnionRectWithRegion(&e->area, pGlxPixmap->pDamageRegion, pGlxPixmap->pDamageRegion);
2172 }
2173 }
2174 }
2175
2176 pGlxPixmap->bPixmapImageDirty = True;
2177 }
2178}
2179
2180static GLX_Pixmap_t* stubInitGlxPixmap(GLX_Pixmap_t* pCreateInfoPixmap, Display *dpy, GLXDrawable draw, ContextInfo *pContext)
2181{
2182 int x, y;
2183 unsigned int w, h;
2184 unsigned int border;
2185 unsigned int depth;
2186 Window root;
2187 GLX_Pixmap_t *pGlxPixmap;
2188
2189 CRASSERT(pContext && pCreateInfoPixmap);
2190
2191 XLOCK(dpy);
2192 if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
2193 {
2194 XSync(dpy, False);
2195 if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
2196 {
2197 crWarning("stubInitGlxPixmap failed in call to XGetGeometry for 0x%x", (int) draw);
2198 XUNLOCK(dpy);
2199 return NULL;
2200 }
2201 }
2202
2203 pGlxPixmap = crAlloc(sizeof(GLX_Pixmap_t));
2204 if (!pGlxPixmap)
2205 {
2206 crWarning("stubInitGlxPixmap failed to allocate memory");
2207 XUNLOCK(dpy);
2208 return NULL;
2209 }
2210
2211 pGlxPixmap->x = x;
2212 pGlxPixmap->y = y;
2213 pGlxPixmap->w = w;
2214 pGlxPixmap->h = h;
2215 pGlxPixmap->border = border;
2216 pGlxPixmap->depth = depth;
2217 pGlxPixmap->root = root;
2218 pGlxPixmap->format = pCreateInfoPixmap->format;
2219 pGlxPixmap->target = pCreateInfoPixmap->target;
2220
2221 /* Try to allocate shared memory
2222 * As we're allocating huge chunk of memory, do it in this function, only if this extension is really used
2223 */
2224 if (!stub.bShmInitFailed && stub.xshmSI.shmid<0)
2225 {
2226 stubInitXSharedMemory(dpy);
2227 }
2228
2229 if (stub.xshmSI.shmid>=0)
2230 {
2231 XGCValues xgcv;
2232 xgcv.graphics_exposures = False;
2233 xgcv.subwindow_mode = IncludeInferiors;
2234 pGlxPixmap->gc = XCreateGC(dpy, (Pixmap)draw, GCGraphicsExposures|GCSubwindowMode, &xgcv);
2235
2236 pGlxPixmap->hShmPixmap = XShmCreatePixmap(dpy, pGlxPixmap->root, stub.xshmSI.shmaddr, &stub.xshmSI,
2237 pGlxPixmap->w, pGlxPixmap->h, pGlxPixmap->depth);
2238 }
2239 else
2240 {
2241 pGlxPixmap->gc = NULL;
2242 pGlxPixmap->hShmPixmap = 0;
2243 }
2244 XUNLOCK(dpy);
2245
2246 stubInitXDamageExtension(pContext);
2247
2248 /* If there's damage extension, then get handle for damage events related to this pixmap */
2249 if (pContext->damageDpy)
2250 {
2251 pGlxPixmap->hDamage = XDamageCreate(pContext->damageDpy, (Pixmap)draw, XDamageReportRawRectangles);
2252 /*crDebug("Create: Damage for drawable 0x%x, handle 0x%x (level=%i)",
2253 (unsigned int) draw, (unsigned int) pGlxPixmap->damage, (int) XDamageReportRawRectangles);*/
2254 pGlxPixmap->pDamageRegion = XCreateRegion();
2255 if (!pGlxPixmap->pDamageRegion)
2256 {
2257 crWarning("stubInitGlxPixmap failed to create empty damage region for drawable 0x%x", (unsigned int) draw);
2258 }
2259
2260 /*We have never seen this pixmap before, so mark it as dirty for first use*/
2261 pGlxPixmap->bPixmapImageDirty = True;
2262 }
2263 else
2264 {
2265 pGlxPixmap->hDamage = 0;
2266 pGlxPixmap->pDamageRegion = NULL;
2267 }
2268
2269 /* glTexSubImage2D generates GL_INVALID_OP if texture array hasn't been defined by a call to glTexImage2D first.
2270 * It's fine for small textures which would be updated in stubXshmUpdateWholeImage, but we'd never call glTexImage2D for big ones.
2271 * Note that we're making empty texture by passing NULL as pixels pointer, so there's no overhead transferring data to host.*/
2272 if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
2273 {
2274 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pGlxPixmap->w, pGlxPixmap->h, 0,
2275 GL_BGRA, GL_UNSIGNED_BYTE, NULL);
2276 }
2277
2278 crHashtableAdd(pContext->pGLXPixmapsHash, (unsigned int) draw, pGlxPixmap);
2279 crHashtableDelete(stub.pGLXPixmapsHash, (unsigned int) draw, crFree);
2280
2281 return pGlxPixmap;
2282}
2283
2284static void stubXshmUpdateWholeImage(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap)
2285{
2286 /* To limit the size of transferring buffer, split bigger texture into regions
2287 * which fit into connection buffer. Could be done in hgcm or packspu but implementation in this place allows to avoid
2288 * unnecessary memcpy.
2289 * This also workarounds guest driver failures when sending 6+mb texture buffers on linux.
2290 */
2291 if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
2292 {
2293 XRectangle rect;
2294
2295 rect.x = pGlxPixmap->x;
2296 rect.y = pGlxPixmap->y;
2297 rect.width = pGlxPixmap->w;
2298 rect.height = CR_MAX_TRANSFER_SIZE/(4*pGlxPixmap->w);
2299
2300 /*crDebug("Texture size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
2301 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, rect.height);*/
2302
2303 for (; (rect.y+rect.height)<=(pGlxPixmap->y+pGlxPixmap->h); rect.y+=rect.height)
2304 {
2305 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2306 }
2307
2308 if (rect.y!=(pGlxPixmap->y+pGlxPixmap->h))
2309 {
2310 rect.height=pGlxPixmap->h-rect.y;
2311 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2312 }
2313 }
2314 else
2315 {
2316 XLOCK(dpy);
2317 XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
2318 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, 0, 0);
2319 /* Have to make sure XCopyArea is processed */
2320 XSync(dpy, False);
2321 XUNLOCK(dpy);
2322 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pGlxPixmap->w, pGlxPixmap->h, 0,
2323 GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
2324 /*crDebug("Sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
2325 (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
2326 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);*/
2327 }
2328}
2329
2330static void stubXshmUpdateImageRect(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap, XRectangle *pRect)
2331{
2332 /* See comment in stubXshmUpdateWholeImage */
2333 if (CR_MAX_TRANSFER_SIZE < 4*pRect->width*pRect->height)
2334 {
2335 XRectangle rect;
2336
2337 rect.x = pRect->x;
2338 rect.y = pRect->y;
2339 rect.width = pRect->width;
2340 rect.height = CR_MAX_TRANSFER_SIZE/(4*pRect->width);
2341
2342 /*crDebug("Region size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
2343 pRect->x, pRect->y, pRect->width, pRect->height, rect.height);*/
2344
2345 for (; (rect.y+rect.height)<=(pRect->y+pRect->height); rect.y+=rect.height)
2346 {
2347 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2348 }
2349
2350 if (rect.y!=(pRect->y+pRect->height))
2351 {
2352 rect.height=pRect->y+pRect->height-rect.y;
2353 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2354 }
2355 }
2356 else
2357 {
2358 GLint origUnpackRowLength;
2359
2360 XLOCK(dpy);
2361 XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
2362 pRect->x, pRect->y, pRect->width, pRect->height, 0, 0);
2363 /* Have to make sure XCopyArea is processed */
2364 XSync(dpy, False);
2365 XUNLOCK(dpy);
2366
2367 /* Save original value, doesn't cause sync as it's reported by state tracker*/
2368 if (pRect->width!=pGlxPixmap->w)
2369 {
2370 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_ROW_LENGTH, &origUnpackRowLength);
2371 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, pGlxPixmap->w);
2372 }
2373 stub.spu->dispatch_table.TexSubImage2D(pGlxPixmap->target, 0, pRect->x, pRect->y, pRect->width, pRect->height,
2374 GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
2375 if (pRect->width!=pGlxPixmap->w)
2376 {
2377 /* Restore original value*/
2378 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, origUnpackRowLength);
2379 }
2380
2381 /*crDebug("Region sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
2382 (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
2383 pRect->x, pRect->y, pRect->width, pRect->height);*/
2384 }
2385}
2386
2387#if 0
2388Bool checkevents(Display *display, XEvent *event, XPointer arg)
2389{
2390 //crDebug("got type: 0x%x", event->type);
2391 if (event->type==damage_evb+XDamageNotify)
2392 {
2393 XDamageNotifyEvent *e = (XDamageNotifyEvent *) event;
2394 /* we're interested in pixmaps only...and those have e->drawable set to 0 or other strange value for some odd reason
2395 * so have to walk glxpixmaps hashtable to find if we have damage event handle assigned to some pixmap
2396 */
2397 /*crDebug("Event: Damage for drawable 0x%x, handle 0x%x (level=%i) [%i,%i,%i,%i]",
2398 (unsigned int) e->drawable, (unsigned int) e->damage, (int) e->level,
2399 e->area.x, e->area.y, e->area.width, e->area.height);*/
2400 CRASSERT(stub.currentContext);
2401 crHashtableWalk(stub.currentContext->pGLXPixmapsHash, checkdamageCB, e);
2402 }
2403 return False;
2404}
2405#endif
2406
2407/*@todo check what error codes could we throw for failures here*/
2408DECLEXPORT(void) VBOXGLXTAG(glXBindTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer, const int *attrib_list)
2409{
2410 static int cnt=0;
2411 XImage dummyimg;
2412
2413 GLX_Pixmap_t *pGlxPixmap;
2414
2415 if (!stub.currentContext)
2416 {
2417 crWarning("glXBindTexImageEXT called without current context");
2418 return;
2419 }
2420
2421 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.currentContext->pGLXPixmapsHash, (unsigned int) draw);
2422 if (!pGlxPixmap)
2423 {
2424 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) draw);
2425 if (!pGlxPixmap)
2426 {
2427 crDebug("Unknown drawable 0x%x in glXBindTexImageEXT!", (unsigned int) draw);
2428 return;
2429 }
2430 pGlxPixmap = stubInitGlxPixmap(pGlxPixmap, dpy, draw, stub.currentContext);
2431 if (!pGlxPixmap)
2432 {
2433 crDebug("glXBindTexImageEXT failed to get pGlxPixmap");
2434 return;
2435 }
2436 }
2437
2438 /* If there's damage extension, then process incoming events as we need the information right now */
2439 if (stub.currentContext->damageDpy)
2440 {
2441 /* Sync connections, note that order of syncs is important here.
2442 * First make sure client commands are finished, then make sure we get all the damage events back*/
2443 XLOCK(dpy);
2444 XSync(dpy, False);
2445 XUNLOCK(dpy);
2446 XSync(stub.currentContext->damageDpy, False);
2447
2448 while (XPending(stub.currentContext->damageDpy))
2449 {
2450 XEvent event;
2451 XNextEvent(stub.currentContext->damageDpy, &event);
2452 if (event.type==stub.currentContext->damageEventsBase+XDamageNotify)
2453 {
2454 crHashtableWalk(stub.currentContext->pGLXPixmapsHash, stubCheckXDamageCB, &event);
2455 }
2456 }
2457 }
2458
2459 /* No shared memory? Rollback to use slow x protocol then */
2460 if (stub.xshmSI.shmid<0)
2461 {
2462 /*@todo add damage support here too*/
2463 XImage *pxim;
2464
2465 XLOCK(dpy);
2466 pxim = XGetImage(dpy, (Pixmap)draw, pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, AllPlanes, ZPixmap);
2467 XUNLOCK(dpy);
2468 /*if (pxim)
2469 {
2470 if (!ptextable)
2471 {
2472 ptextable = crAllocHashtable();
2473 }
2474 pm = crHashtableSearch(ptextable, (unsigned int) draw);
2475 if (!pm)
2476 {
2477 pm = crCalloc(sizeof(pminfo));
2478 crHashtableAdd(ptextable, (unsigned int) draw, pm);
2479 }
2480 pm->w = w;
2481 pm->h = h;
2482 if (pm->data) crFree(pm->data);
2483 pm->data = crAlloc(4*w*h);
2484 crMemcpy(pm->data, (void*)(&(pxim->data[0])), 4*w*h);
2485 }*/
2486
2487 if (NULL==pxim)
2488 {
2489 crWarning("Failed, to get pixmap data for 0x%x", (unsigned int) draw);
2490 return;
2491 }
2492
2493 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pxim->width, pxim->height, 0,
2494 GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(pxim->data[0])));
2495 XDestroyImage(pxim);
2496 }
2497 else /* Use shm to get pixmap data */
2498 {
2499 /* Check if we have damage extension */
2500 if (stub.currentContext->damageDpy)
2501 {
2502 if (pGlxPixmap->bPixmapImageDirty)
2503 {
2504 /* Either we failed to allocate damage region or this pixmap is marked for full update */
2505 if (!pGlxPixmap->pDamageRegion || XEmptyRegion(pGlxPixmap->pDamageRegion))
2506 {
2507 /*crDebug("**FULL** update for 0x%x", (unsigned int)draw);*/
2508 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2509 }
2510 else
2511 {
2512 long fullArea, damageArea=0, clipdamageArea, i;
2513 XRectangle damageClipBox;
2514
2515 fullArea = pGlxPixmap->w * pGlxPixmap->h;
2516 XClipBox(pGlxPixmap->pDamageRegion, &damageClipBox);
2517 clipdamageArea = damageClipBox.width * damageClipBox.height;
2518
2519 //crDebug("FullSize [%i,%i,%i,%i]", pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);
2520 //crDebug("Clip [%i,%i,%i,%i]", damageClipBox.x, damageClipBox.y, damageClipBox.width, damageClipBox.height);
2521
2522 for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
2523 {
2524 BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
2525 damageArea += (pBox->x2-pBox->x1)*(pBox->y2-pBox->y1);
2526 //crDebug("Damage rect [%i,%i,%i,%i]", pBox->x1, pBox->y1, pBox->x2, pBox->y2);
2527 }
2528
2529 if (damageArea>clipdamageArea || clipdamageArea>fullArea)
2530 {
2531 crWarning("glXBindTexImageEXT, damage regions seems to be broken, forcing full update");
2532 /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
2533 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2534 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2535 }
2536 else /*We have corect damage info*/
2537 {
2538 if (CR_MIN_DAMAGE_PROFIT_SIZE > (fullArea-damageArea))
2539 {
2540 /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
2541 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2542 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2543 }
2544 else if (CR_MIN_DAMAGE_PROFIT_SIZE > (clipdamageArea-damageArea))
2545 {
2546 /*crDebug("**PARTIAL** update for 0x%x, numRect=%li, FS=%li, *CS*=%li, DS=%li",
2547 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2548 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &damageClipBox);
2549 }
2550 else
2551 {
2552 /*crDebug("**PARTIAL** update for 0x%x, numRect=*%li*, FS=%li, CS=%li, *DS*=%li",
2553 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2554 for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
2555 {
2556 XRectangle rect;
2557 BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
2558
2559 rect.x = pBox->x1;
2560 rect.y = pBox->y1;
2561 rect.width = pBox->x2-pBox->x1;
2562 rect.height = pBox->y2-pBox->y1;
2563
2564 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2565 }
2566 }
2567 }
2568 }
2569
2570 /* Clean dirty flag and damage region */
2571 pGlxPixmap->bPixmapImageDirty = False;
2572 if (pGlxPixmap->pDamageRegion)
2573 EMPTY_REGION(pGlxPixmap->pDamageRegion);
2574 }
2575 }
2576 else
2577 {
2578 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2579 }
2580 }
2581}
2582
2583DECLEXPORT(void) VBOXGLXTAG(glXReleaseTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer)
2584{
2585 (void) dpy;
2586 (void) draw;
2587 (void) buffer;
2588 //crDebug("glXReleaseTexImageEXT 0x%x", (unsigned int)draw);
2589}
2590#endif
2591
2592#endif /* GLX_EXTRAS */
2593
2594
2595#ifdef GLX_SGIX_video_resize
2596/* more dummy funcs. These help when linking with older GLUTs */
2597
2598DECLEXPORT(int) VBOXGLXTAG(glXBindChannelToWindowSGIX)(Display *dpy, int scrn, int chan, Window w)
2599{
2600 (void) dpy;
2601 (void) scrn;
2602 (void) chan;
2603 (void) w;
2604 crDebug("glXBindChannelToWindowSGIX");
2605 return 0;
2606}
2607
2608DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSGIX)(Display *dpy, int scrn, int chan, int x , int y, int w, int h)
2609{
2610 (void) dpy;
2611 (void) scrn;
2612 (void) chan;
2613 (void) x;
2614 (void) y;
2615 (void) w;
2616 (void) h;
2617 crDebug("glXChannelRectSGIX");
2618 return 0;
2619}
2620
2621DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelRectSGIX)(Display *dpy, int scrn, int chan, int *x, int *y, int *w, int *h)
2622{
2623 (void) dpy;
2624 (void) scrn;
2625 (void) chan;
2626 (void) x;
2627 (void) y;
2628 (void) w;
2629 (void) h;
2630 crDebug("glXQueryChannelRectSGIX");
2631 return 0;
2632}
2633
2634DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelDeltasSGIX)(Display *dpy, int scrn, int chan, int *dx, int *dy, int *dw, int *dh)
2635{
2636 (void) dpy;
2637 (void) scrn;
2638 (void) chan;
2639 (void) dx;
2640 (void) dy;
2641 (void) dw;
2642 (void) dh;
2643 crDebug("glXQueryChannelDeltasSGIX");
2644 return 0;
2645}
2646
2647DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSyncSGIX)(Display *dpy, int scrn, int chan, GLenum synctype)
2648{
2649 (void) dpy;
2650 (void) scrn;
2651 (void) chan;
2652 (void) synctype;
2653 crDebug("glXChannelRectSyncSGIX");
2654 return 0;
2655}
2656
2657#endif /* GLX_SGIX_video_resize */
2658
2659#ifdef VBOXOGL_FAKEDRI
2660DECLEXPORT(const char *) VBOXGLXTAG(glXGetDriverConfig)(const char *driverName)
2661{
2662 return NULL;
2663}
2664
2665DECLEXPORT(void) VBOXGLXTAG(glXFreeMemoryMESA)(Display *dpy, int scrn, void *pointer)
2666{
2667 (void) dpy;
2668 (void) scrn;
2669 (void) pointer;
2670}
2671
2672DECLEXPORT(GLXContext) VBOXGLXTAG(glXImportContextEXT)(Display *dpy, GLXContextID contextID)
2673{
2674 (void) dpy;
2675 (void) contextID;
2676 return NULL;
2677}
2678
2679DECLEXPORT(GLXContextID) VBOXGLXTAG(glXGetContextIDEXT)(const GLXContext ctx)
2680{
2681 (void) ctx;
2682 return 0;
2683}
2684
2685DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrentReadSGI)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
2686{
2687 return VBOXGLXTAG(glXMakeContextCurrent)(display, draw, read, ctx);
2688}
2689
2690DECLEXPORT(const char *) VBOXGLXTAG(glXGetScreenDriver)(Display *dpy, int scrNum)
2691{
2692 static char *screendriver = "vboxvideo";
2693 return screendriver;
2694}
2695
2696DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplayEXT)(void)
2697{
2698 return VBOXGLXTAG(glXGetCurrentDisplay());
2699}
2700
2701DECLEXPORT(void) VBOXGLXTAG(glXFreeContextEXT)(Display *dpy, GLXContext ctx)
2702{
2703 VBOXGLXTAG(glXDestroyContext(dpy, ctx));
2704}
2705
2706/*Mesa internal*/
2707DECLEXPORT(int) VBOXGLXTAG(glXQueryContextInfoEXT)(Display *dpy, GLXContext ctx)
2708{
2709 (void) dpy;
2710 (void) ctx;
2711 return 0;
2712}
2713
2714DECLEXPORT(void *) VBOXGLXTAG(glXAllocateMemoryMESA)(Display *dpy, int scrn,
2715 size_t size, float readFreq,
2716 float writeFreq, float priority)
2717{
2718 (void) dpy;
2719 (void) scrn;
2720 (void) size;
2721 (void) readFreq;
2722 (void) writeFreq;
2723 (void) priority;
2724 return NULL;
2725}
2726
2727DECLEXPORT(GLuint) VBOXGLXTAG(glXGetMemoryOffsetMESA)(Display *dpy, int scrn, const void *pointer)
2728{
2729 (void) dpy;
2730 (void) scrn;
2731 (void) pointer;
2732 return 0;
2733}
2734
2735DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap)
2736{
2737 (void) dpy;
2738 (void) visual;
2739 (void) pixmap;
2740 (void) cmap;
2741 return 0;
2742}
2743
2744#endif /*VBOXOGL_FAKEDRI*/
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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