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