OSDN Git Service

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