VirtualBox

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

Last change on this file since 69496 was 69496, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 61.5 KB
Line 
1/* $Id: glx.c 69496 2017-10-28 14:55:58Z vboxsync $ */
2/** @file
3 * VBox OpenGL GLX implementation
4 */
5
6/*
7 * Copyright (C) 2009-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 * Original copyright notice:
17 *
18 * Copyright (c) 2001, Stanford University
19 * All rights reserved
20 *
21 * See the file LICENSE.txt for information on redistributing this software.
22 */
23
24/* opengl_stub/glx.c */
25#include "chromium.h"
26#include "cr_error.h"
27#include "cr_spu.h"
28#include "cr_mem.h"
29#include "cr_string.h"
30#include "stub.h"
31#include "dri_glx.h"
32#include "GL/internal/glcore.h"
33#include "cr_glstate.h"
34
35#include <X11/Xregion.h>
36
37/* Force full pixmap update if there're more damaged regions than this number*/
38#define CR_MAX_DAMAGE_REGIONS_TRACKED 50
39
40/* Force "bigger" update (full or clip) if it's reducing number of regions updated
41 * but doesn't increase updated area more than given number
42 */
43#define CR_MIN_DAMAGE_PROFIT_SIZE 64*64
44
45/** @todo combine it in some other place*/
46/* Size of pack spu buffer - some delta for commands packing, see pack/packspu_config.c*/
47
48/** Ramshankar: Solaris compiz fix */
49#ifdef RT_OS_SOLARIS
50# define CR_MAX_TRANSFER_SIZE 20*1024*1024
51#else
52# define CR_MAX_TRANSFER_SIZE 4*1024*1024
53#endif
54
55/** For optimizing glXMakeCurrent */
56static Display *currentDisplay = NULL;
57static GLXDrawable currentDrawable = 0;
58static GLXDrawable currentReadDrawable = 0;
59
60static void stubXshmUpdateImageRect(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap, XRectangle *pRect);
61static void stubQueryXDamageExtension(Display *dpy, ContextInfo *pContext);
62
63static bool isGLXVisual(Display *dpy, XVisualInfo *vis)
64{
65 return vis->visualid == XVisualIDFromVisual(DefaultVisual(dpy, vis->screen));
66}
67
68static GLXFBConfig fbConfigFromVisual(Display *dpy, XVisualInfo *vis)
69{
70 (void)dpy;
71
72 if (!isGLXVisual(dpy, vis))
73 return 0;
74 return (GLXFBConfig)vis->visualid;
75}
76
77static GLXFBConfig defaultFBConfigForScreen(Display *dpy, int screen)
78{
79 return (GLXFBConfig) XVisualIDFromVisual(DefaultVisual(dpy, screen));
80}
81
82static XVisualInfo *visualInfoFromFBConfig(Display *dpy, GLXFBConfig config)
83{
84 XVisualInfo info, *pret;
85 int nret;
86
87 info.visualid = (VisualID)config;
88 pret = XGetVisualInfo(dpy, VisualIDMask, &info, &nret);
89 if (nret == 1)
90 return pret;
91 XFree(pret);
92 return NULL;
93}
94
95DECLEXPORT(XVisualInfo *)
96VBOXGLXTAG(glXChooseVisual)( Display *dpy, int screen, int *attribList )
97{
98 bool useRGBA = false;
99 int *attrib;
100 XVisualInfo searchvis, *pret;
101 int nvisuals;
102 stubInit();
103
104 for (attrib = attribList; *attrib != None; attrib++)
105 {
106 switch (*attrib)
107 {
108 case GLX_USE_GL:
109 /* ignored, this is mandatory */
110 break;
111
112 case GLX_BUFFER_SIZE:
113 /* this is for color-index visuals, which we don't support */
114 attrib++;
115 break;
116
117 case GLX_LEVEL:
118 if (attrib[1] != 0)
119 goto err_exit;
120 attrib++;
121 break;
122
123 case GLX_RGBA:
124 useRGBA = true;
125 break;
126
127 case GLX_STEREO:
128 goto err_exit;
129 /*
130 crWarning( "glXChooseVisual: stereo unsupported" );
131 return NULL;
132 */
133 break;
134
135 case GLX_AUX_BUFFERS:
136 if (attrib[1] != 0)
137 goto err_exit;
138 attrib++;
139 break;
140
141 case GLX_RED_SIZE:
142 case GLX_GREEN_SIZE:
143 case GLX_BLUE_SIZE:
144 if (attrib[1] > 8)
145 goto err_exit;
146 attrib++;
147 break;
148
149 case GLX_ALPHA_SIZE:
150 if (attrib[1] > 8)
151 goto err_exit;
152 attrib++;
153 break;
154
155 case GLX_DEPTH_SIZE:
156 if (attrib[1] > 24)
157 goto err_exit;
158 attrib++;
159 break;
160
161 case GLX_STENCIL_SIZE:
162 if (attrib[1] > 8)
163 goto err_exit;
164 attrib++;
165 break;
166
167 case GLX_ACCUM_RED_SIZE:
168 case GLX_ACCUM_GREEN_SIZE:
169 case GLX_ACCUM_BLUE_SIZE:
170 case GLX_ACCUM_ALPHA_SIZE:
171 if (attrib[1] > 16)
172 goto err_exit;
173 attrib++;
174 break;
175
176 case GLX_SAMPLE_BUFFERS_SGIS: /* aka GLX_SAMPLES_ARB */
177 if (attrib[1] > 0)
178 goto err_exit;
179 attrib++;
180 break;
181 case GLX_SAMPLES_SGIS: /* aka GLX_SAMPLES_ARB */
182 if (attrib[1] > 0)
183 goto err_exit;
184 attrib++;
185 break;
186
187 case GLX_DOUBLEBUFFER: /* @todo, check if we support it */
188 break;
189
190#ifdef GLX_VERSION_1_3
191 case GLX_X_VISUAL_TYPE:
192 case GLX_TRANSPARENT_TYPE_EXT:
193 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
194 case GLX_TRANSPARENT_RED_VALUE_EXT:
195 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
196 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
197 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
198 /* ignore */
199 crWarning("glXChooseVisual: ignoring attribute 0x%x", *attrib);
200 attrib++;
201 break;
202#endif
203
204 default:
205 crWarning( "glXChooseVisual: bad attrib=0x%x, ignoring", *attrib );
206 attrib++;
207 //return NULL;
208 }
209 }
210
211 if (!useRGBA)
212 return NULL;
213
214 XLOCK(dpy);
215 searchvis.visualid = XVisualIDFromVisual(DefaultVisual(dpy, screen));
216 pret = XGetVisualInfo(dpy, VisualIDMask, &searchvis, &nvisuals);
217 XUNLOCK(dpy);
218
219 if (nvisuals!=1) crWarning("glXChooseVisual: XGetVisualInfo returned %i visuals for %x", nvisuals, (unsigned int) searchvis.visualid);
220 if (pret)
221 crDebug("glXChooseVisual returned %x depth=%i", (unsigned int)pret->visualid, pret->depth);
222 return pret;
223
224err_exit:
225 crDebug("glXChooseVisual returning NULL, due to attrib=0x%x, next=0x%x", attrib[0], attrib[1]);
226 return NULL;
227}
228
229/**
230 ** There is a problem with glXCopyContext.
231 ** IRIX and Mesa both define glXCopyContext
232 ** to have the mask argument being a
233 ** GLuint. XFree 4 and oss.sgi.com
234 ** define it to be an unsigned long.
235 ** Solution: We don't support
236 ** glXCopyContext anyway so we'll just
237 ** \#ifdef out the code.
238 */
239DECLEXPORT(void)
240VBOXGLXTAG(glXCopyContext)( Display *dpy, GLXContext src, GLXContext dst,
241#if defined(AIX) || defined(PLAYSTATION2)
242GLuint mask
243#elif defined(SunOS)
244unsigned long mask
245#else
246unsigned long mask
247#endif
248)
249{
250 (void) dpy;
251 (void) src;
252 (void) dst;
253 (void) mask;
254 crWarning( "Unsupported GLX Call: glXCopyContext()" );
255}
256
257
258/**
259 * Get the display string for the given display pointer.
260 * Never return just ":0.0". In that case, prefix with our host name.
261 */
262static void
263stubGetDisplayString( Display *dpy, char *nameResult, int maxResult )
264{
265 const char *dpyName = DisplayString(dpy);
266 char host[1000];
267
268 host[0] = 0;
269 if (crStrlen(host) + crStrlen(dpyName) >= maxResult - 1)
270 {
271 /* return null string */
272 crWarning("Very long host / display name string in stubDisplayString!");
273 nameResult[0] = 0;
274 }
275 else
276 {
277 /* return host concatenated with dpyName */
278 crStrcpy(nameResult, host);
279 crStrcat(nameResult, dpyName);
280 }
281}
282
283
284
285DECLEXPORT(GLXContext)
286VBOXGLXTAG(glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext share, Bool direct)
287{
288 char dpyName[MAX_DPY_NAME];
289 ContextInfo *context;
290 int visBits = CR_RGB_BIT | CR_DOUBLE_BIT | CR_DEPTH_BIT; /* default vis */
291
292 (void)vis;
293 stubInit();
294
295 CRASSERT(stub.contextTable);
296
297 /*
298 {
299 int i, numExt;
300 char **list;
301
302 list = XListExtensions(dpy, &numExt);
303 crDebug("X extensions [%i]:", numExt);
304 for (i=0; i<numExt; ++i)
305 {
306 crDebug("%s", list[i]);
307 }
308 XFreeExtensionList(list);
309 }
310 */
311
312 stubGetDisplayString(dpy, dpyName, MAX_DPY_NAME);
313
314 context = stubNewContext(dpyName, visBits, UNDECIDED, (unsigned long) share);
315 if (!context)
316 return 0;
317
318 context->dpy = dpy;
319 context->direct = direct;
320
321 stubQueryXDamageExtension(dpy, context);
322
323 return (GLXContext) context->id;
324}
325
326
327DECLEXPORT(void) VBOXGLXTAG(glXDestroyContext)( Display *dpy, GLXContext ctx )
328{
329 (void) dpy;
330 stubDestroyContext( (unsigned long) ctx );
331}
332
333typedef struct _stubFindPixmapParms_t {
334 ContextInfo *pCtx;
335 GLX_Pixmap_t *pGlxPixmap;
336 GLXDrawable draw;
337} stubFindPixmapParms_t;
338
339static void stubFindPixmapCB(unsigned long key, void *data1, void *data2)
340{
341 ContextInfo *pCtx = (ContextInfo *) data1;
342 stubFindPixmapParms_t *pParms = (stubFindPixmapParms_t *) data2;
343 GLX_Pixmap_t *pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(pCtx->pGLXPixmapsHash, (unsigned int) pParms->draw);
344 (void)key;
345
346 if (pGlxPixmap)
347 {
348 pParms->pCtx = pCtx;
349 pParms->pGlxPixmap = pGlxPixmap;
350 }
351}
352
353DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx )
354{
355 ContextInfo *context;
356 WindowInfo *window;
357 Bool retVal;
358
359 /*crDebug("glXMakeCurrent(%p, 0x%x, 0x%x)", (void *) dpy, (int) drawable, (int) ctx);*/
360
361 /*check if passed drawable is GLXPixmap and not X Window*/
362 if (drawable)
363 {
364 GLX_Pixmap_t *pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) drawable);
365
366 if (!pGlxPixmap)
367 {
368 stubFindPixmapParms_t parms;
369 parms.pGlxPixmap = NULL;
370 parms.draw = drawable;
371 crHashtableWalk(stub.contextTable, stubFindPixmapCB, &parms);
372 pGlxPixmap = parms.pGlxPixmap;
373 }
374
375 if (pGlxPixmap)
376 {
377 /** @todo */
378 crWarning("Unimplemented glxMakeCurrent call with GLXPixmap passed, unexpected things might happen.");
379 }
380 }
381
382 if (ctx && drawable)
383 {
384 crHashtableLock(stub.windowTable);
385 crHashtableLock(stub.contextTable);
386
387 context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) ctx);
388 window = stubGetWindowInfo(dpy, drawable);
389
390 if (context && context->type == UNDECIDED) {
391 XLOCK(dpy);
392 XSync(dpy, 0); /* sync to force window creation on the server */
393 XUNLOCK(dpy);
394 }
395 }
396 else
397 {
398 dpy = NULL;
399 window = NULL;
400 context = NULL;
401 }
402
403 currentDisplay = dpy;
404 currentDrawable = drawable;
405
406 retVal = stubMakeCurrent(window, context);
407
408 if (ctx && drawable)
409 {
410 crHashtableUnlock(stub.contextTable);
411 crHashtableUnlock(stub.windowTable);
412 }
413
414 return retVal;
415}
416
417DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmap)( Display *dpy, XVisualInfo *vis, Pixmap pixmap )
418{
419 stubInit();
420 return VBOXGLXTAG(glXCreatePixmap)(dpy, fbConfigFromVisual(dpy, vis), pixmap, NULL);
421}
422
423DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPixmap)( Display *dpy, GLXPixmap pix )
424{
425 VBOXGLXTAG(glXDestroyPixmap)(dpy, pix);
426}
427
428DECLEXPORT(int) VBOXGLXTAG(glXGetConfig)( Display *dpy, XVisualInfo *vis, int attrib, int *value )
429{
430 if (!vis) {
431 /* SGI OpenGL Performer hits this */
432 crWarning("glXGetConfig called with NULL XVisualInfo");
433 return GLX_BAD_VISUAL;
434 }
435
436 stubInit();
437
438 *value = 0; /* For sanity */
439
440 switch ( attrib ) {
441
442 case GLX_USE_GL:
443 *value = isGLXVisual(dpy, vis);
444 break;
445
446 case GLX_BUFFER_SIZE:
447 *value = 32;
448 break;
449
450 case GLX_LEVEL:
451 *value = 0; /* for now */
452 break;
453
454 case GLX_RGBA:
455 *value = 1;
456 break;
457
458 case GLX_DOUBLEBUFFER:
459 *value = 1;
460 break;
461
462 case GLX_STEREO:
463 *value = 1;
464 break;
465
466 case GLX_AUX_BUFFERS:
467 *value = 0;
468 break;
469
470 case GLX_RED_SIZE:
471 *value = 8;
472 break;
473
474 case GLX_GREEN_SIZE:
475 *value = 8;
476 break;
477
478 case GLX_BLUE_SIZE:
479 *value = 8;
480 break;
481
482 case GLX_ALPHA_SIZE:
483 *value = 8;
484 break;
485
486 case GLX_DEPTH_SIZE:
487 *value = 24;
488 break;
489
490 case GLX_STENCIL_SIZE:
491 *value = 8;
492 break;
493
494 case GLX_ACCUM_RED_SIZE:
495 *value = 16;
496 break;
497
498 case GLX_ACCUM_GREEN_SIZE:
499 *value = 16;
500 break;
501
502 case GLX_ACCUM_BLUE_SIZE:
503 *value = 16;
504 break;
505
506 case GLX_ACCUM_ALPHA_SIZE:
507 *value = 16;
508 break;
509
510 case GLX_SAMPLE_BUFFERS_SGIS:
511 *value = 0; /* fix someday */
512 break;
513
514 case GLX_SAMPLES_SGIS:
515 *value = 0; /* fix someday */
516 break;
517
518 case GLX_VISUAL_CAVEAT_EXT:
519 *value = GLX_NONE_EXT;
520 break;
521#if defined(SunOS) || 1
522 /*
523 I don't think this is even a valid attribute for glxGetConfig.
524 No idea why this gets called under SunOS but we simply ignore it
525 -- jw
526 */
527 case GLX_X_VISUAL_TYPE:
528 crWarning ("Ignoring Unsupported GLX Call: glxGetConfig with attrib 0x%x", attrib);
529 break;
530#endif
531
532 case GLX_TRANSPARENT_TYPE:
533 *value = GLX_NONE_EXT;
534 break;
535 case GLX_TRANSPARENT_INDEX_VALUE:
536 *value = 0;
537 break;
538 case GLX_TRANSPARENT_RED_VALUE:
539 *value = 0;
540 break;
541 case GLX_TRANSPARENT_GREEN_VALUE:
542 *value = 0;
543 break;
544 case GLX_TRANSPARENT_BLUE_VALUE:
545 *value = 0;
546 break;
547 case GLX_TRANSPARENT_ALPHA_VALUE:
548 *value = 0;
549 break;
550 case GLX_DRAWABLE_TYPE:
551 *value = GLX_WINDOW_BIT;
552 break;
553 default:
554 crWarning( "Unsupported GLX Call: glXGetConfig with attrib 0x%x, ignoring...", attrib );
555 //return GLX_BAD_ATTRIBUTE;
556 *value = 0;
557 }
558
559 return 0;
560}
561
562DECLEXPORT(GLXContext) VBOXGLXTAG(glXGetCurrentContext)( void )
563{
564 ContextInfo *context = stubGetCurrentContext();
565 if (context)
566 return (GLXContext) context->id;
567 else
568 return (GLXContext) NULL;
569}
570
571DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentDrawable)(void)
572{
573 return currentDrawable;
574}
575
576DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplay)(void)
577{
578 return currentDisplay;
579}
580
581DECLEXPORT(Bool) VBOXGLXTAG(glXIsDirect)(Display *dpy, GLXContext ctx)
582{
583 (void) dpy;
584 (void) ctx;
585 crDebug("->glXIsDirect");
586 return True;
587}
588
589DECLEXPORT(Bool) VBOXGLXTAG(glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase)
590{
591 (void) dpy;
592 (void) errorBase;
593 (void) eventBase;
594 return 1; /* You BET we do... */
595}
596
597DECLEXPORT(Bool) VBOXGLXTAG(glXQueryVersion)( Display *dpy, int *major, int *minor )
598{
599 (void) dpy;
600 *major = 1;
601 *minor = 3;
602 return 1;
603}
604
605DECLEXPORT(void) VBOXGLXTAG(glXSwapBuffers)( Display *dpy, GLXDrawable drawable )
606{
607 WindowInfo *window = stubGetWindowInfo(dpy, drawable);
608 stubSwapBuffers( window, 0 );
609}
610
611DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)( Font font, int first, int count, int listBase )
612{
613 ContextInfo *context = stubGetCurrentContext();
614 Display *dpy = context->dpy;
615 if (dpy) {
616 stubUseXFont( dpy, font, first, count, listBase );
617 }
618 else {
619 dpy = XOpenDisplay(NULL);
620 if (!dpy)
621 return;
622 stubUseXFont( dpy, font, first, count, listBase );
623 XCloseDisplay(dpy);
624 }
625}
626
627DECLEXPORT(void) VBOXGLXTAG(glXWaitGL)( void )
628{
629 static int first_call = 1;
630
631 if ( first_call )
632 {
633 crDebug( "Ignoring unsupported GLX call: glXWaitGL()" );
634 first_call = 0;
635 }
636}
637
638DECLEXPORT(void) VBOXGLXTAG(glXWaitX)( void )
639{
640 static int first_call = 1;
641
642 if ( first_call )
643 {
644 crDebug( "Ignoring unsupported GLX call: glXWaitX()" );
645 first_call = 0;
646 }
647}
648
649DECLEXPORT(const char *) VBOXGLXTAG(glXQueryExtensionsString)( Display *dpy, int screen )
650{
651 /* XXX maybe also advertise GLX_SGIS_multisample? */
652
653 static const char *retval = "GLX_ARB_multisample GLX_EXT_texture_from_pixmap GLX_SGIX_fbconfig GLX_ARB_get_proc_address";
654
655 (void) dpy;
656 (void) screen;
657
658 crDebug("->glXQueryExtensionsString");
659 return retval;
660}
661
662DECLEXPORT(const char *) VBOXGLXTAG(glXGetClientString)( Display *dpy, int name )
663{
664 const char *retval;
665 (void) dpy;
666 (void) name;
667
668 switch ( name ) {
669
670 case GLX_VENDOR:
671 retval = "Chromium";
672 break;
673
674 case GLX_VERSION:
675 retval = "1.3 Chromium";
676 break;
677
678 case GLX_EXTENSIONS:
679 /** @todo should be a screen not a name...but it's not used anyway*/
680 retval = glXQueryExtensionsString(dpy, name);
681 break;
682
683 default:
684 retval = NULL;
685 }
686
687 return retval;
688}
689
690DECLEXPORT(const char *) VBOXGLXTAG(glXQueryServerString)( Display *dpy, int screen, int name )
691{
692 const char *retval;
693 (void) dpy;
694 (void) screen;
695
696 switch ( name ) {
697
698 case GLX_VENDOR:
699 retval = "Chromium";
700 break;
701
702 case GLX_VERSION:
703 retval = "1.3 Chromium";
704 break;
705
706 case GLX_EXTENSIONS:
707 retval = glXQueryExtensionsString(dpy, screen);
708 break;
709
710 default:
711 retval = NULL;
712 }
713
714 return retval;
715}
716
717DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddressARB)( const GLubyte *name )
718{
719 return (CR_GLXFuncPtr) crGetProcAddress( (const char *) name );
720}
721
722DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddress)( const GLubyte *name )
723{
724 return (CR_GLXFuncPtr) crGetProcAddress( (const char *) name );
725}
726
727
728#if GLX_EXTRAS
729
730DECLEXPORT(GLXPbufferSGIX)
731VBOXGLXTAG(glXCreateGLXPbufferSGIX)(Display *dpy, GLXFBConfigSGIX config,
732 unsigned int width, unsigned int height,
733 int *attrib_list)
734{
735 (void) dpy;
736 (void) config;
737 (void) width;
738 (void) height;
739 (void) attrib_list;
740 crWarning("glXCreateGLXPbufferSGIX not implemented by Chromium");
741 return 0;
742}
743
744DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf)
745{
746 (void) dpy;
747 (void) pbuf;
748 crWarning("glXDestroyGLXPbufferSGIX not implemented by Chromium");
749}
750
751DECLEXPORT(void) VBOXGLXTAG(glXSelectEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long mask)
752{
753 (void) dpy;
754 (void) drawable;
755 (void) mask;
756}
757
758DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long *mask)
759{
760 (void) dpy;
761 (void) drawable;
762 (void) mask;
763}
764
765DECLEXPORT(int) VBOXGLXTAG(glXQueryGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf,
766 int attribute, unsigned int *value)
767{
768 (void) dpy;
769 (void) pbuf;
770 (void) attribute;
771 (void) value;
772 crWarning("glXQueryGLXPbufferSGIX not implemented by Chromium");
773 return 0;
774}
775
776DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttribSGIX)(Display *dpy, GLXFBConfig config,
777 int attribute, int *value)
778{
779 return VBOXGLXTAG(glXGetFBConfigAttrib)(dpy, config, attribute, value);
780}
781
782DECLEXPORT(GLXFBConfigSGIX *)
783VBOXGLXTAG(glXChooseFBConfigSGIX)(Display *dpy, int screen,
784 int *attrib_list, int *nelements)
785{
786 return VBOXGLXTAG(glXChooseFBConfig)(dpy, screen, attrib_list, nelements);
787}
788
789DECLEXPORT(GLXPixmap)
790VBOXGLXTAG(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy,
791 GLXFBConfig config,
792 Pixmap pixmap)
793{
794 return VBOXGLXTAG(glXCreatePixmap)(dpy, config, pixmap, NULL);
795}
796
797DECLEXPORT(GLXContext)
798VBOXGLXTAG(glXCreateContextWithConfigSGIX)(Display *dpy, GLXFBConfig config,
799 int render_type,
800 GLXContext share_list,
801 Bool direct)
802{
803 (void)config;
804 if (render_type!=GLX_RGBA_TYPE_SGIX)
805 {
806 crWarning("glXCreateContextWithConfigSGIX: Unsupported render type %i", render_type);
807 return NULL;
808 }
809 return VBOXGLXTAG(glXCreateContext)(dpy, NULL, share_list, direct);
810}
811
812DECLEXPORT(XVisualInfo *)
813VBOXGLXTAG(glXGetVisualFromFBConfigSGIX)(Display *dpy,
814 GLXFBConfig config)
815{
816 return visualInfoFromFBConfig(dpy, config);
817}
818
819DECLEXPORT(GLXFBConfigSGIX)
820VBOXGLXTAG(glXGetFBConfigFromVisualSGIX)(Display *dpy, XVisualInfo *vis)
821{
822 if (!vis)
823 {
824 return NULL;
825 }
826 /*Note: Caller is supposed to call XFree on returned value, so can't just return (GLXFBConfig)vis->visualid*/
827 return (GLXFBConfigSGIX) visualInfoFromFBConfig(dpy, fbConfigFromVisual(dpy, vis));
828}
829
830/*
831 * GLX 1.3 functions
832 */
833DECLEXPORT(GLXFBConfig *)
834VBOXGLXTAG(glXChooseFBConfig)(Display *dpy, int screen, ATTRIB_TYPE *attrib_list, int *nelements)
835{
836 ATTRIB_TYPE *attrib;
837 intptr_t fbconfig = 0;
838
839 stubInit();
840
841 if (!attrib_list)
842 {
843 return VBOXGLXTAG(glXGetFBConfigs)(dpy, screen, nelements);
844 }
845
846 for (attrib = attrib_list; *attrib != None; attrib++)
847 {
848 switch (*attrib)
849 {
850 case GLX_FBCONFIG_ID:
851 fbconfig = attrib[1];
852 attrib++;
853 break;
854
855 case GLX_BUFFER_SIZE:
856 /* this is ignored except for color-index visuals, which we don't support */
857 attrib++;
858 break;
859
860 case GLX_LEVEL:
861 if (attrib[1] != 0)
862 goto err_exit;
863 attrib++;
864 break;
865
866 case GLX_AUX_BUFFERS:
867 if (attrib[1] != 0)
868 goto err_exit;
869 attrib++;
870 break;
871
872 case GLX_DOUBLEBUFFER: /* @todo, check if we support it */
873 attrib++;
874 break;
875
876 case GLX_STEREO:
877 if (attrib[1] != 0)
878 goto err_exit;
879 attrib++;
880 break;
881
882 case GLX_RED_SIZE:
883 case GLX_GREEN_SIZE:
884 case GLX_BLUE_SIZE:
885 case GLX_ALPHA_SIZE:
886 if (attrib[1] > 8)
887 goto err_exit;
888 attrib++;
889 break;
890
891 case GLX_DEPTH_SIZE:
892 if (attrib[1] > 24)
893 goto err_exit;
894 attrib++;
895 break;
896
897 case GLX_STENCIL_SIZE:
898 if (attrib[1] > 8)
899 goto err_exit;
900 attrib++;
901 break;
902
903 case GLX_ACCUM_RED_SIZE:
904 case GLX_ACCUM_GREEN_SIZE:
905 case GLX_ACCUM_BLUE_SIZE:
906 case GLX_ACCUM_ALPHA_SIZE:
907 if (attrib[1] > 16)
908 goto err_exit;
909 attrib++;
910 break;
911
912 case GLX_X_RENDERABLE:
913 case GLX_CONFIG_CAVEAT:
914 attrib++;
915 break;
916
917 case GLX_RENDER_TYPE:
918 if (attrib[1]!=GLX_RGBA_BIT)
919 goto err_exit;
920 attrib++;
921 break;
922
923 case GLX_DRAWABLE_TYPE:
924 if ( !(attrib[1] & GLX_WINDOW_BIT)
925 && !(attrib[1] & GLX_PIXMAP_BIT))
926 goto err_exit;
927 attrib++;
928 break;
929
930 case GLX_X_VISUAL_TYPE:
931 case GLX_TRANSPARENT_TYPE_EXT:
932 case GLX_TRANSPARENT_INDEX_VALUE_EXT:
933 case GLX_TRANSPARENT_RED_VALUE_EXT:
934 case GLX_TRANSPARENT_GREEN_VALUE_EXT:
935 case GLX_TRANSPARENT_BLUE_VALUE_EXT:
936 case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
937 /* ignore */
938 crWarning("glXChooseVisual: ignoring attribute 0x%x", *attrib);
939 attrib++;
940 break;
941
942 break;
943 default:
944 crWarning( "glXChooseVisual: bad attrib=0x%x, ignoring", *attrib );
945 attrib++;
946 break;
947 }
948 }
949
950 if (fbconfig)
951 {
952 GLXFBConfig *pGLXFBConfigs;
953
954 *nelements = 1;
955 pGLXFBConfigs = (GLXFBConfig *) crAlloc(*nelements * sizeof(GLXFBConfig));
956 pGLXFBConfigs[0] = (GLXFBConfig)fbconfig;
957 return pGLXFBConfigs;
958 }
959 else
960 {
961 return VBOXGLXTAG(glXGetFBConfigs)(dpy, screen, nelements);
962 }
963
964err_exit:
965 crWarning("glXChooseFBConfig returning NULL, due to attrib=0x%x, next=0x%x", attrib[0], attrib[1]);
966 return NULL;
967}
968
969DECLEXPORT(GLXContext)
970VBOXGLXTAG(glXCreateNewContext)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
971{
972 (void) dpy;
973 (void) config;
974 (void) render_type;
975 (void) share_list;
976 (void) direct;
977
978 if (render_type != GLX_RGBA_TYPE)
979 {
980 crWarning("glXCreateNewContext, unsupported render_type %x", render_type);
981 return NULL;
982 }
983
984 return VBOXGLXTAG(glXCreateContext)(dpy, NULL, share_list, direct);
985}
986
987DECLEXPORT(GLXPbuffer)
988VBOXGLXTAG(glXCreatePbuffer)(Display *dpy, GLXFBConfig config, ATTRIB_TYPE *attrib_list)
989{
990 (void) dpy;
991 (void) config;
992 (void) attrib_list;
993 crWarning("glXCreatePbuffer not implemented by Chromium");
994 return 0;
995}
996
997/* Note: there're examples where glxpixmaps are created without current context, so can't do much of the work here.
998 * Instead we'd do necessary initialization on first use of those pixmaps.
999 */
1000DECLEXPORT(GLXPixmap)
1001VBOXGLXTAG(glXCreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, ATTRIB_TYPE *attrib_list)
1002{
1003 ATTRIB_TYPE *attrib;
1004 GLX_Pixmap_t *pGlxPixmap;
1005 (void) dpy;
1006 (void) config;
1007
1008#if 0
1009 {
1010 int x, y;
1011 unsigned int w, h;
1012 unsigned int border;
1013 unsigned int depth;
1014 Window root;
1015
1016 crDebug("glXCreatePixmap called for %lu", pixmap);
1017
1018 XLOCK(dpy);
1019 if (!XGetGeometry(dpy, pixmap, &root, &x, &y, &w, &h, &border, &depth))
1020 {
1021 XSync(dpy, False);
1022 if (!XGetGeometry(dpy, pixmap, &root, &x, &y, &w, &h, &border, &depth))
1023 {
1024 crDebug("fail");
1025 }
1026 }
1027 crDebug("root: %lu, [%i,%i %u,%u]", root, x, y, w, h);
1028 XUNLOCK(dpy);
1029 }
1030#endif
1031
1032 pGlxPixmap = crCalloc(sizeof(GLX_Pixmap_t));
1033 if (!pGlxPixmap)
1034 {
1035 crWarning("glXCreatePixmap failed to allocate memory");
1036 return 0;
1037 }
1038
1039 pGlxPixmap->format = GL_RGBA;
1040 pGlxPixmap->target = GL_TEXTURE_2D;
1041
1042 if (attrib_list)
1043 {
1044 for (attrib = attrib_list; *attrib != None; attrib++)
1045 {
1046 switch (*attrib)
1047 {
1048 case GLX_TEXTURE_FORMAT_EXT:
1049 attrib++;
1050 switch (*attrib)
1051 {
1052 case GLX_TEXTURE_FORMAT_RGBA_EXT:
1053 pGlxPixmap->format = GL_RGBA;
1054 break;
1055 case GLX_TEXTURE_FORMAT_RGB_EXT:
1056 pGlxPixmap->format = GL_RGB;
1057 break;
1058 default:
1059 crDebug("Unexpected GLX_TEXTURE_FORMAT_EXT 0x%x", (unsigned int) *attrib);
1060 }
1061 break;
1062 case GLX_TEXTURE_TARGET_EXT:
1063 attrib++;
1064 switch (*attrib)
1065 {
1066 case GLX_TEXTURE_2D_EXT:
1067 pGlxPixmap->target = GL_TEXTURE_2D;
1068 break;
1069 case GLX_TEXTURE_RECTANGLE_EXT:
1070 pGlxPixmap->target = GL_TEXTURE_RECTANGLE_NV;
1071 break;
1072 default:
1073 crDebug("Unexpected GLX_TEXTURE_TARGET_EXT 0x%x", (unsigned int) *attrib);
1074 }
1075 break;
1076 default: attrib++;
1077 }
1078 }
1079 }
1080
1081 crHashtableAdd(stub.pGLXPixmapsHash, (unsigned int) pixmap, pGlxPixmap);
1082 return (GLXPixmap) pixmap;
1083}
1084
1085DECLEXPORT(GLXWindow)
1086VBOXGLXTAG(glXCreateWindow)(Display *dpy, GLXFBConfig config, Window win, ATTRIB_TYPE *attrib_list)
1087{
1088 GLXFBConfig *realcfg;
1089 int nconfigs;
1090 (void) config;
1091
1092 if (stub.wsInterface.glXGetFBConfigs)
1093 {
1094 realcfg = stub.wsInterface.glXGetFBConfigs(dpy, 0, &nconfigs);
1095 if (!realcfg || nconfigs<1)
1096 {
1097 crWarning("glXCreateWindow !realcfg || nconfigs<1");
1098 return 0;
1099 }
1100 else
1101 {
1102 return stub.wsInterface.glXCreateWindow(dpy, realcfg[0], win, attrib_list);
1103 }
1104 }
1105 else
1106 {
1107 if (attrib_list && *attrib_list!=None)
1108 {
1109 crWarning("Non empty attrib list in glXCreateWindow");
1110 return 0;
1111 }
1112 return (GLXWindow)win;
1113 }
1114}
1115
1116DECLEXPORT(void) VBOXGLXTAG(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf)
1117{
1118 (void) dpy;
1119 (void) pbuf;
1120 crWarning("glXDestroyPbuffer not implemented by Chromium");
1121}
1122
1123DECLEXPORT(void) VBOXGLXTAG(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap)
1124{
1125 stubFindPixmapParms_t parms;
1126
1127 if (crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) pixmap))
1128 {
1129 /*it's valid but never used glxpixmap, so simple free stored ptr*/
1130 crHashtableDelete(stub.pGLXPixmapsHash, (unsigned int) pixmap, crFree);
1131 return;
1132 }
1133 else
1134 {
1135 /*it's either invalid glxpixmap or one which was already initialized, so it's stored in appropriate ctx hash*/
1136 parms.pCtx = NULL;
1137 parms.pGlxPixmap = NULL;
1138 parms.draw = pixmap;
1139 crHashtableWalk(stub.contextTable, stubFindPixmapCB, &parms);
1140 }
1141
1142 if (!parms.pGlxPixmap)
1143 {
1144 crWarning("glXDestroyPixmap called for unknown glxpixmap 0x%x", (unsigned int) pixmap);
1145 return;
1146 }
1147
1148 XLOCK(dpy);
1149 if (parms.pGlxPixmap->gc)
1150 {
1151 XFreeGC(dpy, parms.pGlxPixmap->gc);
1152 }
1153
1154 if (parms.pGlxPixmap->hShmPixmap>0)
1155 {
1156 XFreePixmap(dpy, parms.pGlxPixmap->hShmPixmap);
1157 }
1158 XUNLOCK(dpy);
1159
1160 if (parms.pGlxPixmap->hDamage>0)
1161 {
1162 //crDebug("Destroy: Damage for drawable 0x%x, handle 0x%x", (unsigned int) pixmap, (unsigned int) parms.pGlxPixmap->damage);
1163 XDamageDestroy(dpy, parms.pGlxPixmap->hDamage);
1164 }
1165
1166 if (parms.pGlxPixmap->pDamageRegion)
1167 {
1168 XDestroyRegion(parms.pGlxPixmap->pDamageRegion);
1169 }
1170
1171 crHashtableDelete(parms.pCtx->pGLXPixmapsHash, (unsigned int) pixmap, crFree);
1172}
1173
1174DECLEXPORT(void) VBOXGLXTAG(glXDestroyWindow)(Display *dpy, GLXWindow win)
1175{
1176 (void) dpy;
1177 (void) win;
1178 /*crWarning("glXDestroyWindow not implemented by Chromium");*/
1179}
1180
1181DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentReadDrawable)(void)
1182{
1183 return currentReadDrawable;
1184}
1185
1186DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value)
1187{
1188 XVisualInfo * pVisual;
1189 const char * pExt;
1190
1191 switch (attribute)
1192 {
1193 case GLX_DRAWABLE_TYPE:
1194 *value = GLX_PIXMAP_BIT | GLX_WINDOW_BIT;
1195 break;
1196 case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
1197 *value = GLX_TEXTURE_2D_BIT_EXT;
1198 pExt = (const char *) stub.spu->dispatch_table.GetString(GL_EXTENSIONS);
1199 if (crStrstr(pExt, "GL_NV_texture_rectangle")
1200 || crStrstr(pExt, "GL_ARB_texture_rectangle")
1201 || crStrstr(pExt, "GL_EXT_texture_rectangle"))
1202 {
1203 *value |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
1204 }
1205 break;
1206 case GLX_BIND_TO_TEXTURE_RGBA_EXT:
1207 *value = True;
1208 break;
1209 case GLX_BIND_TO_TEXTURE_RGB_EXT:
1210 *value = True;
1211 break;
1212 case GLX_DOUBLEBUFFER:
1213 //crDebug("attribute=GLX_DOUBLEBUFFER");
1214 *value = True;
1215 break;
1216 case GLX_Y_INVERTED_EXT:
1217 *value = True;
1218 break;
1219 case GLX_ALPHA_SIZE:
1220 //crDebug("attribute=GLX_ALPHA_SIZE");
1221 *value = 8;
1222 break;
1223 case GLX_BUFFER_SIZE:
1224 //crDebug("attribute=GLX_BUFFER_SIZE");
1225 *value = 32;
1226 break;
1227 case GLX_STENCIL_SIZE:
1228 //crDebug("attribute=GLX_STENCIL_SIZE");
1229 *value = 8;
1230 break;
1231 case GLX_DEPTH_SIZE:
1232 *value = 24;
1233 //crDebug("attribute=GLX_DEPTH_SIZE");
1234 break;
1235 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
1236 *value = 0;
1237 break;
1238 case GLX_RENDER_TYPE:
1239 //crDebug("attribute=GLX_RENDER_TYPE");
1240 *value = GLX_RGBA_BIT;
1241 break;
1242 case GLX_CONFIG_CAVEAT:
1243 //crDebug("attribute=GLX_CONFIG_CAVEAT");
1244 *value = GLX_NONE;
1245 break;
1246 case GLX_VISUAL_ID:
1247 //crDebug("attribute=GLX_VISUAL_ID");
1248 pVisual = visualInfoFromFBConfig(dpy, config);
1249 if (!pVisual)
1250 {
1251 crWarning("glXGetFBConfigAttrib for %p, failed to get XVisualInfo", config);
1252 return GLX_BAD_ATTRIBUTE;
1253 }
1254 *value = pVisual->visualid;
1255 XFree(pVisual);
1256 break;
1257 case GLX_FBCONFIG_ID:
1258 *value = (int)(intptr_t)config;
1259 break;
1260 case GLX_RED_SIZE:
1261 case GLX_GREEN_SIZE:
1262 case GLX_BLUE_SIZE:
1263 *value = 8;
1264 break;
1265 case GLX_LEVEL:
1266 *value = 0;
1267 break;
1268 case GLX_STEREO:
1269 *value = false;
1270 break;
1271 case GLX_AUX_BUFFERS:
1272 *value = 0;
1273 break;
1274 case GLX_ACCUM_RED_SIZE:
1275 case GLX_ACCUM_GREEN_SIZE:
1276 case GLX_ACCUM_BLUE_SIZE:
1277 case GLX_ACCUM_ALPHA_SIZE:
1278 *value = 0;
1279 break;
1280 case GLX_X_VISUAL_TYPE:
1281 *value = GLX_TRUE_COLOR;
1282 break;
1283 case GLX_TRANSPARENT_TYPE:
1284 *value = GLX_NONE;
1285 break;
1286 case GLX_SAMPLE_BUFFERS:
1287 case GLX_SAMPLES:
1288 *value = 1;
1289 break;
1290 case GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:
1291 *value = 0;
1292 break;
1293 default:
1294 crDebug("glXGetFBConfigAttrib: unknown attribute=0x%x", attribute);
1295 return GLX_BAD_ATTRIBUTE;
1296 }
1297
1298 return Success;
1299}
1300
1301DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
1302{
1303 int i;
1304
1305 GLXFBConfig *pGLXFBConfigs = crAlloc(sizeof(GLXFBConfig));
1306
1307 *nelements = 1;
1308 XLOCK(dpy);
1309 *pGLXFBConfigs = defaultFBConfigForScreen(dpy, screen);
1310 XUNLOCK(dpy);
1311
1312 crDebug("glXGetFBConfigs returned %i configs", *nelements);
1313 for (i=0; i<*nelements; ++i)
1314 {
1315 crDebug("glXGetFBConfigs[%i]=0x%x", i, (unsigned)(uintptr_t) pGLXFBConfigs[i]);
1316 }
1317 return pGLXFBConfigs;
1318}
1319
1320DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEvent)(Display *dpy, GLXDrawable draw, unsigned long *event_mask)
1321{
1322 (void) dpy;
1323 (void) draw;
1324 (void) event_mask;
1325 crWarning("glXGetSelectedEvent not implemented by Chromium");
1326}
1327
1328DECLEXPORT(XVisualInfo *) VBOXGLXTAG(glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config)
1329{
1330 return visualInfoFromFBConfig(dpy, config);
1331}
1332
1333DECLEXPORT(Bool) VBOXGLXTAG(glXMakeContextCurrent)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
1334{
1335 currentReadDrawable = read;
1336 return VBOXGLXTAG(glXMakeCurrent)(display, draw, ctx);
1337}
1338
1339DECLEXPORT(int) VBOXGLXTAG(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value)
1340{
1341 (void) dpy;
1342 (void) ctx;
1343 (void) attribute;
1344 (void) value;
1345 crWarning("glXQueryContext not implemented by Chromium");
1346 return 0;
1347}
1348
1349DECLEXPORT(void) VBOXGLXTAG(glXQueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
1350{
1351 (void) dpy;
1352 (void) draw;
1353 (void) attribute;
1354 (void) value;
1355 crWarning("glXQueryDrawable not implemented by Chromium");
1356}
1357
1358DECLEXPORT(void) VBOXGLXTAG(glXSelectEvent)(Display *dpy, GLXDrawable draw, unsigned long event_mask)
1359{
1360 (void) dpy;
1361 (void) draw;
1362 (void) event_mask;
1363 crWarning("glXSelectEvent not implemented by Chromium");
1364}
1365
1366#ifdef CR_EXT_texture_from_pixmap
1367/*typedef struct
1368{
1369 int x, y;
1370 unsigned int w, h, border, depth;
1371 Window root;
1372 void *data;
1373} pminfo;*/
1374
1375static void stubInitXSharedMemory(Display *dpy)
1376{
1377 int vma, vmi;
1378 Bool pixmaps;
1379
1380 if (stub.bShmInitFailed || stub.xshmSI.shmid>=0)
1381 return;
1382
1383 stub.bShmInitFailed = GL_TRUE;
1384
1385 /* Check for extension and pixmaps format */
1386 XLOCK(dpy);
1387 if (!XShmQueryExtension(dpy))
1388 {
1389 crWarning("No XSHM extension");
1390 XUNLOCK(dpy);
1391 return;
1392 }
1393
1394 if (!XShmQueryVersion(dpy, &vma, &vmi, &pixmaps) || !pixmaps)
1395 {
1396 crWarning("XSHM extension doesn't support pixmaps");
1397 XUNLOCK(dpy);
1398 return;
1399 }
1400
1401 if (XShmPixmapFormat(dpy)!=ZPixmap)
1402 {
1403 crWarning("XSHM extension doesn't support ZPixmap format");
1404 XUNLOCK(dpy);
1405 return;
1406 }
1407 XUNLOCK(dpy);
1408
1409 /* Alloc shared memory, so far using hardcoded value...could fail for bigger displays one day */
1410 stub.xshmSI.readOnly = false;
1411 stub.xshmSI.shmid = shmget(IPC_PRIVATE, 4*4096*2048, IPC_CREAT | 0600);
1412 if (stub.xshmSI.shmid<0)
1413 {
1414 crWarning("XSHM Failed to create shared segment");
1415 return;
1416 }
1417
1418 stub.xshmSI.shmaddr = (char*) shmat(stub.xshmSI.shmid, NULL, 0);
1419 if (stub.xshmSI.shmaddr==(void*)-1)
1420 {
1421 crWarning("XSHM Failed to attach shared segment");
1422 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
1423 return;
1424 }
1425
1426 XLOCK(dpy);
1427 if (!XShmAttach(dpy, &stub.xshmSI))
1428 {
1429 crWarning("XSHM Failed to attach shared segment to XServer");
1430 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
1431 shmdt(stub.xshmSI.shmaddr);
1432 XUNLOCK(dpy);
1433 return;
1434 }
1435 XUNLOCK(dpy);
1436
1437 stub.bShmInitFailed = GL_FALSE;
1438 crInfo("Using XSHM for GLX_EXT_texture_from_pixmap");
1439
1440 /*Anyway mark to be deleted when our process detaches it, in case of segfault etc*/
1441
1442/* Ramshankar: Solaris compiz fix */
1443#ifndef RT_OS_SOLARIS
1444 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
1445#endif
1446}
1447
1448void stubQueryXDamageExtension(Display *dpy, ContextInfo *pContext)
1449{
1450 int erb, vma, vmi;
1451
1452 CRASSERT(pContext);
1453
1454 if (pContext->damageQueryFailed)
1455 return;
1456
1457 pContext->damageQueryFailed = True;
1458
1459 if (!XDamageQueryExtension(dpy, &pContext->damageEventsBase, &erb)
1460 || !XDamageQueryVersion(dpy, &vma, &vmi))
1461 {
1462 crWarning("XDamage not found or old version (%i.%i), going to run *very* slow", vma, vmi);
1463 return;
1464 }
1465
1466 crDebug("XDamage %i.%i", vma, vmi);
1467 pContext->damageQueryFailed = False;
1468}
1469
1470static void stubFetchDamageOnDrawable(Display *dpy, GLX_Pixmap_t *pGlxPixmap)
1471{
1472 Damage damage = pGlxPixmap->hDamage;
1473
1474 if (damage)
1475 {
1476 XRectangle *returnRects;
1477 int nReturnRects;
1478
1479 /* Get the damage region as a server region */
1480 XserverRegion serverDamageRegion = XFixesCreateRegion (dpy, NULL, 0);
1481
1482 /* Unite damage region with server region and clear damage region */
1483 XDamageSubtract (dpy,
1484 damage,
1485 None, /* subtract all damage from this region */
1486 serverDamageRegion /* save in serverDamageRegion */);
1487
1488 /* Fetch damage rectangles */
1489 returnRects = XFixesFetchRegion (dpy, serverDamageRegion, &nReturnRects);
1490
1491 /* Delete region */
1492 XFixesDestroyRegion (dpy, serverDamageRegion);
1493
1494 if (pGlxPixmap->pDamageRegion)
1495 {
1496 /* If it's dirty and regions are empty, it marked for full update, so do nothing.*/
1497 if (!pGlxPixmap->bPixmapImageDirty || !XEmptyRegion(pGlxPixmap->pDamageRegion))
1498 {
1499 int i = 0;
1500 for (; i < nReturnRects; ++i)
1501 {
1502 if (CR_MAX_DAMAGE_REGIONS_TRACKED <= pGlxPixmap->pDamageRegion->numRects)
1503 {
1504 /* Mark for full update */
1505 EMPTY_REGION(pGlxPixmap->pDamageRegion);
1506 }
1507 else
1508 {
1509 /* Add to damage regions */
1510 XUnionRectWithRegion(&returnRects[i], pGlxPixmap->pDamageRegion, pGlxPixmap->pDamageRegion);
1511 }
1512 }
1513 }
1514 }
1515
1516 XFree(returnRects);
1517
1518 pGlxPixmap->bPixmapImageDirty = True;
1519 }
1520}
1521
1522static const CRPixelPackState defaultPacking =
1523{
1524 0, /*rowLength*/
1525 0, /*skipRows*/
1526 0, /*skipPixels*/
1527 1, /*alignment*/
1528 0, /*imageHeight*/
1529 0, /*skipImages*/
1530 GL_FALSE, /*swapBytes*/
1531 GL_FALSE /*lsbFirst*/
1532};
1533
1534static void stubGetUnpackState(CRPixelPackState *pUnpackState)
1535{
1536 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_ROW_LENGTH, &pUnpackState->rowLength);
1537 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_SKIP_ROWS, &pUnpackState->skipRows);
1538 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_SKIP_PIXELS, &pUnpackState->skipPixels);
1539 stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_ALIGNMENT, &pUnpackState->alignment);
1540 stub.spu->dispatch_table.GetBooleanv(GL_UNPACK_SWAP_BYTES, &pUnpackState->swapBytes);
1541 stub.spu->dispatch_table.GetBooleanv(GL_UNPACK_LSB_FIRST, &pUnpackState->psLSBFirst);
1542}
1543
1544static void stubSetUnpackState(const CRPixelPackState *pUnpackState)
1545{
1546 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, pUnpackState->rowLength);
1547 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_SKIP_ROWS, pUnpackState->skipRows);
1548 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_SKIP_PIXELS, pUnpackState->skipPixels);
1549 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ALIGNMENT, pUnpackState->alignment);
1550 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_SWAP_BYTES, pUnpackState->swapBytes);
1551 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_LSB_FIRST, pUnpackState->psLSBFirst);
1552}
1553
1554static GLX_Pixmap_t* stubInitGlxPixmap(GLX_Pixmap_t* pCreateInfoPixmap, Display *dpy, GLXDrawable draw, ContextInfo *pContext)
1555{
1556 int x, y;
1557 unsigned int w, h;
1558 unsigned int border;
1559 unsigned int depth;
1560 Window root;
1561 GLX_Pixmap_t *pGlxPixmap;
1562
1563 CRASSERT(pContext && pCreateInfoPixmap);
1564
1565 XLOCK(dpy);
1566 if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
1567 {
1568 XSync(dpy, False);
1569 if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
1570 {
1571 crWarning("stubInitGlxPixmap failed in call to XGetGeometry for 0x%x", (int) draw);
1572 XUNLOCK(dpy);
1573 return NULL;
1574 }
1575 }
1576
1577 pGlxPixmap = crAlloc(sizeof(GLX_Pixmap_t));
1578 if (!pGlxPixmap)
1579 {
1580 crWarning("stubInitGlxPixmap failed to allocate memory");
1581 XUNLOCK(dpy);
1582 return NULL;
1583 }
1584
1585 pGlxPixmap->x = x;
1586 pGlxPixmap->y = y;
1587 pGlxPixmap->w = w;
1588 pGlxPixmap->h = h;
1589 pGlxPixmap->border = border;
1590 pGlxPixmap->depth = depth;
1591 pGlxPixmap->root = root;
1592 pGlxPixmap->format = pCreateInfoPixmap->format;
1593 pGlxPixmap->target = pCreateInfoPixmap->target;
1594
1595 /* Try to allocate shared memory
1596 * As we're allocating huge chunk of memory, do it in this function, only if this extension is really used
1597 */
1598 if (!stub.bShmInitFailed && stub.xshmSI.shmid<0)
1599 {
1600 stubInitXSharedMemory(dpy);
1601 }
1602
1603 if (stub.xshmSI.shmid>=0)
1604 {
1605 XGCValues xgcv;
1606 xgcv.graphics_exposures = False;
1607 xgcv.subwindow_mode = IncludeInferiors;
1608 pGlxPixmap->gc = XCreateGC(dpy, (Pixmap)draw, GCGraphicsExposures|GCSubwindowMode, &xgcv);
1609
1610 pGlxPixmap->hShmPixmap = XShmCreatePixmap(dpy, pGlxPixmap->root, stub.xshmSI.shmaddr, &stub.xshmSI,
1611 pGlxPixmap->w, pGlxPixmap->h, pGlxPixmap->depth);
1612 }
1613 else
1614 {
1615 pGlxPixmap->gc = NULL;
1616 pGlxPixmap->hShmPixmap = 0;
1617 }
1618 XUNLOCK(dpy);
1619
1620 /* If there's damage extension, then get handle for damage events related to this pixmap */
1621 if (!pContext->damageQueryFailed)
1622 {
1623 pGlxPixmap->hDamage = XDamageCreate(dpy, (Pixmap)draw, XDamageReportNonEmpty);
1624 /*crDebug("Create: Damage for drawable 0x%x, handle 0x%x (level=%i)",
1625 (unsigned int) draw, (unsigned int) pGlxPixmap->damage, (int) XDamageReportRawRectangles);*/
1626 pGlxPixmap->pDamageRegion = XCreateRegion();
1627 if (!pGlxPixmap->pDamageRegion)
1628 {
1629 crWarning("stubInitGlxPixmap failed to create empty damage region for drawable 0x%x", (unsigned int) draw);
1630 }
1631
1632 /*We have never seen this pixmap before, so mark it as dirty for first use*/
1633 pGlxPixmap->bPixmapImageDirty = True;
1634 }
1635 else
1636 {
1637 pGlxPixmap->hDamage = 0;
1638 pGlxPixmap->pDamageRegion = NULL;
1639 }
1640
1641 /* glTexSubImage2D generates GL_INVALID_OP if texture array hasn't been defined by a call to glTexImage2D first.
1642 * It's fine for small textures which would be updated in stubXshmUpdateWholeImage, but we'd never call glTexImage2D for big ones.
1643 * Note that we're making empty texture by passing NULL as pixels pointer, so there's no overhead transferring data to host.*/
1644 if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
1645 {
1646 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pGlxPixmap->w, pGlxPixmap->h, 0,
1647 GL_BGRA, GL_UNSIGNED_BYTE, NULL);
1648 }
1649
1650 crHashtableAdd(pContext->pGLXPixmapsHash, (unsigned int) draw, pGlxPixmap);
1651 crHashtableDelete(stub.pGLXPixmapsHash, (unsigned int) draw, crFree);
1652
1653 return pGlxPixmap;
1654}
1655
1656static void stubXshmUpdateWholeImage(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap)
1657{
1658 /* To limit the size of transferring buffer, split bigger texture into regions
1659 * which fit into connection buffer. Could be done in hgcm or packspu but implementation in this place allows to avoid
1660 * unnecessary memcpy.
1661 * This also workarounds guest driver failures when sending 6+mb texture buffers on linux.
1662 */
1663 if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
1664 {
1665 XRectangle rect;
1666
1667 rect.x = pGlxPixmap->x;
1668 rect.y = pGlxPixmap->y;
1669 rect.width = pGlxPixmap->w;
1670 rect.height = CR_MAX_TRANSFER_SIZE/(4*pGlxPixmap->w);
1671
1672 /*crDebug("Texture size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
1673 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, rect.height);*/
1674
1675 for (; (rect.y+rect.height)<=(pGlxPixmap->y+(int)pGlxPixmap->h); rect.y+=rect.height)
1676 {
1677 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
1678 }
1679
1680 if (rect.y!=(pGlxPixmap->y+(int)pGlxPixmap->h))
1681 {
1682 rect.height=pGlxPixmap->h-rect.y;
1683 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
1684 }
1685 }
1686 else
1687 {
1688 CRPixelPackState unpackState;
1689
1690 XLOCK(dpy);
1691 XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
1692 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, 0, 0);
1693 /* Have to make sure XCopyArea is processed */
1694 XSync(dpy, False);
1695 XUNLOCK(dpy);
1696
1697 stubGetUnpackState(&unpackState);
1698 stubSetUnpackState(&defaultPacking);
1699 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pGlxPixmap->w, pGlxPixmap->h, 0,
1700 GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
1701 stubSetUnpackState(&unpackState);
1702 /*crDebug("Sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
1703 (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
1704 pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);*/
1705 }
1706}
1707
1708static void stubXshmUpdateImageRect(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap, XRectangle *pRect)
1709{
1710 /* See comment in stubXshmUpdateWholeImage */
1711 if (CR_MAX_TRANSFER_SIZE < 4*pRect->width*pRect->height)
1712 {
1713 XRectangle rect;
1714
1715 rect.x = pRect->x;
1716 rect.y = pRect->y;
1717 rect.width = pRect->width;
1718 rect.height = CR_MAX_TRANSFER_SIZE/(4*pRect->width);
1719
1720 /*crDebug("Region size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
1721 pRect->x, pRect->y, pRect->width, pRect->height, rect.height);*/
1722
1723 for (; (rect.y+rect.height)<=(pRect->y+pRect->height); rect.y+=rect.height)
1724 {
1725 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
1726 }
1727
1728 if (rect.y!=(pRect->y+pRect->height))
1729 {
1730 rect.height=pRect->y+pRect->height-rect.y;
1731 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
1732 }
1733 }
1734 else
1735 {
1736 CRPixelPackState unpackState;
1737
1738 XLOCK(dpy);
1739 XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
1740 pRect->x, pRect->y, pRect->width, pRect->height, 0, 0);
1741 /* Have to make sure XCopyArea is processed */
1742 XSync(dpy, False);
1743 XUNLOCK(dpy);
1744
1745 stubGetUnpackState(&unpackState);
1746 stubSetUnpackState(&defaultPacking);
1747 if (pRect->width!=pGlxPixmap->w)
1748 {
1749 stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, pGlxPixmap->w);
1750 }
1751 stub.spu->dispatch_table.TexSubImage2D(pGlxPixmap->target, 0, pRect->x, pRect->y, pRect->width, pRect->height,
1752 GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
1753 stubSetUnpackState(&unpackState);
1754
1755 /*crDebug("Region sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
1756 (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
1757 pRect->x, pRect->y, pRect->width, pRect->height);*/
1758 }
1759}
1760
1761#if 0
1762Bool checkevents(Display *display, XEvent *event, XPointer arg)
1763{
1764 //crDebug("got type: 0x%x", event->type);
1765 if (event->type==damage_evb+XDamageNotify)
1766 {
1767 ContextInfo *context = stubGetCurrentContext();
1768 XDamageNotifyEvent *e = (XDamageNotifyEvent *) event;
1769 /* we're interested in pixmaps only...and those have e->drawable set to 0 or other strange value for some odd reason
1770 * so have to walk glxpixmaps hashtable to find if we have damage event handle assigned to some pixmap
1771 */
1772 /*crDebug("Event: Damage for drawable 0x%x, handle 0x%x (level=%i) [%i,%i,%i,%i]",
1773 (unsigned int) e->drawable, (unsigned int) e->damage, (int) e->level,
1774 e->area.x, e->area.y, e->area.width, e->area.height);*/
1775 CRASSERT(context);
1776 crHashtableWalk(context->pGLXPixmapsHash, checkdamageCB, e);
1777 }
1778 return False;
1779}
1780#endif
1781
1782/** @todo check what error codes could we throw for failures here*/
1783DECLEXPORT(void) VBOXGLXTAG(glXBindTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer, const int *attrib_list)
1784{
1785 ContextInfo *context = stubGetCurrentContext();
1786 GLX_Pixmap_t *pGlxPixmap;
1787 RT_NOREF(buffer, attrib_list);
1788
1789 if (!context)
1790 {
1791 crWarning("glXBindTexImageEXT called without current context");
1792 return;
1793 }
1794
1795 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(context->pGLXPixmapsHash, (unsigned int) draw);
1796 if (!pGlxPixmap)
1797 {
1798 pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) draw);
1799 if (!pGlxPixmap)
1800 {
1801 crDebug("Unknown drawable 0x%x in glXBindTexImageEXT!", (unsigned int) draw);
1802 return;
1803 }
1804 pGlxPixmap = stubInitGlxPixmap(pGlxPixmap, dpy, draw, context);
1805 if (!pGlxPixmap)
1806 {
1807 crDebug("glXBindTexImageEXT failed to get pGlxPixmap");
1808 return;
1809 }
1810 }
1811
1812 /* If there's damage extension, then process incoming events as we need the information right now */
1813 if (!context->damageQueryFailed)
1814 {
1815 /* Sync connection */
1816 XLOCK(dpy);
1817 XSync(dpy, False);
1818 XUNLOCK(dpy);
1819
1820 stubFetchDamageOnDrawable(dpy, pGlxPixmap);
1821 }
1822
1823 /* No shared memory? Rollback to use slow x protocol then */
1824 if (stub.xshmSI.shmid<0)
1825 {
1826 /** @todo add damage support here too*/
1827 XImage *pxim;
1828 CRPixelPackState unpackState;
1829
1830 XLOCK(dpy);
1831 pxim = XGetImage(dpy, (Pixmap)draw, pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, AllPlanes, ZPixmap);
1832 XUNLOCK(dpy);
1833 /*if (pxim)
1834 {
1835 if (!ptextable)
1836 {
1837 ptextable = crAllocHashtable();
1838 }
1839 pm = crHashtableSearch(ptextable, (unsigned int) draw);
1840 if (!pm)
1841 {
1842 pm = crCalloc(sizeof(pminfo));
1843 crHashtableAdd(ptextable, (unsigned int) draw, pm);
1844 }
1845 pm->w = w;
1846 pm->h = h;
1847 if (pm->data) crFree(pm->data);
1848 pm->data = crAlloc(4*w*h);
1849 crMemcpy(pm->data, (void*)(&(pxim->data[0])), 4*w*h);
1850 }*/
1851
1852 if (NULL==pxim)
1853 {
1854 crWarning("Failed, to get pixmap data for 0x%x", (unsigned int) draw);
1855 return;
1856 }
1857
1858 stubGetUnpackState(&unpackState);
1859 stubSetUnpackState(&defaultPacking);
1860 stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pxim->width, pxim->height, 0,
1861 GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(pxim->data[0])));
1862 stubSetUnpackState(&unpackState);
1863 XDestroyImage(pxim);
1864 }
1865 else /* Use shm to get pixmap data */
1866 {
1867 /* Check if we have damage extension */
1868 if (!context->damageQueryFailed)
1869 {
1870 if (pGlxPixmap->bPixmapImageDirty)
1871 {
1872 /* Either we failed to allocate damage region or this pixmap is marked for full update */
1873 if (!pGlxPixmap->pDamageRegion || XEmptyRegion(pGlxPixmap->pDamageRegion))
1874 {
1875 /*crDebug("**FULL** update for 0x%x", (unsigned int)draw);*/
1876 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
1877 }
1878 else
1879 {
1880 long fullArea, damageArea=0, clipdamageArea, i;
1881 XRectangle damageClipBox;
1882
1883 fullArea = pGlxPixmap->w * pGlxPixmap->h;
1884 XClipBox(pGlxPixmap->pDamageRegion, &damageClipBox);
1885 clipdamageArea = damageClipBox.width * damageClipBox.height;
1886
1887 //crDebug("FullSize [%i,%i,%i,%i]", pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);
1888 //crDebug("Clip [%i,%i,%i,%i]", damageClipBox.x, damageClipBox.y, damageClipBox.width, damageClipBox.height);
1889
1890 for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
1891 {
1892 BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
1893 damageArea += (pBox->x2-pBox->x1)*(pBox->y2-pBox->y1);
1894 //crDebug("Damage rect [%i,%i,%i,%i]", pBox->x1, pBox->y1, pBox->x2, pBox->y2);
1895 }
1896
1897 if (damageArea>clipdamageArea || clipdamageArea>fullArea)
1898 {
1899 crWarning("glXBindTexImageEXT, damage regions seems to be broken, forcing full update");
1900 /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
1901 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
1902 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
1903 }
1904 else /*We have corect damage info*/
1905 {
1906 if (CR_MIN_DAMAGE_PROFIT_SIZE > (fullArea-damageArea))
1907 {
1908 /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
1909 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
1910 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
1911 }
1912 else if (CR_MIN_DAMAGE_PROFIT_SIZE > (clipdamageArea-damageArea))
1913 {
1914 /*crDebug("**PARTIAL** update for 0x%x, numRect=%li, FS=%li, *CS*=%li, DS=%li",
1915 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
1916 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &damageClipBox);
1917 }
1918 else
1919 {
1920 /*crDebug("**PARTIAL** update for 0x%x, numRect=*%li*, FS=%li, CS=%li, *DS*=%li",
1921 (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
1922 for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
1923 {
1924 XRectangle rect;
1925 BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
1926
1927 rect.x = pBox->x1;
1928 rect.y = pBox->y1;
1929 rect.width = pBox->x2-pBox->x1;
1930 rect.height = pBox->y2-pBox->y1;
1931
1932 stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
1933 }
1934 }
1935 }
1936 }
1937
1938 /* Clean dirty flag and damage region */
1939 pGlxPixmap->bPixmapImageDirty = False;
1940 if (pGlxPixmap->pDamageRegion)
1941 EMPTY_REGION(pGlxPixmap->pDamageRegion);
1942 }
1943 }
1944 else
1945 {
1946 stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
1947 }
1948 }
1949}
1950
1951DECLEXPORT(void) VBOXGLXTAG(glXReleaseTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer)
1952{
1953 (void) dpy;
1954 (void) draw;
1955 (void) buffer;
1956 //crDebug("glXReleaseTexImageEXT 0x%x", (unsigned int)draw);
1957}
1958#endif
1959
1960#endif /* GLX_EXTRAS */
1961
1962
1963#ifdef GLX_SGIX_video_resize
1964/* more dummy funcs. These help when linking with older GLUTs */
1965
1966DECLEXPORT(int) VBOXGLXTAG(glXBindChannelToWindowSGIX)(Display *dpy, int scrn, int chan, Window w)
1967{
1968 (void) dpy;
1969 (void) scrn;
1970 (void) chan;
1971 (void) w;
1972 crDebug("glXBindChannelToWindowSGIX");
1973 return 0;
1974}
1975
1976DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSGIX)(Display *dpy, int scrn, int chan, int x , int y, int w, int h)
1977{
1978 (void) dpy;
1979 (void) scrn;
1980 (void) chan;
1981 (void) x;
1982 (void) y;
1983 (void) w;
1984 (void) h;
1985 crDebug("glXChannelRectSGIX");
1986 return 0;
1987}
1988
1989DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelRectSGIX)(Display *dpy, int scrn, int chan, int *x, int *y, int *w, int *h)
1990{
1991 (void) dpy;
1992 (void) scrn;
1993 (void) chan;
1994 (void) x;
1995 (void) y;
1996 (void) w;
1997 (void) h;
1998 crDebug("glXQueryChannelRectSGIX");
1999 return 0;
2000}
2001
2002DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelDeltasSGIX)(Display *dpy, int scrn, int chan, int *dx, int *dy, int *dw, int *dh)
2003{
2004 (void) dpy;
2005 (void) scrn;
2006 (void) chan;
2007 (void) dx;
2008 (void) dy;
2009 (void) dw;
2010 (void) dh;
2011 crDebug("glXQueryChannelDeltasSGIX");
2012 return 0;
2013}
2014
2015DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSyncSGIX)(Display *dpy, int scrn, int chan, GLenum synctype)
2016{
2017 (void) dpy;
2018 (void) scrn;
2019 (void) chan;
2020 (void) synctype;
2021 crDebug("glXChannelRectSyncSGIX");
2022 return 0;
2023}
2024
2025#endif /* GLX_SGIX_video_resize */
2026
2027#ifdef VBOXOGL_FAKEDRI
2028DECLEXPORT(const char *) VBOXGLXTAG(glXGetDriverConfig)(const char *driverName)
2029{
2030 return NULL;
2031}
2032
2033DECLEXPORT(void) VBOXGLXTAG(glXFreeMemoryMESA)(Display *dpy, int scrn, void *pointer)
2034{
2035 (void) dpy;
2036 (void) scrn;
2037 (void) pointer;
2038}
2039
2040DECLEXPORT(GLXContext) VBOXGLXTAG(glXImportContextEXT)(Display *dpy, GLXContextID contextID)
2041{
2042 (void) dpy;
2043 (void) contextID;
2044 return NULL;
2045}
2046
2047DECLEXPORT(GLXContextID) VBOXGLXTAG(glXGetContextIDEXT)(const GLXContext ctx)
2048{
2049 (void) ctx;
2050 return 0;
2051}
2052
2053DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrentReadSGI)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
2054{
2055 return VBOXGLXTAG(glXMakeContextCurrent)(display, draw, read, ctx);
2056}
2057
2058DECLEXPORT(const char *) VBOXGLXTAG(glXGetScreenDriver)(Display *dpy, int scrNum)
2059{
2060 static char *screendriver = "vboxvideo";
2061 return screendriver;
2062}
2063
2064DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplayEXT)(void)
2065{
2066 return VBOXGLXTAG(glXGetCurrentDisplay());
2067}
2068
2069DECLEXPORT(void) VBOXGLXTAG(glXFreeContextEXT)(Display *dpy, GLXContext ctx)
2070{
2071 VBOXGLXTAG(glXDestroyContext(dpy, ctx));
2072}
2073
2074/*Mesa internal*/
2075DECLEXPORT(int) VBOXGLXTAG(glXQueryContextInfoEXT)(Display *dpy, GLXContext ctx)
2076{
2077 (void) dpy;
2078 (void) ctx;
2079 return 0;
2080}
2081
2082DECLEXPORT(void *) VBOXGLXTAG(glXAllocateMemoryMESA)(Display *dpy, int scrn,
2083 size_t size, float readFreq,
2084 float writeFreq, float priority)
2085{
2086 (void) dpy;
2087 (void) scrn;
2088 (void) size;
2089 (void) readFreq;
2090 (void) writeFreq;
2091 (void) priority;
2092 return NULL;
2093}
2094
2095DECLEXPORT(GLuint) VBOXGLXTAG(glXGetMemoryOffsetMESA)(Display *dpy, int scrn, const void *pointer)
2096{
2097 (void) dpy;
2098 (void) scrn;
2099 (void) pointer;
2100 return 0;
2101}
2102
2103DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap)
2104{
2105 (void) dpy;
2106 (void) visual;
2107 (void) pixmap;
2108 (void) cmap;
2109 return 0;
2110}
2111
2112#endif /*VBOXOGL_FAKEDRI*/
Note: See TracBrowser for help on using the repository browser.

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