VirtualBox

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

最後變更 在這個檔案從31517是 30474,由 vboxsync 提交於 15 年 前

crOpenGL: enable new window tracking code for linux

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

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