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