VirtualBox

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

Last change on this file since 61522 was 58846, checked in by vboxsync, 9 years ago

Additions/common/3D: added Oracle copyright to glx.c.

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