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