VirtualBox

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

Last change on this file since 20509 was 18882, checked in by vboxsync, 16 years ago

crOpenGL: exported the remaining Additions bits to OSE

  • Property svn:eol-style set to native
File size: 69.0 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
16#include <X11/Xregion.h>
17
18//#define VBOX_NO_NATIVEGL
19
20/* Force full pixmap update if there're more damaged regions than this number*/
21#define CR_MAX_DAMAGE_REGIONS_TRACKED 50
22
23/* Force "bigger" update (full or clip) if it's reducing number of regions updated
24 * but doesn't increase updated area more than given number
25 */
26#define CR_MIN_DAMAGE_PROFIT_SIZE 64*64
27
28/*@todo combine it in some other place*/
29/* Size of pack spu buffer - some delta for commands packing, see pack/packspu_config.c*/
30
31/** Ramshankar: Solaris compiz fix */
32#ifdef RT_OS_SOLARIS
33# define CR_MAX_TRANSFER_SIZE 20*1024*1024
34#else
35# define CR_MAX_TRANSFER_SIZE 4*1024*1024
36#endif
37
38/** For optimizing glXMakeCurrent */
39static Display *currentDisplay = NULL;
40static GLXDrawable currentDrawable = 0;
41static GLXDrawable currentReadDrawable = 0;
42
43/**
44 * Keep a list of structures which associates X visual IDs with
45 * Chromium visual bitmasks.
46 */
47struct VisualInfo {
48 Display *dpy;
49 int screen;
50 VisualID visualid;
51 int visBits;
52 struct VisualInfo *next;
53};
54
55static struct VisualInfo *VisualInfoList = NULL;
56
57static void stubXshmUpdateImageRect(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap, XRectangle *pRect);
58
59static void
60AddVisualInfo(Display *dpy, int screen, VisualID visualid, int visBits)
61{
62 struct VisualInfo *v;
63 for (v = VisualInfoList; v; v = v->next) {
64 if (v->dpy == dpy && v->screen == screen && v->visualid == visualid) {
65 v->visBits |= visBits;
66 return;
67 }
68 }
69 v = (struct VisualInfo *) crAlloc(sizeof(struct VisualInfo));
70 v->dpy = dpy;
71 v->screen = screen;
72 v->visualid = visualid;
73 v->visBits = visBits;
74 v->next = VisualInfoList;
75 VisualInfoList = v;
76}
77
78static struct VisualInfo *
79FindVisualInfo(Display *dpy, int screen, VisualID visualid)
80{
81 struct VisualInfo *v;
82 for (v = VisualInfoList; v; v = v->next) {
83 if (v->dpy == dpy && v->screen == screen && v->visualid == visualid)
84 return v;
85 }
86 return NULL;
87}
88
89/**
90 * Return string for a GLX error code
91 */
92static const char *glx_error_string(int err)
93{
94 static const char *glxErrors[] = {
95 "none",
96 "GLX_BAD_SCREEN",
97 "GLX_BAD_ATTRIBUTE",
98 "GLX_NO_EXTENSION",
99 "GLX_BAD_VISUAL",
100 "GLX_BAD_CONTEXT",
101 "GLX_BAD_VALUE",
102 "GLX_BAD_ENUM"
103 };
104 if (err > 0 && err < 8) {
105 return glxErrors[err];
106 }
107 else {
108 static char tmp[100];
109 sprintf(tmp, "0x%x", err);
110 return tmp;
111 }
112}
113
114/* Given an XVisualInfo structure, try to figure out what its
115 * OpenGL capabilities are, if we have a native OpenGL.
116 * Returns 0 if no information is available.
117 */
118static struct {
119 int gl_attrib;
120 char *attrib_name;
121 enum {TEST_TRUE, TEST_GREATER_0} test;
122 int match_vis_bits;
123} attrib_map[] = {
124 {GLX_RGBA, "GLX_RGBA", TEST_TRUE, CR_RGB_BIT},
125 {GLX_DOUBLEBUFFER, "GLX_DOUBLEBUFFER", TEST_TRUE, CR_DOUBLE_BIT},
126 {GLX_STEREO, "GLX_STEREO", TEST_TRUE, CR_STEREO_BIT},
127 {GLX_LEVEL, "GLX_LEVEL", TEST_GREATER_0, CR_OVERLAY_BIT},
128 {GLX_ALPHA_SIZE, "GLX_ALPHA_SIZE", TEST_GREATER_0, CR_ALPHA_BIT},
129 {GLX_DEPTH_SIZE, "GLX_DEPTH_SIZE", TEST_GREATER_0, CR_DEPTH_BIT},
130 {GLX_STENCIL_SIZE, "GLX_STENCIL_SIZE", TEST_GREATER_0, CR_STENCIL_BIT},
131 {GLX_ACCUM_RED_SIZE, "GLX_ACCUM_RED_SIZE", TEST_GREATER_0, CR_ACCUM_BIT},
132 {GLX_SAMPLE_BUFFERS_SGIS, "GLX_SAMPLE_BUFFERS_SGIS", TEST_GREATER_0, CR_MULTISAMPLE_BIT},
133};
134#ifndef VBOX_NO_NATIVEGL /* Currently not used */
135static int QueryVisBits(Display *dpy, XVisualInfo *vis)
136{
137 int visBits = 0;
138 int foo, bar, return_val, value;
139 unsigned int i;
140
141 /* We can only query the OpenGL capabilities if we actually
142 * have a native OpenGL underneath us. Without it, we can't
143 * get at all the actual OpenGL characteristics.
144 */
145 if (!stub.haveNativeOpenGL) return 0;
146
147 if (!stub.wsInterface.glXQueryExtension(dpy, &foo, &bar)) return 0;
148
149 /* If we don't have the GLX_USE_GL attribute, we've failed. */
150 return_val = stub.wsInterface.glXGetConfig(dpy, vis, GLX_USE_GL, &value);
151 if (return_val) {
152 crDebug("native glXGetConfig returned %d (%s) at %s line %d",
153 return_val, glx_error_string(return_val), __FILE__, __LINE__);
154 return 0;
155 }
156 if (value == 0) {
157 crDebug("visual ID 0x%x doesn't support OpenGL at %s line %d",
158 (int) vis->visual->visualid, __FILE__, __LINE__);
159 return 0;
160 }
161
162 for (i = 0; i < sizeof(attrib_map)/sizeof(attrib_map[0]); i++) {
163 return_val = stub.wsInterface.glXGetConfig(dpy, vis, attrib_map[i].gl_attrib, &value);
164 if (return_val) {
165 crDebug("native glXGetConfig(%s) returned %d (%s) at %s line %d",
166 attrib_map[i].attrib_name, return_val, glx_error_string(return_val), __FILE__, __LINE__);
167 return 0;
168 }
169
170 switch(attrib_map[i].test) {
171 case TEST_TRUE:
172 if (value)
173 visBits |= attrib_map[i].match_vis_bits;
174 break;
175
176 case TEST_GREATER_0:
177 if (value > 0)
178 visBits |= attrib_map[i].match_vis_bits;
179 break;
180
181 default:
182 crWarning("illegal attribute map test for %s at %s line %d",
183 attrib_map[i].attrib_name, __FILE__, __LINE__);
184 return 0;
185 }
186 }
187
188 return visBits;
189}
190#endif /* not 0 */
191
192
193
194#ifndef VBOX_NO_NATIVEGL /* Old code */
195DECLEXPORT(XVisualInfo *)
196VBOXGLXTAG(glXChooseVisual)( Display *dpy, int screen, int *attribList )
197{
198 XVisualInfo *vis;
199 int *attrib;
200 int visBits = 0;
201
202 stubInit();
203
204 for (attrib = attribList; *attrib != None; attrib++)
205 {
206 switch (*attrib)
207 {
208 case GLX_USE_GL:
209 /* ignored, this is mandatory */
210 break;
211
212 case GLX_BUFFER_SIZE:
213 /* this is for color-index visuals, which we don't support */
214 attrib++;
215 break;
216
217 case GLX_LEVEL:
218 if (attrib[1] > 0)
219 visBits |= CR_OVERLAY_BIT;
220 attrib++;
221 break;
222
223 case GLX_RGBA:
224 visBits |= CR_RGB_BIT;
225 break;
226
227 case GLX_DOUBLEBUFFER:
228 visBits |= CR_DOUBLE_BIT;
229 break;
230
231 case GLX_STEREO:
232 visBits |= CR_STEREO_BIT;
233 /*
234 crWarning( "glXChooseVisual: stereo unsupported" );
235 return NULL;
236 */
237 break;
238
239 case GLX_AUX_BUFFERS:
240 {
241 int aux_buffers = attrib[1];
242 if (aux_buffers != 0)
243 {
244 crWarning("glXChooseVisual: aux_buffers=%d unsupported",
245 aux_buffers);
246 return NULL;
247 }
248 }
249 attrib++;
250 break;
251
252 case GLX_RED_SIZE:
253 case GLX_GREEN_SIZE:
254 case GLX_BLUE_SIZE:
255 if (attrib[1] > 0)
256 visBits |= CR_RGB_BIT;
257 attrib++;
258 break;
259
260 case GLX_ALPHA_SIZE:
261 if (attrib[1] > 0)
262 visBits |= CR_ALPHA_BIT;
263 attrib++;
264 break;
265
266 case GLX_DEPTH_SIZE:
267 if (attrib[1] > 0)
268 visBits |= CR_DEPTH_BIT;
269 attrib++;
270 break;
271
272 case GLX_STENCIL_SIZE:
273 if (attrib[1] > 0)
274 visBits |= CR_STENCIL_BIT;
275 attrib++;
276 break;
277
278 case GLX_ACCUM_RED_SIZE:
279 case GLX_ACCUM_GREEN_SIZE:
280 case GLX_ACCUM_BLUE_SIZE:
281 case GLX_ACCUM_ALPHA_SIZE:
282 if (attrib[1] > 0)
283 visBits |= CR_ACCUM_BIT;
284 attrib++;
285 break;
286
287 case GLX_SAMPLE_BUFFERS_SGIS: /* aka GLX_SAMPLES_ARB */
288 if (attrib[1] > 0)
289 visBits |= CR_MULTISAMPLE_BIT;
290 attrib++;
291 break;
292 case GLX_SAMPLES_SGIS: /* aka GLX_SAMPLES_ARB */
293 /* just ignore value for now, we'll try to get 4 samples/pixel */
294 if (attrib[1] > 4)
295 return NULL;
296 visBits |= CR_MULTISAMPLE_BIT;
297 attrib++;
298 break;
299
300#ifdef GLX_VERSION_1_3
301 case GLX_X_VISUAL_TYPE:
302 case GLX_TRANSPARENT_TYPE_EXT:
303 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
304 case GLX_TRANSPARENT_RED_VALUE_EXT:
305 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
306 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
307 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
308 /* ignore */
309 crWarning("glXChooseVisual: ignoring attribute 0x%x", *attrib);
310 attrib++;
311 break;
312#endif
313
314 default:
315 crWarning( "glXChooseVisual: bad attrib=0x%x", *attrib );
316 return NULL;
317 }
318 }
319
320 if ((visBits & CR_RGB_BIT) == 0 && (visBits & CR_OVERLAY_BIT) == 0)
321 {
322 /* normal layer, color index mode not supported */
323 crWarning( "glXChooseVisual: didn't request RGB visual?" );
324 return NULL;
325 }
326
327 vis = crChooseVisual(&stub.wsInterface, dpy, screen, GL_FALSE, visBits);
328 if (!vis && (visBits & CR_STEREO_BIT)) {
329 /* try non-stereo */
330 visBits &= ~CR_STEREO_BIT;
331 vis = crChooseVisual(&stub.wsInterface, dpy, screen, GL_FALSE, visBits);
332 }
333
334 if (vis) {
335 AddVisualInfo(dpy, screen, vis->visual->visualid, visBits);
336 }
337 return vis;
338}
339#else /* not 0 */
340DECLEXPORT(XVisualInfo *)
341VBOXGLXTAG(glXChooseVisual)( Display *dpy, int screen, int *attribList )
342{
343 bool useRGBA = false;
344 int *attrib;
345 XVisualInfo searchvis, *pret;
346 int nvisuals;
347 stubInit();
348
349 for (attrib = attribList; *attrib != None; attrib++)
350 {
351 switch (*attrib)
352 {
353 case GLX_USE_GL:
354 /* ignored, this is mandatory */
355 break;
356
357 case GLX_BUFFER_SIZE:
358 /* this is for color-index visuals, which we don't support */
359 attrib++;
360 break;
361
362 case GLX_LEVEL:
363 if (attrib[1] != 0)
364 goto err_exit;
365 attrib++;
366 break;
367
368 case GLX_RGBA:
369 useRGBA = true;
370 break;
371
372 case GLX_STEREO:
373 goto err_exit;
374 /*
375 crWarning( "glXChooseVisual: stereo unsupported" );
376 return NULL;
377 */
378 break;
379
380 case GLX_AUX_BUFFERS:
381 if (attrib[1] != 0)
382 goto err_exit;
383 attrib++;
384 break;
385
386 case GLX_RED_SIZE:
387 case GLX_GREEN_SIZE:
388 case GLX_BLUE_SIZE:
389 if (attrib[1] > 8)
390 goto err_exit;
391 attrib++;
392 break;
393
394 case GLX_ALPHA_SIZE:
395 if (attrib[1] > 8)
396 goto err_exit;
397 attrib++;
398 break;
399
400 case GLX_DEPTH_SIZE:
401 if (attrib[1] > 16)
402 goto err_exit;
403 attrib++;
404 break;
405
406 case GLX_STENCIL_SIZE:
407 if (attrib[1] > 8)
408 goto err_exit;
409 attrib++;
410 break;
411
412 case GLX_ACCUM_RED_SIZE:
413 case GLX_ACCUM_GREEN_SIZE:
414 case GLX_ACCUM_BLUE_SIZE:
415 case GLX_ACCUM_ALPHA_SIZE:
416 if (attrib[1] > 16)
417 goto err_exit;
418 attrib++;
419 break;
420
421 case GLX_SAMPLE_BUFFERS_SGIS: /* aka GLX_SAMPLES_ARB */
422 if (attrib[1] > 0)
423 goto err_exit;
424 attrib++;
425 break;
426 case GLX_SAMPLES_SGIS: /* aka GLX_SAMPLES_ARB */
427 if (attrib[1] > 0)
428 goto err_exit;
429 attrib++;
430 break;
431
432 case GLX_DOUBLEBUFFER: /* @todo, check if we support it */
433 break;
434
435#ifdef GLX_VERSION_1_3
436 case GLX_X_VISUAL_TYPE:
437 case GLX_TRANSPARENT_TYPE_EXT:
438 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
439 case GLX_TRANSPARENT_RED_VALUE_EXT:
440 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
441 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
442 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
443 /* ignore */
444 crWarning("glXChooseVisual: ignoring attribute 0x%x", *attrib);
445 attrib++;
446 break;
447#endif
448
449 default:
450 crWarning( "glXChooseVisual: bad attrib=0x%x, ignoring", *attrib );
451 attrib++;
452 //return NULL;
453 }
454 }
455
456 if (!useRGBA)
457 return NULL;
458
459 searchvis.visualid = XVisualIDFromVisual(DefaultVisual(dpy, screen));
460 pret = XGetVisualInfo(dpy, VisualIDMask, &searchvis, &nvisuals);
461
462 if (nvisuals!=1) crWarning("glXChooseVisual: XGetVisualInfo returned %i visuals for %x", nvisuals, (unsigned int) searchvis.visualid);
463 if (pret)
464 crDebug("glXChooseVisual returned %x depth=%i", (unsigned int)pret->visualid, pret->depth);
465 return pret;
466
467err_exit:
468 crDebug("glXChooseVisual returning NULL, due to attrib=0x%x, next=0x%x", attrib[0], attrib[1]);
469 return NULL;
470}
471#endif
472
473/**
474 ** There is a problem with glXCopyContext.
475 ** IRIX and Mesa both define glXCopyContext
476 ** to have the mask argument being a
477 ** GLuint. XFree 4 and oss.sgi.com
478 ** define it to be an unsigned long.
479 ** Solution: We don't support
480 ** glXCopyContext anyway so we'll just
481 ** #ifdef out the code.
482 */
483DECLEXPORT(void)
484VBOXGLXTAG(glXCopyContext)( Display *dpy, GLXContext src, GLXContext dst,
485#if defined(AIX) || defined(PLAYSTATION2)
486GLuint mask )
487#elif defined(SunOS)
488unsigned long mask )
489#else
490unsigned long mask )
491#endif
492{
493 (void) dpy;
494 (void) src;
495 (void) dst;
496 (void) mask;
497 crWarning( "Unsupported GLX Call: glXCopyContext()" );
498}
499
500
501/**
502 * Get the display string for the given display pointer.
503 * Never return just ":0.0". In that case, prefix with our host name.
504 */
505static void
506stubGetDisplayString( Display *dpy, char *nameResult, int maxResult )
507{
508 const char *dpyName = DisplayString(dpy);
509 char host[1000];
510#ifndef VBOX_NO_NATIVEGL
511 if (dpyName[0] == ':')
512 {
513 crGetHostname(host, 1000);
514 }
515 else
516#endif
517 {
518 host[0] = 0;
519 }
520 if (crStrlen(host) + crStrlen(dpyName) >= maxResult - 1)
521 {
522 /* return null string */
523 crWarning("Very long host / display name string in stubDisplayString!");
524 nameResult[0] = 0;
525 }
526 else
527 {
528 /* return host concatenated with dpyName */
529 crStrcpy(nameResult, host);
530 crStrcat(nameResult, dpyName);
531 }
532}
533
534
535
536DECLEXPORT(GLXContext)
537VBOXGLXTAG(glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext share, Bool direct)
538{
539 char dpyName[MAX_DPY_NAME];
540 ContextInfo *context;
541 int visBits = CR_RGB_BIT | CR_DOUBLE_BIT | CR_DEPTH_BIT; /* default vis */
542 int i, numExt;
543
544 stubInit();
545
546 CRASSERT(stub.contextTable);
547
548 /*
549 {
550 char **list;
551
552 list = XListExtensions(dpy, &numExt);
553 crDebug("X extensions [%i]:", numExt);
554 for (i=0; i<numExt; ++i)
555 {
556 crDebug("%s", list[i]);
557 }
558 XFreeExtensionList(list);
559 }
560 */
561
562 stubGetDisplayString(dpy, dpyName, MAX_DPY_NAME);
563#ifndef VBOX_NO_NATIVEGL /* We only care about the host capabilities, not the guest. */
564 if (stub.haveNativeOpenGL) {
565 int foo, bar;
566 if (stub.wsInterface.glXQueryExtension(dpy, &foo, &bar)) {
567 /* If we have real GLX, compute the Chromium visual bitmask now.
568 * otherwise, we'll use the default desiredVisual bitmask.
569 */
570 struct VisualInfo *v = FindVisualInfo(dpy, DefaultScreen(dpy),
571 vis->visual->visualid);
572 if (v) {
573 visBits = v->visBits;
574 /*crDebug("%s visBits=0x%x", __FUNCTION__, visBits);*/
575 }
576 else {
577 /* For some reason, we haven't tested this visual
578 * before. This could be because the visual was found
579 * through a different display connection to the same
580 * display (as happens in GeoProbe), or through a
581 * connection to an external daemon that queries
582 * visuals. If we can query it directly, we can still
583 * find the proper visBits.
584 */
585 int newVisBits = QueryVisBits(dpy, vis);
586 if (newVisBits > 0) {
587 AddVisualInfo(dpy, DefaultScreen(dpy), vis->visual->visualid, newVisBits);
588 crDebug("Application used unexpected but queryable visual id 0x%x", (int) vis->visual->visualid);
589 visBits = newVisBits;
590 }
591 else {
592 crWarning("Application used unexpected and unqueryable visual id 0x%x; using default visbits", (int) vis->visual->visualid);
593 }
594 }
595
596 /*crDebug("ComputeVisBits(0x%x) = 0x%x", (int)vis->visual->visualid, visBits);*/
597 if (stub.force_pbuffers) {
598 crDebug("App faker: Forcing use of Pbuffers");
599 visBits |= CR_PBUFFER_BIT;
600 }
601
602 if (!v) {
603 AddVisualInfo(dpy, DefaultScreen(dpy),
604 vis->visual->visualid, visBits);
605 }
606
607 }
608 }
609 else {
610 crDebug("No native OpenGL; cannot compute visbits");
611 }
612#endif
613
614 context = stubNewContext(dpyName, visBits, UNDECIDED, (unsigned long) share);
615 if (!context)
616 return 0;
617
618 context->dpy = dpy;
619 context->visual = vis;
620 context->direct = direct;
621
622 return (GLXContext) context->id;
623}
624
625
626DECLEXPORT(void) VBOXGLXTAG(glXDestroyContext)( Display *dpy, GLXContext ctx )
627{
628 (void) dpy;
629 stubDestroyContext( (unsigned long) ctx );
630}
631
632
633DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx )
634{
635 ContextInfo *context;
636 WindowInfo *window;
637 Bool retVal;
638
639 /*crDebug("glXMakeCurrent(%p, 0x%x, 0x%x)", (void *) dpy, (int) drawable, (int) ctx);*/
640
641 if (ctx && drawable) {
642 context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) ctx);
643 window = stubGetWindowInfo(dpy, drawable);
644
645 if (context && context->type == UNDECIDED) {
646 XSync(dpy, 0); /* sync to force window creation on the server */
647 }
648 }
649 else {
650 dpy = NULL;
651 window = NULL;
652 context = NULL;
653 }
654
655 currentDisplay = dpy;
656 currentDrawable = drawable;
657
658 retVal = stubMakeCurrent(window, context);
659 return retVal;
660}
661
662
663DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmap)( Display *dpy, XVisualInfo *vis, Pixmap pixmap )
664{
665 (void) dpy;
666 (void) vis;
667 (void) pixmap;
668
669 stubInit();
670 crWarning( "Unsupported GLX Call: glXCreateGLXPixmap()" );
671 return (GLXPixmap) 0;
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 Unsuported 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 Unsuported 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
1030DECLEXPORT(void) VBOXGLXTAG(glXSwapBuffers)( Display *dpy, GLXDrawable drawable )
1031{
1032 const WindowInfo *window = stubGetWindowInfo(dpy, drawable);
1033 stubSwapBuffers( window, 0 );
1034}
1035
1036#ifndef VBOX_NO_NATIVEGL
1037DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)( Font font, int first, int count, int listBase )
1038{
1039 if (stub.currentContext->type == CHROMIUM)
1040 {
1041 Display *dpy = stub.wsInterface.glXGetCurrentDisplay();
1042 if (dpy) {
1043 stubUseXFont( dpy, font, first, count, listBase );
1044 }
1045 else {
1046 dpy = XOpenDisplay(NULL);
1047 if (!dpy)
1048 return;
1049 stubUseXFont( dpy, font, first, count, listBase );
1050 XCloseDisplay(dpy);
1051 }
1052 } else
1053 stub.wsInterface.glXUseXFont( font, first, count, listBase );
1054}
1055#else /* not 0 */
1056DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)( Font font, int first, int count, int listBase )
1057{
1058 Display *dpy = stub.currentContext->dpy;
1059 if (dpy) {
1060 stubUseXFont( dpy, font, first, count, listBase );
1061 }
1062 else {
1063 dpy = XOpenDisplay(NULL);
1064 if (!dpy)
1065 return;
1066 stubUseXFont( dpy, font, first, count, listBase );
1067 XCloseDisplay(dpy);
1068 }
1069}
1070#endif
1071
1072DECLEXPORT(void) VBOXGLXTAG(glXWaitGL)( void )
1073{
1074 static int first_call = 1;
1075
1076 if ( first_call )
1077 {
1078 crDebug( "Ignoring unsupported GLX call: glXWaitGL()" );
1079 first_call = 0;
1080 }
1081}
1082
1083DECLEXPORT(void) VBOXGLXTAG(glXWaitX)( void )
1084{
1085 static int first_call = 1;
1086
1087 if ( first_call )
1088 {
1089 crDebug( "Ignoring unsupported GLX call: glXWaitX()" );
1090 first_call = 0;
1091 }
1092}
1093
1094DECLEXPORT(const char *) VBOXGLXTAG(glXQueryExtensionsString)( Display *dpy, int screen )
1095{
1096 /* XXX maybe also advertise GLX_SGIS_multisample? */
1097
1098 static const char *retval = "GLX_ARB_multisample GLX_EXT_texture_from_pixmap GLX_SGIX_fbconfig";
1099
1100 (void) dpy;
1101 (void) screen;
1102
1103 crDebug("->glXQueryExtensionsString");
1104 return retval;
1105}
1106
1107DECLEXPORT(const char *) VBOXGLXTAG(glXGetClientString)( Display *dpy, int name )
1108{
1109 const char *retval;
1110 (void) dpy;
1111 (void) name;
1112
1113 switch ( name ) {
1114
1115 case GLX_VENDOR:
1116 retval = "Chromium";
1117 break;
1118
1119 case GLX_VERSION:
1120 retval = "1.2 Chromium";
1121 break;
1122
1123 case GLX_EXTENSIONS:
1124 /*@todo should be a screen not a name...but it's not used anyway*/
1125 retval = glXQueryExtensionsString(dpy, name);
1126 break;
1127
1128 default:
1129 retval = NULL;
1130 }
1131
1132 return retval;
1133}
1134
1135DECLEXPORT(const char *) VBOXGLXTAG(glXQueryServerString)( Display *dpy, int screen, int name )
1136{
1137 const char *retval;
1138 (void) dpy;
1139 (void) screen;
1140
1141 switch ( name ) {
1142
1143 case GLX_VENDOR:
1144 retval = "Chromium";
1145 break;
1146
1147 case GLX_VERSION:
1148 retval = "1.2 Chromium";
1149 break;
1150
1151 case GLX_EXTENSIONS:
1152 retval = glXQueryExtensionsString(dpy, screen);
1153 break;
1154
1155 default:
1156 retval = NULL;
1157 }
1158
1159 return retval;
1160}
1161
1162DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddressARB)( const GLubyte *name )
1163{
1164 return (CR_GLXFuncPtr) crGetProcAddress( (const char *) name );
1165}
1166
1167DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddress)( const GLubyte *name )
1168{
1169 return (CR_GLXFuncPtr) crGetProcAddress( (const char *) name );
1170}
1171
1172
1173#if GLX_EXTRAS
1174
1175DECLEXPORT(GLXPbufferSGIX)
1176VBOXGLXTAG(glXCreateGLXPbufferSGIX)(Display *dpy, GLXFBConfigSGIX config,
1177 unsigned int width, unsigned int height,
1178 int *attrib_list)
1179{
1180 (void) dpy;
1181 (void) config;
1182 (void) width;
1183 (void) height;
1184 (void) attrib_list;
1185 crWarning("glXCreateGLXPbufferSGIX not implemented by Chromium");
1186 return 0;
1187}
1188
1189DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf)
1190{
1191 (void) dpy;
1192 (void) pbuf;
1193 crWarning("glXDestroyGLXPbufferSGIX not implemented by Chromium");
1194}
1195
1196DECLEXPORT(void) VBOXGLXTAG(glXSelectEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long mask)
1197{
1198 (void) dpy;
1199 (void) drawable;
1200 (void) mask;
1201}
1202
1203DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long *mask)
1204{
1205 (void) dpy;
1206 (void) drawable;
1207 (void) mask;
1208}
1209
1210DECLEXPORT(int) VBOXGLXTAG(glXQueryGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf,
1211 int attribute, unsigned int *value)
1212{
1213 (void) dpy;
1214 (void) pbuf;
1215 (void) attribute;
1216 (void) value;
1217 crWarning("glXQueryGLXPbufferSGIX not implemented by Chromium");
1218 return 0;
1219}
1220
1221DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttribSGIX)(Display *dpy, GLXFBConfig config,
1222 int attribute, int *value)
1223{
1224 return VBOXGLXTAG(glXGetFBConfigAttrib)(dpy, config, attribute, value);
1225}
1226
1227DECLEXPORT(GLXFBConfigSGIX *)
1228VBOXGLXTAG(glXChooseFBConfigSGIX)(Display *dpy, int screen,
1229 int *attrib_list, int *nelements)
1230{
1231 (void) dpy;
1232 (void) screen;
1233 (void) attrib_list;
1234 (void) nelements;
1235 crWarning("glXChooseFBConfigSGIX not implemented by Chromium");
1236 return NULL;
1237}
1238
1239DECLEXPORT(GLXPixmap)
1240VBOXGLXTAG(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy,
1241 GLXFBConfig config,
1242 Pixmap pixmap)
1243{
1244 (void) dpy;
1245 (void) config;
1246 (void) pixmap;
1247 crWarning("glXCreateGLXPixmapWithConfigSGIX not implemented by Chromium");
1248 return 0; }
1249
1250DECLEXPORT(GLXContext)
1251VBOXGLXTAG(glXCreateContextWithConfigSGIX)(Display *dpy, GLXFBConfig config,
1252 int render_type,
1253 GLXContext share_list,
1254 Bool direct)
1255{
1256 (void) dpy;
1257 (void) config;
1258 (void) render_type;
1259 (void) share_list;
1260 (void) direct;
1261 crWarning("glXCreateContextWithConfigSGIX not implemented by Chromium");
1262 return NULL;
1263}
1264
1265DECLEXPORT(XVisualInfo *)
1266VBOXGLXTAG(glXGetVisualFromFBConfigSGIX)(Display *dpy,
1267 GLXFBConfig config)
1268{
1269 (void) dpy;
1270 (void) config;
1271 crWarning("glXGetVisualFromFBConfigSGIX not implemented by Chromium");
1272 return NULL;
1273}
1274
1275DECLEXPORT(GLXFBConfigSGIX)
1276VBOXGLXTAG(glXGetFBConfigFromVisualSGIX)(Display *dpy, XVisualInfo *vis)
1277{
1278 (void) dpy;
1279 (void) vis;
1280 crWarning("glXGetFBConfigFromVisualSGIX not implemented by Chromium");
1281 return NULL;
1282}
1283
1284/*
1285 * GLX 1.3 functions
1286 */
1287DECLEXPORT(GLXFBConfig *)
1288VBOXGLXTAG(glXChooseFBConfig)(Display *dpy, int screen, ATTRIB_TYPE *attrib_list, int *nelements)
1289{
1290 (void) dpy;
1291 (void) screen;
1292 (void) attrib_list;
1293 (void) nelements;
1294 crWarning("glXChooseFBConfig not implemented by Chromium");
1295 return NULL;
1296}
1297
1298DECLEXPORT(GLXContext)
1299VBOXGLXTAG(glXCreateNewContext)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
1300{
1301 XVisualInfo *vis;
1302
1303 (void) dpy;
1304 (void) config;
1305 (void) render_type;
1306 (void) share_list;
1307 (void) direct;
1308
1309 if (render_type != GLX_RGBA_TYPE)
1310 {
1311 crWarning("glXCreateNewContext, unsupported render_type %x", render_type);
1312 return NULL;
1313 }
1314
1315 vis = VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1316 return VBOXGLXTAG(glXCreateContext)(dpy, vis, share_list, direct);
1317}
1318
1319DECLEXPORT(GLXPbuffer)
1320VBOXGLXTAG(glXCreatePbuffer)(Display *dpy, GLXFBConfig config, ATTRIB_TYPE *attrib_list)
1321{
1322 (void) dpy;
1323 (void) config;
1324 (void) attrib_list;
1325 crWarning("glXCreatePbuffer not implemented by Chromium");
1326 return 0;
1327}
1328
1329/* Note: there're examples where glxpixmaps are created without current context, so can't do much of the work here.
1330 * Instead we'd do necessary initialization on first use of those pixmaps.
1331 */
1332DECLEXPORT(GLXPixmap)
1333VBOXGLXTAG(glXCreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const ATTRIB_TYPE *attrib_list)
1334{
1335 (void) dpy;
1336 (void) config;
1337 (void) attrib_list;
1338
1339 return (GLXPixmap) pixmap;
1340}
1341
1342DECLEXPORT(GLXWindow)
1343VBOXGLXTAG(glXCreateWindow)(Display *dpy, GLXFBConfig config, Window win, ATTRIB_TYPE *attrib_list)
1344{
1345 GLXFBConfig *realcfg;
1346 int nconfigs;
1347 //XVisualInfo *vis;
1348 (void) dpy;
1349 (void) config;
1350 (void) win;
1351 (void) attrib_list;
1352 //crWarning("glXCreateWindow not implemented by Chromium");
1353 //vis = VBOXGLXTAG(glXGetVisualFromFBConfig)(config);
1354 if (stub.wsInterface.glXGetFBConfigs)
1355 {
1356 realcfg = stub.wsInterface.glXGetFBConfigs(dpy, 0, &nconfigs);
1357 if (!realcfg || nconfigs<1)
1358 {
1359 crWarning("glXCreateWindow !realcfg || nconfigs<1");
1360 return 0;
1361 }
1362 else
1363 {
1364 return stub.wsInterface.glXCreateWindow(dpy, realcfg[0], win, attrib_list);
1365 }
1366 }
1367 else
1368 {
1369 crWarning("glXCreateWindow stub.wsInterface.glXChooseFBConfig==NULL");
1370 return 0;
1371 }
1372}
1373
1374DECLEXPORT(void) VBOXGLXTAG(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf)
1375{
1376 (void) dpy;
1377 (void) pbuf;
1378 crWarning("glXDestroyPbuffer not implemented by Chromium");
1379}
1380
1381DECLEXPORT(void) VBOXGLXTAG(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap)
1382{
1383 GLX_Pixmap_t *pGlxPixmap;
1384
1385 if (!stub.currentContext)
1386 {
1387 crWarning("glXDestroyPixmap failed, no current context");
1388 return;
1389 }
1390
1391 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.currentContext->pGLXPixmapsHash, (unsigned int) pixmap);
1392
1393 if (pGlxPixmap)
1394 {
1395 if (pGlxPixmap->gc)
1396 {
1397 XFreeGC(dpy, pGlxPixmap->gc);
1398 }
1399
1400 if (pGlxPixmap->hShmPixmap>0)
1401 {
1402 XFreePixmap(dpy, pGlxPixmap->hShmPixmap);
1403 }
1404
1405 if (pGlxPixmap->hDamage>0)
1406 {
1407 //crDebug("Destroy: Damage for drawable 0x%x, handle 0x%x", (unsigned int) pixmap, (unsigned int) pGlxPixmap->damage);
1408 XDamageDestroy(stub.currentContext->damageDpy, pGlxPixmap->hDamage);
1409 }
1410
1411 if (pGlxPixmap->pDamageRegion)
1412 {
1413 XDestroyRegion(pGlxPixmap->pDamageRegion);
1414 }
1415
1416 crHashtableDelete(stub.currentContext->pGLXPixmapsHash, (unsigned int) pixmap, crFree);
1417 }
1418 /*else
1419 {
1420 crWarning("glXDestroyPixmap called for unknown glxpixmap 0x%x", (unsigned int) pixmap);
1421 }*/
1422}
1423
1424DECLEXPORT(void) VBOXGLXTAG(glXDestroyWindow)(Display *dpy, GLXWindow win)
1425{
1426 (void) dpy;
1427 (void) win;
1428 crWarning("glXDestroyWindow not implemented by Chromium");
1429}
1430
1431DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentReadDrawable)(void)
1432{
1433 //crWarning("glXGetCurrentReadDrawable not implemented by Chromium");
1434 return currentReadDrawable;
1435}
1436
1437DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value)
1438{
1439 XVisualInfo * pVisual;
1440
1441 pVisual = glXGetVisualFromFBConfig(dpy, config);
1442 if (!pVisual)
1443 {
1444 crWarning("glXGetFBConfigAttrib for 0x%x, failed to get XVisualInfo", (int)config);
1445 return GLX_BAD_ATTRIBUTE;
1446 }
1447 //crDebug("glXGetFBConfigAttrib 0x%x for 0x%x, visualid=0x%x, depth=%i", attribute, (int)config, (int)pVisual->visualid, pVisual->depth);
1448
1449
1450 switch (attribute)
1451 {
1452 case GLX_DRAWABLE_TYPE:
1453 *value = GLX_PIXMAP_BIT;
1454 break;
1455 case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
1456 *value = GLX_TEXTURE_2D_BIT_EXT;
1457 break;
1458 case GLX_BIND_TO_TEXTURE_RGBA_EXT:
1459 //crDebug("attribute=GLX_BIND_TO_TEXTURE_RGBA_EXT");
1460 *value = True;
1461 break;
1462 case GLX_BIND_TO_TEXTURE_RGB_EXT:
1463 *value = True;
1464 break;
1465 case GLX_DOUBLEBUFFER:
1466 //crDebug("attribute=GLX_DOUBLEBUFFER");
1467 *value = True;
1468 break;
1469 case GLX_Y_INVERTED_EXT:
1470 *value = True;
1471 break;
1472 case GLX_ALPHA_SIZE:
1473 //crDebug("attribute=GLX_ALPHA_SIZE");
1474 *value = pVisual->depth==32 ? 8:0;
1475 break;
1476 case GLX_BUFFER_SIZE:
1477 //crDebug("attribute=GLX_BUFFER_SIZE");
1478 *value = pVisual->depth;
1479 break;
1480 case GLX_STENCIL_SIZE:
1481 //crDebug("attribute=GLX_STENCIL_SIZE");
1482 *value = 8;
1483 break;
1484 case GLX_DEPTH_SIZE:
1485 *value = 16;
1486 //crDebug("attribute=GLX_DEPTH_SIZE");
1487 break;
1488 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
1489 *value = 0;
1490 break;
1491 case GLX_RENDER_TYPE:
1492 //crDebug("attribute=GLX_RENDER_TYPE");
1493 *value = GLX_RGBA_BIT;
1494 break;
1495 case GLX_CONFIG_CAVEAT:
1496 //crDebug("attribute=GLX_CONFIG_CAVEAT");
1497 *value = GLX_NONE;
1498 break;
1499 case GLX_VISUAL_ID:
1500 //crDebug("attribute=GLX_VISUAL_ID");
1501 *value = pVisual->visualid;
1502 break;
1503 case GLX_FBCONFIG_ID:
1504 *value = pVisual->visualid; /*or config, though those are the same at the moment but this could change one day?*/
1505 break;
1506 case GLX_RED_SIZE:
1507 case GLX_GREEN_SIZE:
1508 case GLX_BLUE_SIZE:
1509 *value = 8;
1510 break;
1511 case GLX_LEVEL:
1512 *value = 0;
1513 break;
1514 case GLX_STEREO:
1515 *value = false;
1516 break;
1517 case GLX_AUX_BUFFERS:
1518 *value = 0;
1519 break;
1520 case GLX_ACCUM_RED_SIZE:
1521 case GLX_ACCUM_GREEN_SIZE:
1522 case GLX_ACCUM_BLUE_SIZE:
1523 case GLX_ACCUM_ALPHA_SIZE:
1524 *value = 0;
1525 break;
1526 case GLX_X_VISUAL_TYPE:
1527 *value = GLX_TRUE_COLOR;
1528 break;
1529 case GLX_TRANSPARENT_TYPE:
1530 *value = GLX_NONE;
1531 break;
1532 case GLX_SAMPLE_BUFFERS:
1533 case GLX_SAMPLES:
1534 *value = 1;
1535 break;
1536 default:
1537 crDebug("glXGetFBConfigAttrib: unknown attribute=0x%x", attribute);
1538 XFree(pVisual);
1539 return GLX_BAD_ATTRIBUTE;
1540 }
1541
1542 XFree(pVisual);
1543 return Success;
1544}
1545
1546#if !defined(VBOX_NO_NATIVEGL) || 1 /* need fbconfigs atleast for depths 24 and 32 */
1547DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
1548{
1549 GLXFBConfig *pGLXFBConfigs = NULL;
1550 struct VisualInfo *v;
1551 int i=0, cVisuals;
1552 XVisualInfo searchvis, *pVisuals;
1553
1554 *nelements = 0;
1555
1556 /*
1557 for (v = VisualInfoList; v; v = v->next) {
1558 if (v->dpy == dpy && v->screen == screen)
1559 ++*nelements;
1560 }
1561
1562 if (*nelements)
1563 pGLXFBConfigs = crAlloc(*nelements * sizeof(GLXFBConfig));
1564
1565 for (v = VisualInfoList; v && i<*nelements; v = v->next) {
1566 if (v->dpy == dpy && v->screen == screen)
1567 pGLXFBConfigs[i++] = (GLXFBConfig) v->visualid;
1568 }
1569 */
1570
1571 /*@todo doesn't really list all the common visuals, have to use some static list*/
1572 searchvis.screen = screen;
1573 pVisuals = XGetVisualInfo(dpy, VisualScreenMask, &searchvis, nelements);
1574
1575 if (*nelements)
1576 pGLXFBConfigs = crAlloc(*nelements * sizeof(GLXFBConfig));
1577
1578 for (i=0; i<*nelements; ++i)
1579 {
1580 pGLXFBConfigs[i] = (GLXFBConfig) pVisuals[i].visualid;
1581 }
1582
1583 XFree(pVisuals);
1584
1585 crDebug("glXGetFBConfigs returned %i configs", *nelements);
1586 for (i=0; i<*nelements; ++i)
1587 {
1588 crDebug("glXGetFBConfigs[%i]=0x%x", i, (unsigned int) pGLXFBConfigs[i]);
1589 }
1590 return pGLXFBConfigs;
1591}
1592#else /* not 0 */
1593DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
1594{
1595 int i;
1596
1597 GLXFBConfig *pGLXFBConfigs = crAlloc(sizeof(GLXFBConfig));
1598
1599 *nelements = 1;
1600 *pGLXFBConfigs = (GLXFBConfig) XVisualIDFromVisual(DefaultVisual(dpy, screen));
1601
1602 crDebug("glXGetFBConfigs returned %i configs", *nelements);
1603 for (i=0; i<*nelements; ++i)
1604 {
1605 crDebug("glXGetFBConfigs[%i]=0x%x", i, (unsigned int) pGLXFBConfigs[i]);
1606 }
1607 return pGLXFBConfigs;
1608}
1609#endif
1610
1611DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEvent)(Display *dpy, GLXDrawable draw, unsigned long *event_mask)
1612{
1613 (void) dpy;
1614 (void) draw;
1615 (void) event_mask;
1616 crWarning("glXGetSelectedEvent not implemented by Chromium");
1617}
1618
1619DECLEXPORT(XVisualInfo *) VBOXGLXTAG(glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config)
1620{
1621 (void) dpy;
1622 (void) config;
1623
1624 struct VisualInfo *v;
1625
1626 /*
1627 for (v = VisualInfoList; v; v = v->next) {
1628 if (v->dpy == dpy && v->visualid == (VisualID)config)
1629 {
1630 XVisualInfo temp, *pret;
1631 int nret;
1632
1633 temp.visualid = v->visualid;
1634 pret = XGetVisualInfo(dpy, VisualIDMask, &temp, &nret);
1635
1636 if (nret!=1) crWarning("XGetVisualInfo returned %i visuals", nret);
1637 crDebug("glXGetVisualFromFBConfig(cfg/visid==0x%x): depth=%i", (int) config, pret->depth);
1638 return pret;
1639 }
1640 }
1641 */
1642
1643 {
1644 XVisualInfo temp, *pret;
1645 int nret;
1646
1647 temp.visualid = (VisualID)config;
1648 pret = XGetVisualInfo(dpy, VisualIDMask, &temp, &nret);
1649
1650 if (nret!=1) crWarning("XGetVisualInfo returned %i visuals for %x", nret, (unsigned int) config);
1651 //crDebug("glXGetVisualFromFBConfig(cfg/visid==0x%x): depth=%i", (int) config, pret->depth);
1652 return pret;
1653 }
1654
1655 crDebug("glXGetVisualFromFBConfig unknown fbconfig 0x%x", (int) config);
1656 return NULL;
1657}
1658
1659DECLEXPORT(Bool) VBOXGLXTAG(glXMakeContextCurrent)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
1660{
1661 (void) display;
1662 (void) draw;
1663 (void) read;
1664 (void) ctx;
1665 //crWarning("glXMakeContextCurrent not implemented by Chromium");
1666 currentReadDrawable = read;
1667 return VBOXGLXTAG(glXMakeCurrent)(display, draw, ctx);
1668}
1669
1670DECLEXPORT(int) VBOXGLXTAG(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value)
1671{
1672 (void) dpy;
1673 (void) ctx;
1674 (void) attribute;
1675 (void) value;
1676 crWarning("glXQueryContext not implemented by Chromium");
1677 return 0;
1678}
1679
1680DECLEXPORT(void) VBOXGLXTAG(glXQueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
1681{
1682 (void) dpy;
1683 (void) draw;
1684 (void) attribute;
1685 (void) value;
1686 crWarning("glXQueryDrawable not implemented by Chromium");
1687}
1688
1689DECLEXPORT(void) VBOXGLXTAG(glXSelectEvent)(Display *dpy, GLXDrawable draw, unsigned long event_mask)
1690{
1691 (void) dpy;
1692 (void) draw;
1693 (void) event_mask;
1694 crWarning("glXSelectEvent not implemented by Chromium");
1695}
1696
1697#ifdef CR_EXT_texture_from_pixmap
1698/*typedef struct
1699{
1700 int x, y;
1701 unsigned int w, h, border, depth;
1702 Window root;
1703 void *data;
1704} pminfo;*/
1705
1706static void stubInitXSharedMemory(Display *dpy)
1707{
1708 int vma, vmi;
1709 Bool pixmaps;
1710
1711 if (stub.bShmInitFailed || stub.xshmSI.shmid>=0)
1712 return;
1713
1714 stub.bShmInitFailed = GL_TRUE;
1715
1716 /* Check for extension and pixmaps format */
1717
1718 if (!XShmQueryExtension(dpy))
1719 {
1720 crWarning("No XSHM extension");
1721 return;
1722 }
1723
1724 if (!XShmQueryVersion(dpy, &vma, &vmi, &pixmaps) || !pixmaps)
1725 {
1726 crWarning("XSHM extension doesn't support pixmaps");
1727 return;
1728 }
1729
1730 if (XShmPixmapFormat(dpy)!=ZPixmap)
1731 {
1732 crWarning("XSHM extension doesn't support ZPixmap format");
1733 return;
1734 }
1735
1736 /* Alloc shared memory, so far using hardcoded value...could fail for bigger displays one day */
1737 stub.xshmSI.readOnly = false;
1738 stub.xshmSI.shmid = shmget(IPC_PRIVATE, 4*4096*2048, IPC_CREAT | 0600);
1739 if (stub.xshmSI.shmid<0)
1740 {
1741 crWarning("XSHM Failed to create shared segment");
1742 return;
1743 }
1744
1745 stub.xshmSI.shmaddr = (char*) shmat(stub.xshmSI.shmid, NULL, 0);
1746 if (stub.xshmSI.shmaddr==(void*)-1)
1747 {
1748 crWarning("XSHM Failed to attach shared segment");
1749 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
1750 return;
1751 }
1752
1753
1754 if (!XShmAttach(dpy, &stub.xshmSI))
1755 {
1756 crWarning("XSHM Failed to attach shared segment to XServer");
1757 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
1758 shmdt(stub.xshmSI.shmaddr);
1759 return;
1760 }
1761
1762 stub.bShmInitFailed = GL_FALSE;
1763 crInfo("Using XSHM for GLX_EXT_texture_from_pixmap");
1764
1765 /*Anyway mark to be deleted when our process detaches it, in case of segfault etc*/
1766
1767/* Ramshankar: Solaris compiz fix */
1768#ifndef RT_OS_SOLARIS
1769 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
1770#endif
1771}
1772
1773static void stubInitXDamageExtension(ContextInfo *pContext)
1774{
1775 int erb, vma, vmi;
1776
1777 CRASSERT(pContext);
1778
1779 if (pContext->damageInitFailed || pContext->damageDpy)
1780 return;
1781
1782 pContext->damageInitFailed = True;
1783
1784 /* Open second xserver connection to make sure we'd recieve all the xdamage messages
1785 * and those wouldn't be eaten by application even queue */
1786 pContext->damageDpy = XOpenDisplay(DisplayString(pContext->dpy));
1787
1788 if (!pContext->damageDpy)
1789 {
1790 crWarning("XDamage: Can't connect to display %s", DisplayString(pContext->dpy));
1791 return;
1792 }
1793
1794 if (!XDamageQueryExtension(pContext->damageDpy, &pContext->damageEventsBase, &erb)
1795 || !XDamageQueryVersion(pContext->damageDpy, &vma, &vmi))
1796 {
1797 crWarning("XDamage not found or old version (%i.%i), going to run *very* slow", vma, vmi);
1798 XCloseDisplay(pContext->damageDpy);
1799 pContext->damageDpy = NULL;
1800 return;
1801 }
1802
1803 crDebug("XDamage %i.%i", vma, vmi);
1804 pContext->damageInitFailed = False;
1805}
1806
1807static void stubCheckXDamageCB(unsigned long key, void *data1, void *data2)
1808{
1809 GLX_Pixmap_t *pGlxPixmap = (GLX_Pixmap_t *) data1;
1810 XDamageNotifyEvent *e = (XDamageNotifyEvent *) data2;
1811
1812 if (pGlxPixmap->hDamage==e->damage)
1813 {
1814 /*crDebug("Event: Damage for pixmap 0x%lx(drawable 0x%x), handle 0x%x (level=%i) [%i,%i,%i,%i]",
1815 key, (unsigned int) e->drawable, (unsigned int) e->damage, (int) e->level,
1816 e->area.x, e->area.y, e->area.width, e->area.height);*/
1817
1818 if (pGlxPixmap->pDamageRegion)
1819 {
1820 /* If it's dirty and regions are empty, it marked for full update, so do nothing.*/
1821 if (!pGlxPixmap->bPixmapImageDirty || !XEmptyRegion(pGlxPixmap->pDamageRegion))
1822 {
1823 if (CR_MAX_DAMAGE_REGIONS_TRACKED <= pGlxPixmap->pDamageRegion->numRects)
1824 {
1825 /* Mark for full update */
1826 EMPTY_REGION(pGlxPixmap->pDamageRegion);
1827 }
1828 else
1829 {
1830 /* Add to damage regions */
1831 XUnionRectWithRegion(&e->area, pGlxPixmap->pDamageRegion, pGlxPixmap->pDamageRegion);
1832 }
1833 }
1834 }
1835
1836 pGlxPixmap->bPixmapImageDirty = True;
1837 }
1838}
1839
1840static GLX_Pixmap_t* stubInitGlxPixmap(Display *dpy, GLXDrawable draw, ContextInfo *pContext)
1841{
1842 int x, y;
1843 unsigned int w, h;
1844 unsigned int border;
1845 unsigned int depth;
1846 Window root;
1847 GLX_Pixmap_t *pGlxPixmap;
1848
1849 CRASSERT(pContext);
1850
1851 if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
1852 {
1853 crWarning("stubInitGlxPixmap failed in call to XGetGeometry for 0x%x", (int) draw);
1854 return NULL;
1855 }
1856
1857 pGlxPixmap = crAlloc(sizeof(GLX_Pixmap_t));
1858 if (!pGlxPixmap)
1859 {
1860 crWarning("stubInitGlxPixmap failed to allocate memory");
1861 return NULL;
1862 }
1863
1864 pGlxPixmap->x = x;
1865 pGlxPixmap->y = y;
1866 pGlxPixmap->w = w;
1867 pGlxPixmap->h = h;
1868 pGlxPixmap->border = border;
1869 pGlxPixmap->depth = depth;
1870 pGlxPixmap->root = root;
1871
1872 /* Try to allocate shared memory
1873 * As we're allocating huge chunk of memory, do it in this function, only if this extension is really used
1874 */
1875 if (!stub.bShmInitFailed && stub.xshmSI.shmid<0)
1876 {
1877 stubInitXSharedMemory(dpy);
1878 }
1879
1880 if (stub.xshmSI.shmid>=0)
1881 {
1882 XGCValues xgcv;
1883 xgcv.graphics_exposures = False;
1884 xgcv.subwindow_mode = IncludeInferiors;
1885 pGlxPixmap->gc = XCreateGC(dpy, (Pixmap)draw, GCGraphicsExposures|GCSubwindowMode, &xgcv);
1886
1887 pGlxPixmap->hShmPixmap = XShmCreatePixmap(dpy, pGlxPixmap->root, stub.xshmSI.shmaddr, &stub.xshmSI,
1888 pGlxPixmap->w, pGlxPixmap->h, pGlxPixmap->depth);
1889 }
1890 else
1891 {
1892 pGlxPixmap->gc = NULL;
1893 pGlxPixmap->hShmPixmap = 0;
1894 }
1895
1896 stubInitXDamageExtension(pContext);
1897
1898 /* If there's damage extension, then get handle for damage events related to this pixmap */
1899 if (pContext->damageDpy)
1900 {
1901 pGlxPixmap->hDamage = XDamageCreate(pContext->damageDpy, (Pixmap)draw, XDamageReportRawRectangles);
1902 /*crDebug("Create: Damage for drawable 0x%x, handle 0x%x (level=%i)",
1903 (unsigned int) draw, (unsigned int) pGlxPixmap->damage, (int) XDamageReportRawRectangles);*/
1904 pGlxPixmap->pDamageRegion = XCreateRegion();
1905 if (!pGlxPixmap->pDamageRegion)
1906 {
1907 crWarning("stubInitGlxPixmap failed to create empy damage region for drawable 0x%x", (unsigned int) draw);
1908 }
1909
1910 /*We have never seen this pixmap before, so mark it as dirty for first use*/
1911 pGlxPixmap->bPixmapImageDirty = True;
1912 }
1913 else
1914 {
1915 pGlxPixmap->hDamage = 0;
1916 pGlxPixmap->pDamageRegion = NULL;
1917 }
1918
1919 /* glTexSubImage2D generates GL_INVALID_OP if texture array hasn't been defined by a call to glTexImage2D first.
1920 * It's fine for small textures which would be updated in stubXshmUpdateWholeImage, but we'd never call glTexImage2D for big ones.
1921 * Note that we're making empty texture by passing NULL as pixels pointer, so there's no overhead transferring data to host.*/
1922 if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
1923 {
1924 stub.spu->dispatch_table.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pGlxPixmap->w, pGlxPixmap->h, 0,
1925 GL_BGRA, GL_UNSIGNED_BYTE, NULL);
1926 }
1927
1928 crHashtableAdd(pContext->pGLXPixmapsHash, (unsigned int) draw, pGlxPixmap);
1929
1930 return pGlxPixmap;
1931}
1932
1933static void stubXshmUpdateWholeImage(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap)
1934{
1935 /* To limit the size of transferring buffer, split bigger texture into regions
1936 * which fit into connection buffer. Could be done in hgcm or packspu but implementation in this place allows to avoid
1937 * unnecessary memcpy.
1938 * This also workarounds guest driver failures when sending 6+mb texture buffers on linux.
1939 */
1940 if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
1941 {
1942 XRectangle rect;
1943
1944 rect.x = pGlxPixmap->x;
1945 rect.y = pGlxPixmap->y;
1946 rect.width = pGlxPixmap->w;
1947 rect.height = CR_MAX_TRANSFER_SIZE/(4*pGlxPixmap->w);
1948
1949 /*crDebug("Texture size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
1950 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, rect.height);*/
1951
1952 for (; (rect.y+rect.height)<=(pGlxPixmap->y+pGlxPixmap->h); rect.y+=rect.height)
1953 {
1954 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
1955 }
1956
1957 if (rect.y!=(pGlxPixmap->y+pGlxPixmap->h))
1958 {
1959 rect.height=pGlxPixmap->h-rect.y;
1960 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
1961 }
1962 }
1963 else
1964 {
1965 XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
1966 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, 0, 0);
1967 /* Have to make sure XCopyArea is processed */
1968 XSync(dpy, False);
1969 stub.spu->dispatch_table.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pGlxPixmap->w, pGlxPixmap->h, 0,
1970 GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
1971 /*crDebug("Sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
1972 (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
1973 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);*/
1974 }
1975}
1976
1977static void stubXshmUpdateImageRect(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap, XRectangle *pRect)
1978{
1979 /* See comment in stubXshmUpdateWholeImage */
1980 if (CR_MAX_TRANSFER_SIZE < 4*pRect->width*pRect->height)
1981 {
1982 XRectangle rect;
1983
1984 rect.x = pRect->x;
1985 rect.y = pRect->y;
1986 rect.width = pRect->width;
1987 rect.height = CR_MAX_TRANSFER_SIZE/(4*pRect->width);
1988
1989 /*crDebug("Region size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
1990 pRect->x, pRect->y, pRect->width, pRect->height, rect.height);*/
1991
1992 for (; (rect.y+rect.height)<=(pRect->y+pRect->height); rect.y+=rect.height)
1993 {
1994 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
1995 }
1996
1997 if (rect.y!=(pRect->y+pRect->height))
1998 {
1999 rect.height=pRect->y+pRect->height-rect.y;
2000 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2001 }
2002 }
2003 else
2004 {
2005 GLint origUnpackRowLength;
2006
2007 XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
2008 pRect->x, pRect->y, pRect->width, pRect->height, 0, 0);
2009 /* Have to make sure XCopyArea is processed */
2010 XSync(dpy, False);
2011
2012 /* Save original value, doesn't cause sync as it's reported by state tracker*/
2013 if (pRect->width!=pGlxPixmap->w)
2014 {
2015 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_ROW_LENGTH, &origUnpackRowLength);
2016 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, pGlxPixmap->w);
2017 }
2018 stub.spu->dispatch_table.TexSubImage2D(GL_TEXTURE_2D, 0, pRect->x, pRect->y, pRect->width, pRect->height,
2019 GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
2020 if (pRect->width!=pGlxPixmap->w)
2021 {
2022 /* Restore original value*/
2023 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, origUnpackRowLength);
2024 }
2025
2026 /*crDebug("Region sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
2027 (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
2028 pRect->x, pRect->y, pRect->width, pRect->height);*/
2029 }
2030}
2031
2032#if 0
2033Bool checkevents(Display *display, XEvent *event, XPointer arg)
2034{
2035 //crDebug("got type: 0x%x", event->type);
2036 if (event->type==damage_evb+XDamageNotify)
2037 {
2038 XDamageNotifyEvent *e = (XDamageNotifyEvent *) event;
2039 /* we're interested in pixmaps only...and those have e->drawable set to 0 or other strange value for some odd reason
2040 * so have to walk glxpixmaps hashtable to find if we have damage event handle assigned to some pixmap
2041 */
2042 /*crDebug("Event: Damage for drawable 0x%x, handle 0x%x (level=%i) [%i,%i,%i,%i]",
2043 (unsigned int) e->drawable, (unsigned int) e->damage, (int) e->level,
2044 e->area.x, e->area.y, e->area.width, e->area.height);*/
2045 CRASSERT(stub.currentContext);
2046 crHashtableWalk(stub.currentContext->pGLXPixmapsHash, checkdamageCB, e);
2047 }
2048 return False;
2049}
2050#endif
2051
2052/*@todo check what error codes could we throw for failures here*/
2053DECLEXPORT(void) VBOXGLXTAG(glXBindTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer, const int *attrib_list)
2054{
2055 static int cnt=0;
2056 XImage dummyimg;
2057
2058 GLX_Pixmap_t *pGlxPixmap;
2059
2060 crDebug("->glXBindTexImageEXT");
2061
2062 if (!stub.currentContext)
2063 {
2064 crWarning("glXBindTexImageEXT called without current context");
2065 return;
2066 }
2067
2068 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.currentContext->pGLXPixmapsHash, (unsigned int) draw);
2069 if (!pGlxPixmap)
2070 {
2071 /*Not a fault, just setup the desired information, see comment for glXCreatePixmap function*/
2072 pGlxPixmap = stubInitGlxPixmap(dpy, draw, stub.currentContext);
2073
2074 if (!pGlxPixmap) return;
2075 }
2076
2077 /* If there's damage extension, then process incoming events as we need the information right now */
2078 if (stub.currentContext->damageDpy)
2079 {
2080 /* Sync connections, note that order of syncs is important here.
2081 * First make sure client commands are finished, then make sure we get all the damage events back*/
2082 XSync(dpy, False);
2083 XSync(stub.currentContext->damageDpy, False);
2084
2085 while (XPending(stub.currentContext->damageDpy))
2086 {
2087 XEvent event;
2088 XNextEvent(stub.currentContext->damageDpy, &event);
2089 if (event.type==stub.currentContext->damageEventsBase+XDamageNotify)
2090 {
2091 crHashtableWalk(stub.currentContext->pGLXPixmapsHash, stubCheckXDamageCB, &event);
2092 }
2093 }
2094 }
2095
2096 /* No shared memory? Rollback to use slow x protocol then */
2097 if (stub.xshmSI.shmid<0)
2098 {
2099 /*@todo add damage support here too*/
2100 XImage *pxim;
2101
2102 pxim = XGetImage(dpy, (Pixmap)draw, pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, AllPlanes, ZPixmap);
2103 /*if (pxim)
2104 {
2105 if (!ptextable)
2106 {
2107 ptextable = crAllocHashtable();
2108 }
2109 pm = crHashtableSearch(ptextable, (unsigned int) draw);
2110 if (!pm)
2111 {
2112 pm = crCalloc(sizeof(pminfo));
2113 crHashtableAdd(ptextable, (unsigned int) draw, pm);
2114 }
2115 pm->w = w;
2116 pm->h = h;
2117 if (pm->data) crFree(pm->data);
2118 pm->data = crAlloc(4*w*h);
2119 crMemcpy(pm->data, (void*)(&(pxim->data[0])), 4*w*h);
2120 }*/
2121
2122 if (NULL==pxim)
2123 {
2124 crWarning("Failed, to get pixmap data for 0x%x", (unsigned int) draw);
2125 return;
2126 }
2127
2128 stub.spu->dispatch_table.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pxim->width, pxim->height, 0,
2129 GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(pxim->data[0])));
2130 XDestroyImage(pxim);
2131 }
2132 else /* Use shm to get pixmap data */
2133 {
2134 /* Check if we have damage extension */
2135 if (stub.currentContext->damageDpy)
2136 {
2137 if (pGlxPixmap->bPixmapImageDirty)
2138 {
2139 /* Either we failed to allocate damage region or this pixmap is marked for full update */
2140 if (!pGlxPixmap->pDamageRegion || XEmptyRegion(pGlxPixmap->pDamageRegion))
2141 {
2142 /*crDebug("**FULL** update for 0x%x", (unsigned int)draw);*/
2143 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2144 }
2145 else
2146 {
2147 long fullArea, damageArea=0, clipdamageArea, i;
2148 XRectangle damageClipBox;
2149
2150 fullArea = pGlxPixmap->w * pGlxPixmap->h;
2151 XClipBox(pGlxPixmap->pDamageRegion, &damageClipBox);
2152 clipdamageArea = damageClipBox.width * damageClipBox.height;
2153
2154 //crDebug("FullSize [%i,%i,%i,%i]", pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);
2155 //crDebug("Clip [%i,%i,%i,%i]", damageClipBox.x, damageClipBox.y, damageClipBox.width, damageClipBox.height);
2156
2157 for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
2158 {
2159 BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
2160 damageArea += (pBox->x2-pBox->x1)*(pBox->y2-pBox->y1);
2161 //crDebug("Damage rect [%i,%i,%i,%i]", pBox->x1, pBox->y1, pBox->x2, pBox->y2);
2162 }
2163
2164 if (damageArea>clipdamageArea || clipdamageArea>fullArea)
2165 {
2166 crWarning("glXBindTexImageEXT, damage regions seems to be broken, forcing full update");
2167 /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
2168 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2169 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2170 }
2171 else /*We have corect damage info*/
2172 {
2173 if (CR_MIN_DAMAGE_PROFIT_SIZE > (fullArea-damageArea))
2174 {
2175 /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
2176 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2177 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2178 }
2179 else if (CR_MIN_DAMAGE_PROFIT_SIZE > (clipdamageArea-damageArea))
2180 {
2181 /*crDebug("**PARTIAL** update for 0x%x, numRect=%li, FS=%li, *CS*=%li, DS=%li",
2182 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2183 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &damageClipBox);
2184 }
2185 else
2186 {
2187 /*crDebug("**PARTIAL** update for 0x%x, numRect=*%li*, FS=%li, CS=%li, *DS*=%li",
2188 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2189 for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
2190 {
2191 XRectangle rect;
2192 BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
2193
2194 rect.x = pBox->x1;
2195 rect.y = pBox->y1;
2196 rect.width = pBox->x2-pBox->x1;
2197 rect.height = pBox->y2-pBox->y1;
2198
2199 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2200 }
2201 }
2202 }
2203 }
2204
2205 /* Clean dirty flag and damage region */
2206 pGlxPixmap->bPixmapImageDirty = False;
2207 if (pGlxPixmap->pDamageRegion)
2208 EMPTY_REGION(pGlxPixmap->pDamageRegion);
2209 }
2210 }
2211 else
2212 {
2213 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2214 }
2215 }
2216}
2217
2218DECLEXPORT(void) VBOXGLXTAG(glXReleaseTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer)
2219{
2220 (void) dpy;
2221 (void) draw;
2222 (void) buffer;
2223 //crDebug("glXReleaseTexImageEXT 0x%x", (unsigned int)draw);
2224}
2225#endif
2226
2227#endif /* GLX_EXTRAS */
2228
2229
2230#ifdef GLX_SGIX_video_resize
2231/* more dummy funcs. These help when linking with older GLUTs */
2232
2233DECLEXPORT(int) VBOXGLXTAG(glXBindChannelToWindowSGIX)(Display *dpy, int scrn, int chan, Window w)
2234{
2235 (void) dpy;
2236 (void) scrn;
2237 (void) chan;
2238 (void) w;
2239 crDebug("glXBindChannelToWindowSGIX");
2240 return 0;
2241}
2242
2243DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSGIX)(Display *dpy, int scrn, int chan, int x , int y, int w, int h)
2244{
2245 (void) dpy;
2246 (void) scrn;
2247 (void) chan;
2248 (void) x;
2249 (void) y;
2250 (void) w;
2251 (void) h;
2252 crDebug("glXChannelRectSGIX");
2253 return 0;
2254}
2255
2256DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelRectSGIX)(Display *dpy, int scrn, int chan, int *x, int *y, int *w, int *h)
2257{
2258 (void) dpy;
2259 (void) scrn;
2260 (void) chan;
2261 (void) x;
2262 (void) y;
2263 (void) w;
2264 (void) h;
2265 crDebug("glXQueryChannelRectSGIX");
2266 return 0;
2267}
2268
2269DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelDeltasSGIX)(Display *dpy, int scrn, int chan, int *dx, int *dy, int *dw, int *dh)
2270{
2271 (void) dpy;
2272 (void) scrn;
2273 (void) chan;
2274 (void) dx;
2275 (void) dy;
2276 (void) dw;
2277 (void) dh;
2278 crDebug("glXQueryChannelDeltasSGIX");
2279 return 0;
2280}
2281
2282DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSyncSGIX)(Display *dpy, int scrn, int chan, GLenum synctype)
2283{
2284 (void) dpy;
2285 (void) scrn;
2286 (void) chan;
2287 (void) synctype;
2288 crDebug("glXChannelRectSyncSGIX");
2289 return 0;
2290}
2291
2292#endif /* GLX_SGIX_video_resize */
2293
2294#ifdef VBOXOGL_FAKEDRI
2295DECLEXPORT(const char *) VBOXGLXTAG(glXGetDriverConfig)(const char *driverName)
2296{
2297 return NULL;
2298}
2299
2300DECLEXPORT(void) VBOXGLXTAG(glXFreeMemoryMESA)(Display *dpy, int scrn, void *pointer)
2301{
2302 (void) dpy;
2303 (void) scrn;
2304 (void) pointer;
2305}
2306
2307DECLEXPORT(GLXContext) VBOXGLXTAG(glXImportContextEXT)(Display *dpy, GLXContextID contextID)
2308{
2309 (void) dpy;
2310 (void) contextID;
2311 return NULL;
2312}
2313
2314DECLEXPORT(GLXContextID) VBOXGLXTAG(glXGetContextIDEXT)(const GLXContext ctx)
2315{
2316 (void) ctx;
2317 return 0;
2318}
2319
2320DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrentReadSGI)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
2321{
2322 return VBOXGLXTAG(glXMakeContextCurrent)(display, draw, read, ctx);
2323}
2324
2325DECLEXPORT(const char *) VBOXGLXTAG(glXGetScreenDriver)(Display *dpy, int scrNum)
2326{
2327 static char *screendriver = "vboxvideo";
2328 return screendriver;
2329}
2330
2331DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplayEXT)(void)
2332{
2333 return VBOXGLXTAG(glXGetCurrentDisplay());
2334}
2335
2336DECLEXPORT(void) VBOXGLXTAG(glXFreeContextEXT)(Display *dpy, GLXContext ctx)
2337{
2338 VBOXGLXTAG(glXDestroyContext(dpy, ctx));
2339}
2340
2341/*Mesa internal*/
2342DECLEXPORT(int) VBOXGLXTAG(glXQueryContextInfoEXT)(Display *dpy, GLXContext ctx)
2343{
2344 (void) dpy;
2345 (void) ctx;
2346 return 0;
2347}
2348
2349DECLEXPORT(void *) VBOXGLXTAG(glXAllocateMemoryMESA)(Display *dpy, int scrn,
2350 size_t size, float readFreq,
2351 float writeFreq, float priority)
2352{
2353 (void) dpy;
2354 (void) scrn;
2355 (void) size;
2356 (void) readFreq;
2357 (void) writeFreq;
2358 (void) priority;
2359 return NULL;
2360}
2361
2362DECLEXPORT(GLuint) VBOXGLXTAG(glXGetMemoryOffsetMESA)(Display *dpy, int scrn, const void *pointer)
2363{
2364 (void) dpy;
2365 (void) scrn;
2366 (void) pointer;
2367 return 0;
2368}
2369
2370DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap)
2371{
2372 (void) dpy;
2373 (void) visual;
2374 (void) pixmap;
2375 (void) cmap;
2376 return 0;
2377}
2378
2379#endif /*VBOXOGL_FAKEDRI*/
Note: See TracBrowser for help on using the repository browser.

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