egl.cpp revision 7773c435bc5da8217433e1b242d3a6712a17b5f7
1221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams/* 23522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams ** Copyright 2007, The Android Open Source Project 3221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** 4221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** Licensed under the Apache License, Version 2.0 (the "License"); 5221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** you may not use this file except in compliance with the License. 6221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** You may obtain a copy of the License at 7221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** 8221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** http://www.apache.org/licenses/LICENSE-2.0 9221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** 10221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** Unless required by applicable law or agreed to in writing, software 11221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** distributed under the License is distributed on an "AS IS" BASIS, 12221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** See the License for the specific language governing permissions and 14221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ** limitations under the License. 15221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams */ 16221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 17f1e6d229636c35ad311995853a9cab52c723bed7Jason Sams#include <ctype.h> 18f1e6d229636c35ad311995853a9cab52c723bed7Jason Sams#include <stdlib.h> 19221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <string.h> 20221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 21221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <hardware/gralloc.h> 22221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <system/window.h> 23221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 24221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <EGL/egl.h> 25221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <EGL/eglext.h> 26221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <GLES/gl.h> 2769cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams#include <GLES/glext.h> 2869cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams 29221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <cutils/log.h> 30221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <cutils/atomic.h> 31221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <cutils/properties.h> 32221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <cutils/memory.h> 33221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 34221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <utils/CallStack.h> 35221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include <utils/String8.h> 36221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 3769cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams#include "egldefs.h" 38221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include "egl_impl.h" 39221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include "egl_tls.h" 40221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include "glestrace.h" 41221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include "hooks.h" 42221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include "Loader.h" 43221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 44221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include "egl_display.h" 45221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#include "egl_object.h" 46221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 47221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 48221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsnamespace android { 49221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 5069cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams 5169cccdf0659a193d6a75420ec745421fb5c436e6Jason Samsegl_connection_t gEGLImpl; 5269cccdf0659a193d6a75420ec745421fb5c436e6Jason Samsgl_hooks_t gHooks[2]; 53221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsgl_hooks_t gHooksNoContext; 54221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samspthread_key_t gGLWrapperKey = -1; 55221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 56221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 57221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 58221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#if EGL_TRACE 59221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 60221a4b17cda03916a0599628fcbb5f48605a0e5aJason SamsEGLAPI pthread_key_t gGLTraceKey = -1; 61221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 62221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 633522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams 64221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsint gEGLDebugLevel; 653522f40418fdf877f5a136475dbf75e57a3b7c77Jason Sams 66221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsstatic int sEGLTraceLevel; 67221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsstatic int sEGLApplicationTraceLevel; 68221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 69221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsextern gl_hooks_t gHooksTrace; 70221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 71221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsstatic inline void setGlTraceThreadSpecific(gl_hooks_t const *value) { 72221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams pthread_setspecific(gGLTraceKey, value); 73221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 74221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 7569cccdf0659a193d6a75420ec745421fb5c436e6Jason Samsgl_hooks_t const* getGLTraceThreadSpecific() { 76221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return static_cast<gl_hooks_t*>(pthread_getspecific(gGLTraceKey)); 77221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 78221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 79221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid initEglTraceLevel() { 80221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams char value[PROPERTY_VALUE_MAX]; 81221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams property_get("debug.egl.trace", value, "0"); 82221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams int propertyLevel = atoi(value); 83221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams int applicationLevel = sEGLApplicationTraceLevel; 84221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams sEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel; 85221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 86221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams property_get("debug.egl.debug_proc", value, ""); 87221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (strlen(value) == 0) 88221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return; 89221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 90221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams long pid = getpid(); 91221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams char procPath[128] = {}; 92221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams sprintf(procPath, "/proc/%ld/cmdline", pid); 93221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams FILE * file = fopen(procPath, "r"); 94221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (file) { 95221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams char cmdline[256] = {}; 96221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (fgets(cmdline, sizeof(cmdline) - 1, file)) { 97221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (!strncmp(value, cmdline, strlen(value))) { 98221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams // set EGL debug if the "debug.egl.debug_proc" property 99221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams // matches the prefix of this application's command line 100221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams gEGLDebugLevel = 1; 101221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 102221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 103221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams fclose(file); 104221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 105221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 106221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (gEGLDebugLevel > 0) { 107221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams GLTrace_start(); 108221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 109221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 110221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 111221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid setGLHooksThreadSpecific(gl_hooks_t const *value) { 112221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (sEGLTraceLevel > 0) { 113221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams setGlTraceThreadSpecific(value); 114221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams setGlThreadSpecific(&gHooksTrace); 115221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } else if (gEGLDebugLevel > 0 && value != &gHooksNoContext) { 116221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams setGlTraceThreadSpecific(value); 117221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams setGlThreadSpecific(GLTrace_getGLHooks()); 118221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } else { 119221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams setGlThreadSpecific(value); 120221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 121221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 122221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 123221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams/* 124221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * Global entry point to allow applications to modify their own trace level. 125221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams * The effective trace level is the max of this level and the value of debug.egl.trace. 126221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams */ 127221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsextern "C" 128221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid setGLTraceLevel(int level) { 129221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams sEGLApplicationTraceLevel = level; 130221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 131221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 132221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#else 133221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 13469cccdf0659a193d6a75420ec745421fb5c436e6Jason Samsvoid setGLHooksThreadSpecific(gl_hooks_t const *value) { 13569cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams setGlThreadSpecific(value); 136221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 137221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 138221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#endif 139221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 140221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams/*****************************************************************************/ 141221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 142221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsstatic int gl_no_context() { 143221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (egl_tls_t::logNoContextCall()) { 144221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ALOGE("call to OpenGL ES API with no current context " 145221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams "(logged once per thread)"); 146221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams char value[PROPERTY_VALUE_MAX]; 147221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams property_get("debug.egl.callstack", value, "0"); 148221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (atoi(value)) { 149221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams CallStack stack; 150221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams stack.update(); 151221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams stack.dump(); 152221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 153221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 154221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return 0; 155221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 156221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 157221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsstatic void early_egl_init(void) 158221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams{ 159221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#if !USE_FAST_TLS_KEY 160221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams pthread_key_create(&gGLWrapperKey, NULL); 161221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#endif 162221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#if EGL_TRACE 163221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams pthread_key_create(&gGLTraceKey, NULL); 164221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams initEglTraceLevel(); 165221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#endif 166221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams uint32_t addr = (uint32_t)((void*)gl_no_context); 167221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams android_memset32( 168221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams (uint32_t*)(void*)&gHooksNoContext, 169221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams addr, 170221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams sizeof(gHooksNoContext)); 171221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 172221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams setGLHooksThreadSpecific(&gHooksNoContext); 173221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 174221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 175221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsstatic pthread_once_t once_control = PTHREAD_ONCE_INIT; 176221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsstatic int sEarlyInitState = pthread_once(&once_control, &early_egl_init); 177221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 178221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 179221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 180221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsegl_display_t* validate_display(EGLDisplay dpy) { 181221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams egl_display_t * const dp = get_display(dpy); 182221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (!dp) 183221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return setError(EGL_BAD_DISPLAY, (egl_display_t*)NULL); 184221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (!dp->isReady()) 185221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return setError(EGL_NOT_INITIALIZED, (egl_display_t*)NULL); 186221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 187221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return dp; 188221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 189221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 190221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsegl_connection_t* validate_display_config(EGLDisplay dpy, EGLConfig, 191221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams egl_display_t const*& dp) { 192221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams dp = validate_display(dpy); 193221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (!dp) 194221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return (egl_connection_t*) NULL; 195221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 196221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams egl_connection_t* const cnx = &gEGLImpl; 197221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (cnx->dso == 0) { 198221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); 199221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 200221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return cnx; 201221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 202221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 203221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 204221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 205221a4b17cda03916a0599628fcbb5f48605a0e5aJason SamsEGLImageKHR egl_get_image_for_current_context(EGLImageKHR image) 206221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams{ 207221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams EGLContext context = egl_tls_t::getContext(); 208221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (context == EGL_NO_CONTEXT || image == EGL_NO_IMAGE_KHR) 209221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return EGL_NO_IMAGE_KHR; 210221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 211221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams egl_context_t const * const c = get_context(context); 212221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (c == NULL) // this should never happen, by construction 213221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return EGL_NO_IMAGE_KHR; 214221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 215221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams egl_display_t* display = egl_display_t::get(c->dpy); 216221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (display == NULL) // this should never happen, by construction 217221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return EGL_NO_IMAGE_KHR; 218221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 219221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ImageRef _i(display, image); 220221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (!_i.get()) 221221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return EGL_NO_IMAGE_KHR; 222221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 223221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams // here we don't validate the context because if it's been marked for 224221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams // termination, this call should still succeed since it's internal to 225221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams // EGL. 226221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 22769cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams egl_image_t const * const i = get_image(image); 22869cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams return i->image; 22969cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams} 230221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 231221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 232221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 233221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsconst GLubyte * egl_get_string_for_current_context(GLenum name) { 234221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams // NOTE: returning NULL here will fall-back to the default 235221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams // implementation. 236221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 237221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams EGLContext context = egl_tls_t::getContext(); 238221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (context == EGL_NO_CONTEXT) 239221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return NULL; 240221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 241221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams egl_context_t const * const c = get_context(context); 242221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (c == NULL) // this should never happen, by construction 243221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return NULL; 244221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 245221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (name != GL_EXTENSIONS) 246221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return NULL; 247221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 248221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return (const GLubyte *)c->gl_extensions.string(); 249221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 250221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 251221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 252221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 253221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// this mutex protects: 254221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// d->disp[] 255221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// egl_init_drivers_locked() 256221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// 257221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsstatic EGLBoolean egl_init_drivers_locked() { 258221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (sEarlyInitState) { 259221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams // initialized by static ctor. should be set here. 260221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return EGL_FALSE; 261221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 262221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 263221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams // get our driver loader 264221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams Loader& loader(Loader::getInstance()); 265221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 26669cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams // dynamically load our EGL implementation 26769cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams egl_connection_t* cnx = &gEGLImpl; 26869cccdf0659a193d6a75420ec745421fb5c436e6Jason Sams if (cnx->dso == 0) { 269221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams cnx->hooks[egl_connection_t::GLESv1_INDEX] = 270221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams &gHooks[egl_connection_t::GLESv1_INDEX]; 271221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams cnx->hooks[egl_connection_t::GLESv2_INDEX] = 272221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams &gHooks[egl_connection_t::GLESv2_INDEX]; 273221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams cnx->dso = loader.open(cnx); 274221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams } 275221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 276221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return cnx->dso ? EGL_TRUE : EGL_FALSE; 277221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 278221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 279221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsstatic pthread_mutex_t sInitDriverMutex = PTHREAD_MUTEX_INITIALIZER; 280221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 281221a4b17cda03916a0599628fcbb5f48605a0e5aJason SamsEGLBoolean egl_init_drivers() { 282221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams EGLBoolean res; 283221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams pthread_mutex_lock(&sInitDriverMutex); 284221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams res = egl_init_drivers_locked(); 285221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams pthread_mutex_unlock(&sInitDriverMutex); 286221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return res; 287221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 288221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 289221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid gl_unimplemented() { 290221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams ALOGE("called unimplemented OpenGL ES API"); 291221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 292221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 293221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid gl_noop() { 294221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 295221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 296221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 297221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 298221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#if USE_FAST_TLS_KEY 299221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 300221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// We have a dedicated TLS slot in bionic 301221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsstatic inline gl_hooks_t const * volatile * get_tls_hooks() { 302221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams volatile void *tls_base = __get_tls(); 303221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams gl_hooks_t const * volatile * tls_hooks = 304221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams reinterpret_cast<gl_hooks_t const * volatile *>(tls_base); 305221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return tls_hooks; 306221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 307221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 308221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid setGlThreadSpecific(gl_hooks_t const *value) { 309221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams gl_hooks_t const * volatile * tls_hooks = get_tls_hooks(); 310221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams tls_hooks[TLS_SLOT_OPENGL_API] = value; 311221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 312221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 313221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsgl_hooks_t const* getGlThreadSpecific() { 314221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams gl_hooks_t const * volatile * tls_hooks = get_tls_hooks(); 315221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams gl_hooks_t const* hooks = tls_hooks[TLS_SLOT_OPENGL_API]; 316221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (hooks) return hooks; 317221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return &gHooksNoContext; 318221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 319221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 320221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#else 321221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 322221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsvoid setGlThreadSpecific(gl_hooks_t const *value) { 323221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams pthread_setspecific(gGLWrapperKey, value); 324221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 325221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 326221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samsgl_hooks_t const* getGlThreadSpecific() { 327221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams gl_hooks_t const* hooks = static_cast<gl_hooks_t*>(pthread_getspecific(gGLWrapperKey)); 328221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams if (hooks) return hooks; 329221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams return &gHooksNoContext; 330221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams} 331221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 332221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#endif 333221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 334221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 335221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// GL / EGL hooks 336221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 337221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 338221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#undef GL_ENTRY 339221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#undef EGL_ENTRY 340221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#define GL_ENTRY(_r, _api, ...) #_api, 341221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#define EGL_ENTRY(_r, _api, ...) #_api, 342221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 343221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samschar const * const gl_names[] = { 344221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams #include "entries.in" 345221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams NULL 346221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}; 347221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 348221a4b17cda03916a0599628fcbb5f48605a0e5aJason Samschar const * const egl_names[] = { 349221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams #include "egl_entries.in" 350221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams NULL 351221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}; 352221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 353221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#undef GL_ENTRY 354221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams#undef EGL_ENTRY 355221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 356221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 357221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 358221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams}; // namespace android 359221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams// ---------------------------------------------------------------------------- 360221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams 361221a4b17cda03916a0599628fcbb5f48605a0e5aJason Sams