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