VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/egl.c@ 59170

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

bugref:8087: Additions/x11: support non-root X server: typo

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 32.6 KB
Line 
1/* $Id: egl.c 59170 2015-12-17 10:05:36Z vboxsync $ */
2
3/** @file
4 * VBox OpenGL EGL implentation.
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
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <iprt/cdefs.h>
23#include <iprt/initterm.h>
24#include <iprt/mem.h>
25#include <iprt/once.h>
26#include <iprt/thread.h>
27
28#include <EGL/egl.h>
29#include <GL/glx.h>
30#include <X11/Xlib.h>
31
32/*******************************************************************************
33* Structures and Typedefs *
34*******************************************************************************/
35
36struct VBEGLTLS
37{
38 /** The last EGL error. */
39 EGLint cErr;
40 /** The EGL API currently bound to this thread. */
41 EGLenum enmAPI;
42 /** The current context. */
43 EGLContext hCurrent;
44 /** The display bound to the current context. */
45 EGLDisplay hCurrentDisplay;
46 /** The draw surface bound to the current context. */
47 EGLSurface hCurrentDraw;
48 /** The read surface bound to the current context. */
49 EGLSurface hCurrentRead;
50};
51
52/*******************************************************************************
53* Defined Constants And Macros *
54*******************************************************************************/
55/** @note IDs returned for surfaces should always be lower than these constants.
56 */
57/** This is OR-ed with a surface ID to mark it as a window, as GLX needs to
58 * know. */
59#define VBEGL_WINDOW_SURFACE 0x20000000
60/** This is OR-ed with a surface ID to mark it as a pbuffer, as GLX needs to
61 * know. */
62#define VBEGL_PBUFFER_SURFACE 0x40000000
63/** This is OR-ed with a surface ID to mark it as a pixmap, as GLX needs to
64 * know. */
65#define VBEGL_PIXMAP_SURFACE 0x80000000
66#define VBEGL_ANY_SURFACE (VBEGL_WINDOW_SURFACE | VBEGL_PBUFFER_SURFACE | VBEGL_PIXMAP_SURFACE)
67
68/*******************************************************************************
69* Global variables *
70*******************************************************************************/
71
72static RTTLS g_tls = NIL_RTTLS;
73static RTONCE g_tlsOnce = RTONCE_INITIALIZER;
74static Display *g_pDefaultDisplay = NULL;
75static RTONCE g_defaultDisplayOnce = RTONCE_INITIALIZER;
76
77static int32_t tlsInitOnce(void *pv)
78{
79 NOREF(pv);
80 g_tls = RTTlsAlloc();
81 return VINF_SUCCESS;
82}
83
84static struct VBEGLTLS *getTls(void)
85{
86 struct VBEGLTLS *pTls;
87
88 RTOnce(&g_tlsOnce, tlsInitOnce, NULL);
89 pTls = (struct VBEGLTLS *)RTTlsGet(g_tls);
90 if (RT_LIKELY(pTls))
91 return pTls;
92 pTls = (struct VBEGLTLS *)RTMemAlloc(sizeof(*pTls));
93 if (!VALID_PTR(pTls))
94 return NULL;
95 pTls->cErr = EGL_SUCCESS;
96 pTls->enmAPI = EGL_NONE;
97 pTls->hCurrent = EGL_NO_CONTEXT;
98 pTls->hCurrentDisplay = EGL_NO_DISPLAY;
99 pTls->hCurrentDraw = EGL_NO_SURFACE;
100 pTls->hCurrentRead = EGL_NO_SURFACE;
101 RTTlsSet(g_tls, pTls);
102 return pTls;
103}
104
105static int32_t defaultDisplayInitOnce(void *pv)
106{
107 NOREF(pv);
108 g_pDefaultDisplay = XOpenDisplay(NULL);
109 return VINF_SUCCESS;
110}
111
112static EGLBoolean clearEGLError(void)
113{
114 struct VBEGLTLS *pTls = getTls();
115
116 if (!VALID_PTR(pTls))
117 return EGL_FALSE;
118 pTls->cErr = EGL_SUCCESS;
119 return EGL_TRUE;
120}
121
122static EGLBoolean setEGLError(EGLint cErr)
123{
124 struct VBEGLTLS *pTls = getTls();
125
126 if (pTls)
127 pTls->cErr = cErr;
128 return EGL_FALSE;
129}
130
131DECLEXPORT(EGLDisplay) eglGetDisplay(EGLNativeDisplayType hDisplay)
132{
133 Display *pDisplay;
134 int rc, cError, cEvent, cMajor, cMinor;
135
136 rc = RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
137 if (RT_FAILURE(rc))
138 return EGL_NO_DISPLAY;
139 if (!clearEGLError()) /* Set up our tls. */
140 return EGL_NO_DISPLAY;
141 if (hDisplay != EGL_DEFAULT_DISPLAY)
142 pDisplay = hDisplay;
143 else
144 {
145 RTOnce(&g_defaultDisplayOnce, defaultDisplayInitOnce, NULL);
146 pDisplay = g_pDefaultDisplay;
147 }
148 if (pDisplay && glXQueryExtension(pDisplay, &cError, &cEvent))
149 if (glXQueryVersion(pDisplay, &cMajor, &cMinor))
150 if (cMajor > 1 || (cMajor == 1 && cMinor >= 3))
151 return (EGLDisplay) pDisplay;
152 return EGL_NO_DISPLAY;
153}
154
155DECLEXPORT(EGLint) eglGetError(void)
156{
157 struct VBEGLTLS *pTls = getTls();
158
159 if (pTls)
160 return pTls->cErr;
161 return EGL_NOT_INITIALIZED;
162}
163
164DECLEXPORT(EGLBoolean) eglInitialize (EGLDisplay hDisplay, EGLint *pcMajor, EGLint *pcMinor)
165{
166 if (!VALID_PTR(hDisplay))
167 return setEGLError(EGL_BAD_DISPLAY);
168 if (pcMajor)
169 *pcMajor = 1;
170 if (pcMinor)
171 *pcMinor = 4;
172 return clearEGLError();
173}
174
175/** @todo This function should terminate all allocated resources. */
176DECLEXPORT(EGLBoolean) eglTerminate(EGLDisplay hDisplay)
177{
178 if (!VALID_PTR(hDisplay))
179 return EGL_FALSE;
180 return EGL_TRUE;
181}
182
183DECLEXPORT(const char *) eglQueryString(EGLDisplay hDisplay, EGLint name)
184{
185 switch (name)
186 {
187 case EGL_CLIENT_APIS:
188 return "OpenGL";
189 case EGL_VENDOR:
190 return "Chromium";
191 case EGL_VERSION:
192 return "1.4 Chromium";
193 case EGL_EXTENSIONS:
194 return "";
195 default:
196 return NULL;
197 }
198}
199
200DECLEXPORT(EGLBoolean) eglGetConfigs (EGLDisplay hDisplay, EGLConfig *paConfigs, EGLint caConfigs, EGLint *pcaConfigs)
201{
202 Display *pDisplay = (Display *)hDisplay;
203 GLXFBConfig *paFBConfigs;
204 int caFBConfigs, i;
205
206 if (!VALID_PTR(pDisplay))
207 return setEGLError(EGL_NOT_INITIALIZED);
208 if (!VALID_PTR(pcaConfigs))
209 return setEGLError(EGL_BAD_PARAMETER);
210 if (caConfigs > 0 && !VALID_PTR(paConfigs))
211 return setEGLError(EGL_BAD_PARAMETER);
212 paFBConfigs = glXGetFBConfigs(pDisplay, DefaultScreen(pDisplay), &caFBConfigs);
213 AssertPtrReturn(paFBConfigs, setEGLError(EGL_BAD_PARAMETER));
214 if (caFBConfigs > caConfigs)
215 caFBConfigs = caConfigs;
216 *pcaConfigs = caFBConfigs;
217 for (i = 0; i < caFBConfigs; ++i)
218 paConfigs[i] = (EGLConfig)paFBConfigs[i];
219 XFree(paFBConfigs);
220 return clearEGLError();
221}
222
223static int convertEGLAttribToGLX(EGLint EGLAttrib)
224{
225 switch (EGLAttrib)
226 {
227 case EGL_BUFFER_SIZE:
228 return GLX_BUFFER_SIZE;
229 case EGL_RED_SIZE:
230 return GLX_RED_SIZE;
231 case EGL_GREEN_SIZE:
232 return GLX_GREEN_SIZE;
233 case EGL_BLUE_SIZE:
234 return GLX_BLUE_SIZE;
235 case EGL_LUMINANCE_SIZE:
236 return GLX_RED_SIZE;
237 case EGL_ALPHA_SIZE:
238 return GLX_ALPHA_SIZE;
239 /* case EGL_ALPHA_MASK_SIZE: */
240 /* case EGL_BIND_TO_TEXTURE_RGB: */
241 /* case EGL_BIND_TO_TEXTURE_RGBA: */
242 /* case EGL_COLOR_BUFFER_TYPE: */
243 /* case EGL_CONFIG_CAVEAT: */
244 case EGL_CONFIG_ID:
245 return GLX_FBCONFIG_ID;
246 /* case EGL_CONFORMANT: */
247 case EGL_DEPTH_SIZE:
248 return GLX_DEPTH_SIZE;
249 case EGL_LEVEL:
250 return GLX_LEVEL;
251 case EGL_MAX_PBUFFER_WIDTH:
252 return GLX_MAX_PBUFFER_WIDTH;
253 case EGL_MAX_PBUFFER_HEIGHT:
254 return GLX_MAX_PBUFFER_HEIGHT;
255 case EGL_MAX_PBUFFER_PIXELS:
256 return GLX_MAX_PBUFFER_PIXELS;
257 /* case EGL_MATCH_NATIVE_PIXMAP: */
258 /* case EGL_MAX_SWAP_INTERVAL: */
259 /* case EGL_MIN_SWAP_INTERVAL: */
260 case EGL_NATIVE_RENDERABLE:
261 return GLX_X_RENDERABLE;
262 case EGL_NATIVE_VISUAL_ID:
263 return GLX_VISUAL_ID;
264 /* case EGL_NATIVE_VISUAL_TYPE: */
265 /* case EGL_RENDERABLE_TYPE: */
266 case EGL_SAMPLE_BUFFERS:
267 return GLX_SAMPLE_BUFFERS;
268 case EGL_SAMPLES:
269 return GLX_SAMPLES;
270 case EGL_STENCIL_SIZE:
271 return GLX_STENCIL_SIZE;
272 /* case EGL_SURFACE_TYPE: */
273 /* case EGL_TRANSPARENT_TYPE: */
274 case EGL_TRANSPARENT_RED_VALUE:
275 return GLX_TRANSPARENT_RED_VALUE;
276 case EGL_TRANSPARENT_GREEN_VALUE:
277 return GLX_TRANSPARENT_GREEN_VALUE;
278 case EGL_TRANSPARENT_BLUE_VALUE:
279 return GLX_TRANSPARENT_BLUE_VALUE;
280 default:
281 return None;
282 }
283}
284
285DECLEXPORT(EGLBoolean) eglChooseConfig (EGLDisplay hDisplay, const EGLint *paAttribs, EGLConfig *paConfigs, EGLint caConfigs,
286 EGLint *pcConfigs)
287{
288 Display *pDisplay = (Display *)hDisplay;
289 int aAttribList[256]; /* The list cannot be this long. */
290 unsigned cAttribs = 0, i;
291 const EGLint *pAttrib, *pAttrib2;
292 EGLint cRenderableType = EGL_OPENGL_ES_BIT;
293 int cConfigCaveat = GLX_DONT_CARE, cConformant = GLX_DONT_CARE;
294 GLXFBConfig *paFBConfigs;
295 int caFBConfigs;
296
297 if (!VALID_PTR(hDisplay))
298 return setEGLError(EGL_NOT_INITIALIZED);
299 if (!VALID_PTR(pcConfigs))
300 return setEGLError(EGL_BAD_PARAMETER);
301 if (caConfigs > 0 && !VALID_PTR(paConfigs))
302 return setEGLError(EGL_BAD_PARAMETER);
303 for (pAttrib = paAttribs; pAttrib != NULL && *pAttrib != EGL_NONE; pAttrib += 2)
304 {
305 bool fSkip = false;
306 int cGLXAttrib;
307
308 /* Check for illegal values. */
309 if ((*pAttrib == EGL_LEVEL || *pAttrib == EGL_MATCH_NATIVE_PIXMAP) && pAttrib[1] == EGL_DONT_CARE)
310 return setEGLError(EGL_BAD_ATTRIBUTE);
311 /* Check for values we can't handle. */
312 if ( (*pAttrib == EGL_ALPHA_MASK_SIZE)
313 && pAttrib[1] != EGL_DONT_CARE && pAttrib[1] != 0)
314 return setEGLError(EGL_BAD_ACCESS);
315 /** @todo try creating a pixmap from a native one with the configurations returned. */
316 if (*pAttrib == EGL_MATCH_NATIVE_PIXMAP)
317 return setEGLError(EGL_BAD_ACCESS);
318 if ( ( *pAttrib == EGL_MIN_SWAP_INTERVAL || *pAttrib == EGL_MAX_SWAP_INTERVAL
319 || *pAttrib == EGL_BIND_TO_TEXTURE_RGB || *pAttrib == EGL_BIND_TO_TEXTURE_RGBA)
320 && pAttrib[1] != EGL_DONT_CARE)
321 return setEGLError(EGL_BAD_ACCESS);
322 /* Ignore attributes which are repeated later. */
323 for (pAttrib2 = pAttrib + 2; *pAttrib2 != EGL_NONE; pAttrib2 += 2)
324 if (*pAttrib2 == *pAttrib)
325 fSkip == true;
326 if (fSkip)
327 continue;
328 cGLXAttrib = convertEGLAttribToGLX(*pAttrib);
329 if (cGLXAttrib != None)
330 {
331 aAttribList[cAttribs] = cGLXAttrib;
332 if (pAttrib[1] == EGL_DONT_CARE)
333 aAttribList[cAttribs + 1] = GLX_DONT_CARE;
334 else
335 aAttribList[cAttribs + 1] = pAttrib[1];
336 cAttribs += 2;
337 }
338 else
339 {
340 switch (*pAttrib)
341 {
342 if ( *pAttrib == EGL_COLOR_BUFFER_TYPE
343 && pAttrib[1] != EGL_DONT_CARE && pAttrib[1] != EGL_RGB_BUFFER)
344 return setEGLError(EGL_BAD_ACCESS);
345 case EGL_COLOR_BUFFER_TYPE:
346 aAttribList[cAttribs] = GLX_X_VISUAL_TYPE;
347 aAttribList[cAttribs + 1] = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE
348 : pAttrib[1] == EGL_RGB_BUFFER ? GLX_TRUE_COLOR
349 : pAttrib[1] == EGL_LUMINANCE_BUFFER ? GLX_GRAY_SCALE
350 : GL_FALSE;
351 break;
352 case EGL_CONFIG_CAVEAT:
353 cConfigCaveat = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE
354 : pAttrib[1] == EGL_NONE ? GLX_NONE
355 : pAttrib[1] == EGL_SLOW_CONFIG ? GLX_SLOW_CONFIG
356 : pAttrib[1] == EGL_NON_CONFORMANT_CONFIG ? GLX_NON_CONFORMANT_CONFIG
357 : GL_FALSE;
358 if (!cConfigCaveat)
359 return setEGLError(EGL_BAD_ATTRIBUTE);
360 cAttribs -= 2;
361 break;
362 case EGL_CONFORMANT:
363 if (pAttrib[1] != EGL_OPENGL_BIT && pAttrib[1] != 0)
364 return setEGLError(EGL_BAD_ACCESS);
365 cConformant = pAttrib[1] == EGL_OPENGL_BIT ? GL_TRUE : GL_FALSE;
366 cAttribs -= 2;
367 break;
368 case EGL_NATIVE_VISUAL_TYPE:
369 aAttribList[cAttribs] = GLX_X_VISUAL_TYPE;
370 aAttribList[cAttribs + 1] = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE
371 : pAttrib[1] == StaticGray ? GLX_STATIC_GRAY
372 : pAttrib[1] == StaticColor ? GLX_STATIC_COLOR
373 : pAttrib[1] == TrueColor ? GLX_TRUE_COLOR
374 : pAttrib[1] == GrayScale ? GLX_GRAY_SCALE
375 : pAttrib[1] == PseudoColor ? GLX_PSEUDO_COLOR
376 : pAttrib[1] == DirectColor ? GLX_DIRECT_COLOR
377 : GL_FALSE;
378 break;
379 case EGL_RENDERABLE_TYPE:
380 cRenderableType = pAttrib[1];
381 break;
382 case EGL_SURFACE_TYPE:
383 if (pAttrib[1] & ~(EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT))
384 return setEGLError(EGL_BAD_ACCESS);
385 aAttribList[cAttribs] = GLX_DRAWABLE_TYPE;
386 aAttribList[cAttribs + 1] = (pAttrib[1] & EGL_PBUFFER_BIT ? GLX_PBUFFER_BIT : 0)
387 | (pAttrib[1] & EGL_PIXMAP_BIT ? GLX_PIXMAP_BIT : 0)
388 | (pAttrib[1] & EGL_WINDOW_BIT ? GLX_WINDOW_BIT : 0);
389 break;
390 case EGL_TRANSPARENT_TYPE:
391 aAttribList[cAttribs] = GLX_TRANSPARENT_TYPE;
392 aAttribList[cAttribs + 1] = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE
393 : pAttrib[1] == EGL_NONE ? GLX_NONE
394 : pAttrib[1] == EGL_TRANSPARENT_RGB ? GLX_TRANSPARENT_RGB
395 : GL_FALSE;
396 break;
397 default:
398 return setEGLError(EGL_BAD_ATTRIBUTE);
399 }
400 cAttribs += 2;
401 }
402 }
403 if (cConfigCaveat != GLX_DONT_CARE || cConformant != GLX_DONT_CARE)
404 {
405 aAttribList[cAttribs] = GLX_CONFIG_CAVEAT;
406 aAttribList[cAttribs + 1] = cConformant == GL_FALSE ? GLX_NON_CONFORMANT_CONFIG
407 : cConfigCaveat == EGL_SLOW_CONFIG ? GLX_SLOW_CONFIG
408 : GLX_NONE;
409 cAttribs += 2;
410 }
411 aAttribList[cAttribs] = GLX_RENDER_TYPE;
412 aAttribList[cAttribs + 1] = GLX_RGBA_BIT;
413 cAttribs += 2;
414 if (paAttribs != NULL)
415 {
416 aAttribList[cAttribs] = None;
417 AssertRelease(cAttribs < RT_ELEMENTS(aAttribList));
418 if (!(cRenderableType & EGL_OPENGL_BIT))
419 return setEGLError(EGL_BAD_ACCESS);
420 }
421 paFBConfigs = glXChooseFBConfig(pDisplay, DefaultScreen(pDisplay), paAttribs != NULL ? aAttribList : NULL, &caFBConfigs);
422 if (paFBConfigs == NULL)
423 return setEGLError(EGL_BAD_ACCESS);
424 *pcConfigs = caFBConfigs;
425 for (i = 0; i < caConfigs && i < caFBConfigs; ++i)
426 paConfigs[i] = (EGLConfig)paFBConfigs[i];
427 XFree(paFBConfigs);
428 return clearEGLError();
429}
430
431DECLEXPORT(EGLBoolean) eglGetConfigAttrib (EGLDisplay hDisplay, EGLConfig cConfig, EGLint cAttribute, EGLint *pValue)
432{
433 Display *pDisplay = (Display *)hDisplay;
434 int cGLXAttribute = convertEGLAttribToGLX(cAttribute);
435 int cValue;
436
437 if (!VALID_PTR(hDisplay))
438 return setEGLError(EGL_NOT_INITIALIZED);
439 if (!VALID_PTR(pValue))
440 return setEGLError(EGL_BAD_PARAMETER);
441 if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_FBCONFIG_ID, &cValue))
442 return setEGLError(EGL_BAD_CONFIG);
443 if (cGLXAttribute != None)
444 {
445 if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, cGLXAttribute, &cValue))
446 return setEGLError(EGL_BAD_ACCESS);
447 *pValue = cValue;
448 return clearEGLError();
449 }
450 switch (cAttribute)
451 {
452 case EGL_ALPHA_MASK_SIZE:
453 *pValue = 0;
454 return clearEGLError();
455 case EGL_LUMINANCE_SIZE:
456 if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_X_VISUAL_TYPE, &cValue))
457 return setEGLError(EGL_BAD_ACCESS);
458 if (cValue == GLX_STATIC_GRAY || cValue == GLX_GRAY_SCALE)
459 {
460 if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_RED_SIZE, &cValue))
461 return setEGLError(EGL_BAD_ACCESS);
462 *pValue = cValue;
463 }
464 else
465 *pValue = 0;
466 return clearEGLError();
467 case EGL_COLOR_BUFFER_TYPE:
468 if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_X_VISUAL_TYPE, &cValue))
469 return setEGLError(EGL_BAD_ACCESS);
470 if (cValue == GLX_STATIC_GRAY || cValue == GLX_GRAY_SCALE)
471 *pValue = EGL_LUMINANCE_BUFFER;
472 else
473 *pValue = EGL_RGB_BUFFER;
474 return clearEGLError();
475 case EGL_CONFIG_CAVEAT:
476 if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_CONFIG_CAVEAT, &cValue))
477 return setEGLError(EGL_BAD_ACCESS);
478 *pValue = cValue == GLX_NONE ? EGL_NONE : cValue == GLX_SLOW_CONFIG ? EGL_SLOW_CONFIG : GLX_NON_CONFORMANT_CONFIG;
479 return clearEGLError();
480 case EGL_CONFORMANT:
481 if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_CONFIG_CAVEAT, &cValue))
482 return setEGLError(EGL_BAD_ACCESS);
483 *pValue = cValue == GLX_NON_CONFORMANT_CONFIG ? 0 : EGL_OPENGL_BIT;
484 return clearEGLError();
485 case EGL_MATCH_NATIVE_PIXMAP:
486 case EGL_MIN_SWAP_INTERVAL:
487 case EGL_MAX_SWAP_INTERVAL:
488 return setEGLError(EGL_BAD_ACCESS);
489 case EGL_NATIVE_VISUAL_TYPE:
490 if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_X_VISUAL_TYPE, &cValue))
491 return setEGLError(EGL_BAD_ACCESS);
492 *pValue = cValue == GLX_STATIC_GRAY ? StaticGray
493 : cValue == GLX_STATIC_COLOR ? StaticColor
494 : cValue == GLX_TRUE_COLOR ? TrueColor
495 : cValue == GLX_GRAY_SCALE ? GrayScale
496 : cValue == GLX_PSEUDO_COLOR ? PseudoColor
497 : cValue == GLX_DIRECT_COLOR ? DirectColor
498 : -1;
499 return clearEGLError();
500 case EGL_RENDERABLE_TYPE:
501 *pValue = EGL_OPENGL_BIT;
502 return clearEGLError();
503 case EGL_SURFACE_TYPE:
504 if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_DRAWABLE_TYPE, &cValue))
505 return setEGLError(EGL_BAD_ACCESS);
506 *pValue = (cValue & GLX_PBUFFER_BIT ? EGL_PBUFFER_BIT : 0)
507 | (cValue & GLX_PIXMAP_BIT ? EGL_PIXMAP_BIT : 0)
508 | (cValue & GLX_WINDOW_BIT ? EGL_WINDOW_BIT : 0);
509 return clearEGLError();
510 case EGL_TRANSPARENT_TYPE:
511 if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_TRANSPARENT_TYPE, &cValue))
512 return setEGLError(EGL_BAD_ACCESS);
513 *pValue = cValue == GLX_NONE ? EGL_NONE
514 : cValue == GLX_TRANSPARENT_RGB ? EGL_TRANSPARENT_RGB
515 : EGL_FALSE;
516 return *pValue != EGL_FALSE ? clearEGLError() : setEGLError(EGL_BAD_ACCESS);
517 default:
518 return setEGLError(EGL_BAD_ATTRIBUTE);
519 }
520 return clearEGLError();
521}
522
523DECLEXPORT(EGLSurface) eglCreateWindowSurface(EGLDisplay hDisplay, EGLConfig config, EGLNativeWindowType hWindow,
524 const EGLint *paAttributes)
525{
526 Display *pDisplay = (Display *)hDisplay;
527 GLXWindow hGLXWindow;
528
529 if (!VALID_PTR(hDisplay))
530 {
531 setEGLError(EGL_NOT_INITIALIZED);
532 return EGL_NO_SURFACE;
533 }
534 if (paAttributes != NULL) /* Sanity test only. */
535 while (*paAttributes != EGL_NONE)
536 {
537 if (*paAttributes != EGL_RENDER_BUFFER)
538 {
539 setEGLError(EGL_BAD_MATCH);
540 return EGL_NO_SURFACE;
541 }
542 paAttributes += 2;
543 }
544 hGLXWindow = glXCreateWindow(pDisplay, (GLXFBConfig)config, (Window)hWindow, NULL);
545 if (hGLXWindow == None)
546 {
547 setEGLError(EGL_BAD_ALLOC);
548 return EGL_NO_SURFACE;
549 }
550 AssertRelease(hGLXWindow < VBEGL_WINDOW_SURFACE); /* Greater than the maximum XID. */
551 clearEGLError();
552 return (EGLSurface)(hGLXWindow | VBEGL_WINDOW_SURFACE);
553}
554
555static void setAttribute(int *pcStoreIndex, int *pcCurIndex, int *paGLXAttributes, int cAttribute, int cValue)
556{
557 if (*pcStoreIndex < 0)
558 {
559 *pcStoreIndex = *pcCurIndex;
560 *pcCurIndex += 2;
561 paGLXAttributes[*pcStoreIndex] = cAttribute;
562 }
563 paGLXAttributes[*pcStoreIndex + 1] = cValue;
564}
565
566DECLEXPORT(EGLSurface) eglCreatePbufferSurface(EGLDisplay hDisplay, EGLConfig config, EGLint const *paAttributes)
567{
568 Display *pDisplay = (Display *)hDisplay;
569 enum { CPS_WIDTH = 0, CPS_HEIGHT, CPS_LARGEST, CPS_PRESERVED, CPS_TEX_FORMAT, CPS_TEX_TARGET, CPS_MIPMAP_TEX, CPS_END };
570 int acIndices[CPS_END];
571 int aAttributes[CPS_END * 2];
572 int cIndex = 0;
573 unsigned i;
574 GLXPbuffer hPbuffer;
575
576 if (!VALID_PTR(hDisplay))
577 {
578 setEGLError(EGL_NOT_INITIALIZED);
579 return EGL_NO_SURFACE;
580 }
581 for (i = 0; i < RT_ELEMENTS(acIndices); ++i)
582 acIndices[i] = -1;
583 if (paAttributes != NULL)
584 while (*paAttributes != EGL_NONE)
585 {
586 switch (*paAttributes)
587 {
588 case EGL_WIDTH:
589 setAttribute(&acIndices[CPS_WIDTH], &cIndex, aAttributes, GLX_PBUFFER_WIDTH, paAttributes[1]);
590 break;
591 case EGL_HEIGHT:
592 setAttribute(&acIndices[CPS_HEIGHT], &cIndex, aAttributes, GLX_LARGEST_PBUFFER, paAttributes[1]);
593 break;
594 case EGL_LARGEST_PBUFFER:
595 setAttribute(&acIndices[CPS_LARGEST], &cIndex, aAttributes, GLX_PBUFFER_HEIGHT, paAttributes[1]);
596 break;
597 case EGL_BUFFER_PRESERVED:
598 setAttribute(&acIndices[CPS_PRESERVED], &cIndex, aAttributes, GLX_PRESERVED_CONTENTS, paAttributes[1]);
599 break;
600 case EGL_TEXTURE_FORMAT:
601 setAttribute(&acIndices[CPS_TEX_FORMAT], &cIndex, aAttributes, GLX_TEXTURE_FORMAT_EXT, paAttributes[1]);
602 break;
603 case EGL_TEXTURE_TARGET:
604 setAttribute(&acIndices[CPS_TEX_TARGET], &cIndex, aAttributes, GLX_TEXTURE_TARGET_EXT, paAttributes[1]);
605 break;
606 case EGL_MIPMAP_TEXTURE:
607 setAttribute(&acIndices[CPS_MIPMAP_TEX], &cIndex, aAttributes, GLX_MIPMAP_TEXTURE_EXT, paAttributes[1]);
608 break;
609 case EGL_VG_ALPHA_FORMAT:
610 case EGL_VG_COLORSPACE:
611 {
612 setEGLError(EGL_BAD_MATCH);
613 return EGL_NO_SURFACE;
614 }
615 }
616 paAttributes += 2;
617 }
618 AssertRelease(cIndex < RT_ELEMENTS(aAttributes) - 1);
619 aAttributes[cIndex + 1] = None;
620 hPbuffer = glXCreatePbuffer(pDisplay, (GLXFBConfig)config, aAttributes);
621 if (hPbuffer == None)
622 {
623 setEGLError(EGL_BAD_ALLOC);
624 return EGL_NO_SURFACE;
625 }
626 AssertRelease(hPbuffer < VBEGL_WINDOW_SURFACE); /* Greater than the maximum XID. */
627 clearEGLError();
628 return (EGLSurface)(hPbuffer | VBEGL_PBUFFER_SURFACE);
629}
630
631DECLEXPORT(EGLSurface) eglCreatePixmapSurface(EGLDisplay hDisplay, EGLConfig config, EGLNativePixmapType hPixmap,
632 const EGLint *paAttributes)
633{
634 Display *pDisplay = (Display *)hDisplay;
635 GLXPixmap hGLXPixmap;
636
637 if (!VALID_PTR(hDisplay))
638 {
639 setEGLError(EGL_NOT_INITIALIZED);
640 return EGL_NO_SURFACE;
641 }
642 if (paAttributes != NULL) /* Sanity test only. */
643 if (*paAttributes != EGL_NONE)
644 {
645 if (*paAttributes == EGL_VG_COLORSPACE || *paAttributes == EGL_VG_ALPHA_FORMAT)
646 {
647 setEGLError(EGL_BAD_MATCH);
648 return EGL_NO_SURFACE;
649 }
650 else
651 {
652 setEGLError(EGL_BAD_ATTRIBUTE);
653 return EGL_NO_SURFACE;
654 }
655 }
656 hGLXPixmap = glXCreatePixmap(pDisplay, (GLXFBConfig)config, (Pixmap)hPixmap, NULL);
657 if (hGLXPixmap == None)
658 {
659 setEGLError(EGL_BAD_MATCH);
660 return EGL_NO_SURFACE;
661 }
662 AssertRelease(hGLXPixmap < VBEGL_WINDOW_SURFACE); /* Greater than the maximum XID. */
663 clearEGLError();
664 return (EGLSurface)(hGLXPixmap | VBEGL_PIXMAP_SURFACE);
665}
666
667DECLEXPORT(EGLBoolean) eglDestroySurface(EGLDisplay hDisplay, EGLSurface hSurface)
668{
669 Display *pDisplay = (Display *)hDisplay;
670
671 if (!VALID_PTR(hDisplay))
672 return setEGLError(EGL_NOT_INITIALIZED);
673 switch ((GLXDrawable)hSurface & VBEGL_ANY_SURFACE)
674 {
675 case VBEGL_WINDOW_SURFACE:
676 glXDestroyWindow(pDisplay, (GLXWindow)hSurface & ~VBEGL_WINDOW_SURFACE);
677 return clearEGLError();
678 case VBEGL_PBUFFER_SURFACE:
679 glXDestroyPbuffer(pDisplay, (GLXPbuffer)hSurface & ~VBEGL_PBUFFER_SURFACE);
680 return clearEGLError();
681 case VBEGL_PIXMAP_SURFACE:
682 glXDestroyPixmap(pDisplay, (GLXPixmap)hSurface & ~VBEGL_PIXMAP_SURFACE);
683 return clearEGLError();
684 default:
685 return setEGLError(EGL_BAD_SURFACE);
686 }
687}
688
689DECLEXPORT(EGLBoolean) eglSurfaceAttrib(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cAttribute, EGLint cValue)
690{
691 NOREF(hDisplay);
692 NOREF(hSurface);
693 NOREF(cValue);
694 switch (cAttribute)
695 {
696 case EGL_MIPMAP_LEVEL:
697 case EGL_MULTISAMPLE_RESOLVE:
698 case EGL_SWAP_BEHAVIOR:
699 return setEGLError(EGL_BAD_MATCH);
700 default:
701 return setEGLError(EGL_BAD_ATTRIBUTE);
702 }
703}
704
705DECLEXPORT(EGLBoolean) eglQuerySurface(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cAttribute, EGLint *cValue)
706{
707 NOREF(hDisplay);
708 NOREF(hSurface);
709 NOREF(cAttribute);
710 NOREF(cValue);
711 return setEGLError(EGL_BAD_MATCH);
712}
713
714DECLEXPORT(EGLBoolean) eglBindTexImage(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cBuffer)
715{
716 NOREF(hDisplay);
717 NOREF(hSurface);
718 NOREF(cBuffer);
719 return setEGLError(EGL_BAD_MATCH);
720}
721
722DECLEXPORT(EGLBoolean) eglReleaseTexImage(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cBuffer)
723{
724 NOREF(hDisplay);
725 NOREF(hSurface);
726 NOREF(cBuffer);
727 return setEGLError(EGL_BAD_MATCH);
728}
729
730DECLEXPORT(EGLBoolean) eglBindAPI(EGLenum enmApi)
731{
732 return enmApi == EGL_OPENGL_API ? clearEGLError() : setEGLError(EGL_BAD_PARAMETER);
733}
734
735DECLEXPORT(EGLenum) eglQueryAPI(void)
736{
737 return EGL_OPENGL_API;
738}
739
740DECLEXPORT(EGLContext) eglCreateContext(EGLDisplay hDisplay, EGLConfig hConfig, EGLContext hSharedContext,
741 const EGLint *paAttribs)
742{
743 Display *pDisplay = (Display *)hDisplay;
744 GLXContext hNewContext;
745
746 if (!VALID_PTR(hDisplay))
747 {
748 setEGLError(EGL_NOT_INITIALIZED);
749 return EGL_NO_CONTEXT;
750 }
751 if (paAttribs != NULL && *paAttribs != EGL_NONE)
752 {
753 setEGLError(EGL_BAD_ATTRIBUTE);
754 return EGL_NO_CONTEXT;
755 }
756 hNewContext = glXCreateNewContext(pDisplay, (GLXFBConfig)hConfig, GLX_RGBA_TYPE, (GLXContext)hSharedContext, true);
757 if (hNewContext)
758 {
759 clearEGLError();
760 return (EGLContext)hNewContext;
761 }
762 setEGLError(EGL_BAD_MATCH);
763 return EGL_NO_CONTEXT;
764}
765
766DECLEXPORT(EGLBoolean) eglDestroyContext(EGLDisplay hDisplay, EGLContext hContext)
767{
768 Display *pDisplay = (Display *)hDisplay;
769
770 if (!VALID_PTR(hDisplay))
771 return setEGLError(EGL_NOT_INITIALIZED);
772 glXDestroyContext(pDisplay, (GLXContext) hContext);
773 return clearEGLError();
774}
775
776DECLEXPORT(EGLBoolean) eglMakeCurrent(EGLDisplay hDisplay, EGLSurface hDraw, EGLSurface hRead, EGLContext hContext)
777{
778 Display *pDisplay = (Display *)hDisplay;
779 GLXDrawable hGLXDraw = hDraw == EGL_NO_SURFACE ? None : (GLXDrawable)hDraw & ~VBEGL_ANY_SURFACE;
780 GLXDrawable hGLXRead = hRead == EGL_NO_SURFACE ? None : (GLXDrawable)hRead & ~VBEGL_ANY_SURFACE;
781 GLXContext hGLXContext = hContext == EGL_NO_CONTEXT ? None : (GLXContext)hContext;
782 struct VBEGLTLS *pTls = getTls();
783
784 if (!VALID_PTR(hDisplay) || !VALID_PTR(pTls))
785 return setEGLError(EGL_NOT_INITIALIZED);
786 if (glXMakeContextCurrent(pDisplay, hGLXDraw, hGLXRead, hGLXContext))
787 {
788 pTls->hCurrent = hContext;
789 pTls->hCurrentDraw = hDraw;
790 pTls->hCurrentRead = hRead;
791 return clearEGLError();
792 }
793 else
794 return setEGLError(EGL_BAD_MATCH);
795}
796
797DECLEXPORT(EGLContext) eglGetCurrentContext(void)
798{
799 struct VBEGLTLS *pTls = getTls();
800
801 if (!VALID_PTR(pTls))
802 return EGL_NO_CONTEXT;
803 clearEGLError();
804 return pTls->hCurrent;
805}
806
807DECLEXPORT(EGLSurface) eglGetCurrentSurface(EGLint cOp)
808{
809 struct VBEGLTLS *pTls = getTls();
810
811 if (!VALID_PTR(pTls))
812 return EGL_NO_SURFACE;
813 clearEGLError();
814 switch (cOp)
815 {
816 case EGL_DRAW:
817 return pTls->hCurrentDraw;
818 case EGL_READ:
819 return pTls->hCurrentRead;
820 default:
821 setEGLError(EGL_BAD_PARAMETER);
822 return EGL_NO_SURFACE;
823 }
824}
825
826DECLEXPORT(EGLDisplay) eglGetCurrentDisplay(void)
827{
828 struct VBEGLTLS *pTls = getTls();
829
830 if (!VALID_PTR(pTls))
831 return EGL_NO_DISPLAY;
832 clearEGLError();
833 return pTls->hCurrentDisplay;
834}
835
836DECLEXPORT(EGLBoolean) eglQueryContext(EGLDisplay hDisplay, EGLContext hContext, EGLint cAttribute, EGLint *pcValue)
837{
838 Display *pDisplay = (Display *)hDisplay;
839
840 if (!VALID_PTR(hDisplay))
841 return setEGLError(EGL_NOT_INITIALIZED);
842 if (!VALID_PTR(pcValue))
843 return setEGLError(EGL_BAD_PARAMETER);
844 switch (cAttribute)
845 {
846 case EGL_CONFIG_ID:
847 {
848 int cValue = 0;
849
850 if (glXQueryContext(pDisplay, (GLXContext)hContext, GLX_FBCONFIG_ID, &cValue) == Success)
851 {
852 *pcValue = cValue;
853 return clearEGLError();
854 }
855 return setEGLError(EGL_BAD_MATCH);
856 }
857 case EGL_CONTEXT_CLIENT_TYPE:
858 *pcValue = EGL_OPENGL_API;
859 return clearEGLError();
860 case EGL_CONTEXT_CLIENT_VERSION:
861 *pcValue = 0;
862 return clearEGLError();
863 case EGL_RENDER_BUFFER:
864 *pcValue = EGL_BACK_BUFFER;
865 return clearEGLError();
866 default:
867 return setEGLError(EGL_BAD_ATTRIBUTE);
868 }
869}
870
871DECLEXPORT(EGLBoolean) eglWaitClient(void)
872{
873 glXWaitGL();
874 return clearEGLError();
875}
876
877DECLEXPORT(EGLBoolean) eglWaitGL(void)
878{
879 return setEGLError(EGL_BAD_PARAMETER); /* OpenGL ES only. */
880}
881
882DECLEXPORT(EGLBoolean) eglWaitNative(EGLint cEngine)
883{
884 if (cEngine != EGL_CORE_NATIVE_ENGINE)
885 return setEGLError(EGL_BAD_PARAMETER);
886 glXWaitX();
887 return clearEGLError();
888}
889
890DECLEXPORT(EGLBoolean) eglSwapBuffers(EGLDisplay hDisplay, EGLSurface hSurface)
891{
892 Display *pDisplay = (Display *)hDisplay;
893
894 if (!VALID_PTR(hDisplay))
895 return setEGLError(EGL_NOT_INITIALIZED);
896 glXSwapBuffers(pDisplay, (GLXDrawable)hSurface & ~VBEGL_ANY_SURFACE);
897 return clearEGLError();
898}
899
900/** @todo Work out how this fits over what Chromium has to offer. */
901DECLEXPORT(EGLBoolean) eglCopyBuffers(EGLDisplay hDisplay, EGLSurface hSurface, EGLNativePixmapType hPixmap)
902{
903 Display *pDisplay = (Display *)hDisplay;
904
905 if (!VALID_PTR(hDisplay))
906 return setEGLError(EGL_NOT_INITIALIZED);
907
908 NOREF(hSurface);
909 NOREF(hPixmap);
910 return setEGLError(EGL_BAD_MATCH);
911}
912
913typedef void (*VBEGLFuncPtr)(void);
914DECLEXPORT(VBEGLFuncPtr)eglGetProcAddress(const char *pszName)
915{
916 clearEGLError();
917 return glXGetProcAddress((const GLubyte *)pszName);
918}
919
920DECLEXPORT(EGLBoolean) eglReleaseThread()
921{
922 struct VBEGLTLS *pTls = getTls();
923
924 if (!(pTls))
925 return EGL_TRUE;
926 RTMemFree(pTls);
927 RTTlsSet(g_tls, NULL);
928 return EGL_TRUE;
929}
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