• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #ifdef _WIN32
17 #undef EGLAPI
18 #define EGLAPI
19 #define EGLAPIENTRY
20 #endif
21 
22 #include <GLcommon/GLESmacros.h>
23 #include "GLcommon/GLEScontext.h"
24 #include "GLcommon/GLutils.h"
25 #include "GLcommon/TextureData.h"
26 #include "GLcommon/TextureUtils.h"
27 #include "GLcommon/TranslatorIfaces.h"
28 #include "ThreadInfo.h"
29 #include "aemu/base/synchronization/Lock.h"
30 #include "aemu/base/files/Stream.h"
31 #include "aemu/base/system/System.h"
32 #include "aemu/base/SharedLibrary.h"
33 #include "host-common/GfxstreamFatalError.h"
34 #include "host-common/logging.h"
35 
36 #include "EglWindowSurface.h"
37 #include "EglPbufferSurface.h"
38 #include "EglGlobalInfo.h"
39 #include "EglThreadInfo.h"
40 #include "EglValidate.h"
41 #include "EglDisplay.h"
42 #include "EglContext.h"
43 #include "EglConfig.h"
44 #include "EglOsApi.h"
45 #include "ClientAPIExts.h"
46 
47 #include <EGL/egl.h>
48 #include <EGL/eglext.h>
49 
50 #include <stdio.h>
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 
54 #define MAJOR          1
55 #define MINOR          4
56 
57 using emugl::ABORT_REASON_OTHER;
58 using emugl::FatalError;
59 
60 //declarations
61 
62 namespace translator {
63 namespace egl {
64 
65 ImagePtr getEGLImage(unsigned int imageId);
66 GLEScontext* getGLESContext();
67 GlLibrary* getGlLibrary();
68 void* getProcAddressFromEGL(const char*);
69 static bool createAndBindAuxiliaryContext(
70     EGLContext* context_out, EGLSurface* surface_out);
71 static bool unbindAndDestroyAuxiliaryContext(
72     EGLContext context, EGLSurface surface);
73 static bool bindAuxiliaryContext(
74     EGLContext context, EGLSurface surface);
75 static bool unbindAuxiliaryContext();
76 
77 } // namespace translator
78 } // namespace egl
79 
80 #define tls_thread  EglThreadInfo::get()
81 
82 EglGlobalInfo* g_eglInfo = NULL;
83 android::base::Lock  s_eglLock;
84 android::base::Lock  s_surfaceDestroyLock;
85 
initGlobalInfo()86 void initGlobalInfo()
87 {
88     android::base::AutoLock mutex(s_eglLock);
89     if (!g_eglInfo) {
90         g_eglInfo = EglGlobalInfo::getInstance();
91     }
92 }
93 
94 static const EGLiface s_eglIface = {
95     .getGLESContext = translator::egl::getGLESContext,
96     .getEGLImage = translator::egl::getEGLImage,
97     .eglGetGlLibrary = translator::egl::getGlLibrary,
98     .createAndBindAuxiliaryContext = translator::egl::createAndBindAuxiliaryContext,
99     .unbindAndDestroyAuxiliaryContext = translator::egl::unbindAndDestroyAuxiliaryContext,
100     .bindAuxiliaryContext = translator::egl::bindAuxiliaryContext,
101     .unbindAuxiliaryContext = translator::egl::unbindAuxiliaryContext,
102     .getProcAddress = translator::egl::getProcAddressFromEGL,
103 };
104 
initGLESx(GLESVersion version)105 static void initGLESx(GLESVersion version) {
106     const GLESiface* iface = g_eglInfo->getIface(version);
107     if (!iface) {
108         ERR("EGL failed to initialize GLESv%d; incompatible interface", version);
109         return;
110     }
111     iface->initGLESx(EglGlobalInfo::isEgl2Egl());
112 }
113 
114 /*****************************************  supported extensions  ***********************************************************************/
115 
116 namespace translator {
117 namespace egl {
118 
119 EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
120 EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image);
121 EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay display, EGLenum type, const EGLint* attribs);
122 EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay display, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
123 EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay display, EGLSyncKHR sync);
124 EGLAPI EGLint EGLAPIENTRY eglGetMaxGLESVersion(EGLDisplay display);
125 EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR(EGLDisplay display, EGLSyncKHR sync, EGLint flags);
126 EGLAPI void EGLAPIENTRY eglBlitFromCurrentReadBufferANDROID(EGLDisplay display, EGLImageKHR image);
127 EGLAPI void* EGLAPIENTRY eglSetImageFenceANDROID(EGLDisplay display, EGLImageKHR image);
128 EGLAPI void EGLAPIENTRY eglWaitImageFenceANDROID(EGLDisplay display, void* fence);
129 EGLAPI void EGLAPIENTRY eglAddLibrarySearchPathANDROID(const char* path);
130 EGLAPI EGLBoolean EGLAPIENTRY eglQueryVulkanInteropSupportANDROID(void);
131 EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay display, EGLSyncKHR sync, EGLint attribute, EGLint *value);
132 
133 EGLAPI EGLBoolean EGLAPIENTRY eglSaveConfig(EGLDisplay display, EGLConfig config, EGLStreamKHR stream);
134 EGLAPI EGLConfig EGLAPIENTRY eglLoadConfig(EGLDisplay display, EGLStreamKHR stream);
135 
136 EGLAPI EGLBoolean EGLAPIENTRY eglPreSaveContext(EGLDisplay display, EGLContext contex, EGLStreamKHR stream);
137 EGLAPI EGLBoolean EGLAPIENTRY eglSaveContext(EGLDisplay display, EGLContext contex, EGLStreamKHR stream);
138 EGLAPI EGLBoolean EGLAPIENTRY eglPostSaveContext(EGLDisplay display, EGLContext context, EGLStreamKHR stream);
139 EGLAPI EGLContext EGLAPIENTRY eglLoadContext(EGLDisplay display, const EGLint *attrib_list, EGLStreamKHR stream);
140 
141 EGLAPI EGLBoolean EGLAPIENTRY eglSaveAllImages(EGLDisplay display,
142                                                EGLStreamKHR stream,
143                                                const void* textureSaver);
144 EGLAPI EGLBoolean EGLAPIENTRY eglLoadAllImages(EGLDisplay display,
145                                                EGLStreamKHR stream,
146                                                const void* textureLoader);
147 EGLAPI EGLBoolean EGLAPIENTRY eglPostLoadAllImages(EGLDisplay display, EGLStreamKHR stream);
148 EGLAPI void EGLAPIENTRY eglUseOsEglApi(EGLBoolean enable, EGLBoolean nullEgl);
149 EGLAPI void EGLAPIENTRY eglSetMaxGLESVersion(EGLint version);
150 EGLAPI void EGLAPIENTRY eglFillUsages(void* usages);
151 
152 EGLAPI EGLDisplay EGLAPIENTRY eglGetNativeDisplayANDROID(EGLDisplay);
153 EGLAPI EGLContext EGLAPIENTRY eglGetNativeContextANDROID(EGLDisplay, EGLContext);
154 EGLAPI EGLImage EGLAPIENTRY eglGetNativeImageANDROID(EGLDisplay, EGLImage);
155 EGLAPI EGLBoolean EGLAPIENTRY eglSetImageInfoANDROID(EGLDisplay, EGLImage, EGLint, EGLint, EGLint);
156 EGLAPI EGLImage EGLAPIENTRY eglImportImageANDROID(EGLDisplay, EGLImage);
157 
158 EGLint eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, const EGLAttrib * attrib_list);
159 
160 } // namespace translator
161 } // namespace egl
162 
163 namespace translator {
164 namespace egl {
165 
166 static const ExtensionDescriptor s_eglExtensions[] = {
167         {"eglCreateImageKHR" ,
168                 (__eglMustCastToProperFunctionPointerType)eglCreateImageKHR },
169         {"eglDestroyImageKHR",
170                 (__eglMustCastToProperFunctionPointerType)eglDestroyImageKHR },
171         {"eglCreateSyncKHR" ,
172                 (__eglMustCastToProperFunctionPointerType)eglCreateSyncKHR },
173         {"eglClientWaitSyncKHR",
174                 (__eglMustCastToProperFunctionPointerType)eglClientWaitSyncKHR },
175         {"eglDestroySyncKHR",
176                 (__eglMustCastToProperFunctionPointerType)eglDestroySyncKHR },
177         {"eglGetMaxGLESVersion",
178                 (__eglMustCastToProperFunctionPointerType)eglGetMaxGLESVersion },
179         {"eglWaitSyncKHR",
180                 (__eglMustCastToProperFunctionPointerType)eglWaitSyncKHR },
181         {"eglBlitFromCurrentReadBufferANDROID",
182                 (__eglMustCastToProperFunctionPointerType)eglBlitFromCurrentReadBufferANDROID },
183         {"eglSetImageFenceANDROID",
184                 (__eglMustCastToProperFunctionPointerType)eglSetImageFenceANDROID },
185         {"eglWaitImageFenceANDROID",
186                 (__eglMustCastToProperFunctionPointerType)eglWaitImageFenceANDROID },
187         {"eglAddLibrarySearchPathANDROID",
188                 (__eglMustCastToProperFunctionPointerType)eglAddLibrarySearchPathANDROID },
189         {"eglQueryVulkanInteropSupportANDROID",
190                 (__eglMustCastToProperFunctionPointerType)eglQueryVulkanInteropSupportANDROID },
191         {"eglGetSyncAttribKHR",
192                 (__eglMustCastToProperFunctionPointerType)eglGetSyncAttribKHR },
193 };
194 
195 static const int s_eglExtensionsSize =
196         sizeof(s_eglExtensions) / sizeof(ExtensionDescriptor);
197 
198 } // namespace translator
199 } // namespace egl
200 
201 /****************************************************************************************************************************************/
202 //macros for accessing global egl info & tls objects
203 
204 extern "C" {
205 }
206 
207 namespace translator {
208 namespace egl {
209 
210 #define CURRENT_THREAD() do {} while (0);
211 
212 #define RETURN_ERROR(ret,err)                                \
213         CURRENT_THREAD()                                     \
214         if(tls_thread->getError() == EGL_SUCCESS) {          \
215           tls_thread->setError(err);                         \
216         }                                                    \
217         return ret;
218 
219 #define VALIDATE_DISPLAY_RETURN(EGLDisplay, ret)                \
220     MEM_TRACE_IF(strncmp(__FUNCTION__, "egl", 3) == 0, "EMUGL") \
221     EglDisplay* dpy = g_eglInfo->getDisplay(EGLDisplay);        \
222     if (!dpy) {                                                 \
223         RETURN_ERROR(ret, EGL_BAD_DISPLAY);                     \
224     }                                                           \
225     if (!dpy->isInitialize()) {                                 \
226         RETURN_ERROR(ret, EGL_NOT_INITIALIZED);                 \
227     }
228 
229 #define VALIDATE_CONFIG_RETURN(EGLConfig,ret)                \
230         EglConfig* cfg = dpy->getConfig(EGLConfig);          \
231         if(!cfg) {                                           \
232             RETURN_ERROR(ret,EGL_BAD_CONFIG);                \
233         }
234 
235 #define VALIDATE_SURFACE_RETURN(EGLSurface,ret,varName)      \
236         SurfacePtr varName = dpy->getSurface(EGLSurface);    \
237         if(!varName.get()) {                                 \
238             RETURN_ERROR(ret,EGL_BAD_SURFACE);               \
239         }
240 
241 #define VALIDATE_CONTEXT_RETURN(EGLContext,ret)              \
242         ContextPtr ctx = dpy->getContext(EGLContext);        \
243         if(!ctx.get()) {                                     \
244             RETURN_ERROR(ret,EGL_BAD_CONTEXT);               \
245         }
246 
247 
248 #define VALIDATE_DISPLAY(EGLDisplay) \
249         VALIDATE_DISPLAY_RETURN(EGLDisplay,EGL_FALSE)
250 
251 #define VALIDATE_CONFIG(EGLConfig)   \
252         VALIDATE_CONFIG_RETURN(EGLConfig,EGL_FALSE)
253 
254 #define VALIDATE_SURFACE(EGLSurface,varName) \
255         VALIDATE_SURFACE_RETURN(EGLSurface,EGL_FALSE,varName)
256 
257 #define VALIDATE_CONTEXT(EGLContext) \
258         VALIDATE_CONTEXT_RETURN(EGLContext,EGL_FALSE)
259 
260 
getGLESContext()261 GLEScontext* getGLESContext()
262 {
263     ThreadInfo* thread  = getThreadInfo();
264     return thread->glesContext;
265 }
266 
getGlLibrary()267 GlLibrary* getGlLibrary() {
268     return EglGlobalInfo::getInstance()->getOsEngine()->getGlLibrary();
269 }
270 
getProcAddressFromEGL(const char * func)271 void* getProcAddressFromEGL(const char* func) {
272     return EglGlobalInfo::getInstance()->getOsEngine()->eglGetProcAddress(func);
273 }
274 
eglGetDisplay(EGLNativeDisplayType display_id)275 EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id) {
276     MEM_TRACE("EMUGL");
277     EglDisplay* dpy = NULL;
278     EglOS::Display* internalDisplay = NULL;
279 
280     initGlobalInfo();
281 
282     if ((dpy = g_eglInfo->getDisplay(display_id))) {
283         return dpy;
284     }
285     if (display_id != EGL_DEFAULT_DISPLAY) {
286         return EGL_NO_DISPLAY;
287     }
288     internalDisplay = g_eglInfo->getDefaultNativeDisplay();
289     dpy = g_eglInfo->addDisplay(display_id,internalDisplay);
290     if(!dpy) {
291         return EGL_NO_DISPLAY;
292     }
293     return dpy;
294 }
295 
296 } // namespace translator
297 } // namespace egl
298 
299 #define TRANSLATOR_GETIFACE_NAME "__translator_getIfaces"
300 
301 extern "C" {
302 GLESiface* static_translator_glescm_getIfaces(const EGLiface*);
303 GLESiface* static_translator_glesv2_getIfaces(const EGLiface*);
304 }; // extern "C"
305 
306 #define STATIC_TRANSLATOR_GETIFACE_NAME_GLES_CM static_translator_glescm_getIfaces
307 #define STATIC_TRANSLATOR_GETIFACE_NAME_GLES_V2 static_translator_glesv2_getIfaces
308 
309 #define LIB_GLES_CM_NAME EMUGL_LIBNAME("GLES_CM_translator")
310 #define LIB_GLES_V2_NAME EMUGL_LIBNAME("GLES_V2_translator")
311 
loadIfaces(const char * libName,char * error,size_t errorSize)312 static __translator_getGLESIfaceFunc loadIfaces(const char* libName,
313                                                 char* error,
314                                                 size_t errorSize) {
315 
316     if (!strcmp(libName, LIB_GLES_CM_NAME)) {
317         return STATIC_TRANSLATOR_GETIFACE_NAME_GLES_CM;
318     }
319 
320     if (!strcmp(libName, LIB_GLES_V2_NAME)) {
321         return STATIC_TRANSLATOR_GETIFACE_NAME_GLES_V2;
322     }
323 
324     return 0;
325 }
326 
327 namespace translator {
328 namespace egl {
329 
eglInitialize(EGLDisplay display,EGLint * major,EGLint * minor)330 EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay display, EGLint *major, EGLint *minor) {
331     MEM_TRACE("EMUGL");
332 
333     initGlobalInfo();
334 
335     EglDisplay* dpy = g_eglInfo->getDisplay(display);
336     if(!dpy) {
337          RETURN_ERROR(EGL_FALSE,EGL_BAD_DISPLAY);
338     }
339 
340     if(major) *major = MAJOR;
341     if(minor) *minor = MINOR;
342 
343     __translator_getGLESIfaceFunc func  = NULL;
344     int renderableType = EGL_OPENGL_ES_BIT;
345 
346     g_eglInfo->setEglIface(&s_eglIface);
347 
348     char error[256];
349     // When running on top of another GLES library, our GLES1
350     // translator uses the GLES library's underlying GLES3.
351     if(!g_eglInfo->getIface(GLES_1_1)) {
352         func  = loadIfaces(LIB_GLES_CM_NAME, error, sizeof(error));
353         if (func) {
354             g_eglInfo->setIface(func(&s_eglIface),GLES_1_1);
355         } else {
356            fprintf(stderr, "%s: Could not find ifaces for GLES CM 1.1 [%s]\n",
357                    __FUNCTION__, error);
358            return EGL_FALSE;
359         }
360         initGLESx(GLES_1_1);
361     }
362     if(!g_eglInfo->getIface(GLES_2_0)) {
363         func  = loadIfaces(LIB_GLES_V2_NAME, error, sizeof(error));
364         if (func) {
365             renderableType |= EGL_OPENGL_ES2_BIT;
366             g_eglInfo->setIface(func(&s_eglIface),GLES_2_0);
367         } else {
368            fprintf(stderr, "%s: Could not find ifaces for GLES 2.0 [%s]\n",
369                    __FUNCTION__, error);
370         }
371         initGLESx(GLES_2_0);
372     }
373     if(!g_eglInfo->getIface(GLES_3_0)) {
374         func  = loadIfaces(LIB_GLES_V2_NAME, error, sizeof(error));
375         if (func) {
376             renderableType |= EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
377             g_eglInfo->setIface(func(&s_eglIface),GLES_3_0);
378         } else {
379            fprintf(stderr, "%s: Could not find ifaces for GLES 3.x [%s]\n",
380                    __FUNCTION__, error);
381         }
382         initGLESx(GLES_3_0);
383     }
384     if(!g_eglInfo->getIface(GLES_3_1)) {
385         func  = loadIfaces(LIB_GLES_V2_NAME, error, sizeof(error));
386         if (func) {
387             renderableType |= EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
388             g_eglInfo->setIface(func(&s_eglIface),GLES_3_1);
389         } else {
390            fprintf(stderr, "%s: Could not find ifaces for GLES 3.x [%s]\n",
391                    __FUNCTION__, error);
392         }
393         initGLESx(GLES_3_1);
394     }
395     dpy->initialize(renderableType);
396     return EGL_TRUE;
397 }
398 
eglTerminate(EGLDisplay display)399 EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay display) {
400     VALIDATE_DISPLAY(display);
401     dpy->terminate();
402     return EGL_TRUE;
403 }
404 
eglQueryString(EGLDisplay display,EGLint name)405 EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay display, EGLint name) {
406     VALIDATE_DISPLAY(display);
407     static const char* version    = "1.4";
408     static const char* extensions = "EGL_KHR_image EGL_KHR_image_base "
409                                     "EGL_KHR_gl_texture_2D_image "
410                                     "EGL_ANDROID_recordable ";
411     if(!EglValidate::stringName(name)) {
412         RETURN_ERROR(NULL,EGL_BAD_PARAMETER);
413     }
414     switch(name) {
415     case EGL_VENDOR:
416         return dpy->getVendorString();
417     case EGL_VERSION:
418         return version;
419     case EGL_EXTENSIONS:
420         return extensions;
421     }
422     return NULL;
423 }
424 
eglGetConfigs(EGLDisplay display,EGLConfig * configs,EGLint config_size,EGLint * num_config)425 EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay display, EGLConfig *configs,
426              EGLint config_size, EGLint *num_config) {
427     VALIDATE_DISPLAY(display);
428     if(!num_config) {
429         RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
430     }
431 
432     if(configs == NULL) {
433         *num_config = dpy->nConfigs();
434     } else {
435         *num_config = dpy->getConfigs(configs,config_size);
436     }
437 
438     return EGL_TRUE;
439 }
440 
eglChooseConfig(EGLDisplay display,const EGLint * attrib_list,EGLConfig * configs,EGLint config_size,EGLint * num_config)441 EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay display, const EGLint *attrib_list,
442                EGLConfig *configs, EGLint config_size,
443                EGLint *num_config) {
444     CHOOSE_CONFIG_DLOG("eglChooseConfig: begin. validating arguments...");
445 
446     VALIDATE_DISPLAY(display);
447     if(!num_config) {
448          CHOOSE_CONFIG_DLOG("num_config is NULL. issue EGL_BAD_PARAMETER");
449          RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
450     }
451 
452         //selection defaults
453         // NOTE: Some variables below are commented out to reduce compiler warnings.
454         // TODO(digit): Look if these variables are really needed or not, and if so
455         // fix the code to do it properly.
456         EGLint      surface_type       = EGL_WINDOW_BIT;
457         EGLint      renderable_type    = EGL_OPENGL_ES_BIT;
458         //EGLBoolean  bind_to_tex_rgb    = EGL_DONT_CARE;
459         //EGLBoolean  bind_to_tex_rgba   = EGL_DONT_CARE;
460         EGLenum     caveat             = EGL_DONT_CARE;
461         EGLint      config_id          = EGL_DONT_CARE;
462         EGLBoolean  native_renderable  = EGL_DONT_CARE;
463         EGLint      native_visual_type = EGL_DONT_CARE;
464         //EGLint      max_swap_interval  = EGL_DONT_CARE;
465         //EGLint      min_swap_interval  = EGL_DONT_CARE;
466         EGLint      trans_red_val      = EGL_DONT_CARE;
467         EGLint      trans_green_val    = EGL_DONT_CARE;
468         EGLint      trans_blue_val     = EGL_DONT_CARE;
469         EGLenum     transparent_type   = EGL_NONE;
470         // EGLint      buffer_size        = 0;
471         EGLint      red_size           = 0;
472         EGLint      green_size         = 0;
473         EGLint      blue_size          = 0;
474         EGLint      alpha_size         = 0;
475         EGLint      depth_size         = 0;
476         EGLint      frame_buffer_level = 0;
477         EGLint      sample_buffers_num = 0;
478         EGLint      samples_per_pixel  = 0;
479         EGLint      stencil_size       = 0;
480         EGLint      conformant         = 0;
481 
482         EGLBoolean  recordable_android = EGL_FALSE;
483         EGLBoolean  framebuffer_target_android = EGL_DONT_CARE;
484 
485         EGLint luminance_size = 0;
486         EGLint wanted_buffer_size = EGL_DONT_CARE;
487 
488         std::vector<EGLint> wanted_attribs;
489 
490     if(!EglValidate::noAttribs(attrib_list)) { //there are attribs
491         int i = 0 ;
492         bool hasConfigId = false;
493         while(attrib_list[i] != EGL_NONE && !hasConfigId) {
494 #define CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(attrname) \
495             CHOOSE_CONFIG_DLOG("EGL_BAD_ATTRIBUTE: " #attrname "defined as 0x%x", attrib_list[i+1]);
496 
497             if (attrib_list[i] != EGL_LEVEL &&
498                 attrib_list[i] != EGL_MATCH_NATIVE_PIXMAP &&
499                 attrib_list[i + 1] == EGL_DONT_CARE) {
500                 i+=2;
501                 continue;
502             }
503 
504             switch(attrib_list[i]) {
505             case EGL_MAX_PBUFFER_WIDTH:
506             case EGL_MAX_PBUFFER_HEIGHT:
507             case EGL_MAX_PBUFFER_PIXELS:
508             case EGL_NATIVE_VISUAL_ID:
509                 break; //we dont care from those selection crateria
510             case EGL_LEVEL:
511                 if(attrib_list[i+1] == EGL_DONT_CARE) {
512                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_LEVEL);
513                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
514                 }
515                 frame_buffer_level = attrib_list[i+1];
516                 wanted_attribs.push_back(EGL_LEVEL);
517                 break;
518             case EGL_BUFFER_SIZE:
519                 if(attrib_list[i+1] < 0) {
520                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_BUFFER_SIZE);
521                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
522                 }
523                 wanted_attribs.push_back(EGL_BUFFER_SIZE);
524                 wanted_buffer_size = attrib_list[i + 1];
525                 break;
526             case EGL_RED_SIZE:
527                 if(attrib_list[i+1] < 0) {
528                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_RED_SIZE);
529                      RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
530                 }
531                 red_size = attrib_list[i+1];
532                 wanted_attribs.push_back(EGL_RED_SIZE);
533                 break;
534             case EGL_GREEN_SIZE:
535                 if(attrib_list[i+1] < 0) {
536                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_GREEN_SIZE);
537                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
538                 }
539                 green_size = attrib_list[i+1];
540                 wanted_attribs.push_back(EGL_GREEN_SIZE);
541                 break;
542             case EGL_BLUE_SIZE:
543                 if(attrib_list[i+1] < 0) {
544                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_BLUE_SIZE);
545                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
546                 }
547                 blue_size = attrib_list[i+1];
548                 wanted_attribs.push_back(EGL_BLUE_SIZE);
549                 break;
550             case EGL_LUMINANCE_SIZE:
551                 if(attrib_list[i+1] < 0) {
552                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_LUMINANCE_SIZE);
553                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
554                 }
555                 wanted_attribs.push_back(EGL_LUMINANCE_SIZE);
556                 luminance_size = attrib_list[i + 1];
557                 break;
558             case EGL_ALPHA_SIZE:
559                 if(attrib_list[i+1] < 0) {
560                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_ALPHA_SIZE);
561                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
562                 }
563                 alpha_size = attrib_list[i+1];
564                 wanted_attribs.push_back(EGL_ALPHA_SIZE);
565                 break;
566             case EGL_ALPHA_MASK_SIZE:
567                 if(attrib_list[i+1] < 0) {
568                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_ALPHA_MASK_SIZE);
569                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
570                 }
571                 wanted_attribs.push_back(EGL_ALPHA_MASK_SIZE);
572                 break;
573             case EGL_BIND_TO_TEXTURE_RGB:
574                 if (attrib_list[i+1] != EGL_TRUE &&
575                     attrib_list[i+1] != EGL_FALSE) {
576                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_BIND_TO_TEXTURE_RGB);
577                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
578                 }
579                 wanted_attribs.push_back(EGL_BIND_TO_TEXTURE_RGB);
580                 //bind_to_tex_rgb = attrib_list[i+1];
581                 break;
582             case EGL_BIND_TO_TEXTURE_RGBA:
583                 if (attrib_list[i+1] != EGL_TRUE &&
584                     attrib_list[i+1] != EGL_FALSE) {
585                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_BIND_TO_TEXTURE_RGBA);
586                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
587                 }
588                 wanted_attribs.push_back(EGL_BIND_TO_TEXTURE_RGBA);
589                 //bind_to_tex_rgba = attrib_list[i+1];
590                 break;
591             case EGL_CONFIG_CAVEAT:
592                 if(attrib_list[i+1] != EGL_NONE &&
593                    attrib_list[i+1] != EGL_SLOW_CONFIG &&
594                    attrib_list[i+1] != EGL_NON_CONFORMANT_CONFIG) {
595                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_CONFIG_CAVEAT);
596                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
597                 }
598                 caveat = attrib_list[i+1];
599                 wanted_attribs.push_back(EGL_CONFIG_CAVEAT);
600                 break;
601             case EGL_CONFORMANT:
602                 conformant = attrib_list[i+1];
603                 wanted_attribs.push_back(EGL_CONFORMANT);
604                 break;
605             case EGL_CONFIG_ID:
606                 if(attrib_list[i+1] < 0) {
607                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_CONFIG_ID);
608                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
609                 }
610                 config_id = attrib_list[i+1];
611                 hasConfigId = true;
612                 wanted_attribs.push_back(EGL_CONFIG_ID);
613                 break;
614             case EGL_DEPTH_SIZE:
615                 if(attrib_list[i+1] < 0) {
616                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_DEPTH_SIZE);
617                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
618                 }
619                 depth_size = attrib_list[i+1];
620                 wanted_attribs.push_back(EGL_DEPTH_SIZE);
621                 break;
622             case EGL_MAX_SWAP_INTERVAL:
623                 if(attrib_list[i+1] < 0) {
624                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_MAX_SWAP_INTERVAL);
625                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
626                 }
627                 //max_swap_interval = attrib_list[i+1];
628                 wanted_attribs.push_back(EGL_MAX_SWAP_INTERVAL);
629                 break;
630             case EGL_MIN_SWAP_INTERVAL:
631                 if(attrib_list[i+1] < 0) {
632                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_MIN_SWAP_INTERVAL);
633                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
634                 }
635                 //min_swap_interval = attrib_list[i+1];
636                 wanted_attribs.push_back(EGL_MIN_SWAP_INTERVAL);
637                 break;
638             case EGL_NATIVE_RENDERABLE:
639                 if (attrib_list[i+1] != EGL_TRUE &&
640                     attrib_list[i+1] != EGL_FALSE) {
641                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_NATIVE_RENDERABLE);
642                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
643                 }
644                 native_renderable = attrib_list[i+1];
645                 wanted_attribs.push_back(EGL_NATIVE_RENDERABLE);
646                 break;
647             case EGL_RENDERABLE_TYPE:
648                 renderable_type = attrib_list[i+1];
649                 wanted_attribs.push_back(EGL_RENDERABLE_TYPE);
650                 break;
651             case EGL_NATIVE_VISUAL_TYPE:
652                 native_visual_type = attrib_list[i+1];
653                 break;
654                 if(attrib_list[i+1] < 0 || attrib_list[i+1] > 1 ) {
655                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_NATIVE_VISUAL_TYPE);
656                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
657                 }
658                 wanted_attribs.push_back(EGL_NATIVE_VISUAL_TYPE);
659             case EGL_SAMPLE_BUFFERS:
660                 if(attrib_list[i+1] < 0) {
661                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_SAMPLE_BUFFERS);
662                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
663                 }
664                 sample_buffers_num = attrib_list[i+1];
665                 wanted_attribs.push_back(EGL_SAMPLE_BUFFERS);
666                 break;
667             case EGL_SAMPLES:
668                 if(attrib_list[i+1] < 0) {
669                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_SAMPLES);
670                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
671                 }
672                 samples_per_pixel = attrib_list[i+1];
673                 wanted_attribs.push_back(EGL_SAMPLES);
674                 break;
675             case EGL_STENCIL_SIZE:
676                 if(attrib_list[i+1] < 0) {
677                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_STENCIL_SIZE);
678                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
679                 }
680                 stencil_size = attrib_list[i+1];
681                 wanted_attribs.push_back(EGL_STENCIL_SIZE);
682                 break;
683             case EGL_SURFACE_TYPE:
684                 surface_type = attrib_list[i+1];
685                 wanted_attribs.push_back(EGL_SURFACE_TYPE);
686                 break;
687             case EGL_TRANSPARENT_TYPE:
688                 if(attrib_list[i+1] != EGL_NONE &&
689                    attrib_list[i+1] != EGL_TRANSPARENT_RGB ) {
690                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_TRANSPARENT_TYPE);
691                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
692                 }
693                 transparent_type = attrib_list[i+1];
694                 wanted_attribs.push_back(EGL_TRANSPARENT_TYPE);
695                 break;
696             case EGL_TRANSPARENT_RED_VALUE:
697                 trans_red_val = attrib_list[i+1];
698                 wanted_attribs.push_back(EGL_TRANSPARENT_RED_VALUE);
699                 break;
700             case EGL_TRANSPARENT_GREEN_VALUE:
701                 trans_green_val = attrib_list[i+1];
702                 wanted_attribs.push_back(EGL_TRANSPARENT_GREEN_VALUE);
703                 break;
704             case EGL_TRANSPARENT_BLUE_VALUE:
705                 trans_blue_val = attrib_list[i+1];
706                 wanted_attribs.push_back(EGL_TRANSPARENT_BLUE_VALUE);
707                 break;
708             case EGL_COLOR_BUFFER_TYPE:
709                 if(attrib_list[i+1] != EGL_RGB_BUFFER &&
710                    attrib_list[i+1] != EGL_LUMINANCE_BUFFER) {
711                     CHOOSE_CONFIG_DLOG_BAD_ATTRIBUTE(EGL_COLOR_BUFFER_TYPE);
712                     RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
713                 }
714                 wanted_attribs.push_back(EGL_COLOR_BUFFER_TYPE);
715                 break;
716             case EGL_RECORDABLE_ANDROID:
717                 recordable_android = attrib_list[i+1];
718                 wanted_attribs.push_back(EGL_RECORDABLE_ANDROID);
719                 break;
720             case EGL_FRAMEBUFFER_TARGET_ANDROID:
721                 framebuffer_target_android = attrib_list[i+1];
722                 wanted_attribs.push_back(EGL_FRAMEBUFFER_TARGET_ANDROID);
723                 break;
724             default:
725                 CHOOSE_CONFIG_DLOG("EGL_BAD_ATTRIBUTE: Unknown attribute key 0x%x", attrib_list[i]);
726                 RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
727             }
728             i+=2;
729         }
730         if(hasConfigId) {
731             EglConfig* pConfig = dpy->getConfig(config_id);
732             if(pConfig) {
733                 if(configs) {
734                     configs[0]  = static_cast<EGLConfig>(pConfig);
735                 }
736                 *num_config = 1;
737                 CHOOSE_CONFIG_DLOG("Using config id 0x%x. Return EGL_TRUE", config_id);
738                 return EGL_TRUE;
739             } else {
740                 CHOOSE_CONFIG_DLOG("EGL_BAD_ATTRIBUTE: Using missing config id 0x%x", config_id);
741                 RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
742             }
743         }
744     }
745     EglConfig dummy(red_size,green_size,blue_size,alpha_size,caveat,conformant,depth_size,
746                     frame_buffer_level,0,0,0,native_renderable,renderable_type,0,native_visual_type,
747                     sample_buffers_num, samples_per_pixel,stencil_size,luminance_size,wanted_buffer_size,
748                     surface_type,transparent_type,trans_red_val,trans_green_val,trans_blue_val,recordable_android, framebuffer_target_android,
749                     NULL);
750     for (size_t i = 0; i < wanted_attribs.size(); i++) {
751         dummy.addWantedAttrib(wanted_attribs[i]);
752     }
753     *num_config = dpy->chooseConfigs(dummy,configs,config_size);
754     CHOOSE_CONFIG_DLOG("eglChooseConfig: Success(EGL_TRUE). Num configs returned:%d", *num_config);
755 
756     return EGL_TRUE;
757 }
758 
eglGetConfigAttrib(EGLDisplay display,EGLConfig config,EGLint attribute,EGLint * value)759 EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay display, EGLConfig config,
760                   EGLint attribute, EGLint *value) {
761     VALIDATE_DISPLAY(display);
762     VALIDATE_CONFIG(config);
763     if(!EglValidate::confAttrib(attribute)){
764         RETURN_ERROR(EGL_FALSE, EGL_BAD_ATTRIBUTE);
765     }
766     return cfg->getConfAttrib(attribute,value)? EGL_TRUE:EGL_FALSE;
767 }
768 
eglCreateWindowSurface(EGLDisplay display,EGLConfig config,EGLNativeWindowType win,const EGLint * attrib_list)769 EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay display, EGLConfig config,
770                   EGLNativeWindowType win,
771                   const EGLint *attrib_list) {
772     VALIDATE_DISPLAY_RETURN(display,EGL_NO_SURFACE);
773     VALIDATE_CONFIG_RETURN(config,EGL_NO_SURFACE);
774 
775     if(!(cfg->surfaceType() & EGL_WINDOW_BIT)) {
776         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_MATCH);
777     }
778     if(!dpy->nativeType()->isValidNativeWin(win)) {
779         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_NATIVE_WINDOW);
780     }
781     if(!EglValidate::noAttribs(attrib_list)) {
782         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ATTRIBUTE);
783     }
784     if(EglWindowSurface::alreadyAssociatedWithConfig(win)) {
785         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
786     }
787 
788     android::base::AutoLock mutex(s_eglLock);
789     unsigned int width,height;
790     if(!dpy->nativeType()->checkWindowPixelFormatMatch(
791             win, cfg->nativeFormat(), &width, &height)) {
792         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
793     }
794     SurfacePtr wSurface(new EglWindowSurface(dpy, win,cfg,width,height));
795     if(!wSurface.get()) {
796         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
797     }
798     return dpy->addSurface(wSurface);
799 }
800 
eglCreatePbufferSurface(EGLDisplay display,EGLConfig config,const EGLint * attrib_list)801 EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(
802         EGLDisplay display,
803         EGLConfig config,
804         const EGLint *attrib_list) {
805     VALIDATE_DISPLAY_RETURN(display,EGL_NO_SURFACE);
806     VALIDATE_CONFIG_RETURN(config,EGL_NO_SURFACE);
807     if(!(cfg->surfaceType() & EGL_PBUFFER_BIT)) {
808         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_MATCH);
809     }
810 
811     SurfacePtr pbSurface(new EglPbufferSurface(dpy,cfg));
812     if(!pbSurface.get()) {
813         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ALLOC);
814     }
815 
816     if(!EglValidate::noAttribs(attrib_list)) { // There are attribs.
817         int i = 0 ;
818         while(attrib_list[i] != EGL_NONE) {
819             if(!pbSurface->setAttrib(attrib_list[i],attrib_list[i+1])) {
820                 RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ATTRIBUTE);
821             }
822             i+=2;
823         }
824     }
825 
826     EGLint width, height, largest, texTarget, texFormat;
827     EglPbufferSurface* tmpPbSurfacePtr =
828             static_cast<EglPbufferSurface*>(pbSurface.get());
829 
830     tmpPbSurfacePtr->getDim(&width, &height, &largest);
831     tmpPbSurfacePtr->getTexInfo(&texTarget, &texFormat);
832 
833     if(!EglValidate::pbufferAttribs(width,
834                                     height,
835                                     texFormat == EGL_NO_TEXTURE,
836                                     texTarget == EGL_NO_TEXTURE)) {
837         //TODO: RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_VALUE); dont have bad_value
838         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ATTRIBUTE);
839     }
840 
841     EglOS::PbufferInfo pbinfo;
842 
843     pbinfo.width = width;
844     pbinfo.height = height;
845     pbinfo.largest = largest;
846     pbinfo.target = texTarget;
847     pbinfo.format = texFormat;
848 
849     tmpPbSurfacePtr->getAttrib(EGL_MIPMAP_TEXTURE, &pbinfo.hasMipmap);
850 
851     android::base::AutoLock mutex(s_eglLock);
852     EglOS::Surface* pb = dpy->nativeType()->createPbufferSurface(
853             cfg->nativeFormat(), &pbinfo);
854     if(!pb) {
855         //TODO: RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_VALUE); dont have bad value
856         RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_ATTRIBUTE);
857     }
858 
859     tmpPbSurfacePtr->setNativePbuffer(pb);
860     return dpy->addSurface(pbSurface);
861 }
862 
eglDestroySurface(EGLDisplay display,EGLSurface surface)863 EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay display, EGLSurface surface) {
864     VALIDATE_DISPLAY(display);
865     android::base::AutoLock mutex(s_eglLock);
866     SurfacePtr srfc = dpy->getSurface(surface);
867     if(!srfc.get()) {
868         RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
869     }
870     g_eglInfo->markSurfaceForDestroy(dpy, surface);
871     return EGL_TRUE;
872 }
873 
eglQuerySurface(EGLDisplay display,EGLSurface surface,EGLint attribute,EGLint * value)874 EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay display, EGLSurface surface,
875                EGLint attribute, EGLint *value) {
876    VALIDATE_DISPLAY(display);
877    VALIDATE_SURFACE(surface,srfc);
878 
879    if(!srfc->getAttrib(attribute,value)) {
880        RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
881    }
882    return EGL_TRUE;
883 }
884 
eglSurfaceAttrib(EGLDisplay display,EGLSurface surface,EGLint attribute,EGLint value)885 EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay display, EGLSurface surface,
886                 EGLint attribute, EGLint value) {
887    VALIDATE_DISPLAY(display);
888    VALIDATE_SURFACE(surface,srfc);
889    if(!srfc->setAttrib(attribute,value)) {
890        RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
891    }
892    return EGL_TRUE;
893 }
894 
895 // eglCreateOrLoadContext is the implementation of eglCreateContext and
896 // eglLoadContext.
897 // |stream| is the snapshot file to load from when calling from eglLoadContext
898 // when |stream| is available, config and share group ID will be loaded from stream
899 
eglCreateOrLoadContext(EGLDisplay display,EGLConfig config,EGLContext share_context,const EGLint * attrib_list,android::base::Stream * stream)900 static EGLContext eglCreateOrLoadContext(EGLDisplay display, EGLConfig config,
901                 EGLContext share_context,
902                 const EGLint *attrib_list,
903                 android::base::Stream *stream) {
904     assert(share_context == EGL_NO_CONTEXT || stream == nullptr);
905     VALIDATE_DISPLAY_RETURN(display,EGL_NO_CONTEXT);
906 
907     uint64_t shareGroupId = 0;
908     EglConfig* cfg = nullptr;
909     if (!stream) {
910         cfg = dpy->getConfig(config);
911         if (!cfg) return EGL_NO_CONTEXT;
912     }
913 
914     EGLint major_version = 0;
915     EGLint minor_version = 0;
916     EGLint context_flags = 0;
917     EGLint profile_mask = 0;
918     EGLint reset_notification_strategy = 0;
919     if(!EglValidate::noAttribs(attrib_list)) {
920         int i = 0;
921         while(attrib_list[i] != EGL_NONE) {
922             EGLint attrib_val = attrib_list[i + 1];
923             switch(attrib_list[i]) {
924             case EGL_CONTEXT_MAJOR_VERSION_KHR:
925                 major_version = attrib_val;
926                 break;
927             case EGL_CONTEXT_MINOR_VERSION_KHR:
928                 minor_version = attrib_val;
929                 break;
930             case EGL_CONTEXT_FLAGS_KHR:
931                 if ((attrib_val | EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) ||
932                     (attrib_val | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR)  ||
933                     (attrib_val | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) {
934                     context_flags = attrib_val;
935                 } else {
936                     fprintf(stderr, "%s: wrong context flags, return\n", __func__);
937                     RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE);
938                 }
939                 break;
940             case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
941                 if ((attrib_val | EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR) ||
942                     (attrib_val | EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR)) {
943                     profile_mask = attrib_val;
944                 } else {
945                     fprintf(stderr, "%s: wrong profile mask, return\n", __func__);
946                     RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE);
947                 }
948                 break;
949             case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
950                 switch (attrib_val) {
951                 case EGL_NO_RESET_NOTIFICATION_KHR:
952                 case EGL_LOSE_CONTEXT_ON_RESET_KHR:
953                     break;
954                 default:
955                     fprintf(stderr, "%s: wrong reset notif strat, return\n", __func__);
956                     RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE);
957                 }
958                 reset_notification_strategy = attrib_val;
959                 break;
960             default:
961                 fprintf(stderr, "%s: unknown attrib 0x%x\n", __func__, attrib_list[i]);
962                 RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE);
963             }
964             i+=2;
965         }
966     }
967 
968     // TODO: Investigate these ignored flags and see which are needed
969     (void)context_flags;
970     (void)reset_notification_strategy;
971 
972     GLESVersion glesVersion;
973     switch (major_version) {
974      case 1:
975          glesVersion = GLES_1_1;
976          break;
977      case 2:
978          glesVersion = GLES_2_0;
979          break;
980      case 3:
981          switch (minor_version) {
982          case 0:
983              glesVersion = GLES_3_0;
984              break;
985          case 1:
986              glesVersion = GLES_3_1;
987              break;
988          default:
989              RETURN_ERROR(EGL_NO_CONTEXT, EGL_BAD_ATTRIBUTE);
990              break;
991          }
992          break;
993      default:
994          RETURN_ERROR(EGL_NO_CONTEXT, EGL_BAD_ATTRIBUTE);
995          break;
996     }
997 
998     const GLESiface* iface = g_eglInfo->getIface(glesVersion);
999     GLEScontext* glesCtx = NULL;
1000     if(iface) {
1001         glesCtx = iface->createGLESContext(major_version, minor_version,
1002                 dpy->getGlobalNameSpace(), stream);
1003     } else { // there is no interface for this gles version
1004                 RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE);
1005     }
1006 
1007     if(share_context != EGL_NO_CONTEXT) {
1008         ContextPtr sharedCtxPtr = dpy->getContext(share_context);
1009         if(!sharedCtxPtr.get()) {
1010             RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_CONTEXT);
1011         }
1012         shareGroupId = sharedCtxPtr->getShareGroup()->getId();
1013         assert(shareGroupId);
1014     }
1015 
1016     android::base::AutoLock mutex(s_eglLock);
1017 
1018     ContextPtr ctx(new EglContext(dpy, shareGroupId, cfg,
1019                                   glesCtx, glesVersion,
1020                                   profile_mask,
1021                                   dpy->getManager(glesVersion),
1022                                   stream));
1023     if(ctx->nativeType()) {
1024         return dpy->addContext(ctx);
1025     } else {
1026         iface->deleteGLESContext(glesCtx);
1027     }
1028 
1029     return EGL_NO_CONTEXT;
1030 }
1031 
eglCreateContext(EGLDisplay display,EGLConfig config,EGLContext share_context,const EGLint * attrib_list)1032 EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay display, EGLConfig config,
1033                 EGLContext share_context,
1034                 const EGLint *attrib_list) {
1035     return eglCreateOrLoadContext(display, config, share_context, attrib_list, nullptr);
1036 }
1037 
eglLoadContext(EGLDisplay display,const EGLint * attrib_list,android::base::Stream * stream)1038 EGLAPI EGLContext EGLAPIENTRY eglLoadContext(EGLDisplay display, const EGLint *attrib_list,
1039                                              android::base::Stream *stream) {
1040     return eglCreateOrLoadContext(display, (EGLConfig)0, (EGLContext)0, attrib_list, stream);
1041 }
1042 
eglDestroyContext(EGLDisplay display,EGLContext context)1043 EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay display, EGLContext context) {
1044     VALIDATE_DISPLAY(display);
1045     VALIDATE_CONTEXT(context);
1046 
1047     android::base::AutoLock mutex(s_eglLock);
1048     dpy->removeContext(context);
1049     return EGL_TRUE;
1050 }
1051 
sGetPbufferSurfaceGLProperties(EglPbufferSurface * surface,EGLint * width,EGLint * height,GLint * multisamples,GLint * colorFormat,GLint * depthStencilFormat)1052 static void sGetPbufferSurfaceGLProperties(
1053         EglPbufferSurface* surface,
1054         EGLint* width, EGLint* height, GLint* multisamples,
1055         GLint* colorFormat, GLint* depthStencilFormat) {
1056 
1057     assert(width);
1058     assert(height);
1059     assert(multisamples);
1060     assert(colorFormat);
1061     assert(depthStencilFormat);
1062 
1063     EGLint r, g, b, a, d, s;
1064     surface->getAttrib(EGL_WIDTH, width);
1065     surface->getAttrib(EGL_HEIGHT, height);
1066     surface->getAttrib(EGL_RED_SIZE, &r);
1067     surface->getAttrib(EGL_GREEN_SIZE, &g);
1068     surface->getAttrib(EGL_BLUE_SIZE, &b);
1069     surface->getAttrib(EGL_ALPHA_SIZE, &a);
1070     surface->getAttrib(EGL_DEPTH_SIZE, &d);
1071     surface->getAttrib(EGL_STENCIL_SIZE, &s);
1072     surface->getAttrib(EGL_SAMPLES, multisamples);
1073 
1074     // Currently supported: RGBA8888/RGB888/RGB565/RGBA4/RGB5A1
1075     if (r == 8 && g == 8 && b == 8 && a == 8) {
1076         *colorFormat = GL_RGBA8;
1077     } else if (r == 8 && g == 8 && b == 8 && a == 0) {
1078         *colorFormat = GL_RGB8;
1079     } else if (r == 5 && g == 6 && b == 5 && a == 0) {
1080         *colorFormat = GL_RGB565;
1081     } else if (r == 4 && g == 4 && b == 4 && a == 4) {
1082         *colorFormat = GL_RGBA4;
1083     } else if (r == 5 && g == 5 && b == 5 && a == 1) {
1084         *colorFormat = GL_RGB5_A1;
1085     } else {
1086         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
1087             << "invalid color format R" << r << "G" << g << "B" << b << "A" << a;
1088     }
1089 
1090     // Blanket provide 24/8 depth/stencil format for now.
1091     *depthStencilFormat = GL_DEPTH24_STENCIL8;
1092 
1093     // TODO: Support more if necessary, or even restrict
1094     // EGL configs from host display to only these ones.
1095 }
1096 
eglMakeCurrent(EGLDisplay display,EGLSurface draw,EGLSurface read,EGLContext context)1097 EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display,
1098                                              EGLSurface draw,
1099                                              EGLSurface read,
1100                                              EGLContext context) {
1101     VALIDATE_DISPLAY(display);
1102 
1103     bool releaseContext = EglValidate::releaseContext(context, read, draw);
1104     if(!releaseContext && EglValidate::badContextMatch(context, read, draw)) {
1105         RETURN_ERROR(EGL_FALSE, EGL_BAD_MATCH);
1106     }
1107 
1108     ThreadInfo* thread = getThreadInfo();
1109     ContextPtr prevCtx = thread->eglContext;
1110 
1111     if(releaseContext) { //releasing current context
1112        if(prevCtx.get()) {
1113            g_eglInfo->getIface(prevCtx->version())->flush();
1114            if(!dpy->nativeType()->makeCurrent(NULL,NULL,NULL)) {
1115                RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS);
1116            }
1117            thread->updateInfo(ContextPtr(),dpy,NULL,ShareGroupPtr(),dpy->getManager(prevCtx->version()));
1118        }
1119     } else { //assining new context
1120         VALIDATE_CONTEXT(context);
1121         VALIDATE_SURFACE(draw,newDrawSrfc);
1122         VALIDATE_SURFACE(read,newReadSrfc);
1123 
1124         EglSurface* newDrawPtr = newDrawSrfc.get();
1125         EglSurface* newReadPtr = newReadSrfc.get();
1126         ContextPtr  newCtx     = ctx;
1127 
1128         if (newCtx.get() && prevCtx.get()) {
1129             if (newCtx.get() == prevCtx.get()) {
1130                 if (newDrawPtr == prevCtx->draw().get() &&
1131                     newReadPtr == prevCtx->read().get()) {
1132                     // nothing to do
1133                     return EGL_TRUE;
1134                 }
1135             }
1136             else {
1137                 // Make sure previous context is detached from surfaces
1138                 releaseContext = true;
1139             }
1140         }
1141 
1142         //surfaces compatibility check
1143         if(!((*ctx->getConfig()).compatibleWith((*newDrawPtr->getConfig()))) ||
1144            !((*ctx->getConfig()).compatibleWith((*newReadPtr->getConfig())))) {
1145             RETURN_ERROR(EGL_FALSE,EGL_BAD_MATCH);
1146         }
1147 
1148          EglOS::Display* nativeDisplay = dpy->nativeType();
1149          EglOS::Surface* nativeRead = newReadPtr->native();
1150          EglOS::Surface* nativeDraw = newDrawPtr->native();
1151         //checking native window validity
1152         if(newReadPtr->type() == EglSurface::WINDOW &&
1153                 !nativeDisplay->isValidNativeWin(nativeRead)) {
1154             RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW);
1155         }
1156         if(newDrawPtr->type() == EglSurface::WINDOW &&
1157                 !nativeDisplay->isValidNativeWin(nativeDraw)) {
1158             RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW);
1159         }
1160 
1161         if(prevCtx.get()) {
1162             g_eglInfo->getIface(prevCtx->version())->flush();
1163         }
1164 
1165         {
1166             android::base::AutoLock mutex(s_eglLock);
1167             if (!dpy->nativeType()->makeCurrent(
1168                         newReadPtr->native(),
1169                         newDrawPtr->native(),
1170                         newCtx->nativeType())) {
1171                 RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS);
1172             }
1173             //TODO: handle the following errors
1174             // EGL_BAD_CURRENT_SURFACE , EGL_CONTEXT_LOST  , EGL_BAD_ACCESS
1175 
1176             thread->updateInfo(newCtx,dpy,newCtx->getGlesContext(),newCtx->getShareGroup(),dpy->getManager(newCtx->version()));
1177             newCtx->setSurfaces(newReadSrfc,newDrawSrfc);
1178             g_eglInfo->getIface(newCtx->version())->initContext(newCtx->getGlesContext(),newCtx->getShareGroup());
1179             g_eglInfo->sweepDestroySurfaces();
1180         }
1181 
1182         if (newDrawPtr->type() == EglSurface::PBUFFER &&
1183             newReadPtr->type() == EglSurface::PBUFFER) {
1184 
1185             EglPbufferSurface* tmpPbSurfacePtr =
1186                 static_cast<EglPbufferSurface*>(newDrawPtr);
1187             EglPbufferSurface* tmpReadPbSurfacePtr =
1188                 static_cast<EglPbufferSurface*>(newReadPtr);
1189 
1190             EGLint width, height, readWidth, readHeight;
1191             GLint colorFormat, depthStencilFormat, multisamples;
1192             GLint readColorFormat, readDepthStencilFormat, readMultisamples;
1193 
1194             sGetPbufferSurfaceGLProperties(
1195                     tmpPbSurfacePtr,
1196                     &width, &height,
1197                     &multisamples,
1198                     &colorFormat, &depthStencilFormat);
1199 
1200             sGetPbufferSurfaceGLProperties(
1201                     tmpReadPbSurfacePtr,
1202                     &readWidth, &readHeight,
1203                     &readMultisamples,
1204                     &readColorFormat, &readDepthStencilFormat);
1205 
1206             newCtx->getGlesContext()->initDefaultFBO(
1207                     width, height,
1208                     colorFormat, depthStencilFormat, multisamples,
1209                     &tmpPbSurfacePtr->glRboColor,
1210                     &tmpPbSurfacePtr->glRboDepth,
1211                     readWidth, readHeight,
1212                     readColorFormat, readDepthStencilFormat, readMultisamples,
1213                     &tmpReadPbSurfacePtr->glRboColor,
1214                     &tmpReadPbSurfacePtr->glRboDepth);
1215         }
1216 
1217         // Initialize the GLES extension function table used in
1218         // eglGetProcAddress for the context's GLES version if not
1219         // yet initialized. We initialize it here to make sure we call the
1220         // GLES getProcAddress after when a context is bound.
1221         g_eglInfo->initClientExtFuncTable(newCtx->version());
1222     }
1223 
1224     // release previous context surface binding
1225     if(prevCtx.get() && releaseContext) {
1226         prevCtx->setSurfaces(SurfacePtr(),SurfacePtr());
1227     }
1228 
1229     return EGL_TRUE;
1230 }
1231 
eglQueryContext(EGLDisplay display,EGLContext context,EGLint attribute,EGLint * value)1232 EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay display, EGLContext context,
1233                EGLint attribute, EGLint *value) {
1234     VALIDATE_DISPLAY(display);
1235     VALIDATE_CONTEXT(context);
1236 
1237     if(!ctx->getAttrib(attribute,value)){
1238         RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE);
1239     }
1240     return EGL_TRUE;
1241 }
1242 
eglSwapBuffers(EGLDisplay display,EGLSurface surface)1243 EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay display, EGLSurface surface) {
1244     VALIDATE_DISPLAY(display);
1245     VALIDATE_SURFACE(surface,Srfc);
1246     ThreadInfo* thread        = getThreadInfo();
1247     ContextPtr currentCtx    = thread->eglContext;
1248 
1249 
1250     //if surface not window return
1251     if(Srfc->type() != EglSurface::WINDOW){
1252         RETURN_ERROR(EGL_TRUE,EGL_SUCCESS);
1253     }
1254 
1255     if(!currentCtx.get() || !currentCtx->usingSurface(Srfc) ||
1256             !dpy->nativeType()->isValidNativeWin(Srfc.get()->native())) {
1257         RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
1258     }
1259 
1260     dpy->nativeType()->swapBuffers(Srfc->native());
1261     return EGL_TRUE;
1262 }
1263 
eglGetCurrentContext(void)1264 EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void) {
1265     MEM_TRACE("EMUGL");
1266     android::base::AutoLock mutex(s_eglLock);
1267     ThreadInfo* thread = getThreadInfo();
1268     EglDisplay* dpy    = static_cast<EglDisplay*>(thread->eglDisplay);
1269     ContextPtr  ctx    = thread->eglContext;
1270     if(dpy && ctx.get()){
1271         // This double check is required because a context might still be current after it is destroyed - in which case
1272         // its handle should be invalid, that is EGL_NO_CONTEXT should be returned even though the context is current
1273         EGLContext c = (EGLContext)SafePointerFromUInt(ctx->getHndl());
1274         if(dpy->getContext(c).get())
1275         {
1276             return c;
1277         }
1278     }
1279     return EGL_NO_CONTEXT;
1280 }
1281 
eglGetCurrentSurface(EGLint readdraw)1282 EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw) {
1283     MEM_TRACE("EMUGL");
1284     android::base::AutoLock mutex(s_eglLock);
1285     if (!EglValidate::surfaceTarget(readdraw)) {
1286         return EGL_NO_SURFACE;
1287     }
1288 
1289     ThreadInfo* thread = getThreadInfo();
1290     EglDisplay* dpy    = static_cast<EglDisplay*>(thread->eglDisplay);
1291     ContextPtr  ctx    = thread->eglContext;
1292 
1293     if(dpy && ctx.get()) {
1294         SurfacePtr surface = readdraw == EGL_READ ? ctx->read() : ctx->draw();
1295         if(surface.get())
1296         {
1297             // This double check is required because a surface might still be
1298             // current after it is destroyed - in which case its handle should
1299             // be invalid, that is EGL_NO_SURFACE should be returned even
1300             // though the surface is current.
1301             EGLSurface s = (EGLSurface)SafePointerFromUInt(surface->getHndl());
1302             surface = dpy->getSurface(s);
1303             if(surface.get())
1304             {
1305                 return s;
1306             }
1307         }
1308     }
1309     return EGL_NO_SURFACE;
1310 }
1311 
eglGetCurrentDisplay(void)1312 EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void) {
1313     MEM_TRACE("EMUGL");
1314     ThreadInfo* thread = getThreadInfo();
1315     return (thread->eglContext.get()) ? thread->eglDisplay : EGL_NO_DISPLAY;
1316 }
1317 
eglBindAPI(EGLenum api)1318 EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api) {
1319     MEM_TRACE("EMUGL");
1320     if(!EglValidate::supportedApi(api)) {
1321         RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
1322     }
1323     CURRENT_THREAD();
1324     tls_thread->setApi(api);
1325     return EGL_TRUE;
1326 }
1327 
eglQueryAPI(void)1328 EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void) {
1329     MEM_TRACE("EMUGL");
1330     CURRENT_THREAD();
1331     return tls_thread->getApi();
1332 }
1333 
eglReleaseThread(void)1334 EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void) {
1335     MEM_TRACE("EMUGL");
1336     ThreadInfo* thread  = getThreadInfo();
1337     EglDisplay* dpy     = static_cast<EglDisplay*>(thread->eglDisplay);
1338     if (!dpy) {
1339         return EGL_TRUE;
1340     }
1341     if (!translator::egl::eglMakeCurrent(dpy,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT)) {
1342         return EGL_FALSE;
1343     }
1344     return dpy->releaseThread();
1345 }
1346 
1347 EGLAPI void* EGLAPIENTRY
eglGetProcAddress(const char * procname)1348 eglGetProcAddress(const char *procname){
1349     __eglMustCastToProperFunctionPointerType retVal = NULL;
1350 
1351     if(!strncmp(procname,"egl",3)) { //EGL proc
1352         for(int i=0;i < s_eglExtensionsSize;i++){
1353             if(strcmp(procname,s_eglExtensions[i].name) == 0){
1354                 retVal = s_eglExtensions[i].address;
1355                 break;
1356             }
1357         }
1358     }
1359     else {
1360         // Look at the clientAPI (GLES) supported extension
1361         // function table.
1362         retVal = ClientAPIExts::getProcAddress(procname);
1363     }
1364     return (void*)retVal;
1365 }
1366 
1367 /************************** KHR IMAGE *************************************************************/
getEGLImage(unsigned int imageId)1368 ImagePtr getEGLImage(unsigned int imageId)
1369 {
1370     ThreadInfo* thread  = getThreadInfo();
1371     EglDisplay* dpy     = static_cast<EglDisplay*>(thread->eglDisplay);
1372     ContextPtr  ctx     = thread->eglContext;
1373     if (ctx.get()) {
1374         const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1375         return dpy->getImage(reinterpret_cast<EGLImageKHR>(imageId),
1376                 iface->restoreTexture);
1377     } else {
1378         // Maybe this is a native image, so we don't need a current gl context.
1379         const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1380         return dpy->getImage(reinterpret_cast<EGLImageKHR>(imageId),
1381                 iface->restoreTexture);
1382     }
1383     return nullptr;
1384 }
1385 
eglCreateImageKHR(EGLDisplay display,EGLContext context,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)1386 EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay display, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
1387 {
1388     VALIDATE_DISPLAY(display);
1389 
1390 	if (target != EGL_GL_TEXTURE_2D_KHR) {
1391 		// Create image from underlying and add to registry
1392 		EGLImage image = dpy->createNativeImage(dpy->getHostDriverDisplay(), 0, target, buffer, attrib_list);
1393 
1394 		if (image == EGL_NO_IMAGE_KHR) {
1395 			return EGL_NO_IMAGE_KHR;
1396 		}
1397 
1398 		ImagePtr img( new EglImage() );
1399 		img->isNative = true;
1400 		img->nativeImage = image;
1401 		img->width = 0;
1402 		img->height = 0;
1403 		if (attrib_list) {
1404 			const EGLint* current = attrib_list;
1405 			while (EGL_NONE != *current) {
1406 				switch (*current) {
1407 					case EGL_WIDTH:
1408 						img->width = current[1];
1409 						break;
1410 					case EGL_HEIGHT:
1411 						img->height = current[1];
1412 						break;
1413 					case EGL_LINUX_DRM_FOURCC_EXT:
1414 					    // TODO: Translate drm fourcc to internal format
1415 						// img->fourcc = current[1];
1416 						break;
1417 				}
1418 				current += 2;
1419 			}
1420 		}
1421 		return dpy->addImageKHR(img);
1422 	}
1423 
1424     ThreadInfo* thread  = getThreadInfo();
1425     ShareGroupPtr sg = thread->shareGroup;
1426     if (sg.get() != NULL) {
1427         NamedObjectPtr globalTexObject = sg->getNamedObject(NamedObjectType::TEXTURE,
1428                                                             SafeUIntFromPointer(buffer));
1429         if (!globalTexObject) return EGL_NO_IMAGE_KHR;
1430 
1431         ImagePtr img( new EglImage() );
1432         if (img.get() != NULL) {
1433             auto objData = sg->getObjectData(
1434                     NamedObjectType::TEXTURE, SafeUIntFromPointer(buffer));
1435             if (!objData) return EGL_NO_IMAGE_KHR;
1436 
1437             TextureData *texData = (TextureData *)objData;
1438             if(!texData->width || !texData->height) return EGL_NO_IMAGE_KHR;
1439             img->width = texData->width;
1440             img->height = texData->height;
1441             img->border = texData->border;
1442             img->internalFormat = texData->internalFormat;
1443             img->globalTexObj = globalTexObject;
1444             img->format = texData->format;
1445             img->type = texData->type;
1446             img->texStorageLevels = texData->texStorageLevels;
1447             img->saveableTexture = texData->getSaveableTexture();
1448             img->needRestore = false;
1449             img->sync = nullptr;
1450             return dpy->addImageKHR(img);
1451         }
1452     }
1453 
1454     return EGL_NO_IMAGE_KHR;
1455 }
1456 
1457 
eglDestroyImageKHR(EGLDisplay display,EGLImageKHR image)1458 EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image)
1459 {
1460     VALIDATE_DISPLAY(display);
1461     unsigned int imagehndl = SafeUIntFromPointer(image);
1462     ImagePtr img = getEGLImage(imagehndl);
1463 
1464     if (!img) return EGL_FALSE;
1465 
1466     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1467 
1468     if (img->sync) {
1469         iface->deleteSync((GLsync)img->sync);
1470         img->sync = nullptr;
1471     }
1472 
1473     if (img->isNative && !img->isImported) {
1474         dpy->destroyNativeImage(dpy->getHostDriverDisplay(), img->nativeImage);
1475     }
1476 
1477     return dpy->destroyImageKHR(image) ? EGL_TRUE:EGL_FALSE;
1478 }
1479 
1480 
eglCreateSyncKHR(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list)1481 EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) {
1482     MEM_TRACE("EMUGL");
1483     // swiftshader_indirect used to have a bug with eglCreateSyncKHR
1484     // but it seems to have been fixed now.
1485     // BUG: 65587659
1486     // BUG: 246740239
1487     if (!g_eglInfo->isEgl2EglSyncSafeToUse()) {
1488         return (EGLSyncKHR)0x42;
1489     }
1490 
1491     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1492     GLsync res = iface->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
1493     return (EGLSyncKHR)res;
1494 }
1495 
eglClientWaitSyncKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags,EGLTimeKHR timeout)1496 EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
1497     MEM_TRACE("EMUGL");
1498     android::base::AutoLock mutex(s_eglLock);
1499     if (!g_eglInfo->isEgl2EglSyncSafeToUse()) {
1500         return EGL_CONDITION_SATISFIED_KHR;
1501     }
1502     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1503     GLenum gl_wait_result =
1504         iface->clientWaitSync((GLsync)sync, GL_SYNC_FLUSH_COMMANDS_BIT, timeout);
1505     EGLint egl_wait_result;
1506 
1507     switch (gl_wait_result) {
1508     case GL_ALREADY_SIGNALED:
1509     case GL_CONDITION_SATISFIED:
1510         egl_wait_result = EGL_CONDITION_SATISFIED_KHR;
1511         break;
1512     case GL_TIMEOUT_EXPIRED:
1513         egl_wait_result = EGL_TIMEOUT_EXPIRED_KHR;
1514         break;
1515     case GL_WAIT_FAILED:
1516         egl_wait_result = EGL_FALSE;
1517         break;
1518     default:
1519         egl_wait_result = EGL_CONDITION_SATISFIED_KHR;
1520     }
1521     return egl_wait_result;
1522 }
1523 
eglDestroySyncKHR(EGLDisplay dpy,EGLSyncKHR sync)1524 EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) {
1525     MEM_TRACE("EMUGL");
1526     if (!g_eglInfo->isEgl2EglSyncSafeToUse()) {
1527         return EGL_TRUE;
1528     }
1529     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1530     iface->deleteSync((GLsync)sync);
1531     return EGL_TRUE;
1532 }
1533 
eglGetSyncAttribKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint attribute,EGLint * value)1534 EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(
1535     EGLDisplay dpy, EGLSyncKHR sync,
1536     EGLint attribute, EGLint *value) {
1537     MEM_TRACE("EMUGL");
1538 
1539     if (!g_eglInfo->isEgl2EglSyncSafeToUse()) {
1540         switch (attribute) {
1541             case EGL_SYNC_TYPE_KHR:
1542                 *value = EGL_SYNC_FENCE_KHR;
1543                 break;
1544             case EGL_SYNC_CONDITION_KHR:
1545                 *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
1546                 break;
1547             case EGL_SYNC_STATUS_KHR: {
1548                 *value = EGL_SIGNALED_KHR;
1549                 break;
1550             default:
1551                 return EGL_FALSE;
1552             }
1553         }
1554         return EGL_TRUE;
1555     }
1556 
1557     switch (attribute) {
1558         // Guest doesn't care about sync type (handled in guest),
1559         // but host side might care
1560         case EGL_SYNC_TYPE_KHR:
1561             *value = EGL_SYNC_FENCE_KHR;
1562             break;
1563         case EGL_SYNC_CONDITION_KHR:
1564             *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
1565             break;
1566         case EGL_SYNC_STATUS_KHR: {
1567             const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1568             GLint status = -1;
1569             iface->getSynciv((GLsync)sync, GL_SYNC_STATUS, sizeof(GLint), nullptr, &status);
1570             switch (status) {
1571                 case GL_UNSIGNALED:
1572                     *value = EGL_UNSIGNALED_KHR;
1573                     break;
1574                 case GL_SIGNALED:
1575                     *value = EGL_SIGNALED_KHR;
1576                     break;
1577                 default:
1578                     // error, return EGL_FALSE
1579                     return EGL_FALSE;
1580             }
1581             break;
1582         }
1583         default:
1584             return EGL_FALSE;
1585     }
1586 
1587     return EGL_TRUE;
1588 }
1589 
eglGetMaxGLESVersion(EGLDisplay display)1590 EGLAPI EGLint EGLAPIENTRY eglGetMaxGLESVersion(EGLDisplay display) {
1591     // 0: es2 1: es3.0 2: es3.1 3: es3.2
1592     VALIDATE_DISPLAY_RETURN(display, 0 /* gles2 */);
1593     return (EGLint)dpy->getMaxGlesVersion();
1594 }
1595 
eglWaitSyncKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags)1596 EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
1597     MEM_TRACE("EMUGL");
1598     if (!g_eglInfo->isEgl2EglSyncSafeToUse()) {
1599         return EGL_TRUE;
1600     }
1601     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1602     iface->waitSync((GLsync)sync, 0, -1);
1603     return EGL_TRUE;
1604 }
1605 
eglBlitFromCurrentReadBufferANDROID(EGLDisplay dpy,EGLImageKHR image)1606 EGLAPI void EGLAPIENTRY eglBlitFromCurrentReadBufferANDROID(EGLDisplay dpy, EGLImageKHR image) {
1607     MEM_TRACE("EMUGL");
1608     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1609     iface->blitFromCurrentReadBufferANDROID((GLeglImageOES)image);
1610 }
1611 
1612 // Creates a fence checkpoint for operations that have happened to |image|.
1613 // Other users of |image| can choose to wait on the resulting return fence so
1614 // that operations on |image| occur in the correct order on the GPU.  For
1615 // example, we might render some objects or upload image data to |image| in
1616 // Thread A, and then in Thread B, read the results. It is not guaranteed that
1617 // the write operations on |image| have finished on the GPU when we start
1618 // reading, so we call eglSetImageFenceANDROID at the end of writing operations
1619 // in Thread A, and then wait on the fence in Thread B.
eglSetImageFenceANDROID(EGLDisplay dpy,EGLImageKHR image)1620 EGLAPI void* EGLAPIENTRY eglSetImageFenceANDROID(EGLDisplay dpy, EGLImageKHR image) {
1621     MEM_TRACE("EMUGL");
1622     unsigned int imagehndl = SafeUIntFromPointer(image);
1623     ImagePtr img = getEGLImage(imagehndl);
1624     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1625     if (!img) return iface->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
1626 
1627     if (img->sync) {
1628         iface->deleteSync((GLsync)img->sync);
1629         img->sync = nullptr;
1630     }
1631 
1632     GLsync res = iface->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
1633     iface->flush();
1634     img->sync = res;
1635     return (void*)res;
1636 }
1637 
eglWaitImageFenceANDROID(EGLDisplay dpy,void * fence)1638 EGLAPI void EGLAPIENTRY eglWaitImageFenceANDROID(EGLDisplay dpy, void* fence) {
1639     MEM_TRACE("EMUGL");
1640     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1641     iface->waitSync((GLsync)fence, 0, -1);
1642 }
1643 
eglAddLibrarySearchPathANDROID(const char * path)1644 EGLAPI void EGLAPIENTRY eglAddLibrarySearchPathANDROID(const char* path) {
1645     MEM_TRACE("EMUGL");
1646     android::base::SharedLibrary::addLibrarySearchPath(path);
1647 }
1648 
eglQueryVulkanInteropSupportANDROID(void)1649 EGLAPI EGLBoolean EGLAPIENTRY eglQueryVulkanInteropSupportANDROID(void) {
1650     MEM_TRACE("EMUGL");
1651     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1652     return iface->vulkanInteropSupported() ? EGL_TRUE : EGL_FALSE;
1653 }
1654 
1655 /*********************************************************************************/
1656 
eglPreSaveContext(EGLDisplay display,EGLContext contex,EGLStreamKHR stream)1657 EGLAPI EGLBoolean EGLAPIENTRY eglPreSaveContext(EGLDisplay display, EGLContext contex, EGLStreamKHR stream) {
1658     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1659     assert(iface->saveTexture);
1660     if (!iface || !iface->saveTexture) return EGL_TRUE;
1661     VALIDATE_DISPLAY(display);
1662     VALIDATE_CONTEXT(contex);
1663     ctx->getShareGroup()->preSave(dpy->getGlobalNameSpace());
1664     return EGL_TRUE;
1665 }
1666 
eglSaveContext(EGLDisplay display,EGLContext contex,EGLStreamKHR stream)1667 EGLAPI EGLBoolean EGLAPIENTRY eglSaveContext(EGLDisplay display, EGLContext contex, EGLStreamKHR stream) {
1668     VALIDATE_DISPLAY(display);
1669     VALIDATE_CONTEXT(contex);
1670     ctx->onSave((android::base::Stream*)stream);
1671     return EGL_TRUE;
1672 }
1673 
eglLoadContext(EGLDisplay display,const EGLint * attrib_list,EGLStreamKHR stream)1674 EGLAPI EGLContext EGLAPIENTRY eglLoadContext(EGLDisplay display, const EGLint *attrib_list, EGLStreamKHR stream) {
1675     return eglCreateOrLoadContext(display, (EGLConfig)0, EGL_NO_CONTEXT, attrib_list, (android::base::Stream*)stream);
1676 }
1677 
eglPostSaveContext(EGLDisplay display,EGLContext context,EGLStreamKHR stream)1678 EGLAPI EGLBoolean EGLAPIENTRY eglPostSaveContext(EGLDisplay display, EGLContext context, EGLStreamKHR stream) {
1679     VALIDATE_DISPLAY(display);
1680     VALIDATE_CONTEXT(context);
1681     ctx->postSave((android::base::Stream*)stream);
1682     return EGL_TRUE;
1683 }
1684 
eglSaveConfig(EGLDisplay display,EGLConfig config,EGLStreamKHR stream)1685 EGLAPI EGLBoolean EGLAPIENTRY eglSaveConfig(EGLDisplay display,
1686         EGLConfig config, EGLStreamKHR stream) {
1687     VALIDATE_DISPLAY(display);
1688     VALIDATE_CONFIG(config);
1689     android::base::Stream* stm = static_cast<android::base::Stream*>(stream);
1690     stm->putBe32(cfg->id());
1691     return EGL_TRUE;
1692 }
1693 
eglLoadConfig(EGLDisplay display,EGLStreamKHR stream)1694 EGLAPI EGLConfig EGLAPIENTRY eglLoadConfig(EGLDisplay display, EGLStreamKHR stream) {
1695     VALIDATE_DISPLAY(display);
1696     android::base::Stream* stm = static_cast<android::base::Stream*>(stream);
1697     EGLint cfgId = stm->getBe32();
1698     EglConfig* cfg = dpy->getConfig(cfgId);
1699     if (!cfg) {
1700         fprintf(stderr,
1701                 "WARNING: EGL config mismatch, fallback to default configs\n");
1702         cfg = dpy->getDefaultConfig();
1703     }
1704     return static_cast<EGLConfig>(cfg);
1705 }
1706 
eglSaveAllImages(EGLDisplay display,EGLStreamKHR stream,const void * textureSaver)1707 EGLAPI EGLBoolean EGLAPIENTRY eglSaveAllImages(EGLDisplay display,
1708                                                EGLStreamKHR stream,
1709                                                const void* textureSaver) {
1710     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1711     assert(iface->saveTexture);
1712     if (!iface || !iface->saveTexture)
1713         return true;
1714     VALIDATE_DISPLAY(display);
1715     android::base::Stream* stm = static_cast<android::base::Stream*>(stream);
1716     iface->preSaveTexture();
1717     dpy->onSaveAllImages(
1718             stm,
1719             *static_cast<const android::snapshot::ITextureSaverPtr*>(textureSaver),
1720             iface->saveTexture,
1721             iface->restoreTexture);
1722     iface->postSaveTexture();
1723     return EGL_TRUE;
1724 }
1725 
eglLoadAllImages(EGLDisplay display,EGLStreamKHR stream,const void * textureLoader)1726 EGLAPI EGLBoolean EGLAPIENTRY eglLoadAllImages(EGLDisplay display,
1727                                                EGLStreamKHR stream,
1728                                                const void* textureLoader) {
1729     const GLESiface* iface = g_eglInfo->getIface(GLES_2_0);
1730     assert(iface->createTexture);
1731     if (!iface || !iface->createTexture)
1732         return true;
1733     VALIDATE_DISPLAY(display);
1734     android::base::Stream* stm = static_cast<android::base::Stream*>(stream);
1735     dpy->onLoadAllImages(
1736             stm,
1737             *static_cast<const android::snapshot::ITextureLoaderPtr*>(textureLoader),
1738             iface->createTexture);
1739     return EGL_TRUE;
1740 }
1741 
eglPostLoadAllImages(EGLDisplay display,EGLStreamKHR stream)1742 EGLAPI EGLBoolean EGLAPIENTRY eglPostLoadAllImages(EGLDisplay display, EGLStreamKHR stream) {
1743     VALIDATE_DISPLAY(display);
1744     android::base::Stream* stm = static_cast<android::base::Stream*>(stream);
1745     dpy->postLoadAllImages(stm);
1746     return true;
1747 }
1748 
eglUseOsEglApi(EGLBoolean enable,EGLBoolean nullEgl)1749 EGLAPI void EGLAPIENTRY eglUseOsEglApi(EGLBoolean enable, EGLBoolean nullEgl) {
1750     MEM_TRACE("EMUGL");
1751     EglGlobalInfo::setEgl2Egl(enable, nullEgl == EGL_TRUE);
1752     EglGlobalInfo::setEgl2EglSyncSafeToUse(EGL_TRUE);
1753 }
1754 
eglSetMaxGLESVersion(EGLint version)1755 EGLAPI void EGLAPIENTRY eglSetMaxGLESVersion(EGLint version) {
1756     MEM_TRACE("EMUGL");
1757     // The "version" here follows the convention of eglGetMaxGLESVesion
1758     // 0: es2 1: es3.0 2: es3.1 3: es3.2
1759     GLESVersion glesVersion = GLES_2_0;
1760     switch (version) {
1761     case 0:
1762         glesVersion = GLES_2_0;
1763         break;
1764     case 1:
1765         glesVersion = GLES_3_0;
1766         break;
1767     case 2:
1768     case 3: // TODO: GLES 3.2 support?
1769         glesVersion = GLES_3_1;
1770         break;
1771     }
1772 
1773     if (g_eglInfo->getIface(GLES_1_1)) {
1774         g_eglInfo->getIface(GLES_1_1)->setMaxGlesVersion(glesVersion);
1775     }
1776     g_eglInfo->getIface(GLES_2_0)->setMaxGlesVersion(glesVersion);
1777 }
1778 
eglFillUsages(void * usages)1779 EGLAPI void EGLAPIENTRY eglFillUsages(void* usages) {
1780     MEM_TRACE("EMUGL");
1781     // TODO: Figure out better usage metrics interface
1782     // that doesn't require linking protobuf into Translator
1783     // if (g_eglInfo->getIface(GLES_1_1) &&
1784     //         g_eglInfo->getIface(GLES_1_1)->fillGLESUsages) {
1785     //     g_eglInfo->getIface(GLES_1_1)->fillGLESUsages(
1786     //         (android_studio::EmulatorGLESUsages*)usages);
1787     // }
1788     // if (g_eglInfo->getIface(GLES_2_0) &&
1789     //         g_eglInfo->getIface(GLES_2_0)->fillGLESUsages) {
1790     //     g_eglInfo->getIface(GLES_2_0)->fillGLESUsages(
1791     //         (android_studio::EmulatorGLESUsages*)usages);
1792     // }
1793 }
1794 
eglGetNativeDisplayANDROID(EGLDisplay display)1795 EGLAPI EGLDisplay EGLAPIENTRY eglGetNativeDisplayANDROID(EGLDisplay display) {
1796     VALIDATE_DISPLAY_RETURN(display, (EGLDisplay)0);
1797     return dpy->getHostDriverDisplay();
1798 }
1799 
eglGetNativeContextANDROID(EGLDisplay display,EGLContext context)1800 EGLAPI EGLContext EGLAPIENTRY eglGetNativeContextANDROID(EGLDisplay display, EGLContext context) {
1801     VALIDATE_DISPLAY_RETURN(display, (EGLContext)0);
1802     VALIDATE_CONTEXT_RETURN(context, (EGLContext)0);
1803     return dpy->getNativeContext(context);
1804 }
1805 
eglGetNativeImageANDROID(EGLDisplay display,EGLImage image)1806 EGLAPI EGLImage EGLAPIENTRY eglGetNativeImageANDROID(EGLDisplay display, EGLImage image) {
1807     VALIDATE_DISPLAY_RETURN(display, (EGLImage)0);
1808     unsigned int imagehndl = SafeUIntFromPointer(image);
1809     ImagePtr img = getEGLImage(imagehndl);
1810     if (!img || !img->isNative) return (EGLImage)0;
1811     return img->nativeImage;
1812 }
1813 
eglSetImageInfoANDROID(EGLDisplay display,EGLImage image,EGLint width,EGLint height,EGLint internalFormat)1814 EGLAPI EGLBoolean EGLAPIENTRY eglSetImageInfoANDROID(EGLDisplay display, EGLImage image, EGLint width, EGLint height, EGLint internalFormat) {
1815     VALIDATE_DISPLAY_RETURN(display, EGL_FALSE);
1816     unsigned int imagehndl = SafeUIntFromPointer(image);
1817     ImagePtr img = getEGLImage(imagehndl);
1818     if (!img) {
1819         fprintf(stderr, "%s: error: Could not find image %p\n", __func__, image);
1820         return EGL_FALSE;
1821     }
1822 
1823     img->width = width;
1824     img->height = height;
1825     img->internalFormat = internalFormat;
1826     img->format = getFormatFromInternalFormat(internalFormat);
1827     img->type = getTypeFromInternalFormat(internalFormat);
1828 
1829     return EGL_TRUE;
1830 }
1831 
eglImportImageANDROID(EGLDisplay display,EGLImage nativeImage)1832 EGLImage eglImportImageANDROID(EGLDisplay display, EGLImage nativeImage) {
1833     VALIDATE_DISPLAY_RETURN(display, (EGLImage)0);
1834 	ImagePtr img( new EglImage() );
1835 	img->isNative = true;
1836 	img->isImported = true;
1837 	img->nativeImage = nativeImage;
1838     return dpy->addImageKHR(img);
1839 }
1840 
eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,const EGLAttrib * attribs)1841 EGLint eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, const EGLAttrib* attribs) {
1842     return EglGlobalInfo::getInstance()->getOsEngine()->eglDebugMessageControlKHR(callback, attribs);
1843 }
1844 
1845 static const GLint kAuxiliaryContextAttribsCompat[] = {
1846     EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE
1847 };
1848 
1849 static const GLint kAuxiliaryContextAttribsCore[] = {
1850     EGL_CONTEXT_CLIENT_VERSION, 2,
1851     EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
1852     EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
1853     EGL_NONE
1854 };
1855 
1856 #define NAMESPACED_EGL(f) translator::egl::f
1857 
createAndBindAuxiliaryContext(EGLContext * context_out,EGLSurface * surface_out)1858 static bool createAndBindAuxiliaryContext(EGLContext* context_out, EGLSurface* surface_out) {
1859     // create the context
1860     EGLDisplay dpy = NAMESPACED_EGL(eglGetDisplay)(EGL_DEFAULT_DISPLAY);
1861 
1862     NAMESPACED_EGL(eglBindAPI)(EGL_OPENGL_ES_API);
1863 
1864     static const GLint configAttribs[] = {
1865         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
1866         EGL_RENDERABLE_TYPE,
1867         EGL_OPENGL_ES2_BIT, EGL_NONE };
1868 
1869     EGLConfig config;
1870     int numConfigs;
1871     if (!NAMESPACED_EGL(eglChooseConfig)(dpy, configAttribs, &config, 1, &numConfigs) ||
1872         numConfigs == 0) {
1873         fprintf(stderr, "%s: could not find gles 2 config!\n", __func__);
1874         return false;
1875     }
1876 
1877     static const EGLint pbufAttribs[] =
1878         { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
1879     EGLSurface surface = eglCreatePbufferSurface(dpy, config, pbufAttribs);
1880     if (!surface) {
1881         fprintf(stderr, "%s: could not create surface\n", __func__);
1882         return false;
1883     }
1884 
1885     EGLContext context =
1886         NAMESPACED_EGL(eglCreateContext)(dpy, config, EGL_NO_CONTEXT,
1887             isCoreProfile() ? kAuxiliaryContextAttribsCore :
1888                               kAuxiliaryContextAttribsCompat);
1889 
1890     if (!NAMESPACED_EGL(eglMakeCurrent)(dpy, surface, surface, context)) {
1891         fprintf(stderr, "%s: eglMakeCurrent failed\n", __func__);
1892         return false;
1893     }
1894 
1895     if (context_out) *context_out = context;
1896     if (surface_out) *surface_out = surface;
1897 
1898     return true;
1899 }
1900 
unbindAndDestroyAuxiliaryContext(EGLContext context,EGLSurface surface)1901 static bool unbindAndDestroyAuxiliaryContext(EGLContext context, EGLSurface surface) {
1902 
1903     // create the context
1904     EGLDisplay dpy = NAMESPACED_EGL(eglGetDisplay)(EGL_DEFAULT_DISPLAY);
1905 
1906     if (!NAMESPACED_EGL(eglMakeCurrent)(
1907             dpy, EGL_NO_SURFACE, EGL_NO_SURFACE,
1908             EGL_NO_CONTEXT)) {
1909         fprintf(stderr, "%s: failure to unbind current context!\n",
1910                 __func__);
1911         return false;
1912     }
1913 
1914 
1915     if (!eglDestroySurface(dpy, surface)) {
1916         fprintf(stderr, "%s: failure to destroy surface!\n",
1917                 __func__);
1918         return false;
1919     }
1920 
1921     if (!eglDestroyContext(dpy, context)) {
1922         fprintf(stderr, "%s: failure to destroy context!\n",
1923                 __func__);
1924         return false;
1925     }
1926 
1927     return true;
1928 }
1929 
bindAuxiliaryContext(EGLContext context,EGLSurface surface)1930 static bool bindAuxiliaryContext(EGLContext context, EGLSurface surface) {
1931     // create the context
1932     EGLDisplay dpy = NAMESPACED_EGL(eglGetDisplay)(EGL_DEFAULT_DISPLAY);
1933 
1934     if (!eglMakeCurrent(dpy, surface, surface, context)) {
1935         fprintf(stderr, "%s: eglMakeCurrent failed\n", __func__);
1936         return false;
1937     }
1938 
1939     return true;
1940 }
1941 
unbindAuxiliaryContext()1942 static bool unbindAuxiliaryContext() {
1943 
1944     // create the context
1945     EGLDisplay dpy = NAMESPACED_EGL(eglGetDisplay)(EGL_DEFAULT_DISPLAY);
1946 
1947     if (!eglMakeCurrent(
1948             dpy, EGL_NO_SURFACE, EGL_NO_SURFACE,
1949             EGL_NO_CONTEXT)) {
1950         fprintf(stderr, "%s: failure to unbind current context!\n",
1951                 __func__);
1952         return false;
1953     }
1954 
1955     return true;
1956 }
1957 
eglGetError(void)1958 EGLAPI EGLint EGLAPIENTRY eglGetError(void) {
1959     MEM_TRACE("EMUGL");
1960     CURRENT_THREAD();
1961     EGLint err = tls_thread->getError();
1962     tls_thread->setError(EGL_SUCCESS);
1963     return err;
1964 }
1965 
1966 
1967 } // namespace translator
1968 } // namespace egl
1969