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