Home | History | Annotate | Download | only in EGL
      1 /*
      2 * Copyright (C) 2011 The Android Open Source Project
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 #ifdef _WIN32
     17 #undef EGLAPI
     18 #define EGLAPI __declspec(dllexport)
     19 #endif
     20 
     21 #include <EGL/egl.h>
     22 #include <sys/types.h>
     23 #include <sys/stat.h>
     24 #include <stdio.h>
     25 #include "ThreadInfo.h"
     26 #include <GLcommon/TranslatorIfaces.h>
     27 #include <OpenglOsUtils/osDynLibrary.h>
     28 
     29 #include "EglWindowSurface.h"
     30 #include "EglPbufferSurface.h"
     31 #include "EglPixmapSurface.h"
     32 #include "EglGlobalInfo.h"
     33 #include "EglThreadInfo.h"
     34 #include "EglValidate.h"
     35 #include "EglDisplay.h"
     36 #include "EglContext.h"
     37 #include "EglConfig.h"
     38 #include "EglOsApi.h"
     39 #include "ClientAPIExts.h"
     40 
     41 #define MAJOR          1
     42 #define MINOR          4
     43 
     44 //declarations
     45 
     46 EglImage *attachEGLImage(unsigned int imageId);
     47 void detachEGLImage(unsigned int imageId);
     48 GLEScontext* getGLESContext();
     49 
     50 #define tls_thread  EglThreadInfo::get()
     51 
     52 EglGlobalInfo* g_eglInfo = NULL;
     53 android::Mutex  s_eglLock;
     54 
     55 void initGlobalInfo()
     56 {
     57     android::Mutex::Autolock mutex(s_eglLock);
     58     if (!g_eglInfo) {
     59         g_eglInfo = EglGlobalInfo::getInstance();
     60     }
     61 }
     62 
     63 static EGLiface            s_eglIface = {
     64     getGLESContext    : getGLESContext,
     65     eglAttachEGLImage:attachEGLImage,
     66     eglDetachEGLImage:detachEGLImage
     67 };
     68 
     69 /*****************************************  supported extentions  ***********************************************************************/
     70 
     71 //extentions
     72 #define EGL_EXTENTIONS 2
     73 
     74 //decleration
     75 EGLImageKHR eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
     76 EGLBoolean eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image);
     77 
     78 // extentions descriptors
     79 static ExtentionDescriptor s_eglExtentions[] = {
     80                                                    {"eglCreateImageKHR" ,(__eglMustCastToProperFunctionPointerType)eglCreateImageKHR},
     81                                                    {"eglDestroyImageKHR",(__eglMustCastToProperFunctionPointerType)eglDestroyImageKHR}
     82                                                };
     83 static int s_eglExtentionsSize = sizeof(s_eglExtentions) /
     84                                  sizeof(ExtentionDescriptor);
     85 
     86 /****************************************************************************************************************************************/
     87 //macros for accessing global egl info & tls objects
     88 
     89 #define CURRENT_THREAD() do {} while (0);
     90 
     91 #define RETURN_ERROR(ret,err)                                \
     92         CURRENT_THREAD()                                     \
     93         if(tls_thread->getError() == EGL_SUCCESS) {          \
     94           tls_thread->setError(err);                         \
     95         }                                                    \
     96         return ret;
     97 
     98 #define VALIDATE_DISPLAY_RETURN(EGLDisplay,ret)              \
     99         EglDisplay* dpy = g_eglInfo->getDisplay(EGLDisplay); \
    100         if(!dpy){                                            \
    101             RETURN_ERROR(ret,EGL_BAD_DISPLAY);               \
    102         }                                                    \
    103         if(!dpy->isInitialize()) {                           \
    104             RETURN_ERROR(ret,EGL_NOT_INITIALIZED);           \
    105         }
    106 
    107 #define VALIDATE_CONFIG_RETURN(EGLConfig,ret)                \
    108         EglConfig* cfg = dpy->getConfig(EGLConfig);          \
    109         if(!cfg) {                                           \
    110             RETURN_ERROR(ret,EGL_BAD_CONFIG);                \
    111         }
    112 
    113 #define VALIDATE_SURFACE_RETURN(EGLSurface,ret,varName)      \
    114         SurfacePtr varName = dpy->getSurface(EGLSurface);    \
    115         if(!varName.Ptr()) {                                 \
    116             RETURN_ERROR(ret,EGL_BAD_SURFACE);               \
    117         }
    118 
    119 #define VALIDATE_CONTEXT_RETURN(EGLContext,ret)              \
    120         ContextPtr ctx = dpy->getContext(EGLContext);        \
    121         if(!ctx.Ptr()) {                                     \
    122             RETURN_ERROR(ret,EGL_BAD_CONTEXT);               \
    123         }
    124 
    125 
    126 #define VALIDATE_DISPLAY(EGLDisplay) \
    127         VALIDATE_DISPLAY_RETURN(EGLDisplay,EGL_FALSE)
    128 
    129 #define VALIDATE_CONFIG(EGLConfig)   \
    130         VALIDATE_CONFIG_RETURN(EGLConfig,EGL_FALSE)
    131 
    132 #define VALIDATE_SURFACE(EGLSurface,varName) \
    133         VALIDATE_SURFACE_RETURN(EGLSurface,EGL_FALSE,varName)
    134 
    135 #define VALIDATE_CONTEXT(EGLContext) \
    136         VALIDATE_CONTEXT_RETURN(EGLContext,EGL_FALSE)
    137 
    138 
    139 GLEScontext* getGLESContext()
    140 {
    141     ThreadInfo* thread  = getThreadInfo();
    142     return thread->glesContext;
    143 }
    144 
    145 EGLAPI EGLint EGLAPIENTRY eglGetError(void) {
    146     CURRENT_THREAD();
    147     EGLint err = tls_thread->getError();
    148     tls_thread->setError(EGL_SUCCESS);
    149     return err;
    150 }
    151 
    152 EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id) {
    153     EglDisplay* dpy = NULL;
    154     EGLNativeInternalDisplayType internalDisplay = NULL;
    155 
    156     initGlobalInfo();
    157 
    158     if ((dpy = g_eglInfo->getDisplay(display_id))) {
    159         return dpy;
    160     } else {
    161 
    162         if( display_id == EGL_DEFAULT_DISPLAY) {
    163             internalDisplay = g_eglInfo->getDefaultNativeDisplay();
    164         } else {
    165             internalDisplay = g_eglInfo->generateInternalDisplay(display_id);
    166         }
    167 
    168         dpy = g_eglInfo->addDisplay(display_id,internalDisplay);
    169         if(dpy) return dpy;
    170         return EGL_NO_DISPLAY;
    171     }
    172 }
    173 
    174 
    175 #define TRANSLATOR_GETIFACE_NAME "__translator_getIfaces"
    176 
    177 static __translator_getGLESIfaceFunc loadIfaces(const char* libName){
    178     osUtils::dynLibrary* libGLES = osUtils::dynLibrary::open(libName);
    179 
    180     if(!libGLES) return NULL;
    181     __translator_getGLESIfaceFunc func =  (__translator_getGLESIfaceFunc)libGLES->findSymbol(TRANSLATOR_GETIFACE_NAME);
    182     if(!func) return NULL;
    183     return func;
    184 }
    185 
    186 #ifdef _WIN32
    187 #define LIB_GLES_CM_NAME "libGLES_CM_translator"
    188 #define LIB_GLES_V2_NAME "libGLES_V2_translator"
    189 #elif __linux__
    190 #define LIB_GLES_CM_NAME "libGLES_CM_translator.so"
    191 #define LIB_GLES_V2_NAME "libGLES_V2_translator.so"
    192 #elif __APPLE__
    193 #define LIB_GLES_CM_NAME "libGLES_CM_translator.dylib"
    194 #define LIB_GLES_V2_NAME "libGLES_V2_translator.dylib"
    195 #endif
    196 
    197 EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay display, EGLint *major, EGLint *minor) {
    198 
    199     initGlobalInfo();
    200 
    201     EglDisplay* dpy = g_eglInfo->getDisplay(display);
    202     if(!dpy) {
    203          RETURN_ERROR(EGL_FALSE,EGL_BAD_DISPLAY);
    204     }
    205 
    206     if(major) *major = MAJOR;
    207     if(minor) *minor = MINOR;
    208 
    209     __translator_getGLESIfaceFunc func  = NULL;
    210     int renderableType = EGL_OPENGL_ES_BIT;
    211 
    212     if(!g_eglInfo->getIface(GLES_1_1)) {
    213         func  = loadIfaces(LIB_GLES_CM_NAME);
    214         if(func){
    215             g_eglInfo->setIface(func(&s_eglIface),GLES_1_1);
    216         } else {
    217            fprintf(stderr,"could not find ifaces for GLES CM 1.1\n");
    218            return EGL_FALSE;
    219         }
    220     }
    221     if(!g_eglInfo->getIface(GLES_2_0)) {
    222         func  = loadIfaces(LIB_GLES_V2_NAME);
    223         if(func){
    224             renderableType |= EGL_OPENGL_ES2_BIT;
    225             g_eglInfo->setIface(func(&s_eglIface),GLES_2_0);
    226         } else {
    227            fprintf(stderr,"could not find ifaces for GLES 2.0\n");
    228         }
    229     }
    230     dpy->initialize(renderableType);
    231     return EGL_TRUE;
    232 }
    233 
    234 EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay display) {
    235     VALIDATE_DISPLAY(display);
    236     dpy->terminate();
    237     return EGL_TRUE;
    238 }
    239 
    240 EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay display, EGLint name) {
    241     VALIDATE_DISPLAY(display);
    242     static const char* vendor     = "Google";
    243     static const char* version    = "1.4";
    244     static const char* extensions = "EGL_KHR_image_base EGL_KHR_gl_texture_2D_image";
    245     if(!EglValidate::stringName(name)) {
    246         RETURN_ERROR(NULL,EGL_BAD_PARAMETER);
    247     }
    248     switch(name) {
    249     case EGL_VENDOR:
    250         return vendor;
    251     case EGL_VERSION:
    252         return version;
    253     case EGL_EXTENSIONS:
    254         return extensions;
    255     }
    256     return NULL;
    257 }
    258 
    259 EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay display, EGLConfig *configs,
    260              EGLint config_size, EGLint *num_config) {
    261     VALIDATE_DISPLAY(display);
    262     if(!num_config) {
    263         RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
    264     }
    265 
    266     if(configs == NULL) {
    267         *num_config = dpy->nConfigs();
    268     } else {
    269         *num_config = dpy->getConfigs(configs,config_size);
    270     }
    271 
    272     return EGL_TRUE;
    273 }
    274 
    275 EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay display, const EGLint *attrib_list,
    276                EGLConfig *configs, EGLint config_size,
    277                EGLint *num_config) {
    278     VALIDATE_DISPLAY(display);
    279     if(!num_config) {
    280          RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
    281     }
    282 
    283         //selection defaults
    284         EGLint      surface_type       = EGL_WINDOW_BIT;
    285         EGLint      renderable_type    = EGL_OPENGL_ES_BIT;
    286         EGLBoolean  bind_to_tex_rgb    = EGL_DONT_CARE;
    287         EGLBoolean  bind_to_tex_rgba   = EGL_DONT_CARE;
    288         EGLenum     caveat             = EGL_DONT_CARE;
    289         EGLint      config_id          = EGL_DONT_CARE;
    290         EGLBoolean  native_renderable  = EGL_DONT_CARE;
    291         EGLint      native_visual_type = EGL_DONT_CARE;
    292         EGLint      max_swap_interval  = EGL_DONT_CARE;
    293         EGLint      min_swap_interval  = EGL_DONT_CARE;
    294         EGLint      trans_red_val      = EGL_DONT_CARE;
    295         EGLint      trans_green_val    = EGL_DONT_CARE;
    296         EGLint      trans_blue_val     = EGL_DONT_CARE;
    297         EGLenum     transparent_type   = EGL_NONE;
    298         EGLint      buffer_size        = 0;
    299         EGLint      red_size           = 0;
    300         EGLint      green_size         = 0;
    301         EGLint      blue_size          = 0;
    302         EGLint      alpha_size         = 0;
    303         EGLint      depth_size         = 0;
    304         EGLint      frame_buffer_level = 0;
    305         EGLint      sample_buffers_num = 0;
    306         EGLint      samples_per_pixel  = 0;
    307         EGLint      stencil_size       = 0;
    308 
    309     if(!EglValidate::noAttribs(attrib_list)) { //there are attribs
    310         int i = 0 ;
    311         bool hasConfigId = false;
    312         while(attrib_list[i] != EGL_NONE && !hasConfigId) {
    313             switch(attrib_list[i]) {
    314             case EGL_MAX_PBUFFER_WIDTH:
    315             case EGL_MAX_PBUFFER_HEIGHT:
    316             case EGL_MAX_PBUFFER_PIXELS:
    317             case EGL_NATIVE_VISUAL_ID:
    318                 break; //we dont care from those selection crateria
    319             case EGL_LEVEL:
    320                 if(attrib_list[i+1] == EGL_DONT_CARE) {
    321                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    322                 }
    323                 frame_buffer_level = attrib_list[i+1];
    324                 break;
    325             case EGL_BUFFER_SIZE:
    326                 if(attrib_list[i+1] < 0) {
    327                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    328                 }
    329                 buffer_size = attrib_list[i+1];
    330                 break;
    331             case EGL_RED_SIZE:
    332                 if(attrib_list[i+1] < 0) {
    333                      RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    334                 }
    335                 red_size = attrib_list[i+1];
    336                 break;
    337             case EGL_GREEN_SIZE:
    338                 if(attrib_list[i+1] < 0) {
    339                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    340                 }
    341                 green_size = attrib_list[i+1];
    342                 break;
    343             case EGL_BLUE_SIZE:
    344                 if(attrib_list[i+1] < 0) {
    345                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    346                 }
    347                 blue_size = attrib_list[i+1];
    348                 break;
    349             case EGL_ALPHA_SIZE:
    350                 if(attrib_list[i+1] < 0) {
    351                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    352                 }
    353                 alpha_size = attrib_list[i+1];
    354                 break;
    355             case EGL_BIND_TO_TEXTURE_RGB:
    356                 bind_to_tex_rgb = attrib_list[i+1];
    357                 break;
    358             case EGL_BIND_TO_TEXTURE_RGBA:
    359                 bind_to_tex_rgba = attrib_list[i+1];
    360                 break;
    361             case EGL_CONFIG_CAVEAT:
    362                 if(attrib_list[i+1] != EGL_NONE && attrib_list[i+1] != EGL_SLOW_CONFIG && attrib_list[i+1] != EGL_NON_CONFORMANT_CONFIG) {
    363                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    364                 }
    365                 caveat = attrib_list[i+1];
    366                 break;
    367             case EGL_CONFIG_ID:
    368                 if(attrib_list[i+1] < 0) {
    369                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    370                 }
    371                 config_id = attrib_list[i+1];
    372                 hasConfigId = true;
    373                 break;
    374             case EGL_DEPTH_SIZE:
    375                 if(attrib_list[i+1] < 0) {
    376                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    377                 }
    378                 depth_size = attrib_list[i+1];
    379                 break;
    380             case EGL_MAX_SWAP_INTERVAL:
    381                 if(attrib_list[i+1] < 0) {
    382                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    383                 }
    384                 max_swap_interval = attrib_list[i+1];
    385                 break;
    386             case EGL_MIN_SWAP_INTERVAL:
    387                 if(attrib_list[i+1] < 0) {
    388                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    389                 }
    390                 min_swap_interval = attrib_list[i+1];
    391                 break;
    392             case EGL_NATIVE_RENDERABLE:
    393                 native_renderable = attrib_list[i+1];
    394                 break;
    395             case EGL_RENDERABLE_TYPE:
    396                 renderable_type = attrib_list[i+1];
    397                 break;
    398             case EGL_NATIVE_VISUAL_TYPE:
    399                 native_visual_type = attrib_list[i+1];
    400                 break;
    401                 if(attrib_list[i+1] < 0 || attrib_list[i+1] > 1 ) {
    402                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    403                 }
    404             case EGL_SAMPLE_BUFFERS:
    405                 sample_buffers_num = attrib_list[i+1];
    406                 break;
    407                 if(attrib_list[i+1] < 0) {
    408                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    409                 }
    410             case EGL_SAMPLES:
    411                 if(attrib_list[i+1] < 0) {
    412                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    413                 }
    414                 samples_per_pixel = attrib_list[i+1];
    415                 break;
    416             case EGL_STENCIL_SIZE:
    417                 if(attrib_list[i+1] < 0) {
    418                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    419                 }
    420                 stencil_size = attrib_list[i+1];
    421                 break;
    422             case EGL_SURFACE_TYPE:
    423                 surface_type = attrib_list[i+1];
    424                 break;
    425             case EGL_TRANSPARENT_TYPE:
    426                 if(attrib_list[i+1] != EGL_NONE && attrib_list[i+1] != EGL_TRANSPARENT_RGB ) {
    427                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    428                 }
    429                 transparent_type = attrib_list[i+1];
    430                 break;
    431             case EGL_TRANSPARENT_RED_VALUE:
    432                 trans_red_val = attrib_list[i+1];
    433                 break;
    434             case EGL_TRANSPARENT_GREEN_VALUE:
    435                 trans_green_val = attrib_list[i+1];
    436                 break;
    437             case EGL_TRANSPARENT_BLUE_VALUE:
    438                 trans_blue_val = attrib_list[i+1];
    439                 break;
    440             default:
    441                 RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    442             }
    443             i+=2;
    444         }
    445         if(hasConfigId) {
    446             EglConfig* pConfig = dpy->getConfig(config_id);
    447             if(pConfig) {
    448                 if(configs) {
    449                     configs[0]  = static_cast<EGLConfig>(pConfig);
    450                 }
    451                 *num_config = 1;
    452                 return EGL_TRUE;
    453             } else {
    454                 RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    455             }
    456         }
    457     }
    458     EGLNativePixelFormatType tmpfrmt = PIXEL_FORMAT_INITIALIZER;
    459     EglConfig dummy(red_size,green_size,blue_size,alpha_size,caveat,config_id,depth_size,
    460                     frame_buffer_level,0,0,0,native_renderable,renderable_type,0,native_visual_type,
    461                     samples_per_pixel,stencil_size,surface_type,transparent_type,
    462                     trans_red_val,trans_green_val,trans_blue_val,tmpfrmt);
    463 
    464     *num_config = dpy->chooseConfigs(dummy,configs,config_size);
    465 
    466 
    467     return EGL_TRUE;
    468 }
    469 
    470 EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay display, EGLConfig config,
    471                   EGLint attribute, EGLint *value) {
    472     VALIDATE_DISPLAY(display);
    473     VALIDATE_CONFIG(config);
    474     if(!EglValidate::confAttrib(attribute)){
    475          RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    476     }
    477     return cfg->getConfAttrib(attribute,value)? EGL_TRUE:EGL_FALSE;
    478 }
    479 
    480 EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay display, EGLConfig config,
    481                   EGLNativeWindowType win,
    482                   const EGLint *attrib_list) {
    483     VALIDATE_DISPLAY_RETURN(display,EGL_NO_SURFACE);
    484     VALIDATE_CONFIG_RETURN(config,EGL_NO_SURFACE);
    485 
    486     if(!(cfg->surfaceType() & EGL_WINDOW_BIT)) {
    487         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_MATCH);
    488     }
    489     if(!EglOS::validNativeWin(dpy->nativeType(),win)) {
    490         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_NATIVE_WINDOW);
    491     }
    492     if(!EglValidate::noAttribs(attrib_list)) {
    493         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ATTRIBUTE);
    494     }
    495     if(EglWindowSurface::alreadyAssociatedWithConfig(win)) {
    496         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
    497     }
    498 
    499     unsigned int width,height;
    500     if(!EglOS::checkWindowPixelFormatMatch(dpy->nativeType(),win,cfg,&width,&height)) {
    501         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
    502     }
    503     SurfacePtr wSurface(new EglWindowSurface(dpy, win,cfg,width,height));
    504     if(!wSurface.Ptr()) {
    505         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
    506     }
    507     return dpy->addSurface(wSurface);
    508 }
    509 
    510 EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay display, EGLConfig config,
    511                    const EGLint *attrib_list) {
    512     VALIDATE_DISPLAY_RETURN(display,EGL_NO_SURFACE);
    513     VALIDATE_CONFIG_RETURN(config,EGL_NO_SURFACE);
    514     if(!(cfg->surfaceType() & EGL_PBUFFER_BIT)) {
    515         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_MATCH);
    516     }
    517 
    518 
    519     SurfacePtr pbSurface(new EglPbufferSurface(dpy,cfg));
    520     if(!pbSurface.Ptr()) {
    521         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
    522     }
    523 
    524     if(!EglValidate::noAttribs(attrib_list)) { //there are attribs
    525         int i = 0 ;
    526         while(attrib_list[i] != EGL_NONE) {
    527             if(!pbSurface->setAttrib(attrib_list[i],attrib_list[i+1])) {
    528                 RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ATTRIBUTE);
    529             }
    530             i+=2;
    531         }
    532     }
    533 
    534     EGLint width,height,largest,texTarget,texFormat;
    535     EglPbufferSurface* tmpPbSurfacePtr = static_cast<EglPbufferSurface*>(pbSurface.Ptr());
    536     tmpPbSurfacePtr->getDim(&width,&height,&largest);
    537     tmpPbSurfacePtr->getTexInfo(&texTarget,&texFormat);
    538 
    539     if(!EglValidate::pbufferAttribs(width,height,texFormat == EGL_NO_TEXTURE,texTarget == EGL_NO_TEXTURE)) {
    540         //TODO: RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_VALUE); dont have bad_value
    541         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ATTRIBUTE);
    542     }
    543 
    544     EGLNativeSurfaceType pb = EglOS::createPbufferSurface(dpy->nativeType(),cfg,tmpPbSurfacePtr);
    545     if(!pb) {
    546         //TODO: RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_VALUE); dont have bad value
    547         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ATTRIBUTE);
    548     }
    549 
    550     tmpPbSurfacePtr->setNativePbuffer(pb);
    551     return dpy->addSurface(pbSurface);
    552 }
    553 
    554 EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay display, EGLConfig config,
    555                   EGLNativePixmapType pixmap,
    556                   const EGLint *attrib_list) {
    557     VALIDATE_DISPLAY_RETURN(display,EGL_NO_SURFACE);
    558     VALIDATE_CONFIG_RETURN(config,EGL_NO_SURFACE);
    559     if(!(cfg->surfaceType() & EGL_PIXMAP_BIT)) {
    560         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_MATCH);
    561     }
    562     if(!EglValidate::noAttribs(attrib_list)) {
    563         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ATTRIBUTE);
    564     }
    565     if(EglPixmapSurface::alreadyAssociatedWithConfig(pixmap)) {
    566         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
    567     }
    568 
    569     unsigned int width,height;
    570     if(!EglOS::checkPixmapPixelFormatMatch(dpy->nativeType(),pixmap,cfg,&width,&height)) {
    571         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
    572     }
    573     SurfacePtr pixSurface(new EglPixmapSurface(dpy, pixmap,cfg));
    574     if(!pixSurface.Ptr()) {
    575         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
    576     }
    577 
    578     return dpy->addSurface(pixSurface);
    579 }
    580 
    581 EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay display, EGLSurface surface) {
    582     VALIDATE_DISPLAY(display);
    583     SurfacePtr srfc = dpy->getSurface(surface);
    584     if(!srfc.Ptr()) {
    585         RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
    586     }
    587 
    588     dpy->removeSurface(surface);
    589     return EGL_TRUE;
    590 }
    591 
    592 EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay display, EGLSurface surface,
    593                EGLint attribute, EGLint *value) {
    594    VALIDATE_DISPLAY(display);
    595    VALIDATE_SURFACE(surface,srfc);
    596 
    597    if(!srfc->getAttrib(attribute,value)) {
    598        RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    599    }
    600    return EGL_TRUE;
    601 }
    602 
    603 EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay display, EGLSurface surface,
    604                 EGLint attribute, EGLint value) {
    605    VALIDATE_DISPLAY(display);
    606    VALIDATE_SURFACE(surface,srfc);
    607    if(!srfc->setAttrib(attribute,value)) {
    608        RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    609    }
    610    return EGL_TRUE;
    611 }
    612 
    613 EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay display, EGLConfig config,
    614                 EGLContext share_context,
    615                 const EGLint *attrib_list) {
    616     VALIDATE_DISPLAY_RETURN(display,EGL_NO_CONTEXT);
    617     VALIDATE_CONFIG_RETURN(config,EGL_NO_CONTEXT);
    618 
    619     GLESVersion version = GLES_1_1;
    620     if(!EglValidate::noAttribs(attrib_list)) {
    621         int i = 0;
    622         while(attrib_list[i] != EGL_NONE) {
    623             switch(attrib_list[i]) {
    624             case EGL_CONTEXT_CLIENT_VERSION:
    625                 if(attrib_list[i+1] == 2) {
    626                     version = GLES_2_0;
    627                 } else {
    628                     version = GLES_1_1;
    629                 }
    630                 break;
    631             default:
    632                 RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE);
    633             }
    634             i+=2;
    635         }
    636     }
    637     GLESiface* iface = g_eglInfo->getIface(version);
    638     GLEScontext* glesCtx = NULL;
    639     if(iface) {
    640         glesCtx = iface->createGLESContext();
    641     } else { // there is no interface for this gles version
    642                 RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE);
    643     }
    644 
    645     ContextPtr sharedCtxPtr;
    646     EGLNativeContextType nativeShared = NULL;
    647     if(share_context != EGL_NO_CONTEXT) {
    648         sharedCtxPtr = dpy->getContext(share_context);
    649         if(!sharedCtxPtr.Ptr()) {
    650             RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_CONTEXT);
    651         }
    652         nativeShared = sharedCtxPtr->nativeType();
    653     }
    654 
    655     EGLNativeContextType globalSharedContext = dpy->getGlobalSharedContext();
    656     EGLNativeContextType nativeContext = EglOS::createContext(dpy->nativeType(),cfg,globalSharedContext);
    657 
    658     if(nativeContext) {
    659         ContextPtr ctx(new EglContext(dpy, nativeContext,sharedCtxPtr,cfg,glesCtx,version,dpy->getManager(version)));
    660         return dpy->addContext(ctx);
    661     } else {
    662         iface->deleteGLESContext(glesCtx);
    663     }
    664 
    665 return EGL_NO_CONTEXT;
    666 }
    667 
    668 EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay display, EGLContext context) {
    669     VALIDATE_DISPLAY(display);
    670     VALIDATE_CONTEXT(context);
    671 
    672     dpy->removeContext(context);
    673     return EGL_TRUE;
    674 }
    675 
    676 EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display, EGLSurface draw,
    677               EGLSurface read, EGLContext context) {
    678     VALIDATE_DISPLAY(display);
    679 
    680 
    681     bool releaseContext = EglValidate::releaseContext(context,read,draw);
    682     if(!releaseContext && EglValidate::badContextMatch(context,read,draw)) {
    683         RETURN_ERROR(EGL_FALSE,EGL_BAD_MATCH);
    684     }
    685 
    686     ThreadInfo* thread     = getThreadInfo();
    687     ContextPtr  prevCtx    = thread->eglContext;
    688 
    689     if(releaseContext) { //releasing current context
    690        if(prevCtx.Ptr()) {
    691            g_eglInfo->getIface(prevCtx->version())->flush();
    692            if(!EglOS::makeCurrent(dpy->nativeType(),NULL,NULL,NULL)) {
    693                RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS);
    694            }
    695            thread->updateInfo(ContextPtr(NULL),dpy,NULL,ShareGroupPtr(NULL),dpy->getManager(prevCtx->version()));
    696        }
    697     } else { //assining new context
    698         VALIDATE_CONTEXT(context);
    699         VALIDATE_SURFACE(draw,newDrawSrfc);
    700         VALIDATE_SURFACE(read,newReadSrfc);
    701 
    702         EglSurface* newDrawPtr = newDrawSrfc.Ptr();
    703         EglSurface* newReadPtr = newReadSrfc.Ptr();
    704         ContextPtr  newCtx     = ctx;
    705 
    706         if (newCtx.Ptr() && prevCtx.Ptr()) {
    707             if (newCtx.Ptr() == prevCtx.Ptr()) {
    708                 if (newDrawPtr == prevCtx->draw().Ptr() &&
    709                     newReadPtr == prevCtx->read().Ptr()) {
    710                     // nothing to do
    711                     return EGL_TRUE;
    712                 }
    713             }
    714             else {
    715                 // Make sure previous context is detached from surfaces
    716                 releaseContext = true;
    717             }
    718         }
    719 
    720         //surfaces compitability check
    721         if(!((*ctx->getConfig()).compitableWith((*newDrawPtr->getConfig()))) ||
    722            !((*ctx->getConfig()).compitableWith((*newReadPtr->getConfig())))) {
    723             RETURN_ERROR(EGL_FALSE,EGL_BAD_MATCH);
    724         }
    725 
    726          EGLNativeInternalDisplayType nativeDisplay = dpy->nativeType();
    727          EGLNativeSurfaceType nativeRead = newReadPtr->native();
    728          EGLNativeSurfaceType nativeDraw = newDrawPtr->native();
    729         //checking native window validity
    730         if(newReadPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(nativeDisplay,nativeRead)) {
    731             RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW);
    732         }
    733         if(newDrawPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(nativeDisplay,nativeDraw)) {
    734             RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW);
    735         }
    736 
    737         //checking native pixmap validity
    738         if(newReadPtr->type() == EglSurface::PIXMAP && !EglOS::validNativePixmap(nativeDisplay,nativeRead)) {
    739             RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP);
    740         }
    741         if(newDrawPtr->type() == EglSurface::PIXMAP && !EglOS::validNativePixmap(nativeDisplay,nativeDraw)) {
    742             RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP);
    743         }
    744         if(prevCtx.Ptr()) {
    745             g_eglInfo->getIface(prevCtx->version())->flush();
    746         }
    747         if(!EglOS::makeCurrent(dpy->nativeType(),newReadPtr,newDrawPtr,newCtx->nativeType())) {
    748                RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS);
    749         }
    750         //TODO: handle the following errors
    751         // EGL_BAD_CURRENT_SURFACE , EGL_CONTEXT_LOST  , EGL_BAD_ACCESS
    752 
    753         thread->updateInfo(newCtx,dpy,newCtx->getGlesContext(),newCtx->getShareGroup(),dpy->getManager(newCtx->version()));
    754         newCtx->setSurfaces(newReadSrfc,newDrawSrfc);
    755         g_eglInfo->getIface(newCtx->version())->initContext(newCtx->getGlesContext(),newCtx->getShareGroup());
    756 
    757         // Initialize the GLES extension function table used in
    758         // eglGetProcAddress for the context's GLES version if not
    759         // yet initialized. We initialize it here to make sure we call the
    760         // GLES getProcAddress after when a context is bound.
    761         g_eglInfo->initClientExtFuncTable(newCtx->version());
    762     }
    763 
    764     // release previous context surface binding
    765     if(prevCtx.Ptr() && releaseContext) {
    766         prevCtx->setSurfaces(SurfacePtr(NULL),SurfacePtr(NULL));
    767     }
    768 
    769     return EGL_TRUE;
    770 }
    771 
    772 EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay display, EGLContext context,
    773                EGLint attribute, EGLint *value) {
    774     VALIDATE_DISPLAY(display);
    775     VALIDATE_CONTEXT(context);
    776 
    777     if(!ctx->getAttrib(attribute,value)){
    778         RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
    779     }
    780     return EGL_TRUE;
    781 }
    782 
    783 EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay display, EGLSurface surface) {
    784     VALIDATE_DISPLAY(display);
    785     VALIDATE_SURFACE(surface,Srfc);
    786     ThreadInfo* thread        = getThreadInfo();
    787     ContextPtr currentCtx    = thread->eglContext;
    788 
    789 
    790     //if surface not window return
    791     if(Srfc->type() != EglSurface::WINDOW){
    792         RETURN_ERROR(EGL_TRUE,EGL_SUCCESS);
    793     }
    794 
    795     if(!currentCtx.Ptr() || !currentCtx->usingSurface(Srfc) || !EglOS::validNativeWin(dpy->nativeType(),Srfc.Ptr()->native())) {
    796         RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
    797     }
    798 
    799     EglOS::swapBuffers(dpy->nativeType(),Srfc->native());
    800     return EGL_TRUE;
    801 }
    802 
    803 EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay display, EGLint interval) {
    804     VALIDATE_DISPLAY(display);
    805     ThreadInfo* thread  = getThreadInfo();
    806     ContextPtr currCtx = thread->eglContext;
    807     if(currCtx.Ptr()) {
    808         if(!currCtx->read().Ptr() || !currCtx->draw().Ptr() || currCtx->draw()->type()!=EglSurface::WINDOW) {
    809             RETURN_ERROR(EGL_FALSE,EGL_BAD_CURRENT_SURFACE);
    810         }
    811         EglOS::swapInterval(dpy->nativeType(),currCtx->draw()->native(),interval);
    812     } else {
    813             RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
    814     }
    815     return EGL_TRUE;
    816 }
    817 
    818 
    819 EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void) {
    820     ThreadInfo* thread = getThreadInfo();
    821     EglDisplay* dpy    = static_cast<EglDisplay*>(thread->eglDisplay);
    822     ContextPtr  ctx    = thread->eglContext;
    823     if(dpy && ctx.Ptr()){
    824         // This double check is required because a context might still be current after it is destroyed - in which case
    825         // its handle should be invalid, that is EGL_NO_CONTEXT should be returned even though the context is current
    826         EGLContext c = (EGLContext)ctx->getHndl();
    827         if(dpy->getContext(c).Ptr())
    828         {
    829             return c;
    830         }
    831     }
    832     return EGL_NO_CONTEXT;
    833 }
    834 
    835 EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw) {
    836     if(!EglValidate::surfaceTarget(readdraw)) return EGL_NO_SURFACE;
    837 
    838     ThreadInfo* thread = getThreadInfo();
    839     EglDisplay* dpy    = static_cast<EglDisplay*>(thread->eglDisplay);
    840     ContextPtr  ctx    = thread->eglContext;
    841 
    842     if(dpy && ctx.Ptr()) {
    843         SurfacePtr surface = readdraw == EGL_READ ? ctx->read() : ctx->draw();
    844         if(surface.Ptr())
    845         {
    846             // This double check is required because a surface might still be
    847             // current after it is destroyed - in which case its handle should
    848             // be invalid, that is EGL_NO_SURFACE should be returned even
    849             // though the surface is current.
    850             EGLSurface s = (EGLSurface)surface->getHndl();
    851             surface = dpy->getSurface(s);
    852             if(surface.Ptr())
    853             {
    854                 return s;
    855             }
    856         }
    857     }
    858     return EGL_NO_SURFACE;
    859 }
    860 
    861 EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void) {
    862     ThreadInfo* thread     = getThreadInfo();
    863     return (thread->eglContext.Ptr()) ? thread->eglDisplay : EGL_NO_DISPLAY;
    864 }
    865 
    866 EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void) {
    867     EGLenum api = eglQueryAPI();
    868     eglBindAPI(EGL_OPENGL_ES_API);
    869     return eglWaitClient();
    870 }
    871 
    872 EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine) {
    873     if(!EglValidate::engine(engine)) {
    874         RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
    875     }
    876     ThreadInfo* thread  = getThreadInfo();
    877     ContextPtr  currCtx = thread->eglContext;
    878     EglDisplay* dpy     = static_cast<EglDisplay*>(thread->eglDisplay);
    879     if(currCtx.Ptr()) {
    880         SurfacePtr read = currCtx->read();
    881         SurfacePtr draw = currCtx->draw();
    882 
    883         EGLNativeInternalDisplayType nativeDisplay = dpy->nativeType();
    884         if(read.Ptr()) {
    885             if(read->type() == EglSurface::WINDOW &&
    886                !EglOS::validNativeWin(nativeDisplay,read->native())) {
    887                 RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
    888             }
    889             if(read->type() == EglSurface::PIXMAP &&
    890                !EglOS::validNativePixmap(nativeDisplay,read->native())) {
    891                 RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
    892             }
    893         }
    894         if(draw.Ptr()) {
    895             if(draw->type() == EglSurface::WINDOW &&
    896                !EglOS::validNativeWin(nativeDisplay,draw->native())) {
    897                 RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
    898             }
    899             if(draw->type() == EglSurface::PIXMAP &&
    900                !EglOS::validNativePixmap(nativeDisplay,draw->native())) {
    901                 RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
    902             }
    903         }
    904     }
    905     EglOS::waitNative();
    906     return EGL_TRUE;
    907 }
    908 
    909 EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api) {
    910     if(!EglValidate::supportedApi(api)) {
    911         RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
    912     }
    913     CURRENT_THREAD();
    914     tls_thread->setApi(api);
    915     return EGL_TRUE;
    916 }
    917 
    918 EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void) {
    919     CURRENT_THREAD();
    920     return tls_thread->getApi();
    921 }
    922 
    923 EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void) {
    924     ThreadInfo* thread  = getThreadInfo();
    925     ContextPtr currCtx = thread->eglContext;
    926     if(currCtx.Ptr()) {
    927         if(!currCtx->read().Ptr() || !currCtx->draw().Ptr()) {
    928             RETURN_ERROR(EGL_FALSE,EGL_BAD_CURRENT_SURFACE);
    929         }
    930         g_eglInfo->getIface(currCtx->version())->finish();
    931     }
    932     return EGL_TRUE;
    933 }
    934 
    935 EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void) {
    936     ThreadInfo* thread  = getThreadInfo();
    937     EglDisplay* dpy     = static_cast<EglDisplay*>(thread->eglDisplay);
    938     return eglMakeCurrent(dpy,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
    939 }
    940 
    941 EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
    942        eglGetProcAddress(const char *procname){
    943     __eglMustCastToProperFunctionPointerType retVal = NULL;
    944 
    945     initGlobalInfo();
    946 
    947     if(!strncmp(procname,"egl",3)) { //EGL proc
    948         for(int i=0;i < s_eglExtentionsSize;i++){
    949             if(strcmp(procname,s_eglExtentions[i].name) == 0){
    950                 retVal = s_eglExtentions[i].address;
    951                 break;
    952             }
    953         }
    954     }
    955     else {
    956         // Look at the clientAPI (GLES) supported extension
    957         // function table.
    958         retVal = ClientAPIExts::getProcAddress(procname);
    959     }
    960     return retVal;
    961 }
    962 
    963 //not supported for now
    964 /************************* NOT SUPPORTED FOR NOW ***********************/
    965 EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
    966           EGLDisplay display, EGLenum buftype, EGLClientBuffer buffer,
    967           EGLConfig config, const EGLint *attrib_list) {
    968     VALIDATE_DISPLAY(display);
    969     VALIDATE_CONFIG(config);
    970     //we do not support for now openVG, and the only client API resources which may be bound in this fashion are OpenVG
    971     RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_PARAMETER);
    972 }
    973 
    974 EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay display, EGLSurface surface,
    975               EGLNativePixmapType target) {
    976     VALIDATE_DISPLAY(display);
    977     VALIDATE_SURFACE(surface,srfc);
    978     if(!EglOS::validNativePixmap(dpy->nativeType(),NULL)) {
    979         RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP);
    980     }
    981 
    982     //we do not need to support this for android , since we are not gonna use pixmaps
    983     RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP);
    984 }
    985 
    986 /***********************************************************************/
    987 
    988 
    989 
    990 //do last ( only if needed)
    991 /*********************************************************************************************************/
    992 EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
    993 //TODO:
    994 return 0;
    995 }
    996 
    997 EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
    998 //TODO:
    999 return 0;
   1000 }
   1001 /*********************************************************************************************************/
   1002 
   1003 
   1004 /************************** KHR IMAGE *************************************************************/
   1005 EglImage *attachEGLImage(unsigned int imageId)
   1006 {
   1007     ThreadInfo* thread  = getThreadInfo();
   1008     EglDisplay* dpy     = static_cast<EglDisplay*>(thread->eglDisplay);
   1009     ContextPtr  ctx     = thread->eglContext;
   1010     if (ctx.Ptr()) {
   1011         ImagePtr img = dpy->getImage(reinterpret_cast<EGLImageKHR>(imageId));
   1012         if(img.Ptr()) {
   1013              ctx->attachImage(imageId,img);
   1014              return img.Ptr();
   1015         }
   1016     }
   1017     return NULL;
   1018 }
   1019 
   1020 void detachEGLImage(unsigned int imageId)
   1021 {
   1022     ThreadInfo* thread  = getThreadInfo();
   1023     EglDisplay* dpy     = static_cast<EglDisplay*>(thread->eglDisplay);
   1024     ContextPtr  ctx     = thread->eglContext;
   1025     if (ctx.Ptr()) {
   1026         ctx->detachImage(imageId);
   1027     }
   1028 }
   1029 
   1030 
   1031 EGLImageKHR eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
   1032 {
   1033     VALIDATE_DISPLAY(display);
   1034     VALIDATE_CONTEXT(context);
   1035 
   1036     // We only support EGL_GL_TEXTURE_2D images
   1037     if (target != EGL_GL_TEXTURE_2D_KHR) {
   1038         RETURN_ERROR(EGL_NO_IMAGE_KHR,EGL_BAD_PARAMETER);
   1039     }
   1040 
   1041     ThreadInfo* thread  = getThreadInfo();
   1042     ShareGroupPtr sg = thread->shareGroup;
   1043     if (sg.Ptr() != NULL) {
   1044         unsigned int globalTexName = sg->getGlobalName(TEXTURE, (unsigned int)buffer);
   1045         if (!globalTexName) return EGL_NO_IMAGE_KHR;
   1046 
   1047         ImagePtr img( new EglImage() );
   1048         if (img.Ptr() != NULL) {
   1049 
   1050             ObjectDataPtr objData = sg->getObjectData(TEXTURE, (unsigned int)buffer);
   1051             if (!objData.Ptr()) return EGL_NO_IMAGE_KHR;
   1052 
   1053             TextureData *texData = (TextureData *)objData.Ptr();
   1054             if(!texData->width || !texData->height) return EGL_NO_IMAGE_KHR;
   1055             img->width = texData->width;
   1056             img->height = texData->height;
   1057             img->border = texData->border;
   1058             img->internalFormat = texData->internalFormat;
   1059             img->globalTexName = globalTexName;
   1060             return dpy->addImageKHR(img);
   1061         }
   1062     }
   1063 
   1064     return EGL_NO_IMAGE_KHR;
   1065 }
   1066 
   1067 
   1068 EGLBoolean eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image)
   1069 {
   1070     VALIDATE_DISPLAY(display);
   1071     return dpy->destroyImageKHR(image) ? EGL_TRUE:EGL_FALSE;
   1072 }
   1073 
   1074 /*********************************************************************************/
   1075