OSDN Git Service

Merge "vulkan: update Vulkan headers to 1.0.53" am: 38bcc110b8 am: d0b439e33a am...
[android-x86/frameworks-native.git] / opengl / libs / EGL / eglApi.cpp
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 <ctype.h>
20 #include <dlfcn.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include <hardware/gralloc1.h>
25
26 #include <EGL/egl.h>
27 #include <EGL/eglext.h>
28
29 #include <android/hardware_buffer.h>
30 #include <private/android/AHardwareBufferHelpers.h>
31
32 #include <cutils/compiler.h>
33 #include <cutils/properties.h>
34 #include <log/log.h>
35
36 #include <condition_variable>
37 #include <deque>
38 #include <mutex>
39 #include <unordered_map>
40 #include <string>
41 #include <thread>
42
43 #include "../egl_impl.h"
44
45 #include "egl_display.h"
46 #include "egl_object.h"
47 #include "egl_tls.h"
48 #include "egl_trace.h"
49
50 using namespace android;
51
52 // ----------------------------------------------------------------------------
53
54 namespace android {
55
56 using nsecs_t = int64_t;
57
58 struct extention_map_t {
59     const char* name;
60     __eglMustCastToProperFunctionPointerType address;
61 };
62
63 /*
64  * This is the list of EGL extensions exposed to applications.
65  *
66  * Some of them (gBuiltinExtensionString) are implemented entirely in this EGL
67  * wrapper and are always available.
68  *
69  * The rest (gExtensionString) depend on support in the EGL driver, and are
70  * only available if the driver supports them. However, some of these must be
71  * supported because they are used by the Android system itself; these are
72  * listed as mandatory below and are required by the CDD. The system *assumes*
73  * the mandatory extensions are present and may not function properly if some
74  * are missing.
75  *
76  * NOTE: Both strings MUST have a single space as the last character.
77  */
78
79 extern char const * const gBuiltinExtensionString;
80 extern char const * const gExtensionString;
81
82 // clang-format off
83 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_get_native_client_buffer "
88         "EGL_ANDROID_front_buffer_auto_refresh "
89         "EGL_ANDROID_get_frame_timestamps "
90         "EGL_EXT_gl_colorspace_scrgb "
91         "EGL_EXT_gl_colorspace_scrgb_linear "
92         "EGL_EXT_gl_colorspace_display_p3_linear "
93         "EGL_EXT_gl_colorspace_display_p3 "
94         ;
95
96 char const * const gExtensionString  =
97         "EGL_KHR_image "                        // mandatory
98         "EGL_KHR_image_base "                   // mandatory
99         "EGL_KHR_image_pixmap "
100         "EGL_KHR_lock_surface "
101         "EGL_KHR_gl_colorspace "
102         "EGL_KHR_gl_texture_2D_image "
103         "EGL_KHR_gl_texture_3D_image "
104         "EGL_KHR_gl_texture_cubemap_image "
105         "EGL_KHR_gl_renderbuffer_image "
106         "EGL_KHR_reusable_sync "
107         "EGL_KHR_fence_sync "
108         "EGL_KHR_create_context "
109         "EGL_KHR_config_attribs "
110         "EGL_KHR_surfaceless_context "
111         "EGL_KHR_stream "
112         "EGL_KHR_stream_fifo "
113         "EGL_KHR_stream_producer_eglsurface "
114         "EGL_KHR_stream_consumer_gltexture "
115         "EGL_KHR_stream_cross_process_fd "
116         "EGL_EXT_create_context_robustness "
117         "EGL_NV_system_time "
118         "EGL_ANDROID_image_native_buffer "      // mandatory
119         "EGL_KHR_wait_sync "                    // strongly recommended
120         "EGL_ANDROID_recordable "               // mandatory
121         "EGL_KHR_partial_update "               // strongly recommended
122         "EGL_EXT_pixel_format_float "
123         "EGL_EXT_buffer_age "                   // strongly recommended with partial_update
124         "EGL_KHR_create_context_no_error "
125         "EGL_KHR_mutable_render_buffer "
126         "EGL_EXT_yuv_surface "
127         "EGL_EXT_protected_content "
128         "EGL_IMG_context_priority "
129         "EGL_KHR_no_config_context "
130         ;
131 // clang-format on
132
133 // extensions not exposed to applications but used by the ANDROID system
134 //      "EGL_ANDROID_blob_cache "               // strongly recommended
135 //      "EGL_IMG_hibernate_process "            // optional
136 //      "EGL_ANDROID_native_fence_sync "        // strongly recommended
137 //      "EGL_ANDROID_framebuffer_target "       // mandatory for HWC 1.1
138 //      "EGL_ANDROID_image_crop "               // optional
139
140 /*
141  * EGL Extensions entry-points exposed to 3rd party applications
142  * (keep in sync with gExtensionString above)
143  *
144  */
145 static const extention_map_t sExtensionMap[] = {
146     // EGL_KHR_lock_surface
147     { "eglLockSurfaceKHR",
148             (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR },
149     { "eglUnlockSurfaceKHR",
150             (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR },
151
152     // EGL_KHR_image, EGL_KHR_image_base
153     { "eglCreateImageKHR",
154             (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
155     { "eglDestroyImageKHR",
156             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
157
158     // EGL_KHR_reusable_sync, EGL_KHR_fence_sync
159     { "eglCreateSyncKHR",
160             (__eglMustCastToProperFunctionPointerType)&eglCreateSyncKHR },
161     { "eglDestroySyncKHR",
162             (__eglMustCastToProperFunctionPointerType)&eglDestroySyncKHR },
163     { "eglClientWaitSyncKHR",
164             (__eglMustCastToProperFunctionPointerType)&eglClientWaitSyncKHR },
165     { "eglSignalSyncKHR",
166             (__eglMustCastToProperFunctionPointerType)&eglSignalSyncKHR },
167     { "eglGetSyncAttribKHR",
168             (__eglMustCastToProperFunctionPointerType)&eglGetSyncAttribKHR },
169
170     // EGL_NV_system_time
171     { "eglGetSystemTimeFrequencyNV",
172             (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV },
173     { "eglGetSystemTimeNV",
174             (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV },
175
176     // EGL_KHR_wait_sync
177     { "eglWaitSyncKHR",
178             (__eglMustCastToProperFunctionPointerType)&eglWaitSyncKHR },
179
180     // EGL_ANDROID_presentation_time
181     { "eglPresentationTimeANDROID",
182             (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID },
183
184     // EGL_KHR_swap_buffers_with_damage
185     { "eglSwapBuffersWithDamageKHR",
186             (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
187
188     // EGL_ANDROID_get_native_client_buffer
189     { "eglGetNativeClientBufferANDROID",
190             (__eglMustCastToProperFunctionPointerType)&eglGetNativeClientBufferANDROID },
191
192     // EGL_KHR_partial_update
193     { "eglSetDamageRegionKHR",
194             (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
195
196     { "eglCreateStreamKHR",
197             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamKHR },
198     { "eglDestroyStreamKHR",
199             (__eglMustCastToProperFunctionPointerType)&eglDestroyStreamKHR },
200     { "eglStreamAttribKHR",
201             (__eglMustCastToProperFunctionPointerType)&eglStreamAttribKHR },
202     { "eglQueryStreamKHR",
203             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamKHR },
204     { "eglQueryStreamu64KHR",
205             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamu64KHR },
206     { "eglQueryStreamTimeKHR",
207             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamTimeKHR },
208     { "eglCreateStreamProducerSurfaceKHR",
209             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamProducerSurfaceKHR },
210     { "eglStreamConsumerGLTextureExternalKHR",
211             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerGLTextureExternalKHR },
212     { "eglStreamConsumerAcquireKHR",
213             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerAcquireKHR },
214     { "eglStreamConsumerReleaseKHR",
215             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerReleaseKHR },
216     { "eglGetStreamFileDescriptorKHR",
217             (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR },
218     { "eglCreateStreamFromFileDescriptorKHR",
219             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR },
220
221     // EGL_ANDROID_get_frame_timestamps
222     { "eglGetNextFrameIdANDROID",
223             (__eglMustCastToProperFunctionPointerType)&eglGetNextFrameIdANDROID },
224     { "eglGetCompositorTimingANDROID",
225             (__eglMustCastToProperFunctionPointerType)&eglGetCompositorTimingANDROID },
226     { "eglGetCompositorTimingSupportedANDROID",
227             (__eglMustCastToProperFunctionPointerType)&eglGetCompositorTimingSupportedANDROID },
228     { "eglGetFrameTimestampsANDROID",
229             (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID },
230     { "eglGetFrameTimestampSupportedANDROID",
231             (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampSupportedANDROID },
232
233     // EGL_ANDROID_native_fence_sync
234     { "eglDupNativeFenceFDANDROID",
235             (__eglMustCastToProperFunctionPointerType)&eglDupNativeFenceFDANDROID },
236 };
237
238 /*
239  * These extensions entry-points should not be exposed to applications.
240  * They're used internally by the Android EGL layer.
241  */
242 #define FILTER_EXTENSIONS(procname) \
243         (!strcmp((procname), "eglSetBlobCacheFuncsANDROID") ||    \
244          !strcmp((procname), "eglHibernateProcessIMG")      ||    \
245          !strcmp((procname), "eglAwakenProcessIMG"))
246
247
248
249 // accesses protected by sExtensionMapMutex
250 static std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtentionMap;
251
252 static int sGLExtentionSlot = 0;
253 static pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER;
254
255 static void(*findProcAddress(const char* name,
256         const extention_map_t* map, size_t n))() {
257     for (uint32_t i=0 ; i<n ; i++) {
258         if (!strcmp(name, map[i].name)) {
259             return map[i].address;
260         }
261     }
262     return NULL;
263 }
264
265 // ----------------------------------------------------------------------------
266
267 extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
268 extern EGLBoolean egl_init_drivers();
269 extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
270 extern gl_hooks_t gHooksTrace;
271
272 } // namespace android;
273
274
275 // ----------------------------------------------------------------------------
276
277 static inline void clearError() { egl_tls_t::clearError(); }
278 static inline EGLContext getContext() { return egl_tls_t::getContext(); }
279
280 // ----------------------------------------------------------------------------
281
282 EGLDisplay eglGetDisplay(EGLNativeDisplayType display)
283 {
284     ATRACE_CALL();
285     clearError();
286
287     uintptr_t index = reinterpret_cast<uintptr_t>(display);
288     if (index >= NUM_DISPLAYS) {
289         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
290     }
291
292     if (egl_init_drivers() == EGL_FALSE) {
293         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
294     }
295
296     EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);
297     return dpy;
298 }
299
300 // ----------------------------------------------------------------------------
301 // Initialization
302 // ----------------------------------------------------------------------------
303
304 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
305 {
306     clearError();
307
308     egl_display_ptr dp = get_display(dpy);
309     if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
310
311     EGLBoolean res = dp->initialize(major, minor);
312
313     return res;
314 }
315
316 EGLBoolean eglTerminate(EGLDisplay dpy)
317 {
318     // NOTE: don't unload the drivers b/c some APIs can be called
319     // after eglTerminate() has been called. eglTerminate() only
320     // terminates an EGLDisplay, not a EGL itself.
321
322     clearError();
323
324     egl_display_ptr dp = get_display(dpy);
325     if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
326
327     EGLBoolean res = dp->terminate();
328
329     return res;
330 }
331
332 // ----------------------------------------------------------------------------
333 // configuration
334 // ----------------------------------------------------------------------------
335
336 EGLBoolean eglGetConfigs(   EGLDisplay dpy,
337                             EGLConfig *configs,
338                             EGLint config_size, EGLint *num_config)
339 {
340     clearError();
341
342     const egl_display_ptr dp = validate_display(dpy);
343     if (!dp) return EGL_FALSE;
344
345     if (num_config==0) {
346         return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
347     }
348
349     EGLBoolean res = EGL_FALSE;
350     *num_config = 0;
351
352     egl_connection_t* const cnx = &gEGLImpl;
353     if (cnx->dso) {
354         res = cnx->egl.eglGetConfigs(
355                 dp->disp.dpy, configs, config_size, num_config);
356     }
357
358     return res;
359 }
360
361 EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
362                             EGLConfig *configs, EGLint config_size,
363                             EGLint *num_config)
364 {
365     clearError();
366
367     const egl_display_ptr dp = validate_display(dpy);
368     if (!dp) return EGL_FALSE;
369
370     if (num_config==0) {
371         return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
372     }
373
374     EGLBoolean res = EGL_FALSE;
375     *num_config = 0;
376
377     egl_connection_t* const cnx = &gEGLImpl;
378     if (cnx->dso) {
379         if (attrib_list) {
380             char value[PROPERTY_VALUE_MAX];
381             property_get("debug.egl.force_msaa", value, "false");
382
383             if (!strcmp(value, "true")) {
384                 size_t attribCount = 0;
385                 EGLint attrib = attrib_list[0];
386
387                 // Only enable MSAA if the context is OpenGL ES 2.0 and
388                 // if no caveat is requested
389                 const EGLint *attribRendererable = NULL;
390                 const EGLint *attribCaveat = NULL;
391
392                 // Count the number of attributes and look for
393                 // EGL_RENDERABLE_TYPE and EGL_CONFIG_CAVEAT
394                 while (attrib != EGL_NONE) {
395                     attrib = attrib_list[attribCount];
396                     switch (attrib) {
397                         case EGL_RENDERABLE_TYPE:
398                             attribRendererable = &attrib_list[attribCount];
399                             break;
400                         case EGL_CONFIG_CAVEAT:
401                             attribCaveat = &attrib_list[attribCount];
402                             break;
403                         default:
404                             break;
405                     }
406                     attribCount++;
407                 }
408
409                 if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT &&
410                         (!attribCaveat || attribCaveat[1] != EGL_NONE)) {
411
412                     // Insert 2 extra attributes to force-enable MSAA 4x
413                     EGLint aaAttribs[attribCount + 4];
414                     aaAttribs[0] = EGL_SAMPLE_BUFFERS;
415                     aaAttribs[1] = 1;
416                     aaAttribs[2] = EGL_SAMPLES;
417                     aaAttribs[3] = 4;
418
419                     memcpy(&aaAttribs[4], attrib_list, attribCount * sizeof(EGLint));
420
421                     EGLint numConfigAA;
422                     EGLBoolean resAA = cnx->egl.eglChooseConfig(
423                             dp->disp.dpy, aaAttribs, configs, config_size, &numConfigAA);
424
425                     if (resAA == EGL_TRUE && numConfigAA > 0) {
426                         ALOGD("Enabling MSAA 4x");
427                         *num_config = numConfigAA;
428                         return resAA;
429                     }
430                 }
431             }
432         }
433
434         res = cnx->egl.eglChooseConfig(
435                 dp->disp.dpy, attrib_list, configs, config_size, num_config);
436     }
437     return res;
438 }
439
440 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
441         EGLint attribute, EGLint *value)
442 {
443     clearError();
444
445     egl_connection_t* cnx = NULL;
446     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
447     if (!dp) return EGL_FALSE;
448
449     return cnx->egl.eglGetConfigAttrib(
450             dp->disp.dpy, config, attribute, value);
451 }
452
453 // ----------------------------------------------------------------------------
454 // surfaces
455 // ----------------------------------------------------------------------------
456
457 // Turn linear formats into corresponding sRGB formats when colorspace is
458 // EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
459 // formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
460 // the modification isn't possible, the original dataSpace is returned.
461 static android_dataspace modifyBufferDataspace(android_dataspace dataSpace,
462                                                EGLint colorspace) {
463     if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
464         return HAL_DATASPACE_SRGB_LINEAR;
465     } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
466         return HAL_DATASPACE_SRGB;
467     } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT) {
468         return HAL_DATASPACE_DISPLAY_P3;
469     } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT) {
470         return HAL_DATASPACE_DISPLAY_P3_LINEAR;
471     } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_EXT) {
472         return HAL_DATASPACE_V0_SCRGB;
473     } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT) {
474         return HAL_DATASPACE_V0_SCRGB_LINEAR;
475     }
476     return dataSpace;
477 }
478
479 // Return true if we stripped any EGL_GL_COLORSPACE_KHR attributes.
480 static EGLBoolean stripColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list,
481                                            EGLint format,
482                                            std::vector<EGLint>& stripped_attrib_list) {
483     std::vector<EGLint> allowedColorSpaces;
484     switch (format) {
485         case HAL_PIXEL_FORMAT_RGBA_8888:
486         case HAL_PIXEL_FORMAT_RGB_565:
487             // driver okay with linear & sRGB for 8888, but can't handle
488             // Display-P3 or other spaces.
489             allowedColorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
490             allowedColorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
491             break;
492
493         case HAL_PIXEL_FORMAT_RGBA_FP16:
494         case HAL_PIXEL_FORMAT_RGBA_1010102:
495         default:
496             // driver does not want to see colorspace attributes for 1010102 or fp16.
497             // Future: if driver supports XXXX extension, we can pass down that colorspace
498             break;
499     }
500
501     bool stripped = false;
502     if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
503         for (const EGLint* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
504             if (attr[0] == EGL_GL_COLORSPACE_KHR) {
505                 EGLint colorSpace = attr[1];
506                 bool found = false;
507                 // Verify that color space is allowed
508                 for (auto it : allowedColorSpaces) {
509                     if (colorSpace == it) {
510                         found = true;
511                     }
512                 }
513                 if (!found) {
514                     stripped = true;
515                 } else {
516                     stripped_attrib_list.push_back(attr[0]);
517                     stripped_attrib_list.push_back(attr[1]);
518                 }
519             } else {
520                 stripped_attrib_list.push_back(attr[0]);
521                 stripped_attrib_list.push_back(attr[1]);
522             }
523         }
524     }
525     if (stripped) {
526         stripped_attrib_list.push_back(EGL_NONE);
527         stripped_attrib_list.push_back(EGL_NONE);
528     }
529     return stripped;
530 }
531
532 static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list,
533                                          EGLint& colorSpace, android_dataspace& dataSpace) {
534     colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
535     dataSpace = HAL_DATASPACE_UNKNOWN;
536     if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
537         for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
538             if (*attr == EGL_GL_COLORSPACE_KHR) {
539                 colorSpace = attr[1];
540                 bool found = false;
541                 // Verify that color space is allowed
542                 if (colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
543                     colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR) {
544                     found = true;
545                 } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_linear &&
546                            dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_linear")) {
547                     found = true;
548                 } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_pq &&
549                            dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_pq")) {
550                     found = true;
551                 } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_EXT &&
552                            dp->haveExtension("EGL_EXT_gl_colorspace_scrgb")) {
553                     found = true;
554                 } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT &&
555                            dp->haveExtension("EGL_EXT_gl_colorspace_scrgb_linear")) {
556                     found = true;
557                 } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT &&
558                            dp->haveExtension("EGL_EXT_gl_colorspace_display_p3_linear")) {
559                     found = true;
560                 } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT &&
561                            dp->haveExtension("EGL_EXT_gl_colorspace_display_p3")) {
562                     found = true;
563                 }
564                 if (!found) {
565                     return false;
566                 }
567                 // Only change the dataSpace from default if the application
568                 // has explicitly set the color space with a EGL_GL_COLORSPACE_KHR attribute.
569                 dataSpace = modifyBufferDataspace(dataSpace, colorSpace);
570             }
571         }
572     }
573     return true;
574 }
575
576 void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config, EGLint& format) {
577     // Set the native window's buffers format to match what this config requests.
578     // Whether to use sRGB gamma is not part of the EGLconfig, but is part
579     // of our native format. So if sRGB gamma is requested, we have to
580     // modify the EGLconfig's format before setting the native window's
581     // format.
582
583     EGLint componentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
584     cnx->egl.eglGetConfigAttrib(dpy, config, EGL_COLOR_COMPONENT_TYPE_EXT, &componentType);
585
586     EGLint a = 0;
587     EGLint r, g, b;
588     r = g = b = 0;
589     cnx->egl.eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r);
590     cnx->egl.eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g);
591     cnx->egl.eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b);
592     cnx->egl.eglGetConfigAttrib(dpy, config, EGL_ALPHA_SIZE, &a);
593     EGLint colorDepth = r + g + b;
594
595     // Today, the driver only understands sRGB and linear on 888X
596     // formats. Strip other colorspaces from the attribute list and
597     // only use them to set the dataspace via
598     // native_window_set_buffers_dataspace
599     // if pixel format is RGBX 8888
600     //    TBD: Can test for future extensions that indicate that driver
601     //    handles requested color space and we can let it through.
602     //    allow SRGB and LINEAR. All others need to be stripped.
603     // else if 565, 4444
604     //    TBD: Can we assume these are supported if 8888 is?
605     // else if FP16 or 1010102
606     //    strip colorspace from attribs.
607     // endif
608     if (a == 0) {
609         if (colorDepth <= 16) {
610             format = HAL_PIXEL_FORMAT_RGB_565;
611         } else {
612             if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
613                 if (colorDepth > 24) {
614                     format = HAL_PIXEL_FORMAT_RGBA_1010102;
615                 } else {
616                     format = HAL_PIXEL_FORMAT_RGBX_8888;
617                 }
618             } else {
619                 format = HAL_PIXEL_FORMAT_RGBA_FP16;
620             }
621         }
622     } else {
623         if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
624             if (colorDepth > 24) {
625                 format = HAL_PIXEL_FORMAT_RGBA_1010102;
626             } else {
627                 format = HAL_PIXEL_FORMAT_RGBA_8888;
628             }
629         } else {
630             format = HAL_PIXEL_FORMAT_RGBA_FP16;
631         }
632     }
633 }
634
635 EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
636                                     NativeWindowType window,
637                                     const EGLint *attrib_list)
638 {
639     clearError();
640
641     egl_connection_t* cnx = NULL;
642     egl_display_ptr dp = validate_display_connection(dpy, cnx);
643     if (dp) {
644         EGLDisplay iDpy = dp->disp.dpy;
645
646         if (!window) {
647             return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
648         }
649
650         int value = 0;
651         window->query(window, NATIVE_WINDOW_IS_VALID, &value);
652         if (!value) {
653             return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
654         }
655
656         int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
657         if (result < 0) {
658             ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
659                     "failed (%#x) (already connected to another API?)",
660                     window, result);
661             return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
662         }
663
664         EGLint format;
665         getNativePixelFormat(iDpy, cnx, config, format);
666
667         // now select correct colorspace and dataspace based on user's attribute list
668         EGLint colorSpace;
669         android_dataspace dataSpace;
670         if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
671             ALOGE("error invalid colorspace: %d", colorSpace);
672             return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
673         }
674
675         std::vector<EGLint> strippedAttribList;
676         if (stripColorSpaceAttribute(dp, attrib_list, format, strippedAttribList)) {
677             // Had to modify the attribute list due to use of color space.
678             // Use modified list from here on.
679             attrib_list = strippedAttribList.data();
680         }
681
682         if (format != 0) {
683             int err = native_window_set_buffers_format(window, format);
684             if (err != 0) {
685                 ALOGE("error setting native window pixel format: %s (%d)",
686                         strerror(-err), err);
687                 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
688                 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
689             }
690         }
691
692         if (dataSpace != 0) {
693             int err = native_window_set_buffers_data_space(window, dataSpace);
694             if (err != 0) {
695                 ALOGE("error setting native window pixel dataSpace: %s (%d)",
696                         strerror(-err), err);
697                 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
698                 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
699             }
700         }
701
702         // the EGL spec requires that a new EGLSurface default to swap interval
703         // 1, so explicitly set that on the window here.
704         ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
705         anw->setSwapInterval(anw, 1);
706
707         EGLSurface surface = cnx->egl.eglCreateWindowSurface(
708                 iDpy, config, window, attrib_list);
709         if (surface != EGL_NO_SURFACE) {
710             egl_surface_t* s =
711                     new egl_surface_t(dp.get(), config, window, surface, colorSpace, cnx);
712             return s;
713         }
714
715         // EGLSurface creation failed
716         native_window_set_buffers_format(window, 0);
717         native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
718     }
719     return EGL_NO_SURFACE;
720 }
721
722 EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
723                                     NativePixmapType pixmap,
724                                     const EGLint *attrib_list)
725 {
726     clearError();
727
728     egl_connection_t* cnx = NULL;
729     egl_display_ptr dp = validate_display_connection(dpy, cnx);
730     EGLint colorSpace;
731     android_dataspace dataSpace;
732     if (dp) {
733         // now select a corresponding sRGB format if needed
734         if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
735             ALOGE("error invalid colorspace: %d", colorSpace);
736             return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
737         }
738
739         EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
740                 dp->disp.dpy, config, pixmap, attrib_list);
741         if (surface != EGL_NO_SURFACE) {
742             egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
743             return s;
744         }
745     }
746     return EGL_NO_SURFACE;
747 }
748
749 EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
750                                     const EGLint *attrib_list)
751 {
752     clearError();
753
754     egl_connection_t* cnx = NULL;
755     egl_display_ptr dp = validate_display_connection(dpy, cnx);
756     if (dp) {
757         EGLDisplay iDpy = dp->disp.dpy;
758         EGLint format;
759         getNativePixelFormat(iDpy, cnx, config, format);
760
761         // now select correct colorspace and dataspace based on user's attribute list
762         EGLint colorSpace;
763         android_dataspace dataSpace;
764         if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
765             ALOGE("error invalid colorspace: %d", colorSpace);
766             return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
767         }
768
769         // Pbuffers are not displayed so we don't need to store the
770         // colorspace. We do need to filter out color spaces the
771         // driver doesn't know how to process.
772         std::vector<EGLint> strippedAttribList;
773         if (stripColorSpaceAttribute(dp, attrib_list, format, strippedAttribList)) {
774             // Had to modify the attribute list due to use of color space.
775             // Use modified list from here on.
776             attrib_list = strippedAttribList.data();
777         }
778
779         EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
780                 dp->disp.dpy, config, attrib_list);
781         if (surface != EGL_NO_SURFACE) {
782             egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
783             return s;
784         }
785     }
786     return EGL_NO_SURFACE;
787 }
788
789 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
790 {
791     clearError();
792
793     const egl_display_ptr dp = validate_display(dpy);
794     if (!dp) return EGL_FALSE;
795
796     SurfaceRef _s(dp.get(), surface);
797     if (!_s.get())
798         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
799
800     egl_surface_t * const s = get_surface(surface);
801     EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
802     if (result == EGL_TRUE) {
803         _s.terminate();
804     }
805     return result;
806 }
807
808 EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
809                             EGLint attribute, EGLint *value)
810 {
811     clearError();
812
813     const egl_display_ptr dp = validate_display(dpy);
814     if (!dp) return EGL_FALSE;
815
816     SurfaceRef _s(dp.get(), surface);
817     if (!_s.get())
818         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
819
820     egl_surface_t const * const s = get_surface(surface);
821     if (attribute == EGL_GL_COLORSPACE_KHR) {
822         *value = s->getColorSpace();
823         return EGL_TRUE;
824     }
825     return s->cnx->egl.eglQuerySurface(
826             dp->disp.dpy, s->surface, attribute, value);
827 }
828
829 void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
830     ATRACE_CALL();
831     clearError();
832
833     const egl_display_ptr dp = validate_display(dpy);
834     if (!dp) {
835         return;
836     }
837
838     SurfaceRef _s(dp.get(), surface);
839     if (!_s.get()) {
840         setError(EGL_BAD_SURFACE, EGL_FALSE);
841     }
842 }
843
844 // ----------------------------------------------------------------------------
845 // Contexts
846 // ----------------------------------------------------------------------------
847
848 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
849                             EGLContext share_list, const EGLint *attrib_list)
850 {
851     clearError();
852
853     egl_connection_t* cnx = NULL;
854     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
855     if (dp) {
856         if (share_list != EGL_NO_CONTEXT) {
857             if (!ContextRef(dp.get(), share_list).get()) {
858                 return setError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
859             }
860             egl_context_t* const c = get_context(share_list);
861             share_list = c->context;
862         }
863         EGLContext context = cnx->egl.eglCreateContext(
864                 dp->disp.dpy, config, share_list, attrib_list);
865         if (context != EGL_NO_CONTEXT) {
866             // figure out if it's a GLESv1 or GLESv2
867             int version = 0;
868             if (attrib_list) {
869                 while (*attrib_list != EGL_NONE) {
870                     GLint attr = *attrib_list++;
871                     GLint value = *attrib_list++;
872                     if (attr == EGL_CONTEXT_CLIENT_VERSION) {
873                         if (value == 1) {
874                             version = egl_connection_t::GLESv1_INDEX;
875                         } else if (value == 2 || value == 3) {
876                             version = egl_connection_t::GLESv2_INDEX;
877                         }
878                     }
879                 };
880             }
881             egl_context_t* c = new egl_context_t(dpy, context, config, cnx,
882                     version);
883             return c;
884         }
885     }
886     return EGL_NO_CONTEXT;
887 }
888
889 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
890 {
891     clearError();
892
893     const egl_display_ptr dp = validate_display(dpy);
894     if (!dp)
895         return EGL_FALSE;
896
897     ContextRef _c(dp.get(), ctx);
898     if (!_c.get())
899         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
900
901     egl_context_t * const c = get_context(ctx);
902     EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
903     if (result == EGL_TRUE) {
904         _c.terminate();
905     }
906     return result;
907 }
908
909 EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
910                             EGLSurface read, EGLContext ctx)
911 {
912     clearError();
913
914     egl_display_ptr dp = validate_display(dpy);
915     if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
916
917     // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
918     // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
919     // a valid but uninitialized display.
920     if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
921          (draw != EGL_NO_SURFACE) ) {
922         if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
923     }
924
925     // get a reference to the object passed in
926     ContextRef _c(dp.get(), ctx);
927     SurfaceRef _d(dp.get(), draw);
928     SurfaceRef _r(dp.get(), read);
929
930     // validate the context (if not EGL_NO_CONTEXT)
931     if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
932         // EGL_NO_CONTEXT is valid
933         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
934     }
935
936     // these are the underlying implementation's object
937     EGLContext impl_ctx  = EGL_NO_CONTEXT;
938     EGLSurface impl_draw = EGL_NO_SURFACE;
939     EGLSurface impl_read = EGL_NO_SURFACE;
940
941     // these are our objects structs passed in
942     egl_context_t       * c = NULL;
943     egl_surface_t const * d = NULL;
944     egl_surface_t const * r = NULL;
945
946     // these are the current objects structs
947     egl_context_t * cur_c = get_context(getContext());
948
949     if (ctx != EGL_NO_CONTEXT) {
950         c = get_context(ctx);
951         impl_ctx = c->context;
952     } else {
953         // no context given, use the implementation of the current context
954         if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
955             // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
956             return setError(EGL_BAD_MATCH, (EGLBoolean)EGL_FALSE);
957         }
958         if (cur_c == NULL) {
959             // no current context
960             // not an error, there is just no current context.
961             return EGL_TRUE;
962         }
963     }
964
965     // retrieve the underlying implementation's draw EGLSurface
966     if (draw != EGL_NO_SURFACE) {
967         if (!_d.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
968         d = get_surface(draw);
969         impl_draw = d->surface;
970     }
971
972     // retrieve the underlying implementation's read EGLSurface
973     if (read != EGL_NO_SURFACE) {
974         if (!_r.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
975         r = get_surface(read);
976         impl_read = r->surface;
977     }
978
979
980     EGLBoolean result = dp->makeCurrent(c, cur_c,
981             draw, read, ctx,
982             impl_draw, impl_read, impl_ctx);
983
984     if (result == EGL_TRUE) {
985         if (c) {
986             setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
987             egl_tls_t::setContext(ctx);
988             _c.acquire();
989             _r.acquire();
990             _d.acquire();
991         } else {
992             setGLHooksThreadSpecific(&gHooksNoContext);
993             egl_tls_t::setContext(EGL_NO_CONTEXT);
994         }
995     } else {
996
997         if (cur_c != NULL) {
998             // Force return to current context for drivers that cannot handle errors
999             EGLBoolean restore_result = EGL_FALSE;
1000             // get a reference to the old current objects
1001             ContextRef _c2(dp.get(), cur_c);
1002             SurfaceRef _d2(dp.get(), cur_c->draw);
1003             SurfaceRef _r2(dp.get(), cur_c->read);
1004
1005             c = cur_c;
1006             impl_ctx = c->context;
1007             impl_draw = EGL_NO_SURFACE;
1008             if (cur_c->draw != EGL_NO_SURFACE) {
1009                 d = get_surface(cur_c->draw);
1010                 impl_draw = d->surface;
1011             }
1012             impl_read = EGL_NO_SURFACE;
1013             if (cur_c->read != EGL_NO_SURFACE) {
1014                 r = get_surface(cur_c->read);
1015                 impl_read = r->surface;
1016             }
1017             restore_result = dp->makeCurrent(c, cur_c,
1018                     cur_c->draw, cur_c->read, cur_c->context,
1019                     impl_draw, impl_read, impl_ctx);
1020             if (restore_result == EGL_TRUE) {
1021                 _c2.acquire();
1022                 _r2.acquire();
1023                 _d2.acquire();
1024             } else {
1025                 ALOGE("Could not restore original EGL context");
1026             }
1027         }
1028         // this will ALOGE the error
1029         egl_connection_t* const cnx = &gEGLImpl;
1030         result = setError(cnx->egl.eglGetError(), (EGLBoolean)EGL_FALSE);
1031     }
1032     return result;
1033 }
1034
1035
1036 EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
1037                             EGLint attribute, EGLint *value)
1038 {
1039     clearError();
1040
1041     const egl_display_ptr dp = validate_display(dpy);
1042     if (!dp) return EGL_FALSE;
1043
1044     ContextRef _c(dp.get(), ctx);
1045     if (!_c.get()) return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1046
1047     egl_context_t * const c = get_context(ctx);
1048     return c->cnx->egl.eglQueryContext(
1049             dp->disp.dpy, c->context, attribute, value);
1050
1051 }
1052
1053 EGLContext eglGetCurrentContext(void)
1054 {
1055     // could be called before eglInitialize(), but we wouldn't have a context
1056     // then, and this function would correctly return EGL_NO_CONTEXT.
1057
1058     clearError();
1059
1060     EGLContext ctx = getContext();
1061     return ctx;
1062 }
1063
1064 EGLSurface eglGetCurrentSurface(EGLint readdraw)
1065 {
1066     // could be called before eglInitialize(), but we wouldn't have a context
1067     // then, and this function would correctly return EGL_NO_SURFACE.
1068
1069     clearError();
1070
1071     EGLContext ctx = getContext();
1072     if (ctx) {
1073         egl_context_t const * const c = get_context(ctx);
1074         if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
1075         switch (readdraw) {
1076             case EGL_READ: return c->read;
1077             case EGL_DRAW: return c->draw;
1078             default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
1079         }
1080     }
1081     return EGL_NO_SURFACE;
1082 }
1083
1084 EGLDisplay eglGetCurrentDisplay(void)
1085 {
1086     // could be called before eglInitialize(), but we wouldn't have a context
1087     // then, and this function would correctly return EGL_NO_DISPLAY.
1088
1089     clearError();
1090
1091     EGLContext ctx = getContext();
1092     if (ctx) {
1093         egl_context_t const * const c = get_context(ctx);
1094         if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
1095         return c->dpy;
1096     }
1097     return EGL_NO_DISPLAY;
1098 }
1099
1100 EGLBoolean eglWaitGL(void)
1101 {
1102     clearError();
1103
1104     egl_connection_t* const cnx = &gEGLImpl;
1105     if (!cnx->dso)
1106         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1107
1108     return cnx->egl.eglWaitGL();
1109 }
1110
1111 EGLBoolean eglWaitNative(EGLint engine)
1112 {
1113     clearError();
1114
1115     egl_connection_t* const cnx = &gEGLImpl;
1116     if (!cnx->dso)
1117         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1118
1119     return cnx->egl.eglWaitNative(engine);
1120 }
1121
1122 EGLint eglGetError(void)
1123 {
1124     EGLint err = EGL_SUCCESS;
1125     egl_connection_t* const cnx = &gEGLImpl;
1126     if (cnx->dso) {
1127         err = cnx->egl.eglGetError();
1128     }
1129     if (err == EGL_SUCCESS) {
1130         err = egl_tls_t::getError();
1131     }
1132     return err;
1133 }
1134
1135 static __eglMustCastToProperFunctionPointerType findBuiltinWrapper(
1136         const char* procname) {
1137     const egl_connection_t* cnx = &gEGLImpl;
1138     void* proc = NULL;
1139
1140     proc = dlsym(cnx->libEgl, procname);
1141     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1142
1143     proc = dlsym(cnx->libGles2, procname);
1144     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1145
1146     proc = dlsym(cnx->libGles1, procname);
1147     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1148
1149     return NULL;
1150 }
1151
1152 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
1153 {
1154     // eglGetProcAddress() could be the very first function called
1155     // in which case we must make sure we've initialized ourselves, this
1156     // happens the first time egl_get_display() is called.
1157
1158     clearError();
1159
1160     if (egl_init_drivers() == EGL_FALSE) {
1161         setError(EGL_BAD_PARAMETER, NULL);
1162         return  NULL;
1163     }
1164
1165     if (FILTER_EXTENSIONS(procname)) {
1166         return NULL;
1167     }
1168
1169     __eglMustCastToProperFunctionPointerType addr;
1170     addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap));
1171     if (addr) return addr;
1172
1173     addr = findBuiltinWrapper(procname);
1174     if (addr) return addr;
1175
1176     // this protects accesses to sGLExtentionMap and sGLExtentionSlot
1177     pthread_mutex_lock(&sExtensionMapMutex);
1178
1179         /*
1180          * Since eglGetProcAddress() is not associated to anything, it needs
1181          * to return a function pointer that "works" regardless of what
1182          * the current context is.
1183          *
1184          * For this reason, we return a "forwarder", a small stub that takes
1185          * care of calling the function associated with the context
1186          * currently bound.
1187          *
1188          * We first look for extensions we've already resolved, if we're seeing
1189          * this extension for the first time, we go through all our
1190          * implementations and call eglGetProcAddress() and record the
1191          * result in the appropriate implementation hooks and return the
1192          * address of the forwarder corresponding to that hook set.
1193          *
1194          */
1195
1196         const std::string name(procname);
1197
1198     auto& extentionMap = sGLExtentionMap;
1199     auto pos = extentionMap.find(name);
1200         addr = (pos != extentionMap.end()) ? pos->second : nullptr;
1201         const int slot = sGLExtentionSlot;
1202
1203         ALOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS,
1204                 "no more slots for eglGetProcAddress(\"%s\")",
1205                 procname);
1206
1207         if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
1208             bool found = false;
1209
1210             egl_connection_t* const cnx = &gEGLImpl;
1211             if (cnx->dso && cnx->egl.eglGetProcAddress) {
1212                 // Extensions are independent of the bound context
1213                 addr =
1214                 cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
1215                 cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] =
1216                         cnx->egl.eglGetProcAddress(procname);
1217                 if (addr) found = true;
1218             }
1219
1220             if (found) {
1221                 addr = gExtensionForwarders[slot];
1222                 extentionMap[name] = addr;
1223                 sGLExtentionSlot++;
1224             }
1225         }
1226
1227     pthread_mutex_unlock(&sExtensionMapMutex);
1228     return addr;
1229 }
1230
1231 class FrameCompletionThread {
1232 public:
1233
1234     static void queueSync(EGLSyncKHR sync) {
1235         static FrameCompletionThread thread;
1236
1237         char name[64];
1238
1239         std::lock_guard<std::mutex> lock(thread.mMutex);
1240         snprintf(name, sizeof(name), "kicked off frame %u", (unsigned int)thread.mFramesQueued);
1241         ATRACE_NAME(name);
1242
1243         thread.mQueue.push_back(sync);
1244         thread.mCondition.notify_one();
1245         thread.mFramesQueued++;
1246         ATRACE_INT("GPU Frames Outstanding", int32_t(thread.mQueue.size()));
1247     }
1248
1249 private:
1250
1251     FrameCompletionThread() : mFramesQueued(0), mFramesCompleted(0) {
1252         std::thread thread(&FrameCompletionThread::loop, this);
1253         thread.detach();
1254     }
1255
1256 #pragma clang diagnostic push
1257 #pragma clang diagnostic ignored "-Wmissing-noreturn"
1258     void loop() {
1259         while (true) {
1260             threadLoop();
1261         }
1262     }
1263 #pragma clang diagnostic pop
1264
1265     void threadLoop() {
1266         EGLSyncKHR sync;
1267         uint32_t frameNum;
1268         {
1269             std::unique_lock<std::mutex> lock(mMutex);
1270             while (mQueue.empty()) {
1271                 mCondition.wait(lock);
1272             }
1273             sync = mQueue[0];
1274             frameNum = mFramesCompleted;
1275         }
1276         EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1277         {
1278             char name[64];
1279             snprintf(name, sizeof(name), "waiting for frame %u", (unsigned int)frameNum);
1280             ATRACE_NAME(name);
1281
1282             EGLint result = eglClientWaitSyncKHR(dpy, sync, 0, EGL_FOREVER_KHR);
1283             if (result == EGL_FALSE) {
1284                 ALOGE("FrameCompletion: error waiting for fence: %#x", eglGetError());
1285             } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
1286                 ALOGE("FrameCompletion: timeout waiting for fence");
1287             }
1288             eglDestroySyncKHR(dpy, sync);
1289         }
1290         {
1291             std::lock_guard<std::mutex> lock(mMutex);
1292             mQueue.pop_front();
1293             mFramesCompleted++;
1294             ATRACE_INT("GPU Frames Outstanding", int32_t(mQueue.size()));
1295         }
1296     }
1297
1298     uint32_t mFramesQueued;
1299     uint32_t mFramesCompleted;
1300     std::deque<EGLSyncKHR> mQueue;
1301     std::condition_variable mCondition;
1302     std::mutex mMutex;
1303 };
1304
1305 EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
1306         EGLint *rects, EGLint n_rects)
1307 {
1308     ATRACE_CALL();
1309     clearError();
1310
1311     const egl_display_ptr dp = validate_display(dpy);
1312     if (!dp) return EGL_FALSE;
1313
1314     SurfaceRef _s(dp.get(), draw);
1315     if (!_s.get())
1316         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1317
1318     egl_surface_t const * const s = get_surface(draw);
1319
1320     if (CC_UNLIKELY(dp->traceGpuCompletion)) {
1321         EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL);
1322         if (sync != EGL_NO_SYNC_KHR) {
1323             FrameCompletionThread::queueSync(sync);
1324         }
1325     }
1326
1327     if (CC_UNLIKELY(dp->finishOnSwap)) {
1328         uint32_t pixel;
1329         egl_context_t * const c = get_context( egl_tls_t::getContext() );
1330         if (c) {
1331             // glReadPixels() ensures that the frame is complete
1332             s->cnx->hooks[c->version]->gl.glReadPixels(0,0,1,1,
1333                     GL_RGBA,GL_UNSIGNED_BYTE,&pixel);
1334         }
1335     }
1336
1337     if (n_rects == 0) {
1338         return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1339     }
1340
1341     std::vector<android_native_rect_t> androidRects((size_t)n_rects);
1342     for (int r = 0; r < n_rects; ++r) {
1343         int offset = r * 4;
1344         int x = rects[offset];
1345         int y = rects[offset + 1];
1346         int width = rects[offset + 2];
1347         int height = rects[offset + 3];
1348         android_native_rect_t androidRect;
1349         androidRect.left = x;
1350         androidRect.top = y + height;
1351         androidRect.right = x + width;
1352         androidRect.bottom = y;
1353         androidRects.push_back(androidRect);
1354     }
1355     native_window_set_surface_damage(s->getNativeWindow(), androidRects.data(), androidRects.size());
1356
1357     if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
1358         return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface,
1359                 rects, n_rects);
1360     } else {
1361         return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1362     }
1363 }
1364
1365 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1366 {
1367     return eglSwapBuffersWithDamageKHR(dpy, surface, NULL, 0);
1368 }
1369
1370 EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
1371                             NativePixmapType target)
1372 {
1373     clearError();
1374
1375     const egl_display_ptr dp = validate_display(dpy);
1376     if (!dp) return EGL_FALSE;
1377
1378     SurfaceRef _s(dp.get(), surface);
1379     if (!_s.get())
1380         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1381
1382     egl_surface_t const * const s = get_surface(surface);
1383     return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
1384 }
1385
1386 const char* eglQueryString(EGLDisplay dpy, EGLint name)
1387 {
1388     clearError();
1389
1390     // Generate an error quietly when client extensions (as defined by
1391     // EGL_EXT_client_extensions) are queried.  We do not want to rely on
1392     // validate_display to generate the error as validate_display would log
1393     // the error, which can be misleading.
1394     //
1395     // If we want to support EGL_EXT_client_extensions later, we can return
1396     // the client extension string here instead.
1397     if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
1398         return setErrorQuiet(EGL_BAD_DISPLAY, (const char*)0);
1399
1400     const egl_display_ptr dp = validate_display(dpy);
1401     if (!dp) return (const char *) NULL;
1402
1403     switch (name) {
1404         case EGL_VENDOR:
1405             return dp->getVendorString();
1406         case EGL_VERSION:
1407             return dp->getVersionString();
1408         case EGL_EXTENSIONS:
1409             return dp->getExtensionString();
1410         case EGL_CLIENT_APIS:
1411             return dp->getClientApiString();
1412         default:
1413             break;
1414     }
1415     return setError(EGL_BAD_PARAMETER, (const char *)0);
1416 }
1417
1418 EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name)
1419 {
1420     clearError();
1421
1422     const egl_display_ptr dp = validate_display(dpy);
1423     if (!dp) return (const char *) NULL;
1424
1425     switch (name) {
1426         case EGL_VENDOR:
1427             return dp->disp.queryString.vendor;
1428         case EGL_VERSION:
1429             return dp->disp.queryString.version;
1430         case EGL_EXTENSIONS:
1431             return dp->disp.queryString.extensions;
1432         case EGL_CLIENT_APIS:
1433             return dp->disp.queryString.clientApi;
1434         default:
1435             break;
1436     }
1437     return setError(EGL_BAD_PARAMETER, (const char *)0);
1438 }
1439
1440 // ----------------------------------------------------------------------------
1441 // EGL 1.1
1442 // ----------------------------------------------------------------------------
1443
1444 EGLBoolean eglSurfaceAttrib(
1445         EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
1446 {
1447     clearError();
1448
1449     const egl_display_ptr dp = validate_display(dpy);
1450     if (!dp) return EGL_FALSE;
1451
1452     SurfaceRef _s(dp.get(), surface);
1453     if (!_s.get())
1454         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1455
1456     egl_surface_t * const s = get_surface(surface);
1457
1458     if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) {
1459         if (!s->getNativeWindow()) {
1460             setError(EGL_BAD_SURFACE, EGL_FALSE);
1461         }
1462         int err = native_window_set_auto_refresh(s->getNativeWindow(), value != 0);
1463         return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1464     }
1465
1466     if (attribute == EGL_TIMESTAMPS_ANDROID) {
1467         if (!s->getNativeWindow()) {
1468             return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1469         }
1470         int err = native_window_enable_frame_timestamps(s->getNativeWindow(), value != 0);
1471         return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1472     }
1473
1474     if (s->cnx->egl.eglSurfaceAttrib) {
1475         return s->cnx->egl.eglSurfaceAttrib(
1476                 dp->disp.dpy, s->surface, attribute, value);
1477     }
1478     return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1479 }
1480
1481 EGLBoolean eglBindTexImage(
1482         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1483 {
1484     clearError();
1485
1486     const egl_display_ptr dp = validate_display(dpy);
1487     if (!dp) return EGL_FALSE;
1488
1489     SurfaceRef _s(dp.get(), surface);
1490     if (!_s.get())
1491         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1492
1493     egl_surface_t const * const s = get_surface(surface);
1494     if (s->cnx->egl.eglBindTexImage) {
1495         return s->cnx->egl.eglBindTexImage(
1496                 dp->disp.dpy, s->surface, buffer);
1497     }
1498     return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1499 }
1500
1501 EGLBoolean eglReleaseTexImage(
1502         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1503 {
1504     clearError();
1505
1506     const egl_display_ptr dp = validate_display(dpy);
1507     if (!dp) return EGL_FALSE;
1508
1509     SurfaceRef _s(dp.get(), surface);
1510     if (!_s.get())
1511         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1512
1513     egl_surface_t const * const s = get_surface(surface);
1514     if (s->cnx->egl.eglReleaseTexImage) {
1515         return s->cnx->egl.eglReleaseTexImage(
1516                 dp->disp.dpy, s->surface, buffer);
1517     }
1518     return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1519 }
1520
1521 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
1522 {
1523     clearError();
1524
1525     const egl_display_ptr dp = validate_display(dpy);
1526     if (!dp) return EGL_FALSE;
1527
1528     EGLBoolean res = EGL_TRUE;
1529     egl_connection_t* const cnx = &gEGLImpl;
1530     if (cnx->dso && cnx->egl.eglSwapInterval) {
1531         res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
1532     }
1533
1534     return res;
1535 }
1536
1537
1538 // ----------------------------------------------------------------------------
1539 // EGL 1.2
1540 // ----------------------------------------------------------------------------
1541
1542 EGLBoolean eglWaitClient(void)
1543 {
1544     clearError();
1545
1546     egl_connection_t* const cnx = &gEGLImpl;
1547     if (!cnx->dso)
1548         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1549
1550     EGLBoolean res;
1551     if (cnx->egl.eglWaitClient) {
1552         res = cnx->egl.eglWaitClient();
1553     } else {
1554         res = cnx->egl.eglWaitGL();
1555     }
1556     return res;
1557 }
1558
1559 EGLBoolean eglBindAPI(EGLenum api)
1560 {
1561     clearError();
1562
1563     if (egl_init_drivers() == EGL_FALSE) {
1564         return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
1565     }
1566
1567     // bind this API on all EGLs
1568     EGLBoolean res = EGL_TRUE;
1569     egl_connection_t* const cnx = &gEGLImpl;
1570     if (cnx->dso && cnx->egl.eglBindAPI) {
1571         res = cnx->egl.eglBindAPI(api);
1572     }
1573     return res;
1574 }
1575
1576 EGLenum eglQueryAPI(void)
1577 {
1578     clearError();
1579
1580     if (egl_init_drivers() == EGL_FALSE) {
1581         return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
1582     }
1583
1584     egl_connection_t* const cnx = &gEGLImpl;
1585     if (cnx->dso && cnx->egl.eglQueryAPI) {
1586         return cnx->egl.eglQueryAPI();
1587     }
1588
1589     // or, it can only be OpenGL ES
1590     return EGL_OPENGL_ES_API;
1591 }
1592
1593 EGLBoolean eglReleaseThread(void)
1594 {
1595     clearError();
1596
1597     egl_connection_t* const cnx = &gEGLImpl;
1598     if (cnx->dso && cnx->egl.eglReleaseThread) {
1599         cnx->egl.eglReleaseThread();
1600     }
1601
1602     // If there is context bound to the thread, release it
1603     egl_display_t::loseCurrent(get_context(getContext()));
1604
1605     egl_tls_t::clearTLS();
1606     return EGL_TRUE;
1607 }
1608
1609 EGLSurface eglCreatePbufferFromClientBuffer(
1610           EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
1611           EGLConfig config, const EGLint *attrib_list)
1612 {
1613     clearError();
1614
1615     egl_connection_t* cnx = NULL;
1616     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
1617     if (!dp) return EGL_FALSE;
1618     if (cnx->egl.eglCreatePbufferFromClientBuffer) {
1619         return cnx->egl.eglCreatePbufferFromClientBuffer(
1620                 dp->disp.dpy, buftype, buffer, config, attrib_list);
1621     }
1622     return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
1623 }
1624
1625 // ----------------------------------------------------------------------------
1626 // EGL_EGLEXT_VERSION 3
1627 // ----------------------------------------------------------------------------
1628
1629 EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
1630         const EGLint *attrib_list)
1631 {
1632     clearError();
1633
1634     const egl_display_ptr dp = validate_display(dpy);
1635     if (!dp) return EGL_FALSE;
1636
1637     SurfaceRef _s(dp.get(), surface);
1638     if (!_s.get())
1639         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1640
1641     egl_surface_t const * const s = get_surface(surface);
1642     if (s->cnx->egl.eglLockSurfaceKHR) {
1643         return s->cnx->egl.eglLockSurfaceKHR(
1644                 dp->disp.dpy, s->surface, attrib_list);
1645     }
1646     return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1647 }
1648
1649 EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
1650 {
1651     clearError();
1652
1653     const egl_display_ptr dp = validate_display(dpy);
1654     if (!dp) return EGL_FALSE;
1655
1656     SurfaceRef _s(dp.get(), surface);
1657     if (!_s.get())
1658         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1659
1660     egl_surface_t const * const s = get_surface(surface);
1661     if (s->cnx->egl.eglUnlockSurfaceKHR) {
1662         return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
1663     }
1664     return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1665 }
1666
1667 EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1668         EGLClientBuffer buffer, const EGLint *attrib_list)
1669 {
1670     clearError();
1671
1672     const egl_display_ptr dp = validate_display(dpy);
1673     if (!dp) return EGL_NO_IMAGE_KHR;
1674
1675     ContextRef _c(dp.get(), ctx);
1676     egl_context_t * const c = _c.get();
1677
1678     EGLImageKHR result = EGL_NO_IMAGE_KHR;
1679     egl_connection_t* const cnx = &gEGLImpl;
1680     if (cnx->dso && cnx->egl.eglCreateImageKHR) {
1681         result = cnx->egl.eglCreateImageKHR(
1682                 dp->disp.dpy,
1683                 c ? c->context : EGL_NO_CONTEXT,
1684                 target, buffer, attrib_list);
1685     }
1686     return result;
1687 }
1688
1689 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
1690 {
1691     clearError();
1692
1693     const egl_display_ptr dp = validate_display(dpy);
1694     if (!dp) return EGL_FALSE;
1695
1696     EGLBoolean result = EGL_FALSE;
1697     egl_connection_t* const cnx = &gEGLImpl;
1698     if (cnx->dso && cnx->egl.eglDestroyImageKHR) {
1699         result = cnx->egl.eglDestroyImageKHR(dp->disp.dpy, img);
1700     }
1701     return result;
1702 }
1703
1704 // ----------------------------------------------------------------------------
1705 // EGL_EGLEXT_VERSION 5
1706 // ----------------------------------------------------------------------------
1707
1708
1709 EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1710 {
1711     clearError();
1712
1713     const egl_display_ptr dp = validate_display(dpy);
1714     if (!dp) return EGL_NO_SYNC_KHR;
1715
1716     EGLSyncKHR result = EGL_NO_SYNC_KHR;
1717     egl_connection_t* const cnx = &gEGLImpl;
1718     if (cnx->dso && cnx->egl.eglCreateSyncKHR) {
1719         result = cnx->egl.eglCreateSyncKHR(dp->disp.dpy, type, attrib_list);
1720     }
1721     return result;
1722 }
1723
1724 EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1725 {
1726     clearError();
1727
1728     const egl_display_ptr dp = validate_display(dpy);
1729     if (!dp) return EGL_FALSE;
1730
1731     EGLBoolean result = EGL_FALSE;
1732     egl_connection_t* const cnx = &gEGLImpl;
1733     if (cnx->dso && cnx->egl.eglDestroySyncKHR) {
1734         result = cnx->egl.eglDestroySyncKHR(dp->disp.dpy, sync);
1735     }
1736     return result;
1737 }
1738
1739 EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
1740     clearError();
1741
1742     const egl_display_ptr dp = validate_display(dpy);
1743     if (!dp) return EGL_FALSE;
1744
1745     EGLBoolean result = EGL_FALSE;
1746     egl_connection_t* const cnx = &gEGLImpl;
1747     if (cnx->dso && cnx->egl.eglSignalSyncKHR) {
1748         result = cnx->egl.eglSignalSyncKHR(
1749                 dp->disp.dpy, sync, mode);
1750     }
1751     return result;
1752 }
1753
1754 EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync,
1755         EGLint flags, EGLTimeKHR timeout)
1756 {
1757     clearError();
1758
1759     const egl_display_ptr dp = validate_display(dpy);
1760     if (!dp) return EGL_FALSE;
1761
1762     EGLint result = EGL_FALSE;
1763     egl_connection_t* const cnx = &gEGLImpl;
1764     if (cnx->dso && cnx->egl.eglClientWaitSyncKHR) {
1765         result = cnx->egl.eglClientWaitSyncKHR(
1766                 dp->disp.dpy, sync, flags, timeout);
1767     }
1768     return result;
1769 }
1770
1771 EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync,
1772         EGLint attribute, EGLint *value)
1773 {
1774     clearError();
1775
1776     const egl_display_ptr dp = validate_display(dpy);
1777     if (!dp) return EGL_FALSE;
1778
1779     EGLBoolean result = EGL_FALSE;
1780     egl_connection_t* const cnx = &gEGLImpl;
1781     if (cnx->dso && cnx->egl.eglGetSyncAttribKHR) {
1782         result = cnx->egl.eglGetSyncAttribKHR(
1783                 dp->disp.dpy, sync, attribute, value);
1784     }
1785     return result;
1786 }
1787
1788 EGLStreamKHR eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
1789 {
1790     clearError();
1791
1792     const egl_display_ptr dp = validate_display(dpy);
1793     if (!dp) return EGL_NO_STREAM_KHR;
1794
1795     EGLStreamKHR result = EGL_NO_STREAM_KHR;
1796     egl_connection_t* const cnx = &gEGLImpl;
1797     if (cnx->dso && cnx->egl.eglCreateStreamKHR) {
1798         result = cnx->egl.eglCreateStreamKHR(
1799                 dp->disp.dpy, attrib_list);
1800     }
1801     return result;
1802 }
1803
1804 EGLBoolean eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
1805 {
1806     clearError();
1807
1808     const egl_display_ptr dp = validate_display(dpy);
1809     if (!dp) return EGL_FALSE;
1810
1811     EGLBoolean result = EGL_FALSE;
1812     egl_connection_t* const cnx = &gEGLImpl;
1813     if (cnx->dso && cnx->egl.eglDestroyStreamKHR) {
1814         result = cnx->egl.eglDestroyStreamKHR(
1815                 dp->disp.dpy, stream);
1816     }
1817     return result;
1818 }
1819
1820 EGLBoolean eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream,
1821         EGLenum attribute, EGLint value)
1822 {
1823     clearError();
1824
1825     const egl_display_ptr dp = validate_display(dpy);
1826     if (!dp) return EGL_FALSE;
1827
1828     EGLBoolean result = EGL_FALSE;
1829     egl_connection_t* const cnx = &gEGLImpl;
1830     if (cnx->dso && cnx->egl.eglStreamAttribKHR) {
1831         result = cnx->egl.eglStreamAttribKHR(
1832                 dp->disp.dpy, stream, attribute, value);
1833     }
1834     return result;
1835 }
1836
1837 EGLBoolean eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream,
1838         EGLenum attribute, EGLint *value)
1839 {
1840     clearError();
1841
1842     const egl_display_ptr dp = validate_display(dpy);
1843     if (!dp) return EGL_FALSE;
1844
1845     EGLBoolean result = EGL_FALSE;
1846     egl_connection_t* const cnx = &gEGLImpl;
1847     if (cnx->dso && cnx->egl.eglQueryStreamKHR) {
1848         result = cnx->egl.eglQueryStreamKHR(
1849                 dp->disp.dpy, stream, attribute, value);
1850     }
1851     return result;
1852 }
1853
1854 EGLBoolean eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream,
1855         EGLenum attribute, EGLuint64KHR *value)
1856 {
1857     clearError();
1858
1859     const egl_display_ptr dp = validate_display(dpy);
1860     if (!dp) return EGL_FALSE;
1861
1862     EGLBoolean result = EGL_FALSE;
1863     egl_connection_t* const cnx = &gEGLImpl;
1864     if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) {
1865         result = cnx->egl.eglQueryStreamu64KHR(
1866                 dp->disp.dpy, stream, attribute, value);
1867     }
1868     return result;
1869 }
1870
1871 EGLBoolean eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream,
1872         EGLenum attribute, EGLTimeKHR *value)
1873 {
1874     clearError();
1875
1876     const egl_display_ptr dp = validate_display(dpy);
1877     if (!dp) return EGL_FALSE;
1878
1879     EGLBoolean result = EGL_FALSE;
1880     egl_connection_t* const cnx = &gEGLImpl;
1881     if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) {
1882         result = cnx->egl.eglQueryStreamTimeKHR(
1883                 dp->disp.dpy, stream, attribute, value);
1884     }
1885     return result;
1886 }
1887
1888 EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config,
1889         EGLStreamKHR stream, const EGLint *attrib_list)
1890 {
1891     clearError();
1892
1893     egl_display_ptr dp = validate_display(dpy);
1894     if (!dp) return EGL_NO_SURFACE;
1895
1896     EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
1897     android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
1898     // TODO: Probably need to update EGL_KHR_stream_producer_eglsurface to
1899     // indicate support for EGL_GL_COLORSPACE_KHR.
1900     // now select a corresponding sRGB format if needed
1901     if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
1902         ALOGE("error invalid colorspace: %d", colorSpace);
1903         return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
1904     }
1905
1906     egl_connection_t* const cnx = &gEGLImpl;
1907     if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
1908         EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
1909                 dp->disp.dpy, config, stream, attrib_list);
1910         if (surface != EGL_NO_SURFACE) {
1911             egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
1912             return s;
1913         }
1914     }
1915     return EGL_NO_SURFACE;
1916 }
1917
1918 EGLBoolean eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,
1919         EGLStreamKHR stream)
1920 {
1921     clearError();
1922
1923     const egl_display_ptr dp = validate_display(dpy);
1924     if (!dp) return EGL_FALSE;
1925
1926     EGLBoolean result = EGL_FALSE;
1927     egl_connection_t* const cnx = &gEGLImpl;
1928     if (cnx->dso && cnx->egl.eglStreamConsumerGLTextureExternalKHR) {
1929         result = cnx->egl.eglStreamConsumerGLTextureExternalKHR(
1930                 dp->disp.dpy, stream);
1931     }
1932     return result;
1933 }
1934
1935 EGLBoolean eglStreamConsumerAcquireKHR(EGLDisplay dpy,
1936         EGLStreamKHR stream)
1937 {
1938     clearError();
1939
1940     const egl_display_ptr dp = validate_display(dpy);
1941     if (!dp) return EGL_FALSE;
1942
1943     EGLBoolean result = EGL_FALSE;
1944     egl_connection_t* const cnx = &gEGLImpl;
1945     if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) {
1946         result = cnx->egl.eglStreamConsumerAcquireKHR(
1947                 dp->disp.dpy, stream);
1948     }
1949     return result;
1950 }
1951
1952 EGLBoolean eglStreamConsumerReleaseKHR(EGLDisplay dpy,
1953         EGLStreamKHR stream)
1954 {
1955     clearError();
1956
1957     const egl_display_ptr dp = validate_display(dpy);
1958     if (!dp) return EGL_FALSE;
1959
1960     EGLBoolean result = EGL_FALSE;
1961     egl_connection_t* const cnx = &gEGLImpl;
1962     if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) {
1963         result = cnx->egl.eglStreamConsumerReleaseKHR(
1964                 dp->disp.dpy, stream);
1965     }
1966     return result;
1967 }
1968
1969 EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR(
1970         EGLDisplay dpy, EGLStreamKHR stream)
1971 {
1972     clearError();
1973
1974     const egl_display_ptr dp = validate_display(dpy);
1975     if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR;
1976
1977     EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR;
1978     egl_connection_t* const cnx = &gEGLImpl;
1979     if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) {
1980         result = cnx->egl.eglGetStreamFileDescriptorKHR(
1981                 dp->disp.dpy, stream);
1982     }
1983     return result;
1984 }
1985
1986 EGLStreamKHR eglCreateStreamFromFileDescriptorKHR(
1987         EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor)
1988 {
1989     clearError();
1990
1991     const egl_display_ptr dp = validate_display(dpy);
1992     if (!dp) return EGL_NO_STREAM_KHR;
1993
1994     EGLStreamKHR result = EGL_NO_STREAM_KHR;
1995     egl_connection_t* const cnx = &gEGLImpl;
1996     if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) {
1997         result = cnx->egl.eglCreateStreamFromFileDescriptorKHR(
1998                 dp->disp.dpy, file_descriptor);
1999     }
2000     return result;
2001 }
2002
2003 // ----------------------------------------------------------------------------
2004 // EGL_EGLEXT_VERSION 15
2005 // ----------------------------------------------------------------------------
2006
2007 EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
2008     clearError();
2009     const egl_display_ptr dp = validate_display(dpy);
2010     if (!dp) return EGL_FALSE;
2011     EGLint result = EGL_FALSE;
2012     egl_connection_t* const cnx = &gEGLImpl;
2013     if (cnx->dso && cnx->egl.eglWaitSyncKHR) {
2014         result = cnx->egl.eglWaitSyncKHR(dp->disp.dpy, sync, flags);
2015     }
2016     return result;
2017 }
2018
2019 // ----------------------------------------------------------------------------
2020 // ANDROID extensions
2021 // ----------------------------------------------------------------------------
2022
2023 EGLint eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
2024 {
2025     clearError();
2026
2027     const egl_display_ptr dp = validate_display(dpy);
2028     if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID;
2029
2030     EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
2031     egl_connection_t* const cnx = &gEGLImpl;
2032     if (cnx->dso && cnx->egl.eglDupNativeFenceFDANDROID) {
2033         result = cnx->egl.eglDupNativeFenceFDANDROID(dp->disp.dpy, sync);
2034     }
2035     return result;
2036 }
2037
2038 EGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface,
2039         EGLnsecsANDROID time)
2040 {
2041     clearError();
2042
2043     const egl_display_ptr dp = validate_display(dpy);
2044     if (!dp) {
2045         return EGL_FALSE;
2046     }
2047
2048     SurfaceRef _s(dp.get(), surface);
2049     if (!_s.get()) {
2050         setError(EGL_BAD_SURFACE, EGL_FALSE);
2051         return EGL_FALSE;
2052     }
2053
2054     egl_surface_t const * const s = get_surface(surface);
2055     native_window_set_buffers_timestamp(s->getNativeWindow(), time);
2056
2057     return EGL_TRUE;
2058 }
2059
2060 EGLClientBuffer eglGetNativeClientBufferANDROID(const AHardwareBuffer *buffer) {
2061     clearError();
2062     // AHardwareBuffer_to_ANativeWindowBuffer is a platform-only symbol and thus
2063     // this function cannot be implemented when this libEGL is built for
2064     // vendors.
2065 #ifndef __ANDROID_VNDK__
2066     if (!buffer) return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
2067     return const_cast<ANativeWindowBuffer *>(AHardwareBuffer_to_ANativeWindowBuffer(buffer));
2068 #else
2069     return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
2070 #endif
2071 }
2072
2073 // ----------------------------------------------------------------------------
2074 // NVIDIA extensions
2075 // ----------------------------------------------------------------------------
2076 EGLuint64NV eglGetSystemTimeFrequencyNV()
2077 {
2078     clearError();
2079
2080     if (egl_init_drivers() == EGL_FALSE) {
2081         return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
2082     }
2083
2084     EGLuint64NV ret = 0;
2085     egl_connection_t* const cnx = &gEGLImpl;
2086
2087     if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
2088         return cnx->egl.eglGetSystemTimeFrequencyNV();
2089     }
2090
2091     return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
2092 }
2093
2094 EGLuint64NV eglGetSystemTimeNV()
2095 {
2096     clearError();
2097
2098     if (egl_init_drivers() == EGL_FALSE) {
2099         return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
2100     }
2101
2102     EGLuint64NV ret = 0;
2103     egl_connection_t* const cnx = &gEGLImpl;
2104
2105     if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
2106         return cnx->egl.eglGetSystemTimeNV();
2107     }
2108
2109     return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
2110 }
2111
2112 // ----------------------------------------------------------------------------
2113 // Partial update extension
2114 // ----------------------------------------------------------------------------
2115 EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
2116         EGLint *rects, EGLint n_rects)
2117 {
2118     clearError();
2119
2120     const egl_display_ptr dp = validate_display(dpy);
2121     if (!dp) {
2122         setError(EGL_BAD_DISPLAY, EGL_FALSE);
2123         return EGL_FALSE;
2124     }
2125
2126     SurfaceRef _s(dp.get(), surface);
2127     if (!_s.get()) {
2128         setError(EGL_BAD_SURFACE, EGL_FALSE);
2129         return EGL_FALSE;
2130     }
2131
2132     egl_surface_t const * const s = get_surface(surface);
2133     if (s->cnx->egl.eglSetDamageRegionKHR) {
2134         return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface,
2135                 rects, n_rects);
2136     }
2137
2138     return EGL_FALSE;
2139 }
2140
2141 EGLBoolean eglGetNextFrameIdANDROID(EGLDisplay dpy, EGLSurface surface,
2142             EGLuint64KHR *frameId) {
2143     clearError();
2144
2145     const egl_display_ptr dp = validate_display(dpy);
2146     if (!dp) {
2147         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2148     }
2149
2150     SurfaceRef _s(dp.get(), surface);
2151     if (!_s.get()) {
2152         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2153     }
2154
2155     egl_surface_t const * const s = get_surface(surface);
2156
2157     if (!s->getNativeWindow()) {
2158         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2159     }
2160
2161     uint64_t nextFrameId = 0;
2162     int ret = native_window_get_next_frame_id(s->getNativeWindow(), &nextFrameId);
2163
2164     if (ret != 0) {
2165         // This should not happen. Return an error that is not in the spec
2166         // so it's obvious something is very wrong.
2167         ALOGE("eglGetNextFrameId: Unexpected error.");
2168         return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2169     }
2170
2171     *frameId = nextFrameId;
2172     return EGL_TRUE;
2173 }
2174
2175 EGLBoolean eglGetCompositorTimingANDROID(EGLDisplay dpy, EGLSurface surface,
2176         EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values)
2177 {
2178     clearError();
2179
2180     const egl_display_ptr dp = validate_display(dpy);
2181     if (!dp) {
2182         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2183     }
2184
2185     SurfaceRef _s(dp.get(), surface);
2186     if (!_s.get()) {
2187         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2188     }
2189
2190     egl_surface_t const * const s = get_surface(surface);
2191
2192     if (!s->getNativeWindow()) {
2193         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2194     }
2195
2196     nsecs_t* compositeDeadline = nullptr;
2197     nsecs_t* compositeInterval = nullptr;
2198     nsecs_t* compositeToPresentLatency = nullptr;
2199
2200     for (int i = 0; i < numTimestamps; i++) {
2201         switch (names[i]) {
2202             case EGL_COMPOSITE_DEADLINE_ANDROID:
2203                 compositeDeadline = &values[i];
2204                 break;
2205             case EGL_COMPOSITE_INTERVAL_ANDROID:
2206                 compositeInterval = &values[i];
2207                 break;
2208             case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2209                 compositeToPresentLatency = &values[i];
2210                 break;
2211             default:
2212                 return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2213         }
2214     }
2215
2216     int ret = native_window_get_compositor_timing(s->getNativeWindow(),
2217             compositeDeadline, compositeInterval, compositeToPresentLatency);
2218
2219     switch (ret) {
2220       case 0:
2221         return EGL_TRUE;
2222       case -ENOSYS:
2223         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2224       default:
2225         // This should not happen. Return an error that is not in the spec
2226         // so it's obvious something is very wrong.
2227         ALOGE("eglGetCompositorTiming: Unexpected error.");
2228         return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2229     }
2230 }
2231
2232 EGLBoolean eglGetCompositorTimingSupportedANDROID(
2233         EGLDisplay dpy, EGLSurface surface, EGLint name)
2234 {
2235     clearError();
2236
2237     const egl_display_ptr dp = validate_display(dpy);
2238     if (!dp) {
2239         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2240     }
2241
2242     SurfaceRef _s(dp.get(), surface);
2243     if (!_s.get()) {
2244         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2245     }
2246
2247     egl_surface_t const * const s = get_surface(surface);
2248
2249     ANativeWindow* window = s->getNativeWindow();
2250     if (!window) {
2251         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2252     }
2253
2254     switch (name) {
2255         case EGL_COMPOSITE_DEADLINE_ANDROID:
2256         case EGL_COMPOSITE_INTERVAL_ANDROID:
2257         case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2258             return EGL_TRUE;
2259         default:
2260             return EGL_FALSE;
2261     }
2262 }
2263
2264 EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface,
2265         EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps,
2266         EGLnsecsANDROID *values)
2267 {
2268     clearError();
2269
2270     const egl_display_ptr dp = validate_display(dpy);
2271     if (!dp) {
2272         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2273     }
2274
2275     SurfaceRef _s(dp.get(), surface);
2276     if (!_s.get()) {
2277         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2278     }
2279
2280     egl_surface_t const * const s = get_surface(surface);
2281
2282     if (!s->getNativeWindow()) {
2283         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2284     }
2285
2286     nsecs_t* requestedPresentTime = nullptr;
2287     nsecs_t* acquireTime = nullptr;
2288     nsecs_t* latchTime = nullptr;
2289     nsecs_t* firstRefreshStartTime = nullptr;
2290     nsecs_t* gpuCompositionDoneTime = nullptr;
2291     nsecs_t* lastRefreshStartTime = nullptr;
2292     nsecs_t* displayPresentTime = nullptr;
2293     nsecs_t* dequeueReadyTime = nullptr;
2294     nsecs_t* releaseTime = nullptr;
2295
2296     for (int i = 0; i < numTimestamps; i++) {
2297         switch (timestamps[i]) {
2298             case EGL_REQUESTED_PRESENT_TIME_ANDROID:
2299                 requestedPresentTime = &values[i];
2300                 break;
2301             case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2302                 acquireTime = &values[i];
2303                 break;
2304             case EGL_COMPOSITION_LATCH_TIME_ANDROID:
2305                 latchTime = &values[i];
2306                 break;
2307             case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
2308                 firstRefreshStartTime = &values[i];
2309                 break;
2310             case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
2311                 lastRefreshStartTime = &values[i];
2312                 break;
2313             case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
2314                 gpuCompositionDoneTime = &values[i];
2315                 break;
2316             case EGL_DISPLAY_PRESENT_TIME_ANDROID:
2317                 displayPresentTime = &values[i];
2318                 break;
2319             case EGL_DEQUEUE_READY_TIME_ANDROID:
2320                 dequeueReadyTime = &values[i];
2321                 break;
2322             case EGL_READS_DONE_TIME_ANDROID:
2323                 releaseTime = &values[i];
2324                 break;
2325             default:
2326                 return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2327         }
2328     }
2329
2330     int ret = native_window_get_frame_timestamps(s->getNativeWindow(), frameId,
2331             requestedPresentTime, acquireTime, latchTime, firstRefreshStartTime,
2332             lastRefreshStartTime, gpuCompositionDoneTime, displayPresentTime,
2333             dequeueReadyTime, releaseTime);
2334
2335     switch (ret) {
2336         case 0:
2337             return EGL_TRUE;
2338         case -ENOENT:
2339             return setError(EGL_BAD_ACCESS, (EGLBoolean)EGL_FALSE);
2340         case -ENOSYS:
2341             return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2342         case -EINVAL:
2343             return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2344         default:
2345             // This should not happen. Return an error that is not in the spec
2346             // so it's obvious something is very wrong.
2347             ALOGE("eglGetFrameTimestamps: Unexpected error.");
2348             return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2349     }
2350 }
2351
2352 EGLBoolean eglGetFrameTimestampSupportedANDROID(
2353         EGLDisplay dpy, EGLSurface surface, EGLint timestamp)
2354 {
2355     clearError();
2356
2357     const egl_display_ptr dp = validate_display(dpy);
2358     if (!dp) {
2359         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2360     }
2361
2362     SurfaceRef _s(dp.get(), surface);
2363     if (!_s.get()) {
2364         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2365     }
2366
2367     egl_surface_t const * const s = get_surface(surface);
2368
2369     ANativeWindow* window = s->getNativeWindow();
2370     if (!window) {
2371         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2372     }
2373
2374     switch (timestamp) {
2375         case EGL_COMPOSITE_DEADLINE_ANDROID:
2376         case EGL_COMPOSITE_INTERVAL_ANDROID:
2377         case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2378         case EGL_REQUESTED_PRESENT_TIME_ANDROID:
2379         case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2380         case EGL_COMPOSITION_LATCH_TIME_ANDROID:
2381         case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
2382         case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
2383         case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
2384         case EGL_DEQUEUE_READY_TIME_ANDROID:
2385         case EGL_READS_DONE_TIME_ANDROID:
2386             return EGL_TRUE;
2387         case EGL_DISPLAY_PRESENT_TIME_ANDROID: {
2388             int value = 0;
2389             window->query(window,
2390                     NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT, &value);
2391             return value == 0 ? EGL_FALSE : EGL_TRUE;
2392         }
2393         default:
2394             return EGL_FALSE;
2395     }
2396 }