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