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