• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  ** Copyright 2007, 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 
17 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18 
19 #include <dlfcn.h>
20 #include <ctype.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include <hardware/gralloc.h>
25 #include <system/window.h>
26 
27 #include <EGL/egl.h>
28 #include <EGL/eglext.h>
29 
30 #include <cutils/log.h>
31 #include <cutils/atomic.h>
32 #include <cutils/compiler.h>
33 #include <cutils/properties.h>
34 #include <cutils/memory.h>
35 
36 #include <ui/GraphicBuffer.h>
37 
38 #include <utils/KeyedVector.h>
39 #include <utils/SortedVector.h>
40 #include <utils/String8.h>
41 #include <utils/Trace.h>
42 
43 #include "../egl_impl.h"
44 #include "../hooks.h"
45 
46 #include "egl_display.h"
47 #include "egl_object.h"
48 #include "egl_tls.h"
49 #include "egldefs.h"
50 
51 using namespace android;
52 
53 // This extension has not been ratified yet, so can't be shipped.
54 // Implementation is incomplete and untested.
55 #define ENABLE_EGL_KHR_GL_COLORSPACE 0
56 
57 #define ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS 0
58 
59 // ----------------------------------------------------------------------------
60 
61 namespace android {
62 
63 struct extention_map_t {
64     const char* name;
65     __eglMustCastToProperFunctionPointerType address;
66 };
67 
68 /*
69  * This is the list of EGL extensions exposed to applications.
70  *
71  * Some of them (gBuiltinExtensionString) are implemented entirely in this EGL
72  * wrapper and are always available.
73  *
74  * The rest (gExtensionString) depend on support in the EGL driver, and are
75  * only available if the driver supports them. However, some of these must be
76  * supported because they are used by the Android system itself; these are
77  * listed as mandatory below and are required by the CDD. The system *assumes*
78  * the mandatory extensions are present and may not function properly if some
79  * are missing.
80  *
81  * NOTE: Both strings MUST have a single space as the last character.
82  */
83 extern char const * const gBuiltinExtensionString =
84         "EGL_KHR_get_all_proc_addresses "
85         "EGL_ANDROID_presentation_time "
86         "EGL_KHR_swap_buffers_with_damage "
87         "EGL_ANDROID_create_native_client_buffer "
88         "EGL_ANDROID_front_buffer_auto_refresh "
89 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS
90         "EGL_ANDROID_get_frame_timestamps "
91 #endif
92         ;
93 extern char const * const gExtensionString  =
94         "EGL_KHR_image "                        // mandatory
95         "EGL_KHR_image_base "                   // mandatory
96         "EGL_KHR_image_pixmap "
97         "EGL_KHR_lock_surface "
98 #if (ENABLE_EGL_KHR_GL_COLORSPACE != 0)
99         "EGL_KHR_gl_colorspace "
100 #endif
101         "EGL_KHR_gl_texture_2D_image "
102         "EGL_KHR_gl_texture_3D_image "
103         "EGL_KHR_gl_texture_cubemap_image "
104         "EGL_KHR_gl_renderbuffer_image "
105         "EGL_KHR_reusable_sync "
106         "EGL_KHR_fence_sync "
107         "EGL_KHR_create_context "
108         "EGL_KHR_config_attribs "
109         "EGL_KHR_surfaceless_context "
110         "EGL_KHR_stream "
111         "EGL_KHR_stream_fifo "
112         "EGL_KHR_stream_producer_eglsurface "
113         "EGL_KHR_stream_consumer_gltexture "
114         "EGL_KHR_stream_cross_process_fd "
115         "EGL_EXT_create_context_robustness "
116         "EGL_NV_system_time "
117         "EGL_ANDROID_image_native_buffer "      // mandatory
118         "EGL_KHR_wait_sync "                    // strongly recommended
119         "EGL_ANDROID_recordable "               // mandatory
120         "EGL_KHR_partial_update "               // strongly recommended
121         "EGL_EXT_buffer_age "                   // strongly recommended with partial_update
122         "EGL_KHR_create_context_no_error "
123         "EGL_KHR_mutable_render_buffer "
124         "EGL_EXT_yuv_surface "
125         "EGL_EXT_protected_content "
126         ;
127 
128 // extensions not exposed to applications but used by the ANDROID system
129 //      "EGL_ANDROID_blob_cache "               // strongly recommended
130 //      "EGL_IMG_hibernate_process "            // optional
131 //      "EGL_ANDROID_native_fence_sync "        // strongly recommended
132 //      "EGL_ANDROID_framebuffer_target "       // mandatory for HWC 1.1
133 //      "EGL_ANDROID_image_crop "               // optional
134 
135 /*
136  * EGL Extensions entry-points exposed to 3rd party applications
137  * (keep in sync with gExtensionString above)
138  *
139  */
140 static const extention_map_t sExtensionMap[] = {
141     // EGL_KHR_lock_surface
142     { "eglLockSurfaceKHR",
143             (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR },
144     { "eglUnlockSurfaceKHR",
145             (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR },
146 
147     // EGL_KHR_image, EGL_KHR_image_base
148     { "eglCreateImageKHR",
149             (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
150     { "eglDestroyImageKHR",
151             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
152 
153     // EGL_KHR_reusable_sync, EGL_KHR_fence_sync
154     { "eglCreateSyncKHR",
155             (__eglMustCastToProperFunctionPointerType)&eglCreateSyncKHR },
156     { "eglDestroySyncKHR",
157             (__eglMustCastToProperFunctionPointerType)&eglDestroySyncKHR },
158     { "eglClientWaitSyncKHR",
159             (__eglMustCastToProperFunctionPointerType)&eglClientWaitSyncKHR },
160     { "eglSignalSyncKHR",
161             (__eglMustCastToProperFunctionPointerType)&eglSignalSyncKHR },
162     { "eglGetSyncAttribKHR",
163             (__eglMustCastToProperFunctionPointerType)&eglGetSyncAttribKHR },
164 
165     // EGL_NV_system_time
166     { "eglGetSystemTimeFrequencyNV",
167             (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV },
168     { "eglGetSystemTimeNV",
169             (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV },
170 
171     // EGL_KHR_wait_sync
172     { "eglWaitSyncKHR",
173             (__eglMustCastToProperFunctionPointerType)&eglWaitSyncKHR },
174 
175     // EGL_ANDROID_presentation_time
176     { "eglPresentationTimeANDROID",
177             (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID },
178 
179     // EGL_KHR_swap_buffers_with_damage
180     { "eglSwapBuffersWithDamageKHR",
181             (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
182 
183     // EGL_ANDROID_native_client_buffer
184     { "eglCreateNativeClientBufferANDROID",
185             (__eglMustCastToProperFunctionPointerType)&eglCreateNativeClientBufferANDROID },
186 
187     // EGL_KHR_partial_update
188     { "eglSetDamageRegionKHR",
189             (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
190 
191     { "eglCreateStreamKHR",
192             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamKHR },
193     { "eglDestroyStreamKHR",
194             (__eglMustCastToProperFunctionPointerType)&eglDestroyStreamKHR },
195     { "eglStreamAttribKHR",
196             (__eglMustCastToProperFunctionPointerType)&eglStreamAttribKHR },
197     { "eglQueryStreamKHR",
198             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamKHR },
199     { "eglQueryStreamu64KHR",
200             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamu64KHR },
201     { "eglQueryStreamTimeKHR",
202             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamTimeKHR },
203     { "eglCreateStreamProducerSurfaceKHR",
204             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamProducerSurfaceKHR },
205     { "eglStreamConsumerGLTextureExternalKHR",
206             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerGLTextureExternalKHR },
207     { "eglStreamConsumerAcquireKHR",
208             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerAcquireKHR },
209     { "eglStreamConsumerReleaseKHR",
210             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerReleaseKHR },
211     { "eglGetStreamFileDescriptorKHR",
212             (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR },
213     { "eglCreateStreamFromFileDescriptorKHR",
214             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR },
215 
216     // EGL_ANDROID_get_frame_timestamps
217     { "eglGetFrameTimestampsANDROID",
218             (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID },
219     { "eglQueryTimestampSupportedANDROID",
220             (__eglMustCastToProperFunctionPointerType)&eglQueryTimestampSupportedANDROID },
221 };
222 
223 /*
224  * These extensions entry-points should not be exposed to applications.
225  * They're used internally by the Android EGL layer.
226  */
227 #define FILTER_EXTENSIONS(procname) \
228         (!strcmp((procname), "eglSetBlobCacheFuncsANDROID") ||    \
229          !strcmp((procname), "eglHibernateProcessIMG")      ||    \
230          !strcmp((procname), "eglAwakenProcessIMG")         ||    \
231          !strcmp((procname), "eglDupNativeFenceFDANDROID"))
232 
233 
234 
235 // accesses protected by sExtensionMapMutex
236 static DefaultKeyedVector<String8, __eglMustCastToProperFunctionPointerType> sGLExtentionMap;
237 static int sGLExtentionSlot = 0;
238 static pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER;
239 
findProcAddress(const char * name,const extention_map_t * map,size_t n)240 static void(*findProcAddress(const char* name,
241         const extention_map_t* map, size_t n))() {
242     for (uint32_t i=0 ; i<n ; i++) {
243         if (!strcmp(name, map[i].name)) {
244             return map[i].address;
245         }
246     }
247     return NULL;
248 }
249 
250 // ----------------------------------------------------------------------------
251 
252 extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
253 extern EGLBoolean egl_init_drivers();
254 extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
255 extern gl_hooks_t gHooksTrace;
256 
257 } // namespace android;
258 
259 
260 // ----------------------------------------------------------------------------
261 
clearError()262 static inline void clearError() { egl_tls_t::clearError(); }
getContext()263 static inline EGLContext getContext() { return egl_tls_t::getContext(); }
264 
265 // ----------------------------------------------------------------------------
266 
eglGetDisplay(EGLNativeDisplayType display)267 EGLDisplay eglGetDisplay(EGLNativeDisplayType display)
268 {
269     clearError();
270 
271     uintptr_t index = reinterpret_cast<uintptr_t>(display);
272     if (index >= NUM_DISPLAYS) {
273         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
274     }
275 
276     if (egl_init_drivers() == EGL_FALSE) {
277         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
278     }
279 
280     EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);
281     return dpy;
282 }
283 
284 // ----------------------------------------------------------------------------
285 // Initialization
286 // ----------------------------------------------------------------------------
287 
eglInitialize(EGLDisplay dpy,EGLint * major,EGLint * minor)288 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
289 {
290     clearError();
291 
292     egl_display_ptr dp = get_display(dpy);
293     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
294 
295     EGLBoolean res = dp->initialize(major, minor);
296 
297     return res;
298 }
299 
eglTerminate(EGLDisplay dpy)300 EGLBoolean eglTerminate(EGLDisplay dpy)
301 {
302     // NOTE: don't unload the drivers b/c some APIs can be called
303     // after eglTerminate() has been called. eglTerminate() only
304     // terminates an EGLDisplay, not a EGL itself.
305 
306     clearError();
307 
308     egl_display_ptr dp = get_display(dpy);
309     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
310 
311     EGLBoolean res = dp->terminate();
312 
313     return res;
314 }
315 
316 // ----------------------------------------------------------------------------
317 // configuration
318 // ----------------------------------------------------------------------------
319 
eglGetConfigs(EGLDisplay dpy,EGLConfig * configs,EGLint config_size,EGLint * num_config)320 EGLBoolean eglGetConfigs(   EGLDisplay dpy,
321                             EGLConfig *configs,
322                             EGLint config_size, EGLint *num_config)
323 {
324     clearError();
325 
326     const egl_display_ptr dp = validate_display(dpy);
327     if (!dp) return EGL_FALSE;
328 
329     if (num_config==0) {
330         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
331     }
332 
333     EGLBoolean res = EGL_FALSE;
334     *num_config = 0;
335 
336     egl_connection_t* const cnx = &gEGLImpl;
337     if (cnx->dso) {
338         res = cnx->egl.eglGetConfigs(
339                 dp->disp.dpy, configs, config_size, num_config);
340     }
341 
342     return res;
343 }
344 
eglChooseConfig(EGLDisplay dpy,const EGLint * attrib_list,EGLConfig * configs,EGLint config_size,EGLint * num_config)345 EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
346                             EGLConfig *configs, EGLint config_size,
347                             EGLint *num_config)
348 {
349     clearError();
350 
351     const egl_display_ptr dp = validate_display(dpy);
352     if (!dp) return EGL_FALSE;
353 
354     if (num_config==0) {
355         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
356     }
357 
358     EGLBoolean res = EGL_FALSE;
359     *num_config = 0;
360 
361     egl_connection_t* const cnx = &gEGLImpl;
362     if (cnx->dso) {
363         if (attrib_list) {
364             char value[PROPERTY_VALUE_MAX];
365             property_get("debug.egl.force_msaa", value, "false");
366 
367             if (!strcmp(value, "true")) {
368                 size_t attribCount = 0;
369                 EGLint attrib = attrib_list[0];
370 
371                 // Only enable MSAA if the context is OpenGL ES 2.0 and
372                 // if no caveat is requested
373                 const EGLint *attribRendererable = NULL;
374                 const EGLint *attribCaveat = NULL;
375 
376                 // Count the number of attributes and look for
377                 // EGL_RENDERABLE_TYPE and EGL_CONFIG_CAVEAT
378                 while (attrib != EGL_NONE) {
379                     attrib = attrib_list[attribCount];
380                     switch (attrib) {
381                         case EGL_RENDERABLE_TYPE:
382                             attribRendererable = &attrib_list[attribCount];
383                             break;
384                         case EGL_CONFIG_CAVEAT:
385                             attribCaveat = &attrib_list[attribCount];
386                             break;
387                     }
388                     attribCount++;
389                 }
390 
391                 if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT &&
392                         (!attribCaveat || attribCaveat[1] != EGL_NONE)) {
393 
394                     // Insert 2 extra attributes to force-enable MSAA 4x
395                     EGLint aaAttribs[attribCount + 4];
396                     aaAttribs[0] = EGL_SAMPLE_BUFFERS;
397                     aaAttribs[1] = 1;
398                     aaAttribs[2] = EGL_SAMPLES;
399                     aaAttribs[3] = 4;
400 
401                     memcpy(&aaAttribs[4], attrib_list, attribCount * sizeof(EGLint));
402 
403                     EGLint numConfigAA;
404                     EGLBoolean resAA = cnx->egl.eglChooseConfig(
405                             dp->disp.dpy, aaAttribs, configs, config_size, &numConfigAA);
406 
407                     if (resAA == EGL_TRUE && numConfigAA > 0) {
408                         ALOGD("Enabling MSAA 4x");
409                         *num_config = numConfigAA;
410                         return resAA;
411                     }
412                 }
413             }
414         }
415 
416         res = cnx->egl.eglChooseConfig(
417                 dp->disp.dpy, attrib_list, configs, config_size, num_config);
418     }
419     return res;
420 }
421 
eglGetConfigAttrib(EGLDisplay dpy,EGLConfig config,EGLint attribute,EGLint * value)422 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
423         EGLint attribute, EGLint *value)
424 {
425     clearError();
426 
427     egl_connection_t* cnx = NULL;
428     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
429     if (!dp) return EGL_FALSE;
430 
431     return cnx->egl.eglGetConfigAttrib(
432             dp->disp.dpy, config, attribute, value);
433 }
434 
435 // ----------------------------------------------------------------------------
436 // surfaces
437 // ----------------------------------------------------------------------------
438 
439 // The EGL_KHR_gl_colorspace spec hasn't been ratified yet, so these haven't
440 // been added to the Khronos egl.h.
441 #define EGL_GL_COLORSPACE_KHR           EGL_VG_COLORSPACE
442 #define EGL_GL_COLORSPACE_SRGB_KHR      EGL_VG_COLORSPACE_sRGB
443 #define EGL_GL_COLORSPACE_LINEAR_KHR    EGL_VG_COLORSPACE_LINEAR
444 
445 // Turn linear formats into corresponding sRGB formats when colorspace is
446 // EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
447 // formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
448 // the modification isn't possible, the original dataSpace is returned.
modifyBufferDataspace(android_dataspace dataSpace,EGLint colorspace)449 static android_dataspace modifyBufferDataspace( android_dataspace dataSpace,
450                                                 EGLint colorspace) {
451     if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
452         return HAL_DATASPACE_SRGB_LINEAR;
453     } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
454         return HAL_DATASPACE_SRGB;
455     }
456     return dataSpace;
457 }
458 
eglCreateWindowSurface(EGLDisplay dpy,EGLConfig config,NativeWindowType window,const EGLint * attrib_list)459 EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
460                                     NativeWindowType window,
461                                     const EGLint *attrib_list)
462 {
463     clearError();
464 
465     egl_connection_t* cnx = NULL;
466     egl_display_ptr dp = validate_display_connection(dpy, cnx);
467     if (dp) {
468         EGLDisplay iDpy = dp->disp.dpy;
469 
470         int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
471         if (result != OK) {
472             ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
473                     "failed (%#x) (already connected to another API?)",
474                     window, result);
475             return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
476         }
477 
478         // Set the native window's buffers format to match what this config requests.
479         // Whether to use sRGB gamma is not part of the EGLconfig, but is part
480         // of our native format. So if sRGB gamma is requested, we have to
481         // modify the EGLconfig's format before setting the native window's
482         // format.
483 
484         // by default, just pick RGBA_8888
485         EGLint format = HAL_PIXEL_FORMAT_RGBA_8888;
486         android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
487 
488         EGLint a = 0;
489         cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a);
490         if (a > 0) {
491             // alpha-channel requested, there's really only one suitable format
492             format = HAL_PIXEL_FORMAT_RGBA_8888;
493         } else {
494             EGLint r, g, b;
495             r = g = b = 0;
496             cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_RED_SIZE,   &r);
497             cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_GREEN_SIZE, &g);
498             cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_BLUE_SIZE,  &b);
499             EGLint colorDepth = r + g + b;
500             if (colorDepth <= 16) {
501                 format = HAL_PIXEL_FORMAT_RGB_565;
502             } else {
503                 format = HAL_PIXEL_FORMAT_RGBX_8888;
504             }
505         }
506 
507         // now select a corresponding sRGB format if needed
508         if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
509             for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
510                 if (*attr == EGL_GL_COLORSPACE_KHR) {
511                     if (ENABLE_EGL_KHR_GL_COLORSPACE) {
512                         dataSpace = modifyBufferDataspace(dataSpace, *(attr+1));
513                     } else {
514                         // Normally we'd pass through unhandled attributes to
515                         // the driver. But in case the driver implements this
516                         // extension but we're disabling it, we want to prevent
517                         // it getting through -- support will be broken without
518                         // our help.
519                         ALOGE("sRGB window surfaces not supported");
520                         return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
521                     }
522                 }
523             }
524         }
525 
526         if (format != 0) {
527             int err = native_window_set_buffers_format(window, format);
528             if (err != 0) {
529                 ALOGE("error setting native window pixel format: %s (%d)",
530                         strerror(-err), err);
531                 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
532                 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
533             }
534         }
535 
536         if (dataSpace != 0) {
537             int err = native_window_set_buffers_data_space(window, dataSpace);
538             if (err != 0) {
539                 ALOGE("error setting native window pixel dataSpace: %s (%d)",
540                         strerror(-err), err);
541                 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
542                 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
543             }
544         }
545 
546         // the EGL spec requires that a new EGLSurface default to swap interval
547         // 1, so explicitly set that on the window here.
548         ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
549         anw->setSwapInterval(anw, 1);
550 
551         EGLSurface surface = cnx->egl.eglCreateWindowSurface(
552                 iDpy, config, window, attrib_list);
553         if (surface != EGL_NO_SURFACE) {
554             egl_surface_t* s = new egl_surface_t(dp.get(), config, window,
555                     surface, cnx);
556             return s;
557         }
558 
559         // EGLSurface creation failed
560         native_window_set_buffers_format(window, 0);
561         native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
562     }
563     return EGL_NO_SURFACE;
564 }
565 
eglCreatePixmapSurface(EGLDisplay dpy,EGLConfig config,NativePixmapType pixmap,const EGLint * attrib_list)566 EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
567                                     NativePixmapType pixmap,
568                                     const EGLint *attrib_list)
569 {
570     clearError();
571 
572     egl_connection_t* cnx = NULL;
573     egl_display_ptr dp = validate_display_connection(dpy, cnx);
574     if (dp) {
575         EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
576                 dp->disp.dpy, config, pixmap, attrib_list);
577         if (surface != EGL_NO_SURFACE) {
578             egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
579                     surface, cnx);
580             return s;
581         }
582     }
583     return EGL_NO_SURFACE;
584 }
585 
eglCreatePbufferSurface(EGLDisplay dpy,EGLConfig config,const EGLint * attrib_list)586 EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
587                                     const EGLint *attrib_list)
588 {
589     clearError();
590 
591     egl_connection_t* cnx = NULL;
592     egl_display_ptr dp = validate_display_connection(dpy, cnx);
593     if (dp) {
594         EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
595                 dp->disp.dpy, config, attrib_list);
596         if (surface != EGL_NO_SURFACE) {
597             egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
598                     surface, cnx);
599             return s;
600         }
601     }
602     return EGL_NO_SURFACE;
603 }
604 
eglDestroySurface(EGLDisplay dpy,EGLSurface surface)605 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
606 {
607     clearError();
608 
609     const egl_display_ptr dp = validate_display(dpy);
610     if (!dp) return EGL_FALSE;
611 
612     SurfaceRef _s(dp.get(), surface);
613     if (!_s.get())
614         return setError(EGL_BAD_SURFACE, EGL_FALSE);
615 
616     egl_surface_t * const s = get_surface(surface);
617     EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
618     if (result == EGL_TRUE) {
619         _s.terminate();
620     }
621     return result;
622 }
623 
eglQuerySurface(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint * value)624 EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
625                             EGLint attribute, EGLint *value)
626 {
627     clearError();
628 
629     const egl_display_ptr dp = validate_display(dpy);
630     if (!dp) return EGL_FALSE;
631 
632     SurfaceRef _s(dp.get(), surface);
633     if (!_s.get())
634         return setError(EGL_BAD_SURFACE, EGL_FALSE);
635 
636     egl_surface_t const * const s = get_surface(surface);
637     return s->cnx->egl.eglQuerySurface(
638             dp->disp.dpy, s->surface, attribute, value);
639 }
640 
eglBeginFrame(EGLDisplay dpy,EGLSurface surface)641 void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
642     ATRACE_CALL();
643     clearError();
644 
645     const egl_display_ptr dp = validate_display(dpy);
646     if (!dp) {
647         return;
648     }
649 
650     SurfaceRef _s(dp.get(), surface);
651     if (!_s.get()) {
652         setError(EGL_BAD_SURFACE, EGL_FALSE);
653         return;
654     }
655 }
656 
657 // ----------------------------------------------------------------------------
658 // Contexts
659 // ----------------------------------------------------------------------------
660 
eglCreateContext(EGLDisplay dpy,EGLConfig config,EGLContext share_list,const EGLint * attrib_list)661 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
662                             EGLContext share_list, const EGLint *attrib_list)
663 {
664     clearError();
665 
666     egl_connection_t* cnx = NULL;
667     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
668     if (dp) {
669         if (share_list != EGL_NO_CONTEXT) {
670             if (!ContextRef(dp.get(), share_list).get()) {
671                 return setError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
672             }
673             egl_context_t* const c = get_context(share_list);
674             share_list = c->context;
675         }
676         EGLContext context = cnx->egl.eglCreateContext(
677                 dp->disp.dpy, config, share_list, attrib_list);
678         if (context != EGL_NO_CONTEXT) {
679             // figure out if it's a GLESv1 or GLESv2
680             int version = 0;
681             if (attrib_list) {
682                 while (*attrib_list != EGL_NONE) {
683                     GLint attr = *attrib_list++;
684                     GLint value = *attrib_list++;
685                     if (attr == EGL_CONTEXT_CLIENT_VERSION) {
686                         if (value == 1) {
687                             version = egl_connection_t::GLESv1_INDEX;
688                         } else if (value == 2 || value == 3) {
689                             version = egl_connection_t::GLESv2_INDEX;
690                         }
691                     }
692                 };
693             }
694             egl_context_t* c = new egl_context_t(dpy, context, config, cnx,
695                     version);
696             return c;
697         }
698     }
699     return EGL_NO_CONTEXT;
700 }
701 
eglDestroyContext(EGLDisplay dpy,EGLContext ctx)702 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
703 {
704     clearError();
705 
706     const egl_display_ptr dp = validate_display(dpy);
707     if (!dp)
708         return EGL_FALSE;
709 
710     ContextRef _c(dp.get(), ctx);
711     if (!_c.get())
712         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
713 
714     egl_context_t * const c = get_context(ctx);
715     EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
716     if (result == EGL_TRUE) {
717         _c.terminate();
718     }
719     return result;
720 }
721 
eglMakeCurrent(EGLDisplay dpy,EGLSurface draw,EGLSurface read,EGLContext ctx)722 EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
723                             EGLSurface read, EGLContext ctx)
724 {
725     clearError();
726 
727     egl_display_ptr dp = validate_display(dpy);
728     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
729 
730     // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
731     // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
732     // a valid but uninitialized display.
733     if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
734          (draw != EGL_NO_SURFACE) ) {
735         if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
736     }
737 
738     // get a reference to the object passed in
739     ContextRef _c(dp.get(), ctx);
740     SurfaceRef _d(dp.get(), draw);
741     SurfaceRef _r(dp.get(), read);
742 
743     // validate the context (if not EGL_NO_CONTEXT)
744     if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
745         // EGL_NO_CONTEXT is valid
746         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
747     }
748 
749     // these are the underlying implementation's object
750     EGLContext impl_ctx  = EGL_NO_CONTEXT;
751     EGLSurface impl_draw = EGL_NO_SURFACE;
752     EGLSurface impl_read = EGL_NO_SURFACE;
753 
754     // these are our objects structs passed in
755     egl_context_t       * c = NULL;
756     egl_surface_t const * d = NULL;
757     egl_surface_t const * r = NULL;
758 
759     // these are the current objects structs
760     egl_context_t * cur_c = get_context(getContext());
761 
762     if (ctx != EGL_NO_CONTEXT) {
763         c = get_context(ctx);
764         impl_ctx = c->context;
765     } else {
766         // no context given, use the implementation of the current context
767         if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
768             // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
769             return setError(EGL_BAD_MATCH, EGL_FALSE);
770         }
771         if (cur_c == NULL) {
772             // no current context
773             // not an error, there is just no current context.
774             return EGL_TRUE;
775         }
776     }
777 
778     // retrieve the underlying implementation's draw EGLSurface
779     if (draw != EGL_NO_SURFACE) {
780         if (!_d.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
781         d = get_surface(draw);
782         impl_draw = d->surface;
783     }
784 
785     // retrieve the underlying implementation's read EGLSurface
786     if (read != EGL_NO_SURFACE) {
787         if (!_r.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
788         r = get_surface(read);
789         impl_read = r->surface;
790     }
791 
792 
793     EGLBoolean result = dp->makeCurrent(c, cur_c,
794             draw, read, ctx,
795             impl_draw, impl_read, impl_ctx);
796 
797     if (result == EGL_TRUE) {
798         if (c) {
799             setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
800             egl_tls_t::setContext(ctx);
801             _c.acquire();
802             _r.acquire();
803             _d.acquire();
804         } else {
805             setGLHooksThreadSpecific(&gHooksNoContext);
806             egl_tls_t::setContext(EGL_NO_CONTEXT);
807         }
808     } else {
809         // this will ALOGE the error
810         egl_connection_t* const cnx = &gEGLImpl;
811         result = setError(cnx->egl.eglGetError(), EGL_FALSE);
812     }
813     return result;
814 }
815 
816 
eglQueryContext(EGLDisplay dpy,EGLContext ctx,EGLint attribute,EGLint * value)817 EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
818                             EGLint attribute, EGLint *value)
819 {
820     clearError();
821 
822     const egl_display_ptr dp = validate_display(dpy);
823     if (!dp) return EGL_FALSE;
824 
825     ContextRef _c(dp.get(), ctx);
826     if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
827 
828     egl_context_t * const c = get_context(ctx);
829     return c->cnx->egl.eglQueryContext(
830             dp->disp.dpy, c->context, attribute, value);
831 
832 }
833 
eglGetCurrentContext(void)834 EGLContext eglGetCurrentContext(void)
835 {
836     // could be called before eglInitialize(), but we wouldn't have a context
837     // then, and this function would correctly return EGL_NO_CONTEXT.
838 
839     clearError();
840 
841     EGLContext ctx = getContext();
842     return ctx;
843 }
844 
eglGetCurrentSurface(EGLint readdraw)845 EGLSurface eglGetCurrentSurface(EGLint readdraw)
846 {
847     // could be called before eglInitialize(), but we wouldn't have a context
848     // then, and this function would correctly return EGL_NO_SURFACE.
849 
850     clearError();
851 
852     EGLContext ctx = getContext();
853     if (ctx) {
854         egl_context_t const * const c = get_context(ctx);
855         if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
856         switch (readdraw) {
857             case EGL_READ: return c->read;
858             case EGL_DRAW: return c->draw;
859             default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
860         }
861     }
862     return EGL_NO_SURFACE;
863 }
864 
eglGetCurrentDisplay(void)865 EGLDisplay eglGetCurrentDisplay(void)
866 {
867     // could be called before eglInitialize(), but we wouldn't have a context
868     // then, and this function would correctly return EGL_NO_DISPLAY.
869 
870     clearError();
871 
872     EGLContext ctx = getContext();
873     if (ctx) {
874         egl_context_t const * const c = get_context(ctx);
875         if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
876         return c->dpy;
877     }
878     return EGL_NO_DISPLAY;
879 }
880 
eglWaitGL(void)881 EGLBoolean eglWaitGL(void)
882 {
883     clearError();
884 
885     egl_connection_t* const cnx = &gEGLImpl;
886     if (!cnx->dso)
887         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
888 
889     return cnx->egl.eglWaitGL();
890 }
891 
eglWaitNative(EGLint engine)892 EGLBoolean eglWaitNative(EGLint engine)
893 {
894     clearError();
895 
896     egl_connection_t* const cnx = &gEGLImpl;
897     if (!cnx->dso)
898         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
899 
900     return cnx->egl.eglWaitNative(engine);
901 }
902 
eglGetError(void)903 EGLint eglGetError(void)
904 {
905     EGLint err = EGL_SUCCESS;
906     egl_connection_t* const cnx = &gEGLImpl;
907     if (cnx->dso) {
908         err = cnx->egl.eglGetError();
909     }
910     if (err == EGL_SUCCESS) {
911         err = egl_tls_t::getError();
912     }
913     return err;
914 }
915 
findBuiltinWrapper(const char * procname)916 static __eglMustCastToProperFunctionPointerType findBuiltinWrapper(
917         const char* procname) {
918     const egl_connection_t* cnx = &gEGLImpl;
919     void* proc = NULL;
920 
921     proc = dlsym(cnx->libEgl, procname);
922     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
923 
924     proc = dlsym(cnx->libGles2, procname);
925     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
926 
927     proc = dlsym(cnx->libGles1, procname);
928     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
929 
930     return NULL;
931 }
932 
eglGetProcAddress(const char * procname)933 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
934 {
935     // eglGetProcAddress() could be the very first function called
936     // in which case we must make sure we've initialized ourselves, this
937     // happens the first time egl_get_display() is called.
938 
939     clearError();
940 
941     if (egl_init_drivers() == EGL_FALSE) {
942         setError(EGL_BAD_PARAMETER, NULL);
943         return  NULL;
944     }
945 
946     if (FILTER_EXTENSIONS(procname)) {
947         return NULL;
948     }
949 
950     __eglMustCastToProperFunctionPointerType addr;
951     addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap));
952     if (addr) return addr;
953 
954     addr = findBuiltinWrapper(procname);
955     if (addr) return addr;
956 
957     // this protects accesses to sGLExtentionMap and sGLExtentionSlot
958     pthread_mutex_lock(&sExtensionMapMutex);
959 
960         /*
961          * Since eglGetProcAddress() is not associated to anything, it needs
962          * to return a function pointer that "works" regardless of what
963          * the current context is.
964          *
965          * For this reason, we return a "forwarder", a small stub that takes
966          * care of calling the function associated with the context
967          * currently bound.
968          *
969          * We first look for extensions we've already resolved, if we're seeing
970          * this extension for the first time, we go through all our
971          * implementations and call eglGetProcAddress() and record the
972          * result in the appropriate implementation hooks and return the
973          * address of the forwarder corresponding to that hook set.
974          *
975          */
976 
977         const String8 name(procname);
978         addr = sGLExtentionMap.valueFor(name);
979         const int slot = sGLExtentionSlot;
980 
981         ALOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS,
982                 "no more slots for eglGetProcAddress(\"%s\")",
983                 procname);
984 
985         if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
986             bool found = false;
987 
988             egl_connection_t* const cnx = &gEGLImpl;
989             if (cnx->dso && cnx->egl.eglGetProcAddress) {
990                 // Extensions are independent of the bound context
991                 addr =
992                 cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
993                 cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] =
994                         cnx->egl.eglGetProcAddress(procname);
995                 if (addr) found = true;
996             }
997 
998             if (found) {
999                 addr = gExtensionForwarders[slot];
1000                 sGLExtentionMap.add(name, addr);
1001                 sGLExtentionSlot++;
1002             }
1003         }
1004 
1005     pthread_mutex_unlock(&sExtensionMapMutex);
1006     return addr;
1007 }
1008 
1009 class FrameCompletionThread : public Thread {
1010 public:
1011 
queueSync(EGLSyncKHR sync)1012     static void queueSync(EGLSyncKHR sync) {
1013         static sp<FrameCompletionThread> thread(new FrameCompletionThread);
1014         static bool running = false;
1015         if (!running) {
1016             thread->run("GPUFrameCompletion");
1017             running = true;
1018         }
1019         {
1020             Mutex::Autolock lock(thread->mMutex);
1021             ScopedTrace st(ATRACE_TAG, String8::format("kicked off frame %d",
1022                     thread->mFramesQueued).string());
1023             thread->mQueue.push_back(sync);
1024             thread->mCondition.signal();
1025             thread->mFramesQueued++;
1026             ATRACE_INT("GPU Frames Outstanding", thread->mQueue.size());
1027         }
1028     }
1029 
1030 private:
FrameCompletionThread()1031     FrameCompletionThread() : mFramesQueued(0), mFramesCompleted(0) {}
1032 
threadLoop()1033     virtual bool threadLoop() {
1034         EGLSyncKHR sync;
1035         uint32_t frameNum;
1036         {
1037             Mutex::Autolock lock(mMutex);
1038             while (mQueue.isEmpty()) {
1039                 mCondition.wait(mMutex);
1040             }
1041             sync = mQueue[0];
1042             frameNum = mFramesCompleted;
1043         }
1044         EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1045         {
1046             ScopedTrace st(ATRACE_TAG, String8::format("waiting for frame %d",
1047                     frameNum).string());
1048             EGLint result = eglClientWaitSyncKHR(dpy, sync, 0, EGL_FOREVER_KHR);
1049             if (result == EGL_FALSE) {
1050                 ALOGE("FrameCompletion: error waiting for fence: %#x", eglGetError());
1051             } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
1052                 ALOGE("FrameCompletion: timeout waiting for fence");
1053             }
1054             eglDestroySyncKHR(dpy, sync);
1055         }
1056         {
1057             Mutex::Autolock lock(mMutex);
1058             mQueue.removeAt(0);
1059             mFramesCompleted++;
1060             ATRACE_INT("GPU Frames Outstanding", mQueue.size());
1061         }
1062         return true;
1063     }
1064 
1065     uint32_t mFramesQueued;
1066     uint32_t mFramesCompleted;
1067     Vector<EGLSyncKHR> mQueue;
1068     Condition mCondition;
1069     Mutex mMutex;
1070 };
1071 
eglSwapBuffersWithDamageKHR(EGLDisplay dpy,EGLSurface draw,EGLint * rects,EGLint n_rects)1072 EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
1073         EGLint *rects, EGLint n_rects)
1074 {
1075     ATRACE_CALL();
1076     clearError();
1077 
1078     const egl_display_ptr dp = validate_display(dpy);
1079     if (!dp) return EGL_FALSE;
1080 
1081     SurfaceRef _s(dp.get(), draw);
1082     if (!_s.get())
1083         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1084 
1085     egl_surface_t const * const s = get_surface(draw);
1086 
1087     if (CC_UNLIKELY(dp->traceGpuCompletion)) {
1088         EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL);
1089         if (sync != EGL_NO_SYNC_KHR) {
1090             FrameCompletionThread::queueSync(sync);
1091         }
1092     }
1093 
1094     if (CC_UNLIKELY(dp->finishOnSwap)) {
1095         uint32_t pixel;
1096         egl_context_t * const c = get_context( egl_tls_t::getContext() );
1097         if (c) {
1098             // glReadPixels() ensures that the frame is complete
1099             s->cnx->hooks[c->version]->gl.glReadPixels(0,0,1,1,
1100                     GL_RGBA,GL_UNSIGNED_BYTE,&pixel);
1101         }
1102     }
1103 
1104     if (n_rects == 0) {
1105         return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1106     }
1107 
1108     Vector<android_native_rect_t> androidRects;
1109     for (int r = 0; r < n_rects; ++r) {
1110         int offset = r * 4;
1111         int x = rects[offset];
1112         int y = rects[offset + 1];
1113         int width = rects[offset + 2];
1114         int height = rects[offset + 3];
1115         android_native_rect_t androidRect;
1116         androidRect.left = x;
1117         androidRect.top = y + height;
1118         androidRect.right = x + width;
1119         androidRect.bottom = y;
1120         androidRects.push_back(androidRect);
1121     }
1122     native_window_set_surface_damage(s->win.get(), androidRects.array(),
1123             androidRects.size());
1124 
1125     if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
1126         return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface,
1127                 rects, n_rects);
1128     } else {
1129         return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1130     }
1131 }
1132 
eglSwapBuffers(EGLDisplay dpy,EGLSurface surface)1133 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1134 {
1135     return eglSwapBuffersWithDamageKHR(dpy, surface, NULL, 0);
1136 }
1137 
eglCopyBuffers(EGLDisplay dpy,EGLSurface surface,NativePixmapType target)1138 EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
1139                             NativePixmapType target)
1140 {
1141     clearError();
1142 
1143     const egl_display_ptr dp = validate_display(dpy);
1144     if (!dp) return EGL_FALSE;
1145 
1146     SurfaceRef _s(dp.get(), surface);
1147     if (!_s.get())
1148         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1149 
1150     egl_surface_t const * const s = get_surface(surface);
1151     return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
1152 }
1153 
eglQueryString(EGLDisplay dpy,EGLint name)1154 const char* eglQueryString(EGLDisplay dpy, EGLint name)
1155 {
1156     clearError();
1157 
1158     const egl_display_ptr dp = validate_display(dpy);
1159     if (!dp) return (const char *) NULL;
1160 
1161     switch (name) {
1162         case EGL_VENDOR:
1163             return dp->getVendorString();
1164         case EGL_VERSION:
1165             return dp->getVersionString();
1166         case EGL_EXTENSIONS:
1167             return dp->getExtensionString();
1168         case EGL_CLIENT_APIS:
1169             return dp->getClientApiString();
1170     }
1171     return setError(EGL_BAD_PARAMETER, (const char *)0);
1172 }
1173 
eglQueryStringImplementationANDROID(EGLDisplay dpy,EGLint name)1174 EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name)
1175 {
1176     clearError();
1177 
1178     const egl_display_ptr dp = validate_display(dpy);
1179     if (!dp) return (const char *) NULL;
1180 
1181     switch (name) {
1182         case EGL_VENDOR:
1183             return dp->disp.queryString.vendor;
1184         case EGL_VERSION:
1185             return dp->disp.queryString.version;
1186         case EGL_EXTENSIONS:
1187             return dp->disp.queryString.extensions;
1188         case EGL_CLIENT_APIS:
1189             return dp->disp.queryString.clientApi;
1190     }
1191     return setError(EGL_BAD_PARAMETER, (const char *)0);
1192 }
1193 
1194 // ----------------------------------------------------------------------------
1195 // EGL 1.1
1196 // ----------------------------------------------------------------------------
1197 
eglSurfaceAttrib(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint value)1198 EGLBoolean eglSurfaceAttrib(
1199         EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
1200 {
1201     clearError();
1202 
1203     const egl_display_ptr dp = validate_display(dpy);
1204     if (!dp) return EGL_FALSE;
1205 
1206     SurfaceRef _s(dp.get(), surface);
1207     if (!_s.get())
1208         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1209 
1210     egl_surface_t * const s = get_surface(surface);
1211 
1212     if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) {
1213         int err = native_window_set_auto_refresh(s->win.get(),
1214             value ? true : false);
1215         return (err == NO_ERROR) ? EGL_TRUE :
1216             setError(EGL_BAD_SURFACE, EGL_FALSE);
1217     }
1218 
1219 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS
1220     if (attribute == EGL_TIMESTAMPS_ANDROID) {
1221         s->enableTimestamps = value;
1222         return EGL_TRUE;
1223     }
1224 #endif
1225 
1226     if (s->cnx->egl.eglSurfaceAttrib) {
1227         return s->cnx->egl.eglSurfaceAttrib(
1228                 dp->disp.dpy, s->surface, attribute, value);
1229     }
1230     return setError(EGL_BAD_SURFACE, EGL_FALSE);
1231 }
1232 
eglBindTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)1233 EGLBoolean eglBindTexImage(
1234         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1235 {
1236     clearError();
1237 
1238     const egl_display_ptr dp = validate_display(dpy);
1239     if (!dp) return EGL_FALSE;
1240 
1241     SurfaceRef _s(dp.get(), surface);
1242     if (!_s.get())
1243         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1244 
1245     egl_surface_t const * const s = get_surface(surface);
1246     if (s->cnx->egl.eglBindTexImage) {
1247         return s->cnx->egl.eglBindTexImage(
1248                 dp->disp.dpy, s->surface, buffer);
1249     }
1250     return setError(EGL_BAD_SURFACE, EGL_FALSE);
1251 }
1252 
eglReleaseTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)1253 EGLBoolean eglReleaseTexImage(
1254         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1255 {
1256     clearError();
1257 
1258     const egl_display_ptr dp = validate_display(dpy);
1259     if (!dp) return EGL_FALSE;
1260 
1261     SurfaceRef _s(dp.get(), surface);
1262     if (!_s.get())
1263         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1264 
1265     egl_surface_t const * const s = get_surface(surface);
1266     if (s->cnx->egl.eglReleaseTexImage) {
1267         return s->cnx->egl.eglReleaseTexImage(
1268                 dp->disp.dpy, s->surface, buffer);
1269     }
1270     return setError(EGL_BAD_SURFACE, EGL_FALSE);
1271 }
1272 
eglSwapInterval(EGLDisplay dpy,EGLint interval)1273 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
1274 {
1275     clearError();
1276 
1277     const egl_display_ptr dp = validate_display(dpy);
1278     if (!dp) return EGL_FALSE;
1279 
1280     EGLBoolean res = EGL_TRUE;
1281     egl_connection_t* const cnx = &gEGLImpl;
1282     if (cnx->dso && cnx->egl.eglSwapInterval) {
1283         res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
1284     }
1285 
1286     return res;
1287 }
1288 
1289 
1290 // ----------------------------------------------------------------------------
1291 // EGL 1.2
1292 // ----------------------------------------------------------------------------
1293 
eglWaitClient(void)1294 EGLBoolean eglWaitClient(void)
1295 {
1296     clearError();
1297 
1298     egl_connection_t* const cnx = &gEGLImpl;
1299     if (!cnx->dso)
1300         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
1301 
1302     EGLBoolean res;
1303     if (cnx->egl.eglWaitClient) {
1304         res = cnx->egl.eglWaitClient();
1305     } else {
1306         res = cnx->egl.eglWaitGL();
1307     }
1308     return res;
1309 }
1310 
eglBindAPI(EGLenum api)1311 EGLBoolean eglBindAPI(EGLenum api)
1312 {
1313     clearError();
1314 
1315     if (egl_init_drivers() == EGL_FALSE) {
1316         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1317     }
1318 
1319     // bind this API on all EGLs
1320     EGLBoolean res = EGL_TRUE;
1321     egl_connection_t* const cnx = &gEGLImpl;
1322     if (cnx->dso && cnx->egl.eglBindAPI) {
1323         res = cnx->egl.eglBindAPI(api);
1324     }
1325     return res;
1326 }
1327 
eglQueryAPI(void)1328 EGLenum eglQueryAPI(void)
1329 {
1330     clearError();
1331 
1332     if (egl_init_drivers() == EGL_FALSE) {
1333         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1334     }
1335 
1336     egl_connection_t* const cnx = &gEGLImpl;
1337     if (cnx->dso && cnx->egl.eglQueryAPI) {
1338         return cnx->egl.eglQueryAPI();
1339     }
1340 
1341     // or, it can only be OpenGL ES
1342     return EGL_OPENGL_ES_API;
1343 }
1344 
eglReleaseThread(void)1345 EGLBoolean eglReleaseThread(void)
1346 {
1347     clearError();
1348 
1349     // If there is context bound to the thread, release it
1350     egl_display_t::loseCurrent(get_context(getContext()));
1351 
1352     egl_connection_t* const cnx = &gEGLImpl;
1353     if (cnx->dso && cnx->egl.eglReleaseThread) {
1354         cnx->egl.eglReleaseThread();
1355     }
1356     egl_tls_t::clearTLS();
1357     return EGL_TRUE;
1358 }
1359 
eglCreatePbufferFromClientBuffer(EGLDisplay dpy,EGLenum buftype,EGLClientBuffer buffer,EGLConfig config,const EGLint * attrib_list)1360 EGLSurface eglCreatePbufferFromClientBuffer(
1361           EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
1362           EGLConfig config, const EGLint *attrib_list)
1363 {
1364     clearError();
1365 
1366     egl_connection_t* cnx = NULL;
1367     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
1368     if (!dp) return EGL_FALSE;
1369     if (cnx->egl.eglCreatePbufferFromClientBuffer) {
1370         return cnx->egl.eglCreatePbufferFromClientBuffer(
1371                 dp->disp.dpy, buftype, buffer, config, attrib_list);
1372     }
1373     return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
1374 }
1375 
1376 // ----------------------------------------------------------------------------
1377 // EGL_EGLEXT_VERSION 3
1378 // ----------------------------------------------------------------------------
1379 
eglLockSurfaceKHR(EGLDisplay dpy,EGLSurface surface,const EGLint * attrib_list)1380 EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
1381         const EGLint *attrib_list)
1382 {
1383     clearError();
1384 
1385     const egl_display_ptr dp = validate_display(dpy);
1386     if (!dp) return EGL_FALSE;
1387 
1388     SurfaceRef _s(dp.get(), surface);
1389     if (!_s.get())
1390         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1391 
1392     egl_surface_t const * const s = get_surface(surface);
1393     if (s->cnx->egl.eglLockSurfaceKHR) {
1394         return s->cnx->egl.eglLockSurfaceKHR(
1395                 dp->disp.dpy, s->surface, attrib_list);
1396     }
1397     return setError(EGL_BAD_DISPLAY, EGL_FALSE);
1398 }
1399 
eglUnlockSurfaceKHR(EGLDisplay dpy,EGLSurface surface)1400 EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
1401 {
1402     clearError();
1403 
1404     const egl_display_ptr dp = validate_display(dpy);
1405     if (!dp) return EGL_FALSE;
1406 
1407     SurfaceRef _s(dp.get(), surface);
1408     if (!_s.get())
1409         return setError(EGL_BAD_SURFACE, EGL_FALSE);
1410 
1411     egl_surface_t const * const s = get_surface(surface);
1412     if (s->cnx->egl.eglUnlockSurfaceKHR) {
1413         return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
1414     }
1415     return setError(EGL_BAD_DISPLAY, EGL_FALSE);
1416 }
1417 
eglCreateImageKHR(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)1418 EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1419         EGLClientBuffer buffer, const EGLint *attrib_list)
1420 {
1421     clearError();
1422 
1423     const egl_display_ptr dp = validate_display(dpy);
1424     if (!dp) return EGL_NO_IMAGE_KHR;
1425 
1426     ContextRef _c(dp.get(), ctx);
1427     egl_context_t * const c = _c.get();
1428 
1429     EGLImageKHR result = EGL_NO_IMAGE_KHR;
1430     egl_connection_t* const cnx = &gEGLImpl;
1431     if (cnx->dso && cnx->egl.eglCreateImageKHR) {
1432         result = cnx->egl.eglCreateImageKHR(
1433                 dp->disp.dpy,
1434                 c ? c->context : EGL_NO_CONTEXT,
1435                 target, buffer, attrib_list);
1436     }
1437     return result;
1438 }
1439 
eglDestroyImageKHR(EGLDisplay dpy,EGLImageKHR img)1440 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
1441 {
1442     clearError();
1443 
1444     const egl_display_ptr dp = validate_display(dpy);
1445     if (!dp) return EGL_FALSE;
1446 
1447     EGLBoolean result = EGL_FALSE;
1448     egl_connection_t* const cnx = &gEGLImpl;
1449     if (cnx->dso && cnx->egl.eglDestroyImageKHR) {
1450         result = cnx->egl.eglDestroyImageKHR(dp->disp.dpy, img);
1451     }
1452     return result;
1453 }
1454 
1455 // ----------------------------------------------------------------------------
1456 // EGL_EGLEXT_VERSION 5
1457 // ----------------------------------------------------------------------------
1458 
1459 
eglCreateSyncKHR(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list)1460 EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1461 {
1462     clearError();
1463 
1464     const egl_display_ptr dp = validate_display(dpy);
1465     if (!dp) return EGL_NO_SYNC_KHR;
1466 
1467     EGLSyncKHR result = EGL_NO_SYNC_KHR;
1468     egl_connection_t* const cnx = &gEGLImpl;
1469     if (cnx->dso && cnx->egl.eglCreateSyncKHR) {
1470         result = cnx->egl.eglCreateSyncKHR(dp->disp.dpy, type, attrib_list);
1471     }
1472     return result;
1473 }
1474 
eglDestroySyncKHR(EGLDisplay dpy,EGLSyncKHR sync)1475 EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1476 {
1477     clearError();
1478 
1479     const egl_display_ptr dp = validate_display(dpy);
1480     if (!dp) return EGL_FALSE;
1481 
1482     EGLBoolean result = EGL_FALSE;
1483     egl_connection_t* const cnx = &gEGLImpl;
1484     if (cnx->dso && cnx->egl.eglDestroySyncKHR) {
1485         result = cnx->egl.eglDestroySyncKHR(dp->disp.dpy, sync);
1486     }
1487     return result;
1488 }
1489 
eglSignalSyncKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLenum mode)1490 EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
1491     clearError();
1492 
1493     const egl_display_ptr dp = validate_display(dpy);
1494     if (!dp) return EGL_FALSE;
1495 
1496     EGLBoolean result = EGL_FALSE;
1497     egl_connection_t* const cnx = &gEGLImpl;
1498     if (cnx->dso && cnx->egl.eglSignalSyncKHR) {
1499         result = cnx->egl.eglSignalSyncKHR(
1500                 dp->disp.dpy, sync, mode);
1501     }
1502     return result;
1503 }
1504 
eglClientWaitSyncKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags,EGLTimeKHR timeout)1505 EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync,
1506         EGLint flags, EGLTimeKHR timeout)
1507 {
1508     clearError();
1509 
1510     const egl_display_ptr dp = validate_display(dpy);
1511     if (!dp) return EGL_FALSE;
1512 
1513     EGLBoolean result = EGL_FALSE;
1514     egl_connection_t* const cnx = &gEGLImpl;
1515     if (cnx->dso && cnx->egl.eglClientWaitSyncKHR) {
1516         result = cnx->egl.eglClientWaitSyncKHR(
1517                 dp->disp.dpy, sync, flags, timeout);
1518     }
1519     return result;
1520 }
1521 
eglGetSyncAttribKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint attribute,EGLint * value)1522 EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync,
1523         EGLint attribute, EGLint *value)
1524 {
1525     clearError();
1526 
1527     const egl_display_ptr dp = validate_display(dpy);
1528     if (!dp) return EGL_FALSE;
1529 
1530     EGLBoolean result = EGL_FALSE;
1531     egl_connection_t* const cnx = &gEGLImpl;
1532     if (cnx->dso && cnx->egl.eglGetSyncAttribKHR) {
1533         result = cnx->egl.eglGetSyncAttribKHR(
1534                 dp->disp.dpy, sync, attribute, value);
1535     }
1536     return result;
1537 }
1538 
eglCreateStreamKHR(EGLDisplay dpy,const EGLint * attrib_list)1539 EGLStreamKHR eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
1540 {
1541     clearError();
1542 
1543     const egl_display_ptr dp = validate_display(dpy);
1544     if (!dp) return EGL_NO_STREAM_KHR;
1545 
1546     EGLStreamKHR result = EGL_NO_STREAM_KHR;
1547     egl_connection_t* const cnx = &gEGLImpl;
1548     if (cnx->dso && cnx->egl.eglCreateStreamKHR) {
1549         result = cnx->egl.eglCreateStreamKHR(
1550                 dp->disp.dpy, attrib_list);
1551     }
1552     return result;
1553 }
1554 
eglDestroyStreamKHR(EGLDisplay dpy,EGLStreamKHR stream)1555 EGLBoolean eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
1556 {
1557     clearError();
1558 
1559     const egl_display_ptr dp = validate_display(dpy);
1560     if (!dp) return EGL_FALSE;
1561 
1562     EGLBoolean result = EGL_FALSE;
1563     egl_connection_t* const cnx = &gEGLImpl;
1564     if (cnx->dso && cnx->egl.eglDestroyStreamKHR) {
1565         result = cnx->egl.eglDestroyStreamKHR(
1566                 dp->disp.dpy, stream);
1567     }
1568     return result;
1569 }
1570 
eglStreamAttribKHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint value)1571 EGLBoolean eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream,
1572         EGLenum attribute, EGLint value)
1573 {
1574     clearError();
1575 
1576     const egl_display_ptr dp = validate_display(dpy);
1577     if (!dp) return EGL_FALSE;
1578 
1579     EGLBoolean result = EGL_FALSE;
1580     egl_connection_t* const cnx = &gEGLImpl;
1581     if (cnx->dso && cnx->egl.eglStreamAttribKHR) {
1582         result = cnx->egl.eglStreamAttribKHR(
1583                 dp->disp.dpy, stream, attribute, value);
1584     }
1585     return result;
1586 }
1587 
eglQueryStreamKHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint * value)1588 EGLBoolean eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream,
1589         EGLenum attribute, EGLint *value)
1590 {
1591     clearError();
1592 
1593     const egl_display_ptr dp = validate_display(dpy);
1594     if (!dp) return EGL_FALSE;
1595 
1596     EGLBoolean result = EGL_FALSE;
1597     egl_connection_t* const cnx = &gEGLImpl;
1598     if (cnx->dso && cnx->egl.eglQueryStreamKHR) {
1599         result = cnx->egl.eglQueryStreamKHR(
1600                 dp->disp.dpy, stream, attribute, value);
1601     }
1602     return result;
1603 }
1604 
eglQueryStreamu64KHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLuint64KHR * value)1605 EGLBoolean eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream,
1606         EGLenum attribute, EGLuint64KHR *value)
1607 {
1608     clearError();
1609 
1610     const egl_display_ptr dp = validate_display(dpy);
1611     if (!dp) return EGL_FALSE;
1612 
1613     EGLBoolean result = EGL_FALSE;
1614     egl_connection_t* const cnx = &gEGLImpl;
1615     if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) {
1616         result = cnx->egl.eglQueryStreamu64KHR(
1617                 dp->disp.dpy, stream, attribute, value);
1618     }
1619     return result;
1620 }
1621 
eglQueryStreamTimeKHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLTimeKHR * value)1622 EGLBoolean eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream,
1623         EGLenum attribute, EGLTimeKHR *value)
1624 {
1625     clearError();
1626 
1627     const egl_display_ptr dp = validate_display(dpy);
1628     if (!dp) return EGL_FALSE;
1629 
1630     EGLBoolean result = EGL_FALSE;
1631     egl_connection_t* const cnx = &gEGLImpl;
1632     if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) {
1633         result = cnx->egl.eglQueryStreamTimeKHR(
1634                 dp->disp.dpy, stream, attribute, value);
1635     }
1636     return result;
1637 }
1638 
eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy,EGLConfig config,EGLStreamKHR stream,const EGLint * attrib_list)1639 EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config,
1640         EGLStreamKHR stream, const EGLint *attrib_list)
1641 {
1642     clearError();
1643 
1644     egl_display_ptr dp = validate_display(dpy);
1645     if (!dp) return EGL_NO_SURFACE;
1646 
1647     egl_connection_t* const cnx = &gEGLImpl;
1648     if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
1649         EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
1650                 dp->disp.dpy, config, stream, attrib_list);
1651         if (surface != EGL_NO_SURFACE) {
1652             egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
1653                     surface, cnx);
1654             return s;
1655         }
1656     }
1657     return EGL_NO_SURFACE;
1658 }
1659 
eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,EGLStreamKHR stream)1660 EGLBoolean eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,
1661         EGLStreamKHR stream)
1662 {
1663     clearError();
1664 
1665     const egl_display_ptr dp = validate_display(dpy);
1666     if (!dp) return EGL_FALSE;
1667 
1668     EGLBoolean result = EGL_FALSE;
1669     egl_connection_t* const cnx = &gEGLImpl;
1670     if (cnx->dso && cnx->egl.eglStreamConsumerGLTextureExternalKHR) {
1671         result = cnx->egl.eglStreamConsumerGLTextureExternalKHR(
1672                 dp->disp.dpy, stream);
1673     }
1674     return result;
1675 }
1676 
eglStreamConsumerAcquireKHR(EGLDisplay dpy,EGLStreamKHR stream)1677 EGLBoolean eglStreamConsumerAcquireKHR(EGLDisplay dpy,
1678         EGLStreamKHR stream)
1679 {
1680     clearError();
1681 
1682     const egl_display_ptr dp = validate_display(dpy);
1683     if (!dp) return EGL_FALSE;
1684 
1685     EGLBoolean result = EGL_FALSE;
1686     egl_connection_t* const cnx = &gEGLImpl;
1687     if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) {
1688         result = cnx->egl.eglStreamConsumerAcquireKHR(
1689                 dp->disp.dpy, stream);
1690     }
1691     return result;
1692 }
1693 
eglStreamConsumerReleaseKHR(EGLDisplay dpy,EGLStreamKHR stream)1694 EGLBoolean eglStreamConsumerReleaseKHR(EGLDisplay dpy,
1695         EGLStreamKHR stream)
1696 {
1697     clearError();
1698 
1699     const egl_display_ptr dp = validate_display(dpy);
1700     if (!dp) return EGL_FALSE;
1701 
1702     EGLBoolean result = EGL_FALSE;
1703     egl_connection_t* const cnx = &gEGLImpl;
1704     if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) {
1705         result = cnx->egl.eglStreamConsumerReleaseKHR(
1706                 dp->disp.dpy, stream);
1707     }
1708     return result;
1709 }
1710 
eglGetStreamFileDescriptorKHR(EGLDisplay dpy,EGLStreamKHR stream)1711 EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR(
1712         EGLDisplay dpy, EGLStreamKHR stream)
1713 {
1714     clearError();
1715 
1716     const egl_display_ptr dp = validate_display(dpy);
1717     if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR;
1718 
1719     EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR;
1720     egl_connection_t* const cnx = &gEGLImpl;
1721     if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) {
1722         result = cnx->egl.eglGetStreamFileDescriptorKHR(
1723                 dp->disp.dpy, stream);
1724     }
1725     return result;
1726 }
1727 
eglCreateStreamFromFileDescriptorKHR(EGLDisplay dpy,EGLNativeFileDescriptorKHR file_descriptor)1728 EGLStreamKHR eglCreateStreamFromFileDescriptorKHR(
1729         EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor)
1730 {
1731     clearError();
1732 
1733     const egl_display_ptr dp = validate_display(dpy);
1734     if (!dp) return EGL_NO_STREAM_KHR;
1735 
1736     EGLStreamKHR result = EGL_NO_STREAM_KHR;
1737     egl_connection_t* const cnx = &gEGLImpl;
1738     if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) {
1739         result = cnx->egl.eglCreateStreamFromFileDescriptorKHR(
1740                 dp->disp.dpy, file_descriptor);
1741     }
1742     return result;
1743 }
1744 
1745 // ----------------------------------------------------------------------------
1746 // EGL_EGLEXT_VERSION 15
1747 // ----------------------------------------------------------------------------
1748 
eglWaitSyncKHR(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags)1749 EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
1750     clearError();
1751     const egl_display_ptr dp = validate_display(dpy);
1752     if (!dp) return EGL_FALSE;
1753     EGLint result = EGL_FALSE;
1754     egl_connection_t* const cnx = &gEGLImpl;
1755     if (cnx->dso && cnx->egl.eglWaitSyncKHR) {
1756         result = cnx->egl.eglWaitSyncKHR(dp->disp.dpy, sync, flags);
1757     }
1758     return result;
1759 }
1760 
1761 // ----------------------------------------------------------------------------
1762 // ANDROID extensions
1763 // ----------------------------------------------------------------------------
1764 
eglDupNativeFenceFDANDROID(EGLDisplay dpy,EGLSyncKHR sync)1765 EGLint eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
1766 {
1767     clearError();
1768 
1769     const egl_display_ptr dp = validate_display(dpy);
1770     if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID;
1771 
1772     EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
1773     egl_connection_t* const cnx = &gEGLImpl;
1774     if (cnx->dso && cnx->egl.eglDupNativeFenceFDANDROID) {
1775         result = cnx->egl.eglDupNativeFenceFDANDROID(dp->disp.dpy, sync);
1776     }
1777     return result;
1778 }
1779 
eglPresentationTimeANDROID(EGLDisplay dpy,EGLSurface surface,EGLnsecsANDROID time)1780 EGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface,
1781         EGLnsecsANDROID time)
1782 {
1783     clearError();
1784 
1785     const egl_display_ptr dp = validate_display(dpy);
1786     if (!dp) {
1787         return EGL_FALSE;
1788     }
1789 
1790     SurfaceRef _s(dp.get(), surface);
1791     if (!_s.get()) {
1792         setError(EGL_BAD_SURFACE, EGL_FALSE);
1793         return EGL_FALSE;
1794     }
1795 
1796     egl_surface_t const * const s = get_surface(surface);
1797     native_window_set_buffers_timestamp(s->win.get(), time);
1798 
1799     return EGL_TRUE;
1800 }
1801 
eglCreateNativeClientBufferANDROID(const EGLint * attrib_list)1802 EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
1803 {
1804     clearError();
1805 
1806     int usage = 0;
1807     uint32_t width = 0;
1808     uint32_t height = 0;
1809     uint32_t format = 0;
1810     uint32_t red_size = 0;
1811     uint32_t green_size = 0;
1812     uint32_t blue_size = 0;
1813     uint32_t alpha_size = 0;
1814 
1815 #define GET_NONNEGATIVE_VALUE(case_name, target) \
1816     case case_name: \
1817         if (value >= 0) { \
1818             target = value; \
1819         } else { \
1820             return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0); \
1821         } \
1822         break
1823 
1824     if (attrib_list) {
1825         while (*attrib_list != EGL_NONE) {
1826             GLint attr = *attrib_list++;
1827             GLint value = *attrib_list++;
1828             switch (attr) {
1829                 GET_NONNEGATIVE_VALUE(EGL_WIDTH, width);
1830                 GET_NONNEGATIVE_VALUE(EGL_HEIGHT, height);
1831                 GET_NONNEGATIVE_VALUE(EGL_RED_SIZE, red_size);
1832                 GET_NONNEGATIVE_VALUE(EGL_GREEN_SIZE, green_size);
1833                 GET_NONNEGATIVE_VALUE(EGL_BLUE_SIZE, blue_size);
1834                 GET_NONNEGATIVE_VALUE(EGL_ALPHA_SIZE, alpha_size);
1835                 case EGL_NATIVE_BUFFER_USAGE_ANDROID:
1836                     if (value & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID) {
1837                         usage |= GRALLOC_USAGE_PROTECTED;
1838                     }
1839                     if (value & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID) {
1840                         usage |= GRALLOC_USAGE_HW_RENDER;
1841                     }
1842                     if (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID) {
1843                         usage |= GRALLOC_USAGE_HW_TEXTURE;
1844                     }
1845                     // The buffer must be used for either a texture or a
1846                     // renderbuffer.
1847                     if ((value & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID) &&
1848                         (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)) {
1849                         return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
1850                     }
1851                     break;
1852                 default:
1853                     return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
1854             }
1855         }
1856     }
1857 #undef GET_NONNEGATIVE_VALUE
1858 
1859     // Validate format.
1860     if (red_size == 8 && green_size == 8 && blue_size == 8) {
1861         if (alpha_size == 8) {
1862             format = HAL_PIXEL_FORMAT_RGBA_8888;
1863         } else {
1864             format = HAL_PIXEL_FORMAT_RGB_888;
1865         }
1866     } else if (red_size == 5 && green_size == 6 && blue_size == 5 &&
1867                alpha_size == 0) {
1868         format = HAL_PIXEL_FORMAT_RGB_565;
1869     } else {
1870         ALOGE("Invalid native pixel format { r=%d, g=%d, b=%d, a=%d }",
1871                 red_size, green_size, blue_size, alpha_size);
1872         return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
1873     }
1874 
1875     GraphicBuffer* gBuffer = new GraphicBuffer(width, height, format, usage,
1876             std::string("[eglCreateNativeClientBufferANDROID pid ") +
1877             std::to_string(getpid()) + ']');
1878     const status_t err = gBuffer->initCheck();
1879     if (err != NO_ERROR) {
1880         ALOGE("Unable to create native buffer { w=%d, h=%d, f=%d, u=%#x }: %#x",
1881                 width, height, format, usage, err);
1882         // Destroy the buffer.
1883         sp<GraphicBuffer> holder(gBuffer);
1884         return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0);
1885     }
1886     ALOGD("Created new native buffer %p { w=%d, h=%d, f=%d, u=%#x }",
1887             gBuffer, width, height, format, usage);
1888     return static_cast<EGLClientBuffer>(gBuffer->getNativeBuffer());
1889 }
1890 
1891 // ----------------------------------------------------------------------------
1892 // NVIDIA extensions
1893 // ----------------------------------------------------------------------------
eglGetSystemTimeFrequencyNV()1894 EGLuint64NV eglGetSystemTimeFrequencyNV()
1895 {
1896     clearError();
1897 
1898     if (egl_init_drivers() == EGL_FALSE) {
1899         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1900     }
1901 
1902     EGLuint64NV ret = 0;
1903     egl_connection_t* const cnx = &gEGLImpl;
1904 
1905     if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
1906         return cnx->egl.eglGetSystemTimeFrequencyNV();
1907     }
1908 
1909     return setErrorQuiet(EGL_BAD_DISPLAY, 0);
1910 }
1911 
eglGetSystemTimeNV()1912 EGLuint64NV eglGetSystemTimeNV()
1913 {
1914     clearError();
1915 
1916     if (egl_init_drivers() == EGL_FALSE) {
1917         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1918     }
1919 
1920     EGLuint64NV ret = 0;
1921     egl_connection_t* const cnx = &gEGLImpl;
1922 
1923     if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
1924         return cnx->egl.eglGetSystemTimeNV();
1925     }
1926 
1927     return setErrorQuiet(EGL_BAD_DISPLAY, 0);
1928 }
1929 
1930 // ----------------------------------------------------------------------------
1931 // Partial update extension
1932 // ----------------------------------------------------------------------------
eglSetDamageRegionKHR(EGLDisplay dpy,EGLSurface surface,EGLint * rects,EGLint n_rects)1933 EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
1934         EGLint *rects, EGLint n_rects)
1935 {
1936     clearError();
1937 
1938     const egl_display_ptr dp = validate_display(dpy);
1939     if (!dp) {
1940         setError(EGL_BAD_DISPLAY, EGL_FALSE);
1941         return EGL_FALSE;
1942     }
1943 
1944     SurfaceRef _s(dp.get(), surface);
1945     if (!_s.get()) {
1946         setError(EGL_BAD_SURFACE, EGL_FALSE);
1947         return EGL_FALSE;
1948     }
1949 
1950     egl_surface_t const * const s = get_surface(surface);
1951     if (s->cnx->egl.eglSetDamageRegionKHR) {
1952         return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface,
1953                 rects, n_rects);
1954     }
1955 
1956     return EGL_FALSE;
1957 }
1958 
eglGetFrameTimestampsANDROID(EGLDisplay dpy,EGLSurface surface,EGLint framesAgo,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values)1959 EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface,
1960         EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps,
1961         EGLnsecsANDROID *values)
1962 {
1963     clearError();
1964 
1965     const egl_display_ptr dp = validate_display(dpy);
1966     if (!dp) {
1967         setError(EGL_BAD_DISPLAY, EGL_FALSE);
1968         return EGL_FALSE;
1969     }
1970 
1971     SurfaceRef _s(dp.get(), surface);
1972     if (!_s.get()) {
1973         setError(EGL_BAD_SURFACE, EGL_FALSE);
1974         return EGL_FALSE;
1975     }
1976 
1977     egl_surface_t const * const s = get_surface(surface);
1978 
1979     if (!s->enableTimestamps) {
1980         setError(EGL_BAD_SURFACE, EGL_FALSE);
1981         return EGL_FALSE;
1982     }
1983 
1984     nsecs_t* postedTime = nullptr;
1985     nsecs_t* acquireTime = nullptr;
1986     nsecs_t* refreshStartTime = nullptr;
1987     nsecs_t* GLCompositionDoneTime = nullptr;
1988     nsecs_t* displayRetireTime = nullptr;
1989     nsecs_t* releaseTime = nullptr;
1990 
1991     for (int i = 0; i < numTimestamps; i++) {
1992         switch (timestamps[i]) {
1993             case EGL_QUEUE_TIME_ANDROID:
1994                 postedTime = &values[i];
1995                 break;
1996             case EGL_RENDERING_COMPLETE_TIME_ANDROID:
1997                 acquireTime = &values[i];
1998                 break;
1999             case EGL_COMPOSITION_START_TIME_ANDROID:
2000                 refreshStartTime = &values[i];
2001                 break;
2002             case EGL_COMPOSITION_FINISHED_TIME_ANDROID:
2003                 GLCompositionDoneTime = &values[i];
2004                 break;
2005             case EGL_DISPLAY_RETIRE_TIME_ANDROID:
2006                 displayRetireTime = &values[i];
2007                 break;
2008             case EGL_READS_DONE_TIME_ANDROID:
2009                 releaseTime = &values[i];
2010                 break;
2011             default:
2012                 setError(EGL_BAD_PARAMETER, EGL_FALSE);
2013                 return EGL_FALSE;
2014         }
2015     }
2016 
2017     status_t ret = native_window_get_frame_timestamps(s->win.get(), framesAgo,
2018             postedTime, acquireTime, refreshStartTime, GLCompositionDoneTime,
2019             displayRetireTime, releaseTime);
2020 
2021     if (ret != NO_ERROR) {
2022         setError(EGL_BAD_ACCESS, EGL_FALSE);
2023         return EGL_FALSE;
2024     }
2025 
2026     return EGL_TRUE;
2027 }
2028 
eglQueryTimestampSupportedANDROID(EGLDisplay dpy,EGLSurface surface,EGLint timestamp)2029 EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface,
2030         EGLint timestamp)
2031 {
2032     clearError();
2033 
2034     const egl_display_ptr dp = validate_display(dpy);
2035     if (!dp) {
2036         setError(EGL_BAD_DISPLAY, EGL_FALSE);
2037         return EGL_FALSE;
2038     }
2039 
2040     SurfaceRef _s(dp.get(), surface);
2041     if (!_s.get()) {
2042         setError(EGL_BAD_SURFACE, EGL_FALSE);
2043         return EGL_FALSE;
2044     }
2045 
2046     switch (timestamp) {
2047 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS
2048         case EGL_QUEUE_TIME_ANDROID:
2049         case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2050         case EGL_COMPOSITION_START_TIME_ANDROID:
2051         case EGL_COMPOSITION_FINISHED_TIME_ANDROID:
2052         case EGL_DISPLAY_RETIRE_TIME_ANDROID:
2053         case EGL_READS_DONE_TIME_ANDROID:
2054             return EGL_TRUE;
2055 #endif
2056         default:
2057             return EGL_FALSE;
2058     }
2059 }
2060