• 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 #define LIB_GLES_CM_NAME EMUGL_LIBNAME("GLES_CM_translator")
187 #define LIB_GLES_V2_NAME EMUGL_LIBNAME("GLES_V2_translator")
188 
eglInitialize(EGLDisplay display,EGLint * major,EGLint * minor)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 
eglTerminate(EGLDisplay display)226 EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay display) {
227     VALIDATE_DISPLAY(display);
228     dpy->terminate();
229     return EGL_TRUE;
230 }
231 
eglQueryString(EGLDisplay display,EGLint name)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 
eglGetConfigs(EGLDisplay display,EGLConfig * configs,EGLint config_size,EGLint * num_config)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 
eglChooseConfig(EGLDisplay display,const EGLint * attrib_list,EGLConfig * configs,EGLint config_size,EGLint * num_config)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 
eglGetConfigAttrib(EGLDisplay display,EGLConfig config,EGLint attribute,EGLint * value)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 
eglCreateWindowSurface(EGLDisplay display,EGLConfig config,EGLNativeWindowType win,const EGLint * attrib_list)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 
eglCreatePbufferSurface(EGLDisplay display,EGLConfig config,const EGLint * attrib_list)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 
eglCreatePixmapSurface(EGLDisplay display,EGLConfig config,EGLNativePixmapType pixmap,const EGLint * attrib_list)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 
eglDestroySurface(EGLDisplay display,EGLSurface surface)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 
eglQuerySurface(EGLDisplay display,EGLSurface surface,EGLint attribute,EGLint * value)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 
eglSurfaceAttrib(EGLDisplay display,EGLSurface surface,EGLint attribute,EGLint value)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 
eglCreateContext(EGLDisplay display,EGLConfig config,EGLContext share_context,const EGLint * attrib_list)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 
eglDestroyContext(EGLDisplay display,EGLContext context)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 
eglMakeCurrent(EGLDisplay display,EGLSurface draw,EGLSurface read,EGLContext context)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 
eglQueryContext(EGLDisplay display,EGLContext context,EGLint attribute,EGLint * value)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 
eglSwapBuffers(EGLDisplay display,EGLSurface surface)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 
eglSwapInterval(EGLDisplay display,EGLint interval)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 
eglGetCurrentContext(void)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 
eglGetCurrentSurface(EGLint readdraw)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 
eglGetCurrentDisplay(void)853 EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void) {
854     ThreadInfo* thread     = getThreadInfo();
855     return (thread->eglContext.Ptr()) ? thread->eglDisplay : EGL_NO_DISPLAY;
856 }
857 
eglWaitGL(void)858 EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void) {
859     EGLenum api = eglQueryAPI();
860     eglBindAPI(EGL_OPENGL_ES_API);
861     return eglWaitClient();
862 }
863 
eglWaitNative(EGLint engine)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 
eglBindAPI(EGLenum api)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 
eglQueryAPI(void)910 EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void) {
911     CURRENT_THREAD();
912     return tls_thread->getApi();
913 }
914 
eglWaitClient(void)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 
eglReleaseThread(void)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
eglGetProcAddress(const char * procname)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 ***********************/
eglCreatePbufferFromClientBuffer(EGLDisplay display,EGLenum buftype,EGLClientBuffer buffer,EGLConfig config,const EGLint * attrib_list)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 
eglCopyBuffers(EGLDisplay display,EGLSurface surface,EGLNativePixmapType target)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 /*********************************************************************************************************/
eglBindTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)984 EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
985 //TODO:
986 return 0;
987 }
988 
eglReleaseTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)989 EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
990 //TODO:
991 return 0;
992 }
993 /*********************************************************************************************************/
994 
995 
996 /************************** KHR IMAGE *************************************************************/
attachEGLImage(unsigned int imageId)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 
detachEGLImage(unsigned int imageId)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 
eglCreateImageKHR(EGLDisplay display,EGLContext context,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)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 
eglDestroyImageKHR(EGLDisplay display,EGLImageKHR image)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