/* * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd. All rights reserved. * * Contact: * DongKyun Yun * SangJin Kim * HyunGoo Kang * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Contributors: * - S-Core Co., Ltd * */ #include "implement.h" #include struct GlobalStruct EGLINTER(global) = { EGL_SUCCESS, 1, EGL_OPENGL_ES_API, NULL, NULL, NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, }; void EGLAPIENTRY EGLINTER(NotBound)(void) { fprintf(stderr, "EGL internal error: you are calling not-bound function\n"); } void EGLAPIENTRY EGLINTER(ResetFnptrs)(struct GlobalStruct* ptr) { #define ACTION(name) do { \ *(void**)(&ptr->fp##name) = (void*)(&(EGLINTER(NotBound))); \ } while (0) ACTION( QueryVersion ); ACTION( GetClientString ); ACTION( QueryServerString ); ACTION( ChooseFBConfig ); ACTION( GetFBConfigAttrib ); ACTION( CreatePbuffer ); ACTION( CreatePixmap ); ACTION( CreateWindow ); ACTION( DestroyPbuffer ); ACTION( DestroyPixmap ); ACTION( DestroyWindow ); ACTION( GetProcAddress ); ACTION( QueryDrawable ); ACTION( CreateNewContext ); ACTION( DestroyContext ); ACTION( GetCurrentContext ); ACTION( GetCurrentDisplay ); ACTION( GetCurrentReadDrawable ); ACTION( GetCurrentDrawable ); ACTION( MakeContextCurrent ); ACTION( WaitGL ); ACTION( WaitX ); ACTION( SwapBuffers ); ACTION( BindTexImageARB ); ACTION( ReleaseTexImageARB ); ACTION( SwapIntervalSGI ); #undef ACTION } void EGLAPIENTRY EGLINTER(BindFnptrs)(struct GlobalStruct* ptr) { void* fnptr; assert(ptr->dlGL != NULL); #define ACTION(name) do { \ fnptr = dlsym(ptr->dlGL, "glX" #name ); \ if (fnptr != NULL) *(void**)(&ptr->fp##name) = fnptr; \ } while (0) ACTION( QueryVersion ); ACTION( GetClientString ); ACTION( QueryServerString ); ACTION( ChooseFBConfig ); ACTION( GetFBConfigAttrib ); ACTION( CreatePbuffer ); ACTION( CreatePixmap ); ACTION( CreateWindow ); ACTION( DestroyPbuffer ); ACTION( DestroyPixmap ); ACTION( DestroyWindow ); ACTION( GetProcAddress ); ACTION( QueryDrawable ); ACTION( CreateNewContext ); ACTION( DestroyContext ); ACTION( GetCurrentContext ); ACTION( GetCurrentDisplay ); ACTION( GetCurrentReadDrawable ); ACTION( GetCurrentDrawable ); ACTION( MakeContextCurrent ); ACTION( WaitGL ); ACTION( WaitX ); ACTION( SwapBuffers ); ACTION( BindTexImageARB ); ACTION( ReleaseTexImageARB ); ACTION( SwapIntervalSGI ); #undef ACTION } struct DisplayExtra* EGLAPIENTRY EGLINTER(LookUpDisplay)(EGLDisplay unique) { struct DisplayExtra* pUnit = EGLINTER(global).pDisplayExtra; int nCount = EGLINTER(global).nDisplayExtra; if (pUnit == NULL) return NULL; if (unique == NULL) return NULL; while (nCount--) { if (pUnit->unique == unique) { return pUnit; } pUnit++; } return NULL; } struct DisplayExtra* EGLAPIENTRY EGLINTER(InsertDisplay)(EGLDisplay unique) { struct DisplayExtra* pArea; struct DisplayExtra* pUnit; int nBytes = (EGLINTER(global).nDisplayExtra + 1) * sizeof(struct DisplayExtra); if (unique == NULL) return NULL; if ((pArea = (struct DisplayExtra*)realloc(EGLINTER(global).pDisplayExtra, nBytes)) == NULL) { EGLINTER(SetError)(EGL_BAD_ALLOC); return NULL; } pUnit = pArea + EGLINTER(global).nDisplayExtra; memset(pUnit, 0, sizeof(struct DisplayExtra)); pUnit->unique = unique; EGLINTER(global).pDisplayExtra = pArea; EGLINTER(global).nDisplayExtra++; return pUnit; } void EGLAPIENTRY EGLINTER(DeleteDisplay)(EGLDisplay unique) { struct DisplayExtra* pUnit = EGLINTER(global).pDisplayExtra; int nCount = EGLINTER(global).nDisplayExtra; if (pUnit == NULL) return; if (unique == NULL) return; while (nCount--) { if (pUnit->unique == unique) { memmove(pUnit, pUnit + 1, nCount * sizeof(struct DisplayExtra)); EGLINTER(global).nDisplayExtra--; EGLINTER(global).pDisplayExtra = (struct DisplayExtra*)realloc(EGLINTER(global).pDisplayExtra, EGLINTER(global).nDisplayExtra * sizeof(struct DisplayExtra)); return; } pUnit++; } } struct SurfaceExtra* EGLAPIENTRY EGLINTER(LookUpSurface)(EGLSurface unique) { struct SurfaceExtra* pUnit = EGLINTER(global).pSurfaceExtra; int nCount = EGLINTER(global).nSurfaceExtra; if (pUnit == NULL) return NULL; if (unique == NULL) return NULL; while (nCount--) { if (pUnit->unique == unique) { return pUnit; } pUnit++; } return NULL; } struct SurfaceExtra* EGLAPIENTRY EGLINTER(InsertSurface)(EGLSurface unique) { struct SurfaceExtra* pArea; struct SurfaceExtra* pUnit; int nBytes = (EGLINTER(global).nSurfaceExtra + 1) * sizeof(struct SurfaceExtra); if (unique == NULL) return NULL; if ((pArea = (struct SurfaceExtra*)realloc(EGLINTER(global).pSurfaceExtra, nBytes)) == NULL) { EGLINTER(SetError)(EGL_BAD_ALLOC); return NULL; } pUnit = pArea + EGLINTER(global).nSurfaceExtra; memset(pUnit, 0, sizeof(struct SurfaceExtra)); pUnit->unique = unique; EGLINTER(global).pSurfaceExtra = pArea; EGLINTER(global).nSurfaceExtra++; return pUnit; } void EGLAPIENTRY EGLINTER(DeleteSurface)(EGLSurface unique) { struct SurfaceExtra* pUnit = EGLINTER(global).pSurfaceExtra; int nCount = EGLINTER(global).nSurfaceExtra; if (pUnit == NULL) return; if (unique == NULL) return; while (nCount--) { if (pUnit->unique == unique) { memmove(pUnit, pUnit + 1, nCount * sizeof(struct SurfaceExtra)); EGLINTER(global).nSurfaceExtra--; EGLINTER(global).pSurfaceExtra = (struct SurfaceExtra*)realloc(EGLINTER(global).pSurfaceExtra, EGLINTER(global).nSurfaceExtra * sizeof(struct SurfaceExtra)); return; } pUnit++; } } struct ContextExtra* EGLAPIENTRY EGLINTER(LookUpContext)(EGLContext unique) { struct ContextExtra* pUnit = EGLINTER(global).pContextExtra; int nCount = EGLINTER(global).nContextExtra; if (pUnit == NULL) return NULL; if (unique == NULL) return NULL; while (nCount--) { if (pUnit->unique == unique) { return pUnit; } pUnit++; } return NULL; } struct ContextExtra* EGLAPIENTRY EGLINTER(InsertContext)(EGLContext unique) { struct ContextExtra* pArea; struct ContextExtra* pUnit; int nBytes = (EGLINTER(global).nContextExtra + 1) * sizeof(struct ContextExtra); if (unique == NULL) return NULL; if ((pArea = (struct ContextExtra*)realloc(EGLINTER(global).pContextExtra, nBytes)) == NULL) { EGLINTER(SetError)(EGL_BAD_ALLOC); return NULL; } pUnit = pArea + EGLINTER(global).nContextExtra; memset(pUnit, 0, sizeof(struct ContextExtra)); pUnit->unique = unique; EGLINTER(global).pContextExtra = pArea; EGLINTER(global).nContextExtra++; return pUnit; } void EGLAPIENTRY EGLINTER(DeleteContext)(EGLContext unique) { struct ContextExtra* pUnit = EGLINTER(global).pContextExtra; int nCount = EGLINTER(global).nContextExtra; if (pUnit == NULL) return; if (unique == NULL) return; while (nCount--) { if (pUnit->unique == unique) { memmove(pUnit, pUnit + 1, nCount * sizeof(struct ContextExtra)); EGLINTER(global).nContextExtra--; EGLINTER(global).pContextExtra = (struct ContextExtra*)realloc(EGLINTER(global).pContextExtra, EGLINTER(global).nContextExtra * sizeof(struct ContextExtra)); return; } pUnit++; } } EGLBoolean EGLAPIENTRY EGLINTER(FreeContext)(struct ContextExtra *pContext) { void (*fpVGReleaseContext)(void*) = NULL;//jcpark #if defined(PROVIDING_RUNTIME_BINDING) void (*fpReleaseContext)(void*) = NULL; #endif switch (pContext->apiKind) { default: case EGL_OPENGL_API: assert(pContext->apiContext == NULL); break; #if defined(PROVIDING_RUNTIME_BINDING) case EGL_OPENGL_ES_API: if (pContext->apiVersion == 2) { if (EGLINTER(global).dlES2 == NULL) { if ((EGLINTER(global).dlES2 = dlopen(GL_ES2_SO_FILENAME, RTLD_NOW | RTLD_GLOBAL)) == NULL) { EGLINTER(SetError)(EGL_BAD_ACCESS); return EGL_FALSE; } } fpReleaseContext = dlsym(EGLINTER(global).dlES2, EGLCROSS_PREFIX "ReleaseContext"); if (fpReleaseContext != NULL) { (*fpReleaseContext)(pContext->apiContext); pContext->apiContext = NULL; } } else { if (EGLINTER(global).dlES1 == NULL) { if ((EGLINTER(global).dlES1 = dlopen(GL_ES1_SO_FILENAME, RTLD_NOW | RTLD_GLOBAL)) == NULL) { EGLINTER(SetError)(EGL_BAD_ACCESS); return EGL_FALSE; } } fpReleaseContext = dlsym(EGLINTER(global).dlES1, EGLCROSS_PREFIX "ReleaseContext"); if (fpReleaseContext != NULL) { (*fpReleaseContext)(pContext->apiContext); pContext->apiContext = NULL; } } break; #else case EGL_OPENGL_ES_API: if (pContext->apiContext != NULL) { EGLCROSS(ReleaseContext)(pContext->apiContext); } break; #endif case EGL_OPENVG_API: /* TODO: OpenVG may need some action here */ if (EGLINTER(global).dlVG == NULL) { printf("==jcpark vg4egl_DestroyContext 2\n"); if ((EGLINTER(global).dlVG = dlopen(VG_SO_FILENAME, RTLD_NOW | RTLD_GLOBAL)) == NULL) { printf("==jcpark vg4egl_DestroyContext 3\n"); EGLINTER(SetError)(EGL_BAD_ACCESS); return EGL_FALSE; } } fpVGReleaseContext = dlsym(EGLINTER(global).dlVG, "vg4egl_DestroyContext"); if (fpVGReleaseContext != NULL) { (*fpVGReleaseContext)(pContext->apiContext); pContext->apiContext = NULL; printf("==jcpark== vg4egl_DestroyContext working\n"); } break; } struct DisplayExtra* pDisplay = EGLINTER(LookUpDisplay)(pContext->display); if (pDisplay == NULL) return EGL_FALSE; FNPTR(DestroyContext)(pDisplay->native, pContext->native); EGLINTER(DeleteContext)(pContext->unique); return EGL_TRUE; } struct ImageExtra* EGLAPIENTRY EGLINTER(LookUpEGLImage)(EGLImageKHR unique) { struct ImageExtra* pUnit = EGLINTER(global).pImageExtra; int nCount = EGLINTER(global).nImageExtra; if (pUnit == NULL) return NULL; if (unique == NULL) return NULL; while (nCount--) { if (pUnit->unique == unique) { return pUnit; } pUnit++; } return NULL; } struct ImageExtra* EGLAPIENTRY EGLINTER(InsertEGLImage)(EGLImageKHR unique) { struct ImageExtra* pArea; struct ImageExtra* pUnit; int nBytes = (EGLINTER(global).nImageExtra + 1) * sizeof(struct ImageExtra); if (unique == NULL) return NULL; if ((pArea = (struct ImageExtra*)realloc(EGLINTER(global).pImageExtra, nBytes)) == NULL) { EGLINTER(SetError)(EGL_BAD_ALLOC); return NULL; } pUnit = pArea + EGLINTER(global).nImageExtra; memset(pUnit, 0, sizeof(struct ImageExtra)); pUnit->unique = unique; EGLINTER(global).pImageExtra = pArea; EGLINTER(global).nImageExtra++; return pUnit; } void EGLAPIENTRY EGLINTER(DeleteEGLImage)(EGLImageKHR unique) { struct ImageExtra* pUnit = EGLINTER(global).pImageExtra; int nCount = EGLINTER(global).nImageExtra; if (pUnit == NULL) return; if (unique == NULL) return; while (nCount--) { if (pUnit->unique == unique) { memmove(pUnit, pUnit + 1, nCount * sizeof(struct ImageExtra)); EGLINTER(global).nImageExtra--; EGLINTER(global).pImageExtra = (struct ImageExtra*)realloc(EGLINTER(global).pImageExtra, EGLINTER(global).nImageExtra * sizeof(struct ImageExtra)); return; } pUnit++; } } int EGLAPIENTRY EGLCROSS(GetEGLImagePixmapInfo)(EGLImageKHR img, EGLNativeDisplayType *dpy, Pixmap *pixmap, int *width, int *height, int *depth) { struct ImageExtra *pArea = EGLINTER(LookUpEGLImage)(img); if (pArea == NULL) { return -1; } *width = pArea->width; *height = pArea->height; *depth = pArea->depth; *dpy = pArea->dpy; *pixmap = pArea->pixmap; return 0; } #if defined(PROVIDING_RUNTIME_BINDING) void EGLAPIENTRY EGLINTER(ResetGLFnptrs)(struct GlobalStruct* ptr) { #define ACTION(name) do { \ *(void**)(&ptr->fp##name) = (void*)(&(EGLINTER(NotBound))); \ } while (0) #include "glfunclist.inl" #undef ACTION } void EGLAPIENTRY EGLINTER(BindGLFnptrs)(struct GlobalStruct* ptr) { if (EGLINTER(global).dlGL == NULL) { if ((EGLINTER(global).dlGL = dlopen(GL_SO_FILENAME, RTLD_NOW | RTLD_GLOBAL)) == NULL) { EGLINTER(SetError)(EGL_BAD_ACCESS); return; } } void* dl = EGLINTER(global).dlGL; #define ACTION(name) do { \ *(void**)(&ptr->fp##name) = dlsym(dl, "gl" #name); \ if (ptr->fp##name == NULL) *(void**)(&ptr->fp##name) = (void*)(&(EGLINTER(NotBound))); \ } while (0) #include "glfunclist.inl" #undef ACTION } void EGLAPIENTRY EGLINTER(BindES1Fnptrs)(struct GlobalStruct* ptr) { if (EGLINTER(global).dlES1 == NULL) { if ((EGLINTER(global).dlES1 = dlopen(GL_ES1_SO_FILENAME, RTLD_NOW | RTLD_GLOBAL)) == NULL) { EGLINTER(SetError)(EGL_BAD_ACCESS); return; } } void* dl = EGLINTER(global).dlES1; #define ACTION(name) do { \ *(void**)(&ptr->fp##name) = dlsym(dl, "gl" #name); \ if (ptr->fp##name == NULL) *(void**)(&ptr->fp##name) = (void*)(&(EGLINTER(NotBound))); \ } while (0) #include "glfunclist.inl" #undef ACTION } void EGLAPIENTRY EGLINTER(BindES2Fnptrs)(struct GlobalStruct* ptr) { if (EGLINTER(global).dlES2 == NULL) { if ((EGLINTER(global).dlES2 = dlopen(GL_ES2_SO_FILENAME, RTLD_NOW | RTLD_GLOBAL)) == NULL) { EGLINTER(SetError)(EGL_BAD_ACCESS); return; } } void* dl = EGLINTER(global).dlES2; #define ACTION(name) do { \ *(void**)(&ptr->fp##name) = dlsym(dl, "gl" #name); \ if (ptr->fp##name == NULL) *(void**)(&ptr->fp##name) = (void*)(&(EGLINTER(NotBound))); \ } while (0) #include "glfunclist.inl" #undef ACTION } #include "binding.inl" #endif