DECLEXPORT(EGLSurface) eglCreateWindowSurface(EGLDisplay hDisplay, EGLConfig config, EGLNativeWindowType hWindow, const EGLint *paAttributes) { Display *pDisplay = (Display *)hDisplay; GLXWindow hGLXWindow; if (!VALID_PTR(hDisplay)) { setEGLError(EGL_NOT_INITIALIZED); return EGL_NO_SURFACE; } if (paAttributes != NULL) /* Sanity test only. */ while (*paAttributes != EGL_NONE) { if (*paAttributes != EGL_RENDER_BUFFER) { setEGLError(EGL_BAD_MATCH); return EGL_NO_SURFACE; } paAttributes += 2; } hGLXWindow = glXCreateWindow(pDisplay, (GLXFBConfig)config, (Window)hWindow, NULL); if (hGLXWindow == None) { setEGLError(EGL_BAD_ALLOC); return EGL_NO_SURFACE; } EGL_ASSERT(hGLXWindow < VBEGL_WINDOW_SURFACE); /* Greater than the maximum XID. */ clearEGLError(); return (EGLSurface)(hGLXWindow | VBEGL_WINDOW_SURFACE); }
DECLEXPORT(EGLContext) eglCreateContext(EGLDisplay hDisplay, EGLConfig hConfig, EGLContext hSharedContext, const EGLint *paAttribs) { Display *pDisplay = (Display *)hDisplay; GLXContext hNewContext; if (!VALID_PTR(hDisplay)) { setEGLError(EGL_NOT_INITIALIZED); return EGL_NO_CONTEXT; } if (paAttribs != NULL && *paAttribs != EGL_NONE) { setEGLError(EGL_BAD_ATTRIBUTE); return EGL_NO_CONTEXT; } hNewContext = glXCreateNewContext(pDisplay, (GLXFBConfig)hConfig, GLX_RGBA_TYPE, (GLXContext)hSharedContext, true); if (hNewContext) { clearEGLError(); return (EGLContext)hNewContext; } setEGLError(EGL_BAD_MATCH); return EGL_NO_CONTEXT; }
DECLEXPORT(EGLBoolean) eglQueryContext(EGLDisplay hDisplay, EGLContext hContext, EGLint cAttribute, EGLint *pcValue) { Display *pDisplay = (Display *)hDisplay; if (!VALID_PTR(hDisplay)) return setEGLError(EGL_NOT_INITIALIZED); if (!VALID_PTR(pcValue)) return setEGLError(EGL_BAD_PARAMETER); switch (cAttribute) { case EGL_CONFIG_ID: { int cValue = 0; if (glXQueryContext(pDisplay, (GLXContext)hContext, GLX_FBCONFIG_ID, &cValue) == Success) { *pcValue = cValue; return clearEGLError(); } return setEGLError(EGL_BAD_MATCH); } case EGL_CONTEXT_CLIENT_TYPE: *pcValue = EGL_OPENGL_API; return clearEGLError(); case EGL_CONTEXT_CLIENT_VERSION: *pcValue = 0; return clearEGLError(); case EGL_RENDER_BUFFER: *pcValue = EGL_BACK_BUFFER; return clearEGLError(); default: return setEGLError(EGL_BAD_ATTRIBUTE); } }
DECLEXPORT(EGLSurface) eglCreatePixmapSurface(EGLDisplay hDisplay, EGLConfig config, EGLNativePixmapType hPixmap, const EGLint *paAttributes) { Display *pDisplay = (Display *)hDisplay; GLXPixmap hGLXPixmap; if (!VALID_PTR(hDisplay)) { setEGLError(EGL_NOT_INITIALIZED); return EGL_NO_SURFACE; } if (paAttributes != NULL) /* Sanity test only. */ if (*paAttributes != EGL_NONE) { if (*paAttributes == EGL_VG_COLORSPACE || *paAttributes == EGL_VG_ALPHA_FORMAT) { setEGLError(EGL_BAD_MATCH); return EGL_NO_SURFACE; } else { setEGLError(EGL_BAD_ATTRIBUTE); return EGL_NO_SURFACE; } } hGLXPixmap = glXCreatePixmap(pDisplay, (GLXFBConfig)config, (Pixmap)hPixmap, NULL); if (hGLXPixmap == None) { setEGLError(EGL_BAD_MATCH); return EGL_NO_SURFACE; } EGL_ASSERT(hGLXPixmap < VBEGL_WINDOW_SURFACE); /* Greater than the maximum XID. */ clearEGLError(); return (EGLSurface)(hGLXPixmap | VBEGL_PIXMAP_SURFACE); }
/** @todo Work out how this fits over what Chromium has to offer. */ DECLEXPORT(EGLBoolean) eglCopyBuffers(EGLDisplay hDisplay, EGLSurface hSurface, EGLNativePixmapType hPixmap) { Display *pDisplay = (Display *)hDisplay; if (!VALID_PTR(pDisplay)) return setEGLError(EGL_NOT_INITIALIZED); NOREF(hSurface); NOREF(hPixmap); return setEGLError(EGL_BAD_MATCH); }
DECLEXPORT(EGLBoolean) eglSurfaceAttrib(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cAttribute, EGLint cValue) { NOREF(hDisplay); NOREF(hSurface); NOREF(cValue); switch (cAttribute) { case EGL_MIPMAP_LEVEL: case EGL_MULTISAMPLE_RESOLVE: case EGL_SWAP_BEHAVIOR: return setEGLError(EGL_BAD_MATCH); default: return setEGLError(EGL_BAD_ATTRIBUTE); } }
DECLEXPORT(EGLBoolean) eglReleaseTexImage(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cBuffer) { NOREF(hDisplay); NOREF(hSurface); NOREF(cBuffer); return setEGLError(EGL_BAD_MATCH); }
DECLEXPORT(EGLBoolean) eglWaitNative(EGLint cEngine) { if (cEngine != EGL_CORE_NATIVE_ENGINE) return setEGLError(EGL_BAD_PARAMETER); glXWaitX(); return clearEGLError(); }
DECLEXPORT(EGLBoolean) eglQuerySurface(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cAttribute, EGLint *cValue) { NOREF(hDisplay); NOREF(hSurface); NOREF(cAttribute); NOREF(cValue); return setEGLError(EGL_BAD_MATCH); }
DECLEXPORT(EGLBoolean) eglSwapBuffers(EGLDisplay hDisplay, EGLSurface hSurface) { Display *pDisplay = (Display *)hDisplay; if (!VALID_PTR(hDisplay)) return setEGLError(EGL_NOT_INITIALIZED); glXSwapBuffers(pDisplay, (GLXDrawable)hSurface & ~VBEGL_ANY_SURFACE); return clearEGLError(); }
DECLEXPORT(EGLBoolean) eglDestroyContext(EGLDisplay hDisplay, EGLContext hContext) { Display *pDisplay = (Display *)hDisplay; if (!VALID_PTR(hDisplay)) return setEGLError(EGL_NOT_INITIALIZED); glXDestroyContext(pDisplay, (GLXContext) hContext); return clearEGLError(); }
DECLEXPORT(EGLBoolean) eglInitialize (EGLDisplay hDisplay, EGLint *pcMajor, EGLint *pcMinor) { if (!VALID_PTR(hDisplay)) return setEGLError(EGL_BAD_DISPLAY); if (pcMajor) *pcMajor = 1; if (pcMinor) *pcMinor = 4; return clearEGLError(); }
DECLEXPORT(EGLBoolean) eglMakeCurrent(EGLDisplay hDisplay, EGLSurface hDraw, EGLSurface hRead, EGLContext hContext) { Display *pDisplay = (Display *)hDisplay; GLXDrawable hGLXDraw = hDraw == EGL_NO_SURFACE ? None : (GLXDrawable)hDraw & ~VBEGL_ANY_SURFACE; GLXDrawable hGLXRead = hRead == EGL_NO_SURFACE ? None : (GLXDrawable)hRead & ~VBEGL_ANY_SURFACE; GLXContext hGLXContext = hContext == EGL_NO_CONTEXT ? None : (GLXContext)hContext; struct VBEGLTLS *pTls = getTls(); if (!VALID_PTR(hDisplay) || !VALID_PTR(pTls)) return setEGLError(EGL_NOT_INITIALIZED); if (glXMakeContextCurrent(pDisplay, hGLXDraw, hGLXRead, hGLXContext)) { pTls->hCurrent = hContext; pTls->hCurrentDraw = hDraw; pTls->hCurrentRead = hRead; return clearEGLError(); } else return setEGLError(EGL_BAD_MATCH); }
DECLEXPORT(EGLBoolean) eglDestroySurface(EGLDisplay hDisplay, EGLSurface hSurface) { Display *pDisplay = (Display *)hDisplay; if (!VALID_PTR(hDisplay)) return setEGLError(EGL_NOT_INITIALIZED); switch ((GLXDrawable)hSurface & VBEGL_ANY_SURFACE) { case VBEGL_WINDOW_SURFACE: glXDestroyWindow(pDisplay, (GLXWindow)hSurface & ~VBEGL_WINDOW_SURFACE); return clearEGLError(); case VBEGL_PBUFFER_SURFACE: glXDestroyPbuffer(pDisplay, (GLXPbuffer)hSurface & ~VBEGL_PBUFFER_SURFACE); return clearEGLError(); case VBEGL_PIXMAP_SURFACE: glXDestroyPixmap(pDisplay, (GLXPixmap)hSurface & ~VBEGL_PIXMAP_SURFACE); return clearEGLError(); default: return setEGLError(EGL_BAD_SURFACE); } }
DECLEXPORT(EGLBoolean) eglGetConfigs (EGLDisplay hDisplay, EGLConfig *paConfigs, EGLint caConfigs, EGLint *pcaConfigs) { Display *pDisplay = (Display *)hDisplay; GLXFBConfig *paFBConfigs; int caFBConfigs, i; if (!VALID_PTR(pDisplay)) return setEGLError(EGL_NOT_INITIALIZED); if (!VALID_PTR(pcaConfigs)) return setEGLError(EGL_BAD_PARAMETER); if (caConfigs > 0 && !VALID_PTR(paConfigs)) return setEGLError(EGL_BAD_PARAMETER); paFBConfigs = glXGetFBConfigs(pDisplay, DefaultScreen(pDisplay), &caFBConfigs); AssertPtrReturn(paFBConfigs, setEGLError(EGL_BAD_PARAMETER)); if (caFBConfigs > caConfigs) caFBConfigs = caConfigs; *pcaConfigs = caFBConfigs; for (i = 0; i < caFBConfigs; ++i) paConfigs[i] = (EGLConfig)paFBConfigs[i]; XFree(paFBConfigs); return clearEGLError(); }
DECLEXPORT(EGLSurface) eglGetCurrentSurface(EGLint cOp) { struct VBEGLTLS *pTls = getTls(); if (!VALID_PTR(pTls)) return EGL_NO_SURFACE; clearEGLError(); switch (cOp) { case EGL_DRAW: return pTls->hCurrentDraw; case EGL_READ: return pTls->hCurrentRead; default: setEGLError(EGL_BAD_PARAMETER); return EGL_NO_SURFACE; } }
DECLEXPORT(EGLBoolean) eglWaitGL(void) { return setEGLError(EGL_BAD_PARAMETER); /* OpenGL ES only. */ }
DECLEXPORT(EGLBoolean) eglChooseConfig (EGLDisplay hDisplay, const EGLint *paAttribs, EGLConfig *paConfigs, EGLint caConfigs, EGLint *pcConfigs) { Display *pDisplay = (Display *)hDisplay; int aAttribList[256]; /* The list cannot be this long. */ unsigned cAttribs = 0, i; const EGLint *pAttrib, *pAttrib2; EGLint cRenderableType = EGL_OPENGL_ES_BIT; unsigned cConfigCaveat = GLX_DONT_CARE, cConformant = GLX_DONT_CARE; GLXFBConfig *paFBConfigs; int caFBConfigs; if (!VALID_PTR(hDisplay)) return setEGLError(EGL_NOT_INITIALIZED); if (!VALID_PTR(pcConfigs)) return setEGLError(EGL_BAD_PARAMETER); if (caConfigs > 0 && !VALID_PTR(paConfigs)) return setEGLError(EGL_BAD_PARAMETER); for (pAttrib = paAttribs; pAttrib != NULL && *pAttrib != EGL_NONE; pAttrib += 2) { bool fSkip = false; int cGLXAttrib; /* Check for illegal values. */ if ((*pAttrib == EGL_LEVEL || *pAttrib == EGL_MATCH_NATIVE_PIXMAP) && pAttrib[1] == EGL_DONT_CARE) return setEGLError(EGL_BAD_ATTRIBUTE); /* Check for values we can't handle. */ if ( (*pAttrib == EGL_ALPHA_MASK_SIZE) && pAttrib[1] != EGL_DONT_CARE && pAttrib[1] != 0) return setEGLError(EGL_BAD_ACCESS); /** @todo try creating a pixmap from a native one with the configurations returned. */ if (*pAttrib == EGL_MATCH_NATIVE_PIXMAP) return setEGLError(EGL_BAD_ACCESS); if ( ( *pAttrib == EGL_MIN_SWAP_INTERVAL || *pAttrib == EGL_MAX_SWAP_INTERVAL || *pAttrib == EGL_BIND_TO_TEXTURE_RGB || *pAttrib == EGL_BIND_TO_TEXTURE_RGBA) && pAttrib[1] != EGL_DONT_CARE) return setEGLError(EGL_BAD_ACCESS); /* Ignore attributes which are repeated later. */ for (pAttrib2 = pAttrib + 2; *pAttrib2 != EGL_NONE; pAttrib2 += 2) if (*pAttrib2 == *pAttrib) { fSkip = true; break; } if (fSkip) continue; cGLXAttrib = convertEGLAttribToGLX(*pAttrib); if (cGLXAttrib != None) { aAttribList[cAttribs] = cGLXAttrib; if (pAttrib[1] == EGL_DONT_CARE) aAttribList[cAttribs + 1] = GLX_DONT_CARE; else aAttribList[cAttribs + 1] = pAttrib[1]; cAttribs += 2; } else { switch (*pAttrib) { case EGL_COLOR_BUFFER_TYPE: aAttribList[cAttribs] = GLX_X_VISUAL_TYPE; aAttribList[cAttribs + 1] = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE : pAttrib[1] == EGL_RGB_BUFFER ? GLX_TRUE_COLOR : pAttrib[1] == EGL_LUMINANCE_BUFFER ? GLX_GRAY_SCALE : GL_FALSE; if ( *pAttrib == EGL_COLOR_BUFFER_TYPE && pAttrib[1] != EGL_DONT_CARE && pAttrib[1] != EGL_RGB_BUFFER) return setEGLError(EGL_BAD_ACCESS); break; case EGL_CONFIG_CAVEAT: cConfigCaveat = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE : pAttrib[1] == EGL_NONE ? GLX_NONE : pAttrib[1] == EGL_SLOW_CONFIG ? GLX_SLOW_CONFIG : pAttrib[1] == EGL_NON_CONFORMANT_CONFIG ? GLX_NON_CONFORMANT_CONFIG : GL_FALSE; if (!cConfigCaveat) return setEGLError(EGL_BAD_ATTRIBUTE); cAttribs -= 2; break; case EGL_CONFORMANT: if (pAttrib[1] != EGL_OPENGL_BIT && pAttrib[1] != 0) return setEGLError(EGL_BAD_ACCESS); cConformant = pAttrib[1] == EGL_OPENGL_BIT ? GL_TRUE : GL_FALSE; cAttribs -= 2; break; case EGL_NATIVE_VISUAL_TYPE: aAttribList[cAttribs] = GLX_X_VISUAL_TYPE; aAttribList[cAttribs + 1] = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE : pAttrib[1] == StaticGray ? GLX_STATIC_GRAY : pAttrib[1] == StaticColor ? GLX_STATIC_COLOR : pAttrib[1] == TrueColor ? GLX_TRUE_COLOR : pAttrib[1] == GrayScale ? GLX_GRAY_SCALE : pAttrib[1] == PseudoColor ? GLX_PSEUDO_COLOR : pAttrib[1] == DirectColor ? GLX_DIRECT_COLOR : GL_FALSE; break; case EGL_RENDERABLE_TYPE: cRenderableType = pAttrib[1]; cAttribs -= 2; /* We did not add anything to the list. */ break; case EGL_SURFACE_TYPE: if (pAttrib[1] & ~(EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT)) return setEGLError(EGL_BAD_ACCESS); aAttribList[cAttribs] = GLX_DRAWABLE_TYPE; aAttribList[cAttribs + 1] = (pAttrib[1] & EGL_PBUFFER_BIT ? GLX_PBUFFER_BIT : 0) | (pAttrib[1] & EGL_PIXMAP_BIT ? GLX_PIXMAP_BIT : 0) | (pAttrib[1] & EGL_WINDOW_BIT ? GLX_WINDOW_BIT : 0); break; case EGL_TRANSPARENT_TYPE: aAttribList[cAttribs] = GLX_TRANSPARENT_TYPE; aAttribList[cAttribs + 1] = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE : pAttrib[1] == EGL_NONE ? GLX_NONE : pAttrib[1] == EGL_TRANSPARENT_RGB ? GLX_TRANSPARENT_RGB : GL_FALSE; break; default: return setEGLError(EGL_BAD_ATTRIBUTE); } cAttribs += 2; } } if (cConfigCaveat != GLX_DONT_CARE || cConformant != GLX_DONT_CARE) { aAttribList[cAttribs] = GLX_CONFIG_CAVEAT; aAttribList[cAttribs + 1] = cConformant == GL_FALSE ? GLX_NON_CONFORMANT_CONFIG : cConfigCaveat == EGL_SLOW_CONFIG ? GLX_SLOW_CONFIG : GLX_NONE; cAttribs += 2; } aAttribList[cAttribs] = GLX_RENDER_TYPE; aAttribList[cAttribs + 1] = GLX_RGBA_BIT; cAttribs += 2; if (paAttribs != NULL) { aAttribList[cAttribs] = None; EGL_ASSERT(cAttribs < RT_ELEMENTS(aAttribList)); if (!(cRenderableType & EGL_OPENGL_BIT)) return setEGLError(EGL_BAD_ACCESS); } paFBConfigs = glXChooseFBConfig(pDisplay, DefaultScreen(pDisplay), paAttribs != NULL ? aAttribList : NULL, &caFBConfigs); if (paFBConfigs == NULL) return setEGLError(EGL_BAD_ACCESS); *pcConfigs = caFBConfigs; for (i = 0; (GLint)i < caConfigs && (GLint)i < caFBConfigs; ++i) paConfigs[i] = (EGLConfig)paFBConfigs[i]; XFree(paFBConfigs); return clearEGLError(); }
DECLEXPORT(EGLBoolean) eglGetConfigAttrib (EGLDisplay hDisplay, EGLConfig cConfig, EGLint cAttribute, EGLint *pValue) { Display *pDisplay = (Display *)hDisplay; int cGLXAttribute = convertEGLAttribToGLX(cAttribute); int cValue; if (!VALID_PTR(hDisplay)) return setEGLError(EGL_NOT_INITIALIZED); if (!VALID_PTR(pValue)) return setEGLError(EGL_BAD_PARAMETER); if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_FBCONFIG_ID, &cValue)) return setEGLError(EGL_BAD_CONFIG); if (cGLXAttribute != None) { if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, cGLXAttribute, &cValue)) return setEGLError(EGL_BAD_ACCESS); *pValue = cValue; return clearEGLError(); } switch (cAttribute) { case EGL_ALPHA_MASK_SIZE: *pValue = 0; return clearEGLError(); case EGL_LUMINANCE_SIZE: if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_X_VISUAL_TYPE, &cValue)) return setEGLError(EGL_BAD_ACCESS); if (cValue == GLX_STATIC_GRAY || cValue == GLX_GRAY_SCALE) { if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_RED_SIZE, &cValue)) return setEGLError(EGL_BAD_ACCESS); *pValue = cValue; } else *pValue = 0; return clearEGLError(); case EGL_COLOR_BUFFER_TYPE: if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_X_VISUAL_TYPE, &cValue)) return setEGLError(EGL_BAD_ACCESS); if (cValue == GLX_STATIC_GRAY || cValue == GLX_GRAY_SCALE) *pValue = EGL_LUMINANCE_BUFFER; else *pValue = EGL_RGB_BUFFER; return clearEGLError(); case EGL_CONFIG_CAVEAT: if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_CONFIG_CAVEAT, &cValue)) return setEGLError(EGL_BAD_ACCESS); *pValue = cValue == GLX_NONE ? EGL_NONE : cValue == GLX_SLOW_CONFIG ? EGL_SLOW_CONFIG : GLX_NON_CONFORMANT_CONFIG; return clearEGLError(); case EGL_CONFORMANT: if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_CONFIG_CAVEAT, &cValue)) return setEGLError(EGL_BAD_ACCESS); *pValue = cValue == GLX_NON_CONFORMANT_CONFIG ? 0 : EGL_OPENGL_BIT; return clearEGLError(); case EGL_MATCH_NATIVE_PIXMAP: case EGL_MIN_SWAP_INTERVAL: case EGL_MAX_SWAP_INTERVAL: return setEGLError(EGL_BAD_ACCESS); case EGL_NATIVE_VISUAL_TYPE: if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_X_VISUAL_TYPE, &cValue)) return setEGLError(EGL_BAD_ACCESS); *pValue = cValue == GLX_STATIC_GRAY ? StaticGray : cValue == GLX_STATIC_COLOR ? StaticColor : cValue == GLX_TRUE_COLOR ? TrueColor : cValue == GLX_GRAY_SCALE ? GrayScale : cValue == GLX_PSEUDO_COLOR ? PseudoColor : cValue == GLX_DIRECT_COLOR ? DirectColor : -1; return clearEGLError(); case EGL_RENDERABLE_TYPE: *pValue = EGL_OPENGL_BIT; return clearEGLError(); case EGL_SURFACE_TYPE: if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_DRAWABLE_TYPE, &cValue)) return setEGLError(EGL_BAD_ACCESS); *pValue = (cValue & GLX_PBUFFER_BIT ? EGL_PBUFFER_BIT : 0) | (cValue & GLX_PIXMAP_BIT ? EGL_PIXMAP_BIT : 0) | (cValue & GLX_WINDOW_BIT ? EGL_WINDOW_BIT : 0); return clearEGLError(); case EGL_TRANSPARENT_TYPE: if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_TRANSPARENT_TYPE, &cValue)) return setEGLError(EGL_BAD_ACCESS); *pValue = cValue == GLX_NONE ? EGL_NONE : cValue == GLX_TRANSPARENT_RGB ? EGL_TRANSPARENT_RGB : EGL_FALSE; return *pValue != EGL_FALSE ? clearEGLError() : setEGLError(EGL_BAD_ACCESS); default: return setEGLError(EGL_BAD_ATTRIBUTE); } return clearEGLError(); }
DECLEXPORT(EGLBoolean) eglBindAPI(EGLenum enmApi) { return enmApi == EGL_OPENGL_API ? clearEGLError() : setEGLError(EGL_BAD_PARAMETER); }
DECLEXPORT(EGLSurface) eglCreatePbufferSurface(EGLDisplay hDisplay, EGLConfig config, EGLint const *paAttributes) { Display *pDisplay = (Display *)hDisplay; enum { CPS_WIDTH = 0, CPS_HEIGHT, CPS_LARGEST, CPS_PRESERVED, CPS_TEX_FORMAT, CPS_TEX_TARGET, CPS_MIPMAP_TEX, CPS_END }; int acIndices[CPS_END]; int aAttributes[CPS_END * 2]; int cIndex = 0; unsigned i; GLXPbuffer hPbuffer; if (!VALID_PTR(hDisplay)) { setEGLError(EGL_NOT_INITIALIZED); return EGL_NO_SURFACE; } for (i = 0; i < RT_ELEMENTS(acIndices); ++i) acIndices[i] = -1; if (paAttributes != NULL) while (*paAttributes != EGL_NONE) { switch (*paAttributes) { case EGL_WIDTH: setAttribute(&acIndices[CPS_WIDTH], &cIndex, aAttributes, GLX_PBUFFER_WIDTH, paAttributes[1]); break; case EGL_HEIGHT: setAttribute(&acIndices[CPS_HEIGHT], &cIndex, aAttributes, GLX_LARGEST_PBUFFER, paAttributes[1]); break; case EGL_LARGEST_PBUFFER: setAttribute(&acIndices[CPS_LARGEST], &cIndex, aAttributes, GLX_PBUFFER_HEIGHT, paAttributes[1]); break; case EGL_BUFFER_PRESERVED: setAttribute(&acIndices[CPS_PRESERVED], &cIndex, aAttributes, GLX_PRESERVED_CONTENTS, paAttributes[1]); break; case EGL_TEXTURE_FORMAT: setAttribute(&acIndices[CPS_TEX_FORMAT], &cIndex, aAttributes, GLX_TEXTURE_FORMAT_EXT, paAttributes[1]); break; case EGL_TEXTURE_TARGET: setAttribute(&acIndices[CPS_TEX_TARGET], &cIndex, aAttributes, GLX_TEXTURE_TARGET_EXT, paAttributes[1]); break; case EGL_MIPMAP_TEXTURE: setAttribute(&acIndices[CPS_MIPMAP_TEX], &cIndex, aAttributes, GLX_MIPMAP_TEXTURE_EXT, paAttributes[1]); break; case EGL_VG_ALPHA_FORMAT: case EGL_VG_COLORSPACE: { setEGLError(EGL_BAD_MATCH); return EGL_NO_SURFACE; } } paAttributes += 2; } EGL_ASSERT((unsigned)cIndex < RT_ELEMENTS(aAttributes) - 1U); aAttributes[cIndex + 1] = None; hPbuffer = glXCreatePbuffer(pDisplay, (GLXFBConfig)config, aAttributes); if (hPbuffer == None) { setEGLError(EGL_BAD_ALLOC); return EGL_NO_SURFACE; } EGL_ASSERT(hPbuffer < VBEGL_WINDOW_SURFACE); /* Greater than the maximum XID. */ clearEGLError(); return (EGLSurface)(hPbuffer | VBEGL_PBUFFER_SURFACE); }