VirtualBox

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

Last change on this file since 28347 was 28190, checked in by vboxsync, 15 years ago

Additions/crOpenGL: gcc warnings

  • Property svn:eol-style set to native
File size: 71.9 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 ATTRIB_TYPE *attrib;
1336 XVisualInfo *pVis;
1337 GLX_Pixmap_t *pGlxPixmap;
1338 (void) dpy;
1339 (void) config;
1340
1341 pGlxPixmap = crCalloc(sizeof(GLX_Pixmap_t));
1342 if (!pGlxPixmap)
1343 {
1344 crWarning("glXCreatePixmap failed to allocate memory");
1345 return 0;
1346 }
1347
1348 pVis = VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1349 if (!pVis)
1350 {
1351 crWarning("Unknown config %p in glXCreatePixmap", config);
1352 return 0;
1353 }
1354
1355 pGlxPixmap->format = pVis->depth==24 ? GL_RGB:GL_RGBA;
1356 pGlxPixmap->target = GL_TEXTURE_2D;
1357
1358 if (attrib_list)
1359 {
1360 for (attrib = attrib_list; *attrib != None; attrib++)
1361 {
1362 switch (*attrib)
1363 {
1364 case GLX_TEXTURE_FORMAT_EXT:
1365 attrib++;
1366 switch (*attrib)
1367 {
1368 case GLX_TEXTURE_FORMAT_RGBA_EXT:
1369 pGlxPixmap->format = GL_RGBA;
1370 break;
1371 case GLX_TEXTURE_FORMAT_RGB_EXT:
1372 pGlxPixmap->format = GL_RGB;
1373 break;
1374 default:
1375 crDebug("Unexpected GLX_TEXTURE_FORMAT_EXT 0x%x", (unsigned int) *attrib);
1376 }
1377 break;
1378 case GLX_TEXTURE_TARGET_EXT:
1379 attrib++;
1380 switch (*attrib)
1381 {
1382 case GLX_TEXTURE_2D_EXT:
1383 pGlxPixmap->target = GL_TEXTURE_2D;
1384 break;
1385 case GLX_TEXTURE_RECTANGLE_EXT:
1386 pGlxPixmap->target = GL_TEXTURE_RECTANGLE_NV;
1387 break;
1388 default:
1389 crDebug("Unexpected GLX_TEXTURE_TARGET_EXT 0x%x", (unsigned int) *attrib);
1390 }
1391 break;
1392 default: attrib++;
1393 }
1394 }
1395 }
1396
1397 crHashtableAdd(stub.pGLXPixmapsHash, (unsigned int) pixmap, pGlxPixmap);
1398 return (GLXPixmap) pixmap;
1399}
1400
1401DECLEXPORT(GLXWindow)
1402VBOXGLXTAG(glXCreateWindow)(Display *dpy, GLXFBConfig config, Window win, ATTRIB_TYPE *attrib_list)
1403{
1404 GLXFBConfig *realcfg;
1405 int nconfigs;
1406 //XVisualInfo *vis;
1407 (void) dpy;
1408 (void) config;
1409 (void) win;
1410 (void) attrib_list;
1411 //crWarning("glXCreateWindow not implemented by Chromium");
1412 //vis = VBOXGLXTAG(glXGetVisualFromFBConfig)(config);
1413 if (stub.wsInterface.glXGetFBConfigs)
1414 {
1415 realcfg = stub.wsInterface.glXGetFBConfigs(dpy, 0, &nconfigs);
1416 if (!realcfg || nconfigs<1)
1417 {
1418 crWarning("glXCreateWindow !realcfg || nconfigs<1");
1419 return 0;
1420 }
1421 else
1422 {
1423 return stub.wsInterface.glXCreateWindow(dpy, realcfg[0], win, attrib_list);
1424 }
1425 }
1426 else
1427 {
1428 crWarning("glXCreateWindow stub.wsInterface.glXChooseFBConfig==NULL");
1429 return 0;
1430 }
1431}
1432
1433DECLEXPORT(void) VBOXGLXTAG(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf)
1434{
1435 (void) dpy;
1436 (void) pbuf;
1437 crWarning("glXDestroyPbuffer not implemented by Chromium");
1438}
1439
1440DECLEXPORT(void) VBOXGLXTAG(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap)
1441{
1442 GLX_Pixmap_t *pGlxPixmap;
1443
1444 if (!stub.currentContext)
1445 {
1446 crWarning("glXDestroyPixmap failed, no current context");
1447 return;
1448 }
1449
1450 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.currentContext->pGLXPixmapsHash, (unsigned int) pixmap);
1451
1452 if (pGlxPixmap)
1453 {
1454 if (pGlxPixmap->gc)
1455 {
1456 XFreeGC(dpy, pGlxPixmap->gc);
1457 }
1458
1459 if (pGlxPixmap->hShmPixmap>0)
1460 {
1461 XFreePixmap(dpy, pGlxPixmap->hShmPixmap);
1462 }
1463
1464 if (pGlxPixmap->hDamage>0)
1465 {
1466 //crDebug("Destroy: Damage for drawable 0x%x, handle 0x%x", (unsigned int) pixmap, (unsigned int) pGlxPixmap->damage);
1467 XDamageDestroy(stub.currentContext->damageDpy, pGlxPixmap->hDamage);
1468 }
1469
1470 if (pGlxPixmap->pDamageRegion)
1471 {
1472 XDestroyRegion(pGlxPixmap->pDamageRegion);
1473 }
1474
1475 crHashtableDelete(stub.currentContext->pGLXPixmapsHash, (unsigned int) pixmap, crFree);
1476 }
1477 /*else
1478 {
1479 crWarning("glXDestroyPixmap called for unknown glxpixmap 0x%x", (unsigned int) pixmap);
1480 }*/
1481}
1482
1483DECLEXPORT(void) VBOXGLXTAG(glXDestroyWindow)(Display *dpy, GLXWindow win)
1484{
1485 (void) dpy;
1486 (void) win;
1487 crWarning("glXDestroyWindow not implemented by Chromium");
1488}
1489
1490DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentReadDrawable)(void)
1491{
1492 //crWarning("glXGetCurrentReadDrawable not implemented by Chromium");
1493 return currentReadDrawable;
1494}
1495
1496DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value)
1497{
1498 XVisualInfo * pVisual;
1499 const char * pExt;
1500
1501 pVisual = VBOXGLXTAG(glXGetVisualFromFBConfig)(dpy, config);
1502 if (!pVisual)
1503 {
1504 crWarning("glXGetFBConfigAttrib for %p, failed to get XVisualInfo", config);
1505 return GLX_BAD_ATTRIBUTE;
1506 }
1507 //crDebug("glXGetFBConfigAttrib 0x%x for 0x%x, visualid=0x%x, depth=%i", attribute, (int)config, (int)pVisual->visualid, pVisual->depth);
1508
1509
1510 switch (attribute)
1511 {
1512 case GLX_DRAWABLE_TYPE:
1513 *value = GLX_PIXMAP_BIT;
1514 break;
1515 case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
1516 *value = GLX_TEXTURE_2D_BIT_EXT;
1517 pExt = (const char *) stub.spu->dispatch_table.GetString(GL_EXTENSIONS);
1518 if (crStrstr(pExt, "GL_NV_texture_rectangle")
1519 || crStrstr(pExt, "GL_ARB_texture_rectangle")
1520 || crStrstr(pExt, "GL_EXT_texture_rectangle"))
1521 {
1522 *value |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
1523 }
1524 break;
1525 case GLX_BIND_TO_TEXTURE_RGBA_EXT:
1526 *value = pVisual->depth==32;
1527 break;
1528 case GLX_BIND_TO_TEXTURE_RGB_EXT:
1529 *value = True;
1530 break;
1531 case GLX_DOUBLEBUFFER:
1532 //crDebug("attribute=GLX_DOUBLEBUFFER");
1533 *value = True;
1534 break;
1535 case GLX_Y_INVERTED_EXT:
1536 *value = True;
1537 break;
1538 case GLX_ALPHA_SIZE:
1539 //crDebug("attribute=GLX_ALPHA_SIZE");
1540 *value = pVisual->depth==32 ? 8:0;
1541 break;
1542 case GLX_BUFFER_SIZE:
1543 //crDebug("attribute=GLX_BUFFER_SIZE");
1544 *value = pVisual->depth;
1545 break;
1546 case GLX_STENCIL_SIZE:
1547 //crDebug("attribute=GLX_STENCIL_SIZE");
1548 *value = 8;
1549 break;
1550 case GLX_DEPTH_SIZE:
1551 *value = 16;
1552 //crDebug("attribute=GLX_DEPTH_SIZE");
1553 break;
1554 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
1555 *value = 0;
1556 break;
1557 case GLX_RENDER_TYPE:
1558 //crDebug("attribute=GLX_RENDER_TYPE");
1559 *value = GLX_RGBA_BIT;
1560 break;
1561 case GLX_CONFIG_CAVEAT:
1562 //crDebug("attribute=GLX_CONFIG_CAVEAT");
1563 *value = GLX_NONE;
1564 break;
1565 case GLX_VISUAL_ID:
1566 //crDebug("attribute=GLX_VISUAL_ID");
1567 *value = pVisual->visualid;
1568 break;
1569 case GLX_FBCONFIG_ID:
1570 *value = pVisual->visualid; /*or config, though those are the same at the moment but this could change one day?*/
1571 break;
1572 case GLX_RED_SIZE:
1573 case GLX_GREEN_SIZE:
1574 case GLX_BLUE_SIZE:
1575 *value = 8;
1576 break;
1577 case GLX_LEVEL:
1578 *value = 0;
1579 break;
1580 case GLX_STEREO:
1581 *value = false;
1582 break;
1583 case GLX_AUX_BUFFERS:
1584 *value = 0;
1585 break;
1586 case GLX_ACCUM_RED_SIZE:
1587 case GLX_ACCUM_GREEN_SIZE:
1588 case GLX_ACCUM_BLUE_SIZE:
1589 case GLX_ACCUM_ALPHA_SIZE:
1590 *value = 0;
1591 break;
1592 case GLX_X_VISUAL_TYPE:
1593 *value = GLX_TRUE_COLOR;
1594 break;
1595 case GLX_TRANSPARENT_TYPE:
1596 *value = GLX_NONE;
1597 break;
1598 case GLX_SAMPLE_BUFFERS:
1599 case GLX_SAMPLES:
1600 *value = 1;
1601 break;
1602 default:
1603 crDebug("glXGetFBConfigAttrib: unknown attribute=0x%x", attribute);
1604 XFree(pVisual);
1605 return GLX_BAD_ATTRIBUTE;
1606 }
1607
1608 XFree(pVisual);
1609 return Success;
1610}
1611
1612#if !defined(VBOX_NO_NATIVEGL) || 1 /* need fbconfigs atleast for depths 24 and 32 */
1613DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
1614{
1615 GLXFBConfig *pGLXFBConfigs = NULL;
1616 struct VisualInfo *v;
1617 int i=0, cVisuals;
1618 XVisualInfo searchvis, *pVisuals;
1619
1620 *nelements = 0;
1621
1622 /*
1623 for (v = VisualInfoList; v; v = v->next) {
1624 if (v->dpy == dpy && v->screen == screen)
1625 ++*nelements;
1626 }
1627
1628 if (*nelements)
1629 pGLXFBConfigs = crAlloc(*nelements * sizeof(GLXFBConfig));
1630
1631 for (v = VisualInfoList; v && i<*nelements; v = v->next) {
1632 if (v->dpy == dpy && v->screen == screen)
1633 pGLXFBConfigs[i++] = (GLXFBConfig) v->visualid;
1634 }
1635 */
1636
1637 /*@todo doesn't really list all the common visuals, have to use some static list*/
1638 searchvis.screen = screen;
1639 pVisuals = XGetVisualInfo(dpy, VisualScreenMask, &searchvis, nelements);
1640
1641 if (*nelements)
1642 pGLXFBConfigs = crAlloc(*nelements * sizeof(GLXFBConfig));
1643
1644 for (i=0; i<*nelements; ++i)
1645 {
1646 pGLXFBConfigs[i] = (GLXFBConfig) pVisuals[i].visualid;
1647 }
1648
1649 XFree(pVisuals);
1650
1651 crDebug("glXGetFBConfigs returned %i configs", *nelements);
1652 for (i=0; i<*nelements; ++i)
1653 {
1654 crDebug("glXGetFBConfigs[%i]=%p", i, pGLXFBConfigs[i]);
1655 }
1656 return pGLXFBConfigs;
1657}
1658#else /* not 0 */
1659DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
1660{
1661 int i;
1662
1663 GLXFBConfig *pGLXFBConfigs = crAlloc(sizeof(GLXFBConfig));
1664
1665 *nelements = 1;
1666 *pGLXFBConfigs = (GLXFBConfig) XVisualIDFromVisual(DefaultVisual(dpy, screen));
1667
1668 crDebug("glXGetFBConfigs returned %i configs", *nelements);
1669 for (i=0; i<*nelements; ++i)
1670 {
1671 crDebug("glXGetFBConfigs[%i]=0x%x", i, (unsigned int) pGLXFBConfigs[i]);
1672 }
1673 return pGLXFBConfigs;
1674}
1675#endif
1676
1677DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEvent)(Display *dpy, GLXDrawable draw, unsigned long *event_mask)
1678{
1679 (void) dpy;
1680 (void) draw;
1681 (void) event_mask;
1682 crWarning("glXGetSelectedEvent not implemented by Chromium");
1683}
1684
1685DECLEXPORT(XVisualInfo *) VBOXGLXTAG(glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config)
1686{
1687 (void) dpy;
1688 (void) config;
1689
1690 struct VisualInfo *v;
1691
1692 /*
1693 for (v = VisualInfoList; v; v = v->next) {
1694 if (v->dpy == dpy && v->visualid == (VisualID)config)
1695 {
1696 XVisualInfo temp, *pret;
1697 int nret;
1698
1699 temp.visualid = v->visualid;
1700 pret = XGetVisualInfo(dpy, VisualIDMask, &temp, &nret);
1701
1702 if (nret!=1) crWarning("XGetVisualInfo returned %i visuals", nret);
1703 crDebug("glXGetVisualFromFBConfig(cfg/visid==0x%x): depth=%i", (int) config, pret->depth);
1704 return pret;
1705 }
1706 }
1707 */
1708
1709 {
1710 XVisualInfo temp, *pret;
1711 int nret;
1712
1713 temp.visualid = (VisualID)config;
1714 pret = XGetVisualInfo(dpy, VisualIDMask, &temp, &nret);
1715
1716 if (nret!=1) crWarning("XGetVisualInfo returned %i visuals for %p", nret, config);
1717 //crDebug("glXGetVisualFromFBConfig(cfg/visid==0x%x): depth=%i", (int) config, pret->depth);
1718 return pret;
1719 }
1720
1721 crDebug("glXGetVisualFromFBConfig unknown fbconfig %p", config);
1722 return NULL;
1723}
1724
1725DECLEXPORT(Bool) VBOXGLXTAG(glXMakeContextCurrent)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
1726{
1727 (void) display;
1728 (void) draw;
1729 (void) read;
1730 (void) ctx;
1731 //crWarning("glXMakeContextCurrent not implemented by Chromium");
1732 currentReadDrawable = read;
1733 return VBOXGLXTAG(glXMakeCurrent)(display, draw, ctx);
1734}
1735
1736DECLEXPORT(int) VBOXGLXTAG(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value)
1737{
1738 (void) dpy;
1739 (void) ctx;
1740 (void) attribute;
1741 (void) value;
1742 crWarning("glXQueryContext not implemented by Chromium");
1743 return 0;
1744}
1745
1746DECLEXPORT(void) VBOXGLXTAG(glXQueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
1747{
1748 (void) dpy;
1749 (void) draw;
1750 (void) attribute;
1751 (void) value;
1752 crWarning("glXQueryDrawable not implemented by Chromium");
1753}
1754
1755DECLEXPORT(void) VBOXGLXTAG(glXSelectEvent)(Display *dpy, GLXDrawable draw, unsigned long event_mask)
1756{
1757 (void) dpy;
1758 (void) draw;
1759 (void) event_mask;
1760 crWarning("glXSelectEvent not implemented by Chromium");
1761}
1762
1763#ifdef CR_EXT_texture_from_pixmap
1764/*typedef struct
1765{
1766 int x, y;
1767 unsigned int w, h, border, depth;
1768 Window root;
1769 void *data;
1770} pminfo;*/
1771
1772static void stubInitXSharedMemory(Display *dpy)
1773{
1774 int vma, vmi;
1775 Bool pixmaps;
1776
1777 if (stub.bShmInitFailed || stub.xshmSI.shmid>=0)
1778 return;
1779
1780 stub.bShmInitFailed = GL_TRUE;
1781
1782 /* Check for extension and pixmaps format */
1783
1784 if (!XShmQueryExtension(dpy))
1785 {
1786 crWarning("No XSHM extension");
1787 return;
1788 }
1789
1790 if (!XShmQueryVersion(dpy, &vma, &vmi, &pixmaps) || !pixmaps)
1791 {
1792 crWarning("XSHM extension doesn't support pixmaps");
1793 return;
1794 }
1795
1796 if (XShmPixmapFormat(dpy)!=ZPixmap)
1797 {
1798 crWarning("XSHM extension doesn't support ZPixmap format");
1799 return;
1800 }
1801
1802 /* Alloc shared memory, so far using hardcoded value...could fail for bigger displays one day */
1803 stub.xshmSI.readOnly = false;
1804 stub.xshmSI.shmid = shmget(IPC_PRIVATE, 4*4096*2048, IPC_CREAT | 0600);
1805 if (stub.xshmSI.shmid<0)
1806 {
1807 crWarning("XSHM Failed to create shared segment");
1808 return;
1809 }
1810
1811 stub.xshmSI.shmaddr = (char*) shmat(stub.xshmSI.shmid, NULL, 0);
1812 if (stub.xshmSI.shmaddr==(void*)-1)
1813 {
1814 crWarning("XSHM Failed to attach shared segment");
1815 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
1816 return;
1817 }
1818
1819
1820 if (!XShmAttach(dpy, &stub.xshmSI))
1821 {
1822 crWarning("XSHM Failed to attach shared segment to XServer");
1823 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
1824 shmdt(stub.xshmSI.shmaddr);
1825 return;
1826 }
1827
1828 stub.bShmInitFailed = GL_FALSE;
1829 crInfo("Using XSHM for GLX_EXT_texture_from_pixmap");
1830
1831 /*Anyway mark to be deleted when our process detaches it, in case of segfault etc*/
1832
1833/* Ramshankar: Solaris compiz fix */
1834#ifndef RT_OS_SOLARIS
1835 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
1836#endif
1837}
1838
1839static void stubInitXDamageExtension(ContextInfo *pContext)
1840{
1841 int erb, vma, vmi;
1842
1843 CRASSERT(pContext);
1844
1845 if (pContext->damageInitFailed || pContext->damageDpy)
1846 return;
1847
1848 pContext->damageInitFailed = True;
1849
1850 /* Open second xserver connection to make sure we'd recieve all the xdamage messages
1851 * and those wouldn't be eaten by application even queue */
1852 pContext->damageDpy = XOpenDisplay(DisplayString(pContext->dpy));
1853
1854 if (!pContext->damageDpy)
1855 {
1856 crWarning("XDamage: Can't connect to display %s", DisplayString(pContext->dpy));
1857 return;
1858 }
1859
1860 if (!XDamageQueryExtension(pContext->damageDpy, &pContext->damageEventsBase, &erb)
1861 || !XDamageQueryVersion(pContext->damageDpy, &vma, &vmi))
1862 {
1863 crWarning("XDamage not found or old version (%i.%i), going to run *very* slow", vma, vmi);
1864 XCloseDisplay(pContext->damageDpy);
1865 pContext->damageDpy = NULL;
1866 return;
1867 }
1868
1869 crDebug("XDamage %i.%i", vma, vmi);
1870 pContext->damageInitFailed = False;
1871}
1872
1873static void stubCheckXDamageCB(unsigned long key, void *data1, void *data2)
1874{
1875 GLX_Pixmap_t *pGlxPixmap = (GLX_Pixmap_t *) data1;
1876 XDamageNotifyEvent *e = (XDamageNotifyEvent *) data2;
1877
1878 if (pGlxPixmap->hDamage==e->damage)
1879 {
1880 /*crDebug("Event: Damage for pixmap 0x%lx(drawable 0x%x), handle 0x%x (level=%i) [%i,%i,%i,%i]",
1881 key, (unsigned int) e->drawable, (unsigned int) e->damage, (int) e->level,
1882 e->area.x, e->area.y, e->area.width, e->area.height);*/
1883
1884 if (pGlxPixmap->pDamageRegion)
1885 {
1886 /* If it's dirty and regions are empty, it marked for full update, so do nothing.*/
1887 if (!pGlxPixmap->bPixmapImageDirty || !XEmptyRegion(pGlxPixmap->pDamageRegion))
1888 {
1889 if (CR_MAX_DAMAGE_REGIONS_TRACKED <= pGlxPixmap->pDamageRegion->numRects)
1890 {
1891 /* Mark for full update */
1892 EMPTY_REGION(pGlxPixmap->pDamageRegion);
1893 }
1894 else
1895 {
1896 /* Add to damage regions */
1897 XUnionRectWithRegion(&e->area, pGlxPixmap->pDamageRegion, pGlxPixmap->pDamageRegion);
1898 }
1899 }
1900 }
1901
1902 pGlxPixmap->bPixmapImageDirty = True;
1903 }
1904}
1905
1906static GLX_Pixmap_t* stubInitGlxPixmap(GLX_Pixmap_t* pCreateInfoPixmap, Display *dpy, GLXDrawable draw, ContextInfo *pContext)
1907{
1908 int x, y;
1909 unsigned int w, h;
1910 unsigned int border;
1911 unsigned int depth;
1912 Window root;
1913 GLX_Pixmap_t *pGlxPixmap;
1914
1915 CRASSERT(pContext && pCreateInfoPixmap);
1916
1917 if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
1918 {
1919 XSync(dpy, False);
1920 if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
1921 {
1922 crWarning("stubInitGlxPixmap failed in call to XGetGeometry for 0x%x", (int) draw);
1923 return NULL;
1924 }
1925 }
1926
1927 pGlxPixmap = crAlloc(sizeof(GLX_Pixmap_t));
1928 if (!pGlxPixmap)
1929 {
1930 crWarning("stubInitGlxPixmap failed to allocate memory");
1931 return NULL;
1932 }
1933
1934 pGlxPixmap->x = x;
1935 pGlxPixmap->y = y;
1936 pGlxPixmap->w = w;
1937 pGlxPixmap->h = h;
1938 pGlxPixmap->border = border;
1939 pGlxPixmap->depth = depth;
1940 pGlxPixmap->root = root;
1941 pGlxPixmap->format = pCreateInfoPixmap->format;
1942 pGlxPixmap->target = pCreateInfoPixmap->target;
1943
1944 /* Try to allocate shared memory
1945 * As we're allocating huge chunk of memory, do it in this function, only if this extension is really used
1946 */
1947 if (!stub.bShmInitFailed && stub.xshmSI.shmid<0)
1948 {
1949 stubInitXSharedMemory(dpy);
1950 }
1951
1952 if (stub.xshmSI.shmid>=0)
1953 {
1954 XGCValues xgcv;
1955 xgcv.graphics_exposures = False;
1956 xgcv.subwindow_mode = IncludeInferiors;
1957 pGlxPixmap->gc = XCreateGC(dpy, (Pixmap)draw, GCGraphicsExposures|GCSubwindowMode, &xgcv);
1958
1959 pGlxPixmap->hShmPixmap = XShmCreatePixmap(dpy, pGlxPixmap->root, stub.xshmSI.shmaddr, &stub.xshmSI,
1960 pGlxPixmap->w, pGlxPixmap->h, pGlxPixmap->depth);
1961 }
1962 else
1963 {
1964 pGlxPixmap->gc = NULL;
1965 pGlxPixmap->hShmPixmap = 0;
1966 }
1967
1968 stubInitXDamageExtension(pContext);
1969
1970 /* If there's damage extension, then get handle for damage events related to this pixmap */
1971 if (pContext->damageDpy)
1972 {
1973 pGlxPixmap->hDamage = XDamageCreate(pContext->damageDpy, (Pixmap)draw, XDamageReportRawRectangles);
1974 /*crDebug("Create: Damage for drawable 0x%x, handle 0x%x (level=%i)",
1975 (unsigned int) draw, (unsigned int) pGlxPixmap->damage, (int) XDamageReportRawRectangles);*/
1976 pGlxPixmap->pDamageRegion = XCreateRegion();
1977 if (!pGlxPixmap->pDamageRegion)
1978 {
1979 crWarning("stubInitGlxPixmap failed to create empty damage region for drawable 0x%x", (unsigned int) draw);
1980 }
1981
1982 /*We have never seen this pixmap before, so mark it as dirty for first use*/
1983 pGlxPixmap->bPixmapImageDirty = True;
1984 }
1985 else
1986 {
1987 pGlxPixmap->hDamage = 0;
1988 pGlxPixmap->pDamageRegion = NULL;
1989 }
1990
1991 /* glTexSubImage2D generates GL_INVALID_OP if texture array hasn't been defined by a call to glTexImage2D first.
1992 * It's fine for small textures which would be updated in stubXshmUpdateWholeImage, but we'd never call glTexImage2D for big ones.
1993 * Note that we're making empty texture by passing NULL as pixels pointer, so there's no overhead transferring data to host.*/
1994 if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
1995 {
1996 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pGlxPixmap->w, pGlxPixmap->h, 0,
1997 GL_BGRA, GL_UNSIGNED_BYTE, NULL);
1998 }
1999
2000 crHashtableAdd(pContext->pGLXPixmapsHash, (unsigned int) draw, pGlxPixmap);
2001 crHashtableDelete(stub.pGLXPixmapsHash, (unsigned int) draw, crFree);
2002
2003 return pGlxPixmap;
2004}
2005
2006static void stubXshmUpdateWholeImage(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap)
2007{
2008 /* To limit the size of transferring buffer, split bigger texture into regions
2009 * which fit into connection buffer. Could be done in hgcm or packspu but implementation in this place allows to avoid
2010 * unnecessary memcpy.
2011 * This also workarounds guest driver failures when sending 6+mb texture buffers on linux.
2012 */
2013 if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
2014 {
2015 XRectangle rect;
2016
2017 rect.x = pGlxPixmap->x;
2018 rect.y = pGlxPixmap->y;
2019 rect.width = pGlxPixmap->w;
2020 rect.height = CR_MAX_TRANSFER_SIZE/(4*pGlxPixmap->w);
2021
2022 /*crDebug("Texture size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
2023 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, rect.height);*/
2024
2025 for (; (rect.y+rect.height)<=(pGlxPixmap->y+pGlxPixmap->h); rect.y+=rect.height)
2026 {
2027 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2028 }
2029
2030 if (rect.y!=(pGlxPixmap->y+pGlxPixmap->h))
2031 {
2032 rect.height=pGlxPixmap->h-rect.y;
2033 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2034 }
2035 }
2036 else
2037 {
2038 XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
2039 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, 0, 0);
2040 /* Have to make sure XCopyArea is processed */
2041 XSync(dpy, False);
2042 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pGlxPixmap->w, pGlxPixmap->h, 0,
2043 GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
2044 /*crDebug("Sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
2045 (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
2046 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);*/
2047 }
2048}
2049
2050static void stubXshmUpdateImageRect(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap, XRectangle *pRect)
2051{
2052 /* See comment in stubXshmUpdateWholeImage */
2053 if (CR_MAX_TRANSFER_SIZE < 4*pRect->width*pRect->height)
2054 {
2055 XRectangle rect;
2056
2057 rect.x = pRect->x;
2058 rect.y = pRect->y;
2059 rect.width = pRect->width;
2060 rect.height = CR_MAX_TRANSFER_SIZE/(4*pRect->width);
2061
2062 /*crDebug("Region size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
2063 pRect->x, pRect->y, pRect->width, pRect->height, rect.height);*/
2064
2065 for (; (rect.y+rect.height)<=(pRect->y+pRect->height); rect.y+=rect.height)
2066 {
2067 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2068 }
2069
2070 if (rect.y!=(pRect->y+pRect->height))
2071 {
2072 rect.height=pRect->y+pRect->height-rect.y;
2073 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2074 }
2075 }
2076 else
2077 {
2078 GLint origUnpackRowLength;
2079
2080 XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
2081 pRect->x, pRect->y, pRect->width, pRect->height, 0, 0);
2082 /* Have to make sure XCopyArea is processed */
2083 XSync(dpy, False);
2084
2085 /* Save original value, doesn't cause sync as it's reported by state tracker*/
2086 if (pRect->width!=pGlxPixmap->w)
2087 {
2088 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_ROW_LENGTH, &origUnpackRowLength);
2089 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, pGlxPixmap->w);
2090 }
2091 stub.spu->dispatch_table.TexSubImage2D(pGlxPixmap->target, 0, pRect->x, pRect->y, pRect->width, pRect->height,
2092 GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
2093 if (pRect->width!=pGlxPixmap->w)
2094 {
2095 /* Restore original value*/
2096 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, origUnpackRowLength);
2097 }
2098
2099 /*crDebug("Region sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
2100 (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
2101 pRect->x, pRect->y, pRect->width, pRect->height);*/
2102 }
2103}
2104
2105#if 0
2106Bool checkevents(Display *display, XEvent *event, XPointer arg)
2107{
2108 //crDebug("got type: 0x%x", event->type);
2109 if (event->type==damage_evb+XDamageNotify)
2110 {
2111 XDamageNotifyEvent *e = (XDamageNotifyEvent *) event;
2112 /* we're interested in pixmaps only...and those have e->drawable set to 0 or other strange value for some odd reason
2113 * so have to walk glxpixmaps hashtable to find if we have damage event handle assigned to some pixmap
2114 */
2115 /*crDebug("Event: Damage for drawable 0x%x, handle 0x%x (level=%i) [%i,%i,%i,%i]",
2116 (unsigned int) e->drawable, (unsigned int) e->damage, (int) e->level,
2117 e->area.x, e->area.y, e->area.width, e->area.height);*/
2118 CRASSERT(stub.currentContext);
2119 crHashtableWalk(stub.currentContext->pGLXPixmapsHash, checkdamageCB, e);
2120 }
2121 return False;
2122}
2123#endif
2124
2125/*@todo check what error codes could we throw for failures here*/
2126DECLEXPORT(void) VBOXGLXTAG(glXBindTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer, const int *attrib_list)
2127{
2128 static int cnt=0;
2129 XImage dummyimg;
2130
2131 GLX_Pixmap_t *pGlxPixmap;
2132
2133 if (!stub.currentContext)
2134 {
2135 crWarning("glXBindTexImageEXT called without current context");
2136 return;
2137 }
2138
2139 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.currentContext->pGLXPixmapsHash, (unsigned int) draw);
2140 if (!pGlxPixmap)
2141 {
2142 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) draw);
2143 if (!pGlxPixmap)
2144 {
2145 crDebug("Unknown drawable 0x%x in glXBindTexImageEXT!", (unsigned int) draw);
2146 return;
2147 }
2148 pGlxPixmap = stubInitGlxPixmap(pGlxPixmap, dpy, draw, stub.currentContext);
2149 if (!pGlxPixmap)
2150 {
2151 crDebug("glXBindTexImageEXT failed to get pGlxPixmap");
2152 return;
2153 }
2154 }
2155
2156 /* If there's damage extension, then process incoming events as we need the information right now */
2157 if (stub.currentContext->damageDpy)
2158 {
2159 /* Sync connections, note that order of syncs is important here.
2160 * First make sure client commands are finished, then make sure we get all the damage events back*/
2161 XSync(dpy, False);
2162 XSync(stub.currentContext->damageDpy, False);
2163
2164 while (XPending(stub.currentContext->damageDpy))
2165 {
2166 XEvent event;
2167 XNextEvent(stub.currentContext->damageDpy, &event);
2168 if (event.type==stub.currentContext->damageEventsBase+XDamageNotify)
2169 {
2170 crHashtableWalk(stub.currentContext->pGLXPixmapsHash, stubCheckXDamageCB, &event);
2171 }
2172 }
2173 }
2174
2175 /* No shared memory? Rollback to use slow x protocol then */
2176 if (stub.xshmSI.shmid<0)
2177 {
2178 /*@todo add damage support here too*/
2179 XImage *pxim;
2180
2181 pxim = XGetImage(dpy, (Pixmap)draw, pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, AllPlanes, ZPixmap);
2182 /*if (pxim)
2183 {
2184 if (!ptextable)
2185 {
2186 ptextable = crAllocHashtable();
2187 }
2188 pm = crHashtableSearch(ptextable, (unsigned int) draw);
2189 if (!pm)
2190 {
2191 pm = crCalloc(sizeof(pminfo));
2192 crHashtableAdd(ptextable, (unsigned int) draw, pm);
2193 }
2194 pm->w = w;
2195 pm->h = h;
2196 if (pm->data) crFree(pm->data);
2197 pm->data = crAlloc(4*w*h);
2198 crMemcpy(pm->data, (void*)(&(pxim->data[0])), 4*w*h);
2199 }*/
2200
2201 if (NULL==pxim)
2202 {
2203 crWarning("Failed, to get pixmap data for 0x%x", (unsigned int) draw);
2204 return;
2205 }
2206
2207 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pxim->width, pxim->height, 0,
2208 GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(pxim->data[0])));
2209 XDestroyImage(pxim);
2210 }
2211 else /* Use shm to get pixmap data */
2212 {
2213 /* Check if we have damage extension */
2214 if (stub.currentContext->damageDpy)
2215 {
2216 if (pGlxPixmap->bPixmapImageDirty)
2217 {
2218 /* Either we failed to allocate damage region or this pixmap is marked for full update */
2219 if (!pGlxPixmap->pDamageRegion || XEmptyRegion(pGlxPixmap->pDamageRegion))
2220 {
2221 /*crDebug("**FULL** update for 0x%x", (unsigned int)draw);*/
2222 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2223 }
2224 else
2225 {
2226 long fullArea, damageArea=0, clipdamageArea, i;
2227 XRectangle damageClipBox;
2228
2229 fullArea = pGlxPixmap->w * pGlxPixmap->h;
2230 XClipBox(pGlxPixmap->pDamageRegion, &damageClipBox);
2231 clipdamageArea = damageClipBox.width * damageClipBox.height;
2232
2233 //crDebug("FullSize [%i,%i,%i,%i]", pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);
2234 //crDebug("Clip [%i,%i,%i,%i]", damageClipBox.x, damageClipBox.y, damageClipBox.width, damageClipBox.height);
2235
2236 for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
2237 {
2238 BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
2239 damageArea += (pBox->x2-pBox->x1)*(pBox->y2-pBox->y1);
2240 //crDebug("Damage rect [%i,%i,%i,%i]", pBox->x1, pBox->y1, pBox->x2, pBox->y2);
2241 }
2242
2243 if (damageArea>clipdamageArea || clipdamageArea>fullArea)
2244 {
2245 crWarning("glXBindTexImageEXT, damage regions seems to be broken, forcing full update");
2246 /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
2247 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2248 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2249 }
2250 else /*We have corect damage info*/
2251 {
2252 if (CR_MIN_DAMAGE_PROFIT_SIZE > (fullArea-damageArea))
2253 {
2254 /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
2255 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2256 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2257 }
2258 else if (CR_MIN_DAMAGE_PROFIT_SIZE > (clipdamageArea-damageArea))
2259 {
2260 /*crDebug("**PARTIAL** update for 0x%x, numRect=%li, FS=%li, *CS*=%li, DS=%li",
2261 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2262 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &damageClipBox);
2263 }
2264 else
2265 {
2266 /*crDebug("**PARTIAL** update for 0x%x, numRect=*%li*, FS=%li, CS=%li, *DS*=%li",
2267 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
2268 for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
2269 {
2270 XRectangle rect;
2271 BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
2272
2273 rect.x = pBox->x1;
2274 rect.y = pBox->y1;
2275 rect.width = pBox->x2-pBox->x1;
2276 rect.height = pBox->y2-pBox->y1;
2277
2278 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
2279 }
2280 }
2281 }
2282 }
2283
2284 /* Clean dirty flag and damage region */
2285 pGlxPixmap->bPixmapImageDirty = False;
2286 if (pGlxPixmap->pDamageRegion)
2287 EMPTY_REGION(pGlxPixmap->pDamageRegion);
2288 }
2289 }
2290 else
2291 {
2292 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
2293 }
2294 }
2295}
2296
2297DECLEXPORT(void) VBOXGLXTAG(glXReleaseTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer)
2298{
2299 (void) dpy;
2300 (void) draw;
2301 (void) buffer;
2302 //crDebug("glXReleaseTexImageEXT 0x%x", (unsigned int)draw);
2303}
2304#endif
2305
2306#endif /* GLX_EXTRAS */
2307
2308
2309#ifdef GLX_SGIX_video_resize
2310/* more dummy funcs. These help when linking with older GLUTs */
2311
2312DECLEXPORT(int) VBOXGLXTAG(glXBindChannelToWindowSGIX)(Display *dpy, int scrn, int chan, Window w)
2313{
2314 (void) dpy;
2315 (void) scrn;
2316 (void) chan;
2317 (void) w;
2318 crDebug("glXBindChannelToWindowSGIX");
2319 return 0;
2320}
2321
2322DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSGIX)(Display *dpy, int scrn, int chan, int x , int y, int w, int h)
2323{
2324 (void) dpy;
2325 (void) scrn;
2326 (void) chan;
2327 (void) x;
2328 (void) y;
2329 (void) w;
2330 (void) h;
2331 crDebug("glXChannelRectSGIX");
2332 return 0;
2333}
2334
2335DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelRectSGIX)(Display *dpy, int scrn, int chan, int *x, int *y, int *w, int *h)
2336{
2337 (void) dpy;
2338 (void) scrn;
2339 (void) chan;
2340 (void) x;
2341 (void) y;
2342 (void) w;
2343 (void) h;
2344 crDebug("glXQueryChannelRectSGIX");
2345 return 0;
2346}
2347
2348DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelDeltasSGIX)(Display *dpy, int scrn, int chan, int *dx, int *dy, int *dw, int *dh)
2349{
2350 (void) dpy;
2351 (void) scrn;
2352 (void) chan;
2353 (void) dx;
2354 (void) dy;
2355 (void) dw;
2356 (void) dh;
2357 crDebug("glXQueryChannelDeltasSGIX");
2358 return 0;
2359}
2360
2361DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSyncSGIX)(Display *dpy, int scrn, int chan, GLenum synctype)
2362{
2363 (void) dpy;
2364 (void) scrn;
2365 (void) chan;
2366 (void) synctype;
2367 crDebug("glXChannelRectSyncSGIX");
2368 return 0;
2369}
2370
2371#endif /* GLX_SGIX_video_resize */
2372
2373#ifdef VBOXOGL_FAKEDRI
2374DECLEXPORT(const char *) VBOXGLXTAG(glXGetDriverConfig)(const char *driverName)
2375{
2376 return NULL;
2377}
2378
2379DECLEXPORT(void) VBOXGLXTAG(glXFreeMemoryMESA)(Display *dpy, int scrn, void *pointer)
2380{
2381 (void) dpy;
2382 (void) scrn;
2383 (void) pointer;
2384}
2385
2386DECLEXPORT(GLXContext) VBOXGLXTAG(glXImportContextEXT)(Display *dpy, GLXContextID contextID)
2387{
2388 (void) dpy;
2389 (void) contextID;
2390 return NULL;
2391}
2392
2393DECLEXPORT(GLXContextID) VBOXGLXTAG(glXGetContextIDEXT)(const GLXContext ctx)
2394{
2395 (void) ctx;
2396 return 0;
2397}
2398
2399DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrentReadSGI)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
2400{
2401 return VBOXGLXTAG(glXMakeContextCurrent)(display, draw, read, ctx);
2402}
2403
2404DECLEXPORT(const char *) VBOXGLXTAG(glXGetScreenDriver)(Display *dpy, int scrNum)
2405{
2406 static char *screendriver = "vboxvideo";
2407 return screendriver;
2408}
2409
2410DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplayEXT)(void)
2411{
2412 return VBOXGLXTAG(glXGetCurrentDisplay());
2413}
2414
2415DECLEXPORT(void) VBOXGLXTAG(glXFreeContextEXT)(Display *dpy, GLXContext ctx)
2416{
2417 VBOXGLXTAG(glXDestroyContext(dpy, ctx));
2418}
2419
2420/*Mesa internal*/
2421DECLEXPORT(int) VBOXGLXTAG(glXQueryContextInfoEXT)(Display *dpy, GLXContext ctx)
2422{
2423 (void) dpy;
2424 (void) ctx;
2425 return 0;
2426}
2427
2428DECLEXPORT(void *) VBOXGLXTAG(glXAllocateMemoryMESA)(Display *dpy, int scrn,
2429 size_t size, float readFreq,
2430 float writeFreq, float priority)
2431{
2432 (void) dpy;
2433 (void) scrn;
2434 (void) size;
2435 (void) readFreq;
2436 (void) writeFreq;
2437 (void) priority;
2438 return NULL;
2439}
2440
2441DECLEXPORT(GLuint) VBOXGLXTAG(glXGetMemoryOffsetMESA)(Display *dpy, int scrn, const void *pointer)
2442{
2443 (void) dpy;
2444 (void) scrn;
2445 (void) pointer;
2446 return 0;
2447}
2448
2449DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap)
2450{
2451 (void) dpy;
2452 (void) visual;
2453 (void) pixmap;
2454 (void) cmap;
2455 return 0;
2456}
2457
2458#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