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