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 "egl_platform_entries.h"
20 
21 #include <ctype.h>
22 #include <dlfcn.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include <hardware/gralloc1.h>
27 
28 #include <EGL/egl.h>
29 #include <EGL/eglext.h>
30 #include <EGL/eglext_angle.h>
31 
32 #include <android/hardware_buffer.h>
33 #include <android-base/strings.h>
34 #include <graphicsenv/GraphicsEnv.h>
35 #include <private/android/AHardwareBufferHelpers.h>
36 
37 #include <cutils/compiler.h>
38 #include <cutils/properties.h>
39 #include <log/log.h>
40 
41 #include <condition_variable>
42 #include <deque>
43 #include <mutex>
44 #include <unordered_map>
45 #include <string>
46 #include <thread>
47 
48 #include "../egl_impl.h"
49 
50 #include "egl_display.h"
51 #include "egl_object.h"
52 #include "egl_layers.h"
53 #include "egl_tls.h"
54 #include "egl_trace.h"
55 
56 using namespace android;
57 
58 // ----------------------------------------------------------------------------
59 
60 namespace android {
61 
62 using nsecs_t = int64_t;
63 
64 struct extension_map_t {
65     const char* name;
66     __eglMustCastToProperFunctionPointerType address;
67 };
68 
69 /*
70  * This is the list of EGL extensions exposed to applications.
71  *
72  * Some of them (gBuiltinExtensionString) are implemented entirely in this EGL
73  * wrapper and are always available.
74  *
75  * The rest (gExtensionString) depend on support in the EGL driver, and are
76  * only available if the driver supports them. However, some of these must be
77  * supported because they are used by the Android system itself; these are
78  * listed as mandatory below and are required by the CDD. The system *assumes*
79  * the mandatory extensions are present and may not function properly if some
80  * are missing.
81  *
82  * NOTE: Both strings MUST have a single space as the last character.
83  */
84 
85 extern char const * const gBuiltinExtensionString;
86 extern char const * const gExtensionString;
87 
88 // clang-format off
89 // Extensions implemented by the EGL wrapper.
90 char const * const gBuiltinExtensionString =
91         "EGL_KHR_get_all_proc_addresses "
92         "EGL_ANDROID_presentation_time "
93         "EGL_KHR_swap_buffers_with_damage "
94         "EGL_ANDROID_get_native_client_buffer "
95         "EGL_ANDROID_front_buffer_auto_refresh "
96         "EGL_ANDROID_get_frame_timestamps "
97         "EGL_EXT_surface_SMPTE2086_metadata "
98         "EGL_EXT_surface_CTA861_3_metadata "
99         ;
100 
101 // Allowed list of extensions exposed to applications if implemented in the vendor driver.
102 char const * const gExtensionString  =
103         "EGL_KHR_image "                        // mandatory
104         "EGL_KHR_image_base "                   // mandatory
105         "EGL_EXT_image_gl_colorspace "
106         "EGL_KHR_image_pixmap "
107         "EGL_KHR_lock_surface "
108         "EGL_KHR_gl_colorspace "
109         "EGL_KHR_gl_texture_2D_image "
110         "EGL_KHR_gl_texture_3D_image "
111         "EGL_KHR_gl_texture_cubemap_image "
112         "EGL_KHR_gl_renderbuffer_image "
113         "EGL_KHR_reusable_sync "
114         "EGL_KHR_fence_sync "
115         "EGL_KHR_create_context "
116         "EGL_KHR_config_attribs "
117         "EGL_KHR_surfaceless_context "
118         "EGL_KHR_stream "
119         "EGL_KHR_stream_fifo "
120         "EGL_KHR_stream_producer_eglsurface "
121         "EGL_KHR_stream_consumer_gltexture "
122         "EGL_KHR_stream_cross_process_fd "
123         "EGL_EXT_create_context_robustness "
124         "EGL_NV_system_time "
125         "EGL_ANDROID_image_native_buffer "      // mandatory
126         "EGL_KHR_wait_sync "                    // strongly recommended
127         "EGL_ANDROID_recordable "               // mandatory
128         "EGL_KHR_partial_update "               // strongly recommended
129         "EGL_EXT_pixel_format_float "
130         "EGL_EXT_buffer_age "                   // strongly recommended with partial_update
131         "EGL_KHR_create_context_no_error "
132         "EGL_KHR_mutable_render_buffer "
133         "EGL_EXT_yuv_surface "
134         "EGL_EXT_protected_content "
135         "EGL_IMG_context_priority "
136         "EGL_KHR_no_config_context "
137         ;
138 
139 char const * const gClientExtensionString =
140         "EGL_EXT_client_extensions "
141         "EGL_KHR_platform_android "
142         "EGL_ANGLE_platform_angle "
143         "EGL_ANDROID_GLES_layers";
144 // clang-format on
145 
146 // extensions not exposed to applications but used by the ANDROID system
147 //      "EGL_ANDROID_blob_cache "               // strongly recommended
148 //      "EGL_IMG_hibernate_process "            // optional
149 //      "EGL_ANDROID_native_fence_sync "        // strongly recommended
150 //      "EGL_ANDROID_framebuffer_target "       // mandatory for HWC 1.1
151 
152 /*
153  * EGL Extensions entry-points exposed to 3rd party applications
154  * (keep in sync with gExtensionString above)
155  *
156  */
157 static const extension_map_t sExtensionMap[] = {
158     // EGL_KHR_lock_surface
159     { "eglLockSurfaceKHR",
160             (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR },
161     { "eglUnlockSurfaceKHR",
162             (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR },
163 
164     // EGL_KHR_image, EGL_KHR_image_base
165     { "eglCreateImageKHR",
166             (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
167     { "eglDestroyImageKHR",
168             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
169 
170     // EGL_KHR_reusable_sync, EGL_KHR_fence_sync
171     { "eglCreateSyncKHR",
172             (__eglMustCastToProperFunctionPointerType)&eglCreateSyncKHR },
173     { "eglDestroySyncKHR",
174             (__eglMustCastToProperFunctionPointerType)&eglDestroySyncKHR },
175     { "eglClientWaitSyncKHR",
176             (__eglMustCastToProperFunctionPointerType)&eglClientWaitSyncKHR },
177     { "eglSignalSyncKHR",
178             (__eglMustCastToProperFunctionPointerType)&eglSignalSyncKHR },
179     { "eglGetSyncAttribKHR",
180             (__eglMustCastToProperFunctionPointerType)&eglGetSyncAttribKHR },
181 
182     // EGL_NV_system_time
183     { "eglGetSystemTimeFrequencyNV",
184             (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV },
185     { "eglGetSystemTimeNV",
186             (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV },
187 
188     // EGL_KHR_wait_sync
189     { "eglWaitSyncKHR",
190             (__eglMustCastToProperFunctionPointerType)&eglWaitSyncKHR },
191 
192     // EGL_ANDROID_presentation_time
193     { "eglPresentationTimeANDROID",
194             (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID },
195 
196     // EGL_KHR_swap_buffers_with_damage
197     { "eglSwapBuffersWithDamageKHR",
198             (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR },
199 
200     // EGL_ANDROID_get_native_client_buffer
201     { "eglGetNativeClientBufferANDROID",
202             (__eglMustCastToProperFunctionPointerType)&eglGetNativeClientBufferANDROID },
203 
204     // EGL_KHR_partial_update
205     { "eglSetDamageRegionKHR",
206             (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
207 
208     { "eglCreateStreamKHR",
209             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamKHR },
210     { "eglDestroyStreamKHR",
211             (__eglMustCastToProperFunctionPointerType)&eglDestroyStreamKHR },
212     { "eglStreamAttribKHR",
213             (__eglMustCastToProperFunctionPointerType)&eglStreamAttribKHR },
214     { "eglQueryStreamKHR",
215             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamKHR },
216     { "eglQueryStreamu64KHR",
217             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamu64KHR },
218     { "eglQueryStreamTimeKHR",
219             (__eglMustCastToProperFunctionPointerType)&eglQueryStreamTimeKHR },
220     { "eglCreateStreamProducerSurfaceKHR",
221             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamProducerSurfaceKHR },
222     { "eglStreamConsumerGLTextureExternalKHR",
223             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerGLTextureExternalKHR },
224     { "eglStreamConsumerAcquireKHR",
225             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerAcquireKHR },
226     { "eglStreamConsumerReleaseKHR",
227             (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerReleaseKHR },
228     { "eglGetStreamFileDescriptorKHR",
229             (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR },
230     { "eglCreateStreamFromFileDescriptorKHR",
231             (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR },
232 
233     // EGL_ANDROID_get_frame_timestamps
234     { "eglGetNextFrameIdANDROID",
235             (__eglMustCastToProperFunctionPointerType)&eglGetNextFrameIdANDROID },
236     { "eglGetCompositorTimingANDROID",
237             (__eglMustCastToProperFunctionPointerType)&eglGetCompositorTimingANDROID },
238     { "eglGetCompositorTimingSupportedANDROID",
239             (__eglMustCastToProperFunctionPointerType)&eglGetCompositorTimingSupportedANDROID },
240     { "eglGetFrameTimestampsANDROID",
241             (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID },
242     { "eglGetFrameTimestampSupportedANDROID",
243             (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampSupportedANDROID },
244 
245     // EGL_ANDROID_native_fence_sync
246     { "eglDupNativeFenceFDANDROID",
247             (__eglMustCastToProperFunctionPointerType)&eglDupNativeFenceFDANDROID },
248 };
249 
250 /*
251  * These extensions entry-points should not be exposed to applications.
252  * They're used internally by the Android EGL layer.
253  */
254 #define FILTER_EXTENSIONS(procname) \
255         (!strcmp((procname), "eglSetBlobCacheFuncsANDROID") ||    \
256          !strcmp((procname), "eglHibernateProcessIMG")      ||    \
257          !strcmp((procname), "eglAwakenProcessIMG"))
258 
259 // accesses protected by sExtensionMapMutex
260 static std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtensionMap;
261 static std::unordered_map<std::string, int> sGLExtensionSlotMap;
262 
263 static int sGLExtensionSlot = 0;
264 static pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER;
265 
findProcAddress(const char * name,const extension_map_t * map,size_t n)266 static void(*findProcAddress(const char* name,
267         const extension_map_t* map, size_t n))() {
268     for (uint32_t i=0 ; i<n ; i++) {
269         if (!strcmp(name, map[i].name)) {
270             return map[i].address;
271         }
272     }
273     return nullptr;
274 }
275 
276 // ----------------------------------------------------------------------------
277 
278 extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
279 extern EGLBoolean egl_init_drivers();
280 extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
281 extern gl_hooks_t gHooksTrace;
282 
283 // ----------------------------------------------------------------------------
284 
getContext()285 static inline EGLContext getContext() { return egl_tls_t::getContext(); }
286 
287 // ----------------------------------------------------------------------------
288 
eglGetPlatformDisplayTmpl(EGLenum platform,EGLNativeDisplayType display,const EGLAttrib * attrib_list)289 static EGLDisplay eglGetPlatformDisplayTmpl(EGLenum platform, EGLNativeDisplayType display,
290                                             const EGLAttrib* attrib_list) {
291     if (platform != EGL_PLATFORM_ANDROID_KHR) {
292         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
293     }
294 
295     uintptr_t index = reinterpret_cast<uintptr_t>(display);
296     if (index >= NUM_DISPLAYS) {
297         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
298     }
299 
300     EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display, attrib_list);
301     return dpy;
302 }
303 
eglGetDisplayImpl(EGLNativeDisplayType display)304 EGLDisplay eglGetDisplayImpl(EGLNativeDisplayType display) {
305     return eglGetPlatformDisplayTmpl(EGL_PLATFORM_ANDROID_KHR, display, nullptr);
306 }
307 
eglGetPlatformDisplayImpl(EGLenum platform,void * native_display,const EGLAttrib * attrib_list)308 EGLDisplay eglGetPlatformDisplayImpl(EGLenum platform, void* native_display,
309                                      const EGLAttrib* attrib_list) {
310     return eglGetPlatformDisplayTmpl(platform, static_cast<EGLNativeDisplayType>(native_display),
311                                      attrib_list);
312 }
313 
314 // ----------------------------------------------------------------------------
315 // Initialization
316 // ----------------------------------------------------------------------------
317 
eglInitializeImpl(EGLDisplay dpy,EGLint * major,EGLint * minor)318 EGLBoolean eglInitializeImpl(EGLDisplay dpy, EGLint *major, EGLint *minor)
319 {
320     egl_display_ptr dp = get_display(dpy);
321     if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
322 
323     EGLBoolean res = dp->initialize(major, minor);
324 
325     return res;
326 }
327 
eglTerminateImpl(EGLDisplay dpy)328 EGLBoolean eglTerminateImpl(EGLDisplay dpy)
329 {
330     // NOTE: don't unload the drivers b/c some APIs can be called
331     // after eglTerminate() has been called. eglTerminate() only
332     // terminates an EGLDisplay, not a EGL itself.
333 
334     egl_display_ptr dp = get_display(dpy);
335     if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
336 
337     EGLBoolean res = dp->terminate();
338 
339     return res;
340 }
341 
342 // ----------------------------------------------------------------------------
343 // configuration
344 // ----------------------------------------------------------------------------
345 
eglGetConfigsImpl(EGLDisplay dpy,EGLConfig * configs,EGLint config_size,EGLint * num_config)346 EGLBoolean eglGetConfigsImpl(EGLDisplay dpy,
347                              EGLConfig *configs,
348                              EGLint config_size, EGLint *num_config)
349 {
350     const egl_display_ptr dp = validate_display(dpy);
351     if (!dp) return EGL_FALSE;
352 
353     if (num_config==nullptr) {
354         return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
355     }
356 
357     EGLBoolean res = EGL_FALSE;
358     *num_config = 0;
359 
360     egl_connection_t* const cnx = &gEGLImpl;
361     if (cnx->dso) {
362         res = cnx->egl.eglGetConfigs(
363                 dp->disp.dpy, configs, config_size, num_config);
364     }
365 
366     return res;
367 }
368 
eglChooseConfigImpl(EGLDisplay dpy,const EGLint * attrib_list,EGLConfig * configs,EGLint config_size,EGLint * num_config)369 EGLBoolean eglChooseConfigImpl( EGLDisplay dpy, const EGLint *attrib_list,
370                                 EGLConfig *configs, EGLint config_size,
371                                 EGLint *num_config)
372 {
373     const egl_display_ptr dp = validate_display(dpy);
374     if (!dp) return EGL_FALSE;
375 
376     if (num_config==nullptr) {
377         return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
378     }
379 
380     EGLBoolean res = EGL_FALSE;
381     *num_config = 0;
382 
383     egl_connection_t* const cnx = &gEGLImpl;
384     if (cnx->dso) {
385         if (attrib_list) {
386             char value[PROPERTY_VALUE_MAX];
387             property_get("debug.egl.force_msaa", value, "false");
388 
389             if (!strcmp(value, "true")) {
390                 size_t attribCount = 0;
391                 EGLint attrib = attrib_list[0];
392 
393                 // Only enable MSAA if the context is OpenGL ES 2.0 and
394                 // if no caveat is requested
395                 const EGLint *attribRendererable = nullptr;
396                 const EGLint *attribCaveat = nullptr;
397 
398                 // Count the number of attributes and look for
399                 // EGL_RENDERABLE_TYPE and EGL_CONFIG_CAVEAT
400                 while (attrib != EGL_NONE) {
401                     attrib = attrib_list[attribCount];
402                     switch (attrib) {
403                         case EGL_RENDERABLE_TYPE:
404                             attribRendererable = &attrib_list[attribCount];
405                             break;
406                         case EGL_CONFIG_CAVEAT:
407                             attribCaveat = &attrib_list[attribCount];
408                             break;
409                         default:
410                             break;
411                     }
412                     attribCount++;
413                 }
414 
415                 if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT &&
416                         (!attribCaveat || attribCaveat[1] != EGL_NONE)) {
417 
418                     // Insert 2 extra attributes to force-enable MSAA 4x
419                     EGLint aaAttribs[attribCount + 4];
420                     aaAttribs[0] = EGL_SAMPLE_BUFFERS;
421                     aaAttribs[1] = 1;
422                     aaAttribs[2] = EGL_SAMPLES;
423                     aaAttribs[3] = 4;
424 
425                     memcpy(&aaAttribs[4], attrib_list, attribCount * sizeof(EGLint));
426 
427                     EGLint numConfigAA;
428                     EGLBoolean resAA = cnx->egl.eglChooseConfig(
429                             dp->disp.dpy, aaAttribs, configs, config_size, &numConfigAA);
430 
431                     if (resAA == EGL_TRUE && numConfigAA > 0) {
432                         ALOGD("Enabling MSAA 4x");
433                         *num_config = numConfigAA;
434                         return resAA;
435                     }
436                 }
437             }
438         }
439 
440         res = cnx->egl.eglChooseConfig(
441                 dp->disp.dpy, attrib_list, configs, config_size, num_config);
442     }
443     return res;
444 }
445 
eglGetConfigAttribImpl(EGLDisplay dpy,EGLConfig config,EGLint attribute,EGLint * value)446 EGLBoolean eglGetConfigAttribImpl(EGLDisplay dpy, EGLConfig config,
447         EGLint attribute, EGLint *value)
448 {
449     egl_connection_t* cnx = nullptr;
450     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
451     if (!dp) return EGL_FALSE;
452 
453     return cnx->egl.eglGetConfigAttrib(
454             dp->disp.dpy, config, attribute, value);
455 }
456 
457 // ----------------------------------------------------------------------------
458 // surfaces
459 // ----------------------------------------------------------------------------
460 
461 // Translates EGL color spaces to Android data spaces.
dataSpaceFromEGLColorSpace(EGLint colorspace)462 static android_dataspace dataSpaceFromEGLColorSpace(EGLint colorspace) {
463     if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
464         return HAL_DATASPACE_UNKNOWN;
465     } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
466         return HAL_DATASPACE_V0_SRGB;
467     } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT) {
468         return HAL_DATASPACE_DISPLAY_P3;
469     } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT) {
470         return HAL_DATASPACE_DISPLAY_P3_LINEAR;
471     } else if (colorspace == EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT) {
472         return HAL_DATASPACE_DISPLAY_P3;
473     } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_EXT) {
474         return HAL_DATASPACE_V0_SCRGB;
475     } else if (colorspace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT) {
476         return HAL_DATASPACE_V0_SCRGB_LINEAR;
477     } else if (colorspace == EGL_GL_COLORSPACE_BT2020_LINEAR_EXT) {
478         return HAL_DATASPACE_BT2020_LINEAR;
479     } else if (colorspace == EGL_GL_COLORSPACE_BT2020_PQ_EXT) {
480         return HAL_DATASPACE_BT2020_PQ;
481     }
482     return HAL_DATASPACE_UNKNOWN;
483 }
484 
485 // Get the colorspace value that should be reported from queries. When the colorspace
486 // is unknown (no attribute passed), default to reporting LINEAR.
getReportedColorSpace(EGLint colorspace)487 static EGLint getReportedColorSpace(EGLint colorspace) {
488     return colorspace == EGL_UNKNOWN ? EGL_GL_COLORSPACE_LINEAR_KHR : colorspace;
489 }
490 
491 // Returns a list of color spaces understood by the vendor EGL driver.
getDriverColorSpaces(egl_display_ptr dp)492 static std::vector<EGLint> getDriverColorSpaces(egl_display_ptr dp) {
493     std::vector<EGLint> colorSpaces;
494 
495     // sRGB and linear are always supported when color space support is present.
496     colorSpaces.push_back(EGL_GL_COLORSPACE_SRGB_KHR);
497     colorSpaces.push_back(EGL_GL_COLORSPACE_LINEAR_KHR);
498 
499     if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_display_p3")) {
500         colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT);
501     }
502     if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_scrgb")) {
503         colorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_EXT);
504     }
505     if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_scrgb_linear")) {
506         colorSpaces.push_back(EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT);
507     }
508     if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_bt2020_linear")) {
509         colorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_LINEAR_EXT);
510     }
511     if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_bt2020_pq")) {
512         colorSpaces.push_back(EGL_GL_COLORSPACE_BT2020_PQ_EXT);
513     }
514     if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_display_p3_linear")) {
515         colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT);
516     }
517     if (findExtension(dp->disp.queryString.extensions, "EGL_EXT_gl_colorspace_display_p3_passthrough")) {
518         colorSpaces.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT);
519     }
520     return colorSpaces;
521 }
522 
523 // Cleans up color space related parameters that the driver does not understand.
524 // If there is no color space attribute in attrib_list, colorSpace is left
525 // unmodified.
526 template <typename AttrType>
processAttributes(egl_display_ptr dp,ANativeWindow * window,const AttrType * attrib_list,EGLint * colorSpace,std::vector<AttrType> * strippedAttribList)527 static EGLBoolean processAttributes(egl_display_ptr dp, ANativeWindow* window,
528                                     const AttrType* attrib_list, EGLint* colorSpace,
529                                     std::vector<AttrType>* strippedAttribList) {
530     for (const AttrType* attr = attrib_list; attr && attr[0] != EGL_NONE; attr += 2) {
531         bool copyAttribute = true;
532         if (attr[0] == EGL_GL_COLORSPACE_KHR) {
533             switch (attr[1]) {
534                 case EGL_GL_COLORSPACE_LINEAR_KHR:
535                 case EGL_GL_COLORSPACE_SRGB_KHR:
536                 case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
537                 case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT:
538                 case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:
539                 case EGL_GL_COLORSPACE_SCRGB_EXT:
540                 case EGL_GL_COLORSPACE_BT2020_LINEAR_EXT:
541                 case EGL_GL_COLORSPACE_BT2020_PQ_EXT:
542                 case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT:
543                     // Fail immediately if the driver doesn't have color space support at all.
544                     if (!dp->hasColorSpaceSupport) return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
545                     break;
546                 default:
547                     // BAD_ATTRIBUTE if attr is not any of the EGL_GL_COLORSPACE_*
548                     return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
549             }
550             *colorSpace = static_cast<EGLint>(attr[1]);
551 
552             // Strip the attribute if the driver doesn't understand it.
553             copyAttribute = false;
554             std::vector<EGLint> driverColorSpaces = getDriverColorSpaces(dp);
555             for (auto driverColorSpace : driverColorSpaces) {
556                 if (static_cast<EGLint>(attr[1]) == driverColorSpace) {
557                     copyAttribute = true;
558                     break;
559                 }
560             }
561 
562             // If the driver doesn't understand it, we should map sRGB-encoded P3 to
563             // sRGB rather than just dropping the colorspace on the floor.
564             // For this format, the driver is expected to apply the sRGB
565             // transfer function during framebuffer operations.
566             if (!copyAttribute && attr[1] == EGL_GL_COLORSPACE_DISPLAY_P3_EXT) {
567                 strippedAttribList->push_back(attr[0]);
568                 strippedAttribList->push_back(EGL_GL_COLORSPACE_SRGB_KHR);
569             }
570         }
571         if (copyAttribute) {
572             strippedAttribList->push_back(attr[0]);
573             strippedAttribList->push_back(attr[1]);
574         }
575     }
576     // Terminate the attribute list.
577     strippedAttribList->push_back(EGL_NONE);
578 
579     // If the passed color space has wide color gamut, check whether the target native window
580     // supports wide color.
581     const bool colorSpaceIsNarrow = *colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
582             *colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR || *colorSpace == EGL_UNKNOWN;
583     if (window && !colorSpaceIsNarrow) {
584         bool windowSupportsWideColor = true;
585         // Ordinarily we'd put a call to native_window_get_wide_color_support
586         // at the beginning of the function so that we'll have the
587         // result when needed elsewhere in the function.
588         // However, because eglCreateWindowSurface is called by SurfaceFlinger and
589         // SurfaceFlinger is required to answer the call below we would
590         // end up in a deadlock situation. By moving the call to only happen
591         // if the application has specifically asked for wide-color we avoid
592         // the deadlock with SurfaceFlinger since it will not ask for a
593         // wide-color surface.
594         int err = native_window_get_wide_color_support(window, &windowSupportsWideColor);
595 
596         if (err) {
597             ALOGE("processAttributes: invalid window (win=%p) "
598                   "failed (%#x) (already connected to another API?)",
599                   window, err);
600             return setError(EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
601         }
602         if (!windowSupportsWideColor) {
603             // Application has asked for a wide-color colorspace but
604             // wide-color support isn't available on the display the window is on.
605             return setError(EGL_BAD_MATCH, EGL_FALSE);
606         }
607     }
608     return true;
609 }
610 
611 // Note: This only works for existing GLenum's that are all 32bits.
612 // If you have 64bit attributes (e.g. pointers) you shouldn't be calling this.
convertAttribs(const EGLAttrib * attribList,std::vector<EGLint> & newList)613 void convertAttribs(const EGLAttrib* attribList, std::vector<EGLint>& newList) {
614     for (const EGLAttrib* attr = attribList; attr && attr[0] != EGL_NONE; attr += 2) {
615         newList.push_back(static_cast<EGLint>(attr[0]));
616         newList.push_back(static_cast<EGLint>(attr[1]));
617     }
618     newList.push_back(EGL_NONE);
619 }
620 
621 // Gets the native pixel format corrsponding to the passed EGLConfig.
getNativePixelFormat(EGLDisplay dpy,egl_connection_t * cnx,EGLConfig config,android_pixel_format * format)622 void getNativePixelFormat(EGLDisplay dpy, egl_connection_t* cnx, EGLConfig config,
623                           android_pixel_format* format) {
624     // Set the native window's buffers format to match what this config requests.
625     // Whether to use sRGB gamma is not part of the EGLconfig, but is part
626     // of our native format. So if sRGB gamma is requested, we have to
627     // modify the EGLconfig's format before setting the native window's
628     // format.
629 
630     EGLint componentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
631     cnx->egl.eglGetConfigAttrib(dpy, config, EGL_COLOR_COMPONENT_TYPE_EXT, &componentType);
632 
633     EGLint a = 0;
634     EGLint r, g, b;
635     r = g = b = 0;
636     cnx->egl.eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r);
637     cnx->egl.eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g);
638     cnx->egl.eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b);
639     cnx->egl.eglGetConfigAttrib(dpy, config, EGL_ALPHA_SIZE, &a);
640     EGLint colorDepth = r + g + b;
641 
642     // Today, the driver only understands sRGB and linear on 888X
643     // formats. Strip other colorspaces from the attribute list and
644     // only use them to set the dataspace via
645     // native_window_set_buffers_dataspace
646     // if pixel format is RGBX 8888
647     //    TBD: Can test for future extensions that indicate that driver
648     //    handles requested color space and we can let it through.
649     //    allow SRGB and LINEAR. All others need to be stripped.
650     // else if 565, 4444
651     //    TBD: Can we assume these are supported if 8888 is?
652     // else if FP16 or 1010102
653     //    strip colorspace from attribs.
654     // endif
655     if (a == 0) {
656         if (colorDepth <= 16) {
657             *format = HAL_PIXEL_FORMAT_RGB_565;
658         } else {
659             if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
660                 if (colorDepth > 24) {
661                     *format = HAL_PIXEL_FORMAT_RGBA_1010102;
662                 } else {
663                     *format = HAL_PIXEL_FORMAT_RGBX_8888;
664                 }
665             } else {
666                 *format = HAL_PIXEL_FORMAT_RGBA_FP16;
667             }
668         }
669     } else {
670         if (componentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) {
671             if (colorDepth > 24) {
672                 *format = HAL_PIXEL_FORMAT_RGBA_1010102;
673             } else {
674                 *format = HAL_PIXEL_FORMAT_RGBA_8888;
675             }
676         } else {
677             *format = HAL_PIXEL_FORMAT_RGBA_FP16;
678         }
679     }
680 }
681 
sendSurfaceMetadata(egl_surface_t * s)682 EGLBoolean sendSurfaceMetadata(egl_surface_t* s) {
683     android_smpte2086_metadata smpteMetadata;
684     if (s->getSmpte2086Metadata(smpteMetadata)) {
685         int err =
686                 native_window_set_buffers_smpte2086_metadata(s->getNativeWindow(), &smpteMetadata);
687         s->resetSmpte2086Metadata();
688         if (err != 0) {
689             ALOGE("error setting native window smpte2086 metadata: %s (%d)", strerror(-err), err);
690             return EGL_FALSE;
691         }
692     }
693     android_cta861_3_metadata cta8613Metadata;
694     if (s->getCta8613Metadata(cta8613Metadata)) {
695         int err =
696                 native_window_set_buffers_cta861_3_metadata(s->getNativeWindow(), &cta8613Metadata);
697         s->resetCta8613Metadata();
698         if (err != 0) {
699             ALOGE("error setting native window CTS 861.3 metadata: %s (%d)", strerror(-err), err);
700             return EGL_FALSE;
701         }
702     }
703     return EGL_TRUE;
704 }
705 
706 template <typename AttrType, typename CreateFuncType>
eglCreateWindowSurfaceTmpl(egl_display_ptr dp,egl_connection_t * cnx,EGLConfig config,ANativeWindow * window,const AttrType * attrib_list,CreateFuncType createWindowSurfaceFunc)707 EGLSurface eglCreateWindowSurfaceTmpl(egl_display_ptr dp, egl_connection_t* cnx, EGLConfig config,
708                                       ANativeWindow* window, const AttrType* attrib_list,
709                                       CreateFuncType createWindowSurfaceFunc) {
710     const AttrType* origAttribList = attrib_list;
711 
712     if (!window) {
713         return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
714     }
715 
716     int value = 0;
717     window->query(window, NATIVE_WINDOW_IS_VALID, &value);
718     if (!value) {
719         return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
720     }
721 
722     // NOTE: When using Vulkan backend, the Vulkan runtime makes all the
723     // native_window_* calls, so don't do them here.
724     if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
725         int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
726         if (result < 0) {
727             ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
728                   "failed (%#x) (already connected to another API?)",
729                   window, result);
730             return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
731         }
732     }
733 
734     EGLDisplay iDpy = dp->disp.dpy;
735     android_pixel_format format;
736     getNativePixelFormat(iDpy, cnx, config, &format);
737 
738     // now select correct colorspace and dataspace based on user's attribute list
739     EGLint colorSpace = EGL_UNKNOWN;
740     std::vector<AttrType> strippedAttribList;
741     if (!processAttributes<AttrType>(dp, window, attrib_list, &colorSpace, &strippedAttribList)) {
742         ALOGE("error invalid colorspace: %d", colorSpace);
743         if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
744             native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
745         }
746         return EGL_NO_SURFACE;
747     }
748     attrib_list = strippedAttribList.data();
749 
750     if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
751         int err = native_window_set_buffers_format(window, format);
752         if (err != 0) {
753             ALOGE("error setting native window pixel format: %s (%d)", strerror(-err), err);
754             native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
755             return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
756         }
757 
758         android_dataspace dataSpace = dataSpaceFromEGLColorSpace(colorSpace);
759         // Set dataSpace even if it could be HAL_DATASPACE_UNKNOWN.
760         // HAL_DATASPACE_UNKNOWN is the default value, but it may have changed
761         // at this point.
762         err = native_window_set_buffers_data_space(window, dataSpace);
763         if (err != 0) {
764             ALOGE("error setting native window pixel dataSpace: %s (%d)", strerror(-err), err);
765             native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
766             return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
767         }
768     }
769 
770     // the EGL spec requires that a new EGLSurface default to swap interval
771     // 1, so explicitly set that on the window here.
772     window->setSwapInterval(window, 1);
773 
774     EGLSurface surface = createWindowSurfaceFunc(iDpy, config, window, attrib_list);
775     if (surface != EGL_NO_SURFACE) {
776         egl_surface_t* s = new egl_surface_t(dp.get(), config, window, surface,
777                                              getReportedColorSpace(colorSpace), cnx);
778         return s;
779     }
780 
781     // EGLSurface creation failed
782     if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
783         native_window_set_buffers_format(window, 0);
784         native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
785     }
786     return EGL_NO_SURFACE;
787 }
788 
789 typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config,
790                                                                NativeWindowType window,
791                                                                const EGLint* attrib_list);
792 typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)(
793         EGLDisplay dpy, EGLConfig config, void* native_window, const EGLAttrib* attrib_list);
794 
eglCreateWindowSurfaceImpl(EGLDisplay dpy,EGLConfig config,NativeWindowType window,const EGLint * attrib_list)795 EGLSurface eglCreateWindowSurfaceImpl(EGLDisplay dpy, EGLConfig config, NativeWindowType window,
796                                       const EGLint* attrib_list) {
797     egl_connection_t* cnx = NULL;
798     egl_display_ptr dp = validate_display_connection(dpy, cnx);
799     if (dp) {
800         return eglCreateWindowSurfaceTmpl<
801                 EGLint, PFNEGLCREATEWINDOWSURFACEPROC>(dp, cnx, config, window, attrib_list,
802                                                        cnx->egl.eglCreateWindowSurface);
803     }
804     return EGL_NO_SURFACE;
805 }
806 
eglCreatePlatformWindowSurfaceImpl(EGLDisplay dpy,EGLConfig config,void * native_window,const EGLAttrib * attrib_list)807 EGLSurface eglCreatePlatformWindowSurfaceImpl(EGLDisplay dpy, EGLConfig config, void* native_window,
808                                               const EGLAttrib* attrib_list) {
809     egl_connection_t* cnx = NULL;
810     egl_display_ptr dp = validate_display_connection(dpy, cnx);
811     if (dp) {
812         if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
813             if (cnx->egl.eglCreatePlatformWindowSurface) {
814                 return eglCreateWindowSurfaceTmpl<EGLAttrib, PFNEGLCREATEPLATFORMWINDOWSURFACEPROC>(
815                         dp, cnx, config, static_cast<ANativeWindow*>(native_window), attrib_list,
816                         cnx->egl.eglCreatePlatformWindowSurface);
817             }
818             // driver doesn't support native function, return EGL_BAD_DISPLAY
819             ALOGE("Driver indicates EGL 1.5 support, but does not have "
820                   "eglCreatePlatformWindowSurface");
821             return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
822         }
823 
824         std::vector<EGLint> convertedAttribs;
825         convertAttribs(attrib_list, convertedAttribs);
826         if (cnx->egl.eglCreatePlatformWindowSurfaceEXT) {
827             return eglCreateWindowSurfaceTmpl<EGLint, PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC>(
828                     dp, cnx, config, static_cast<ANativeWindow*>(native_window),
829                     convertedAttribs.data(), cnx->egl.eglCreatePlatformWindowSurfaceEXT);
830         } else {
831             return eglCreateWindowSurfaceTmpl<
832                     EGLint, PFNEGLCREATEWINDOWSURFACEPROC>(dp, cnx, config,
833                                                            static_cast<ANativeWindow*>(
834                                                                    native_window),
835                                                            convertedAttribs.data(),
836                                                            cnx->egl.eglCreateWindowSurface);
837         }
838     }
839     return EGL_NO_SURFACE;
840 }
841 
eglCreatePlatformPixmapSurfaceImpl(EGLDisplay dpy,EGLConfig,void *,const EGLAttrib *)842 EGLSurface eglCreatePlatformPixmapSurfaceImpl(EGLDisplay dpy, EGLConfig /*config*/,
843                                               void* /*native_pixmap*/,
844                                               const EGLAttrib* /*attrib_list*/) {
845     // Per EGL_KHR_platform_android:
846     // It is not valid to call eglCreatePlatformPixmapSurface with a <dpy> that
847     // belongs to the Android platform. Any such call fails and generates
848     // an EGL_BAD_PARAMETER error.
849 
850     egl_connection_t* cnx = NULL;
851     egl_display_ptr dp = validate_display_connection(dpy, cnx);
852     if (dp) {
853         return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
854     }
855     return EGL_NO_SURFACE;
856 }
857 
eglCreatePixmapSurfaceImpl(EGLDisplay dpy,EGLConfig,NativePixmapType,const EGLint *)858 EGLSurface eglCreatePixmapSurfaceImpl(EGLDisplay dpy, EGLConfig /*config*/,
859                                       NativePixmapType /*pixmap*/, const EGLint* /*attrib_list*/) {
860     egl_connection_t* cnx = nullptr;
861     egl_display_ptr dp = validate_display_connection(dpy, cnx);
862     if (dp) {
863         return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
864     }
865     return EGL_NO_SURFACE;
866 }
867 
eglCreatePbufferSurfaceImpl(EGLDisplay dpy,EGLConfig config,const EGLint * attrib_list)868 EGLSurface eglCreatePbufferSurfaceImpl(EGLDisplay dpy, EGLConfig config,
869                                        const EGLint* attrib_list) {
870     egl_connection_t* cnx = nullptr;
871     egl_display_ptr dp = validate_display_connection(dpy, cnx);
872     if (dp) {
873         EGLDisplay iDpy = dp->disp.dpy;
874         android_pixel_format format;
875         getNativePixelFormat(iDpy, cnx, config, &format);
876 
877         // Select correct colorspace based on user's attribute list
878         EGLint colorSpace = EGL_UNKNOWN;
879         std::vector<EGLint> strippedAttribList;
880         if (!processAttributes(dp, nullptr, attrib_list, &colorSpace, &strippedAttribList)) {
881             ALOGE("error invalid colorspace: %d", colorSpace);
882             return EGL_NO_SURFACE;
883         }
884         attrib_list = strippedAttribList.data();
885 
886         EGLSurface surface = cnx->egl.eglCreatePbufferSurface(dp->disp.dpy, config, attrib_list);
887         if (surface != EGL_NO_SURFACE) {
888             egl_surface_t* s = new egl_surface_t(dp.get(), config, nullptr, surface,
889                                                  getReportedColorSpace(colorSpace), cnx);
890             return s;
891         }
892     }
893     return EGL_NO_SURFACE;
894 }
895 
eglDestroySurfaceImpl(EGLDisplay dpy,EGLSurface surface)896 EGLBoolean eglDestroySurfaceImpl(EGLDisplay dpy, EGLSurface surface) {
897     const egl_display_ptr dp = validate_display(dpy);
898     if (!dp) return EGL_FALSE;
899 
900     SurfaceRef _s(dp.get(), surface);
901     if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
902 
903     egl_surface_t* const s = get_surface(surface);
904     EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
905     if (result == EGL_TRUE) {
906         _s.terminate();
907     }
908     return result;
909 }
910 
eglQuerySurfaceImpl(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint * value)911 EGLBoolean eglQuerySurfaceImpl(EGLDisplay dpy, EGLSurface surface, EGLint attribute,
912                                EGLint* value) {
913     const egl_display_ptr dp = validate_display(dpy);
914     if (!dp) return EGL_FALSE;
915 
916     SurfaceRef _s(dp.get(), surface);
917     if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
918 
919     egl_surface_t const* const s = get_surface(surface);
920     if (s->getColorSpaceAttribute(attribute, value)) {
921         return EGL_TRUE;
922     } else if (s->getSmpte2086Attribute(attribute, value)) {
923         return EGL_TRUE;
924     } else if (s->getCta8613Attribute(attribute, value)) {
925         return EGL_TRUE;
926     }
927     return s->cnx->egl.eglQuerySurface(dp->disp.dpy, s->surface, attribute, value);
928 }
929 
eglBeginFrameImpl(EGLDisplay dpy,EGLSurface surface)930 void EGLAPI eglBeginFrameImpl(EGLDisplay dpy, EGLSurface surface) {
931     const egl_display_ptr dp = validate_display(dpy);
932     if (!dp) {
933         return;
934     }
935 
936     SurfaceRef _s(dp.get(), surface);
937     if (!_s.get()) {
938         setError(EGL_BAD_SURFACE, EGL_FALSE);
939     }
940 }
941 
942 // ----------------------------------------------------------------------------
943 // Contexts
944 // ----------------------------------------------------------------------------
945 
eglCreateContextImpl(EGLDisplay dpy,EGLConfig config,EGLContext share_list,const EGLint * attrib_list)946 EGLContext eglCreateContextImpl(EGLDisplay dpy, EGLConfig config,
947                                 EGLContext share_list, const EGLint *attrib_list)
948 {
949     egl_connection_t* cnx = nullptr;
950     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
951     if (dp) {
952         if (share_list != EGL_NO_CONTEXT) {
953             if (!ContextRef(dp.get(), share_list).get()) {
954                 return setError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
955             }
956             egl_context_t* const c = get_context(share_list);
957             share_list = c->context;
958         }
959         // b/111083885 - If we are presenting EGL 1.4 interface to apps
960         // error out on robust access attributes that are invalid
961         // in EGL 1.4 as the driver may be fine with them but dEQP expects
962         // tests to fail according to spec.
963         if (attrib_list && (cnx->driverVersion < EGL_MAKE_VERSION(1, 5, 0))) {
964             const EGLint* attrib_ptr = attrib_list;
965             while (*attrib_ptr != EGL_NONE) {
966                 GLint attr = *attrib_ptr++;
967                 GLint value = *attrib_ptr++;
968                 if (attr == EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR) {
969                     // We are GL ES context with EGL 1.4, this is an invalid
970                     // attribute
971                     return setError(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
972                 }
973             };
974         }
975         EGLContext context = cnx->egl.eglCreateContext(
976                 dp->disp.dpy, config, share_list, attrib_list);
977         if (context != EGL_NO_CONTEXT) {
978             // figure out if it's a GLESv1 or GLESv2
979             int version = 0;
980             if (attrib_list) {
981                 while (*attrib_list != EGL_NONE) {
982                     GLint attr = *attrib_list++;
983                     GLint value = *attrib_list++;
984                     if (attr == EGL_CONTEXT_CLIENT_VERSION) {
985                         if (value == 1) {
986                             version = egl_connection_t::GLESv1_INDEX;
987                         } else if (value == 2 || value == 3) {
988                             version = egl_connection_t::GLESv2_INDEX;
989                         }
990                     }
991                 };
992             }
993             egl_context_t* c = new egl_context_t(dpy, context, config, cnx,
994                     version);
995             return c;
996         }
997     }
998     return EGL_NO_CONTEXT;
999 }
1000 
eglDestroyContextImpl(EGLDisplay dpy,EGLContext ctx)1001 EGLBoolean eglDestroyContextImpl(EGLDisplay dpy, EGLContext ctx)
1002 {
1003     const egl_display_ptr dp = validate_display(dpy);
1004     if (!dp)
1005         return EGL_FALSE;
1006 
1007     ContextRef _c(dp.get(), ctx);
1008     if (!_c.get())
1009         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1010 
1011     egl_context_t * const c = get_context(ctx);
1012     EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
1013     if (result == EGL_TRUE) {
1014         _c.terminate();
1015     }
1016     return result;
1017 }
1018 
eglMakeCurrentImpl(EGLDisplay dpy,EGLSurface draw,EGLSurface read,EGLContext ctx)1019 EGLBoolean eglMakeCurrentImpl(  EGLDisplay dpy, EGLSurface draw,
1020                                 EGLSurface read, EGLContext ctx)
1021 {
1022     egl_display_ptr dp = validate_display(dpy);
1023     if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1024 
1025     // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
1026     // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
1027     // a valid but uninitialized display.
1028     if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
1029          (draw != EGL_NO_SURFACE) ) {
1030         if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
1031     }
1032 
1033     // get a reference to the object passed in
1034     ContextRef _c(dp.get(), ctx);
1035     SurfaceRef _d(dp.get(), draw);
1036     SurfaceRef _r(dp.get(), read);
1037 
1038     // validate the context (if not EGL_NO_CONTEXT)
1039     if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
1040         // EGL_NO_CONTEXT is valid
1041         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1042     }
1043 
1044     // these are the underlying implementation's object
1045     EGLContext impl_ctx  = EGL_NO_CONTEXT;
1046     EGLSurface impl_draw = EGL_NO_SURFACE;
1047     EGLSurface impl_read = EGL_NO_SURFACE;
1048 
1049     // these are our objects structs passed in
1050     egl_context_t       * c = nullptr;
1051     egl_surface_t const * d = nullptr;
1052     egl_surface_t const * r = nullptr;
1053 
1054     // these are the current objects structs
1055     egl_context_t * cur_c = get_context(getContext());
1056 
1057     if (ctx != EGL_NO_CONTEXT) {
1058         c = get_context(ctx);
1059         impl_ctx = c->context;
1060     } else {
1061         // no context given, use the implementation of the current context
1062         if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
1063             // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
1064             return setError(EGL_BAD_MATCH, (EGLBoolean)EGL_FALSE);
1065         }
1066         if (cur_c == nullptr) {
1067             // no current context
1068             // not an error, there is just no current context.
1069             return EGL_TRUE;
1070         }
1071     }
1072 
1073     // retrieve the underlying implementation's draw EGLSurface
1074     if (draw != EGL_NO_SURFACE) {
1075         if (!_d.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1076         d = get_surface(draw);
1077         impl_draw = d->surface;
1078     }
1079 
1080     // retrieve the underlying implementation's read EGLSurface
1081     if (read != EGL_NO_SURFACE) {
1082         if (!_r.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1083         r = get_surface(read);
1084         impl_read = r->surface;
1085     }
1086 
1087 
1088     EGLBoolean result = dp->makeCurrent(c, cur_c,
1089             draw, read, ctx,
1090             impl_draw, impl_read, impl_ctx);
1091 
1092     if (result == EGL_TRUE) {
1093         if (c) {
1094             setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
1095             egl_tls_t::setContext(ctx);
1096             _c.acquire();
1097             _r.acquire();
1098             _d.acquire();
1099         } else {
1100             setGLHooksThreadSpecific(&gHooksNoContext);
1101             egl_tls_t::setContext(EGL_NO_CONTEXT);
1102         }
1103     } else {
1104         // this will ALOGE the error
1105         egl_connection_t* const cnx = &gEGLImpl;
1106         result = setError(cnx->egl.eglGetError(), (EGLBoolean)EGL_FALSE);
1107     }
1108     return result;
1109 }
1110 
eglQueryContextImpl(EGLDisplay dpy,EGLContext ctx,EGLint attribute,EGLint * value)1111 EGLBoolean eglQueryContextImpl( EGLDisplay dpy, EGLContext ctx,
1112                                 EGLint attribute, EGLint *value)
1113 {
1114     const egl_display_ptr dp = validate_display(dpy);
1115     if (!dp) return EGL_FALSE;
1116 
1117     ContextRef _c(dp.get(), ctx);
1118     if (!_c.get()) return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1119 
1120     egl_context_t * const c = get_context(ctx);
1121     return c->cnx->egl.eglQueryContext(
1122             dp->disp.dpy, c->context, attribute, value);
1123 
1124 }
1125 
eglGetCurrentContextImpl(void)1126 EGLContext eglGetCurrentContextImpl(void)
1127 {
1128     // could be called before eglInitialize(), but we wouldn't have a context
1129     // then, and this function would correctly return EGL_NO_CONTEXT.
1130     EGLContext ctx = getContext();
1131     return ctx;
1132 }
1133 
eglGetCurrentSurfaceImpl(EGLint readdraw)1134 EGLSurface eglGetCurrentSurfaceImpl(EGLint readdraw)
1135 {
1136     // could be called before eglInitialize(), but we wouldn't have a context
1137     // then, and this function would correctly return EGL_NO_SURFACE.
1138 
1139     EGLContext ctx = getContext();
1140     if (ctx) {
1141         egl_context_t const * const c = get_context(ctx);
1142         if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
1143         switch (readdraw) {
1144             case EGL_READ: return c->read;
1145             case EGL_DRAW: return c->draw;
1146             default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
1147         }
1148     }
1149     return EGL_NO_SURFACE;
1150 }
1151 
eglGetCurrentDisplayImpl(void)1152 EGLDisplay eglGetCurrentDisplayImpl(void)
1153 {
1154     // could be called before eglInitialize(), but we wouldn't have a context
1155     // then, and this function would correctly return EGL_NO_DISPLAY.
1156 
1157     EGLContext ctx = getContext();
1158     if (ctx) {
1159         egl_context_t const * const c = get_context(ctx);
1160         if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
1161         return c->dpy;
1162     }
1163     return EGL_NO_DISPLAY;
1164 }
1165 
eglWaitGLImpl(void)1166 EGLBoolean eglWaitGLImpl(void)
1167 {
1168     egl_connection_t* const cnx = &gEGLImpl;
1169     if (!cnx->dso)
1170         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1171 
1172     return cnx->egl.eglWaitGL();
1173 }
1174 
eglWaitNativeImpl(EGLint engine)1175 EGLBoolean eglWaitNativeImpl(EGLint engine)
1176 {
1177     egl_connection_t* const cnx = &gEGLImpl;
1178     if (!cnx->dso)
1179         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1180 
1181     return cnx->egl.eglWaitNative(engine);
1182 }
1183 
eglGetErrorImpl(void)1184 EGLint eglGetErrorImpl(void)
1185 {
1186     EGLint err = EGL_SUCCESS;
1187     egl_connection_t* const cnx = &gEGLImpl;
1188     if (cnx->dso) {
1189         err = cnx->egl.eglGetError();
1190     }
1191     if (err == EGL_SUCCESS) {
1192         err = egl_tls_t::getError();
1193     }
1194     return err;
1195 }
1196 
findBuiltinWrapper(const char * procname)1197 static __eglMustCastToProperFunctionPointerType findBuiltinWrapper(
1198         const char* procname) {
1199     const egl_connection_t* cnx = &gEGLImpl;
1200     void* proc = nullptr;
1201 
1202     proc = dlsym(cnx->libEgl, procname);
1203     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1204 
1205     proc = dlsym(cnx->libGles2, procname);
1206     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1207 
1208     proc = dlsym(cnx->libGles1, procname);
1209     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1210 
1211     return nullptr;
1212 }
1213 
eglGetProcAddressImpl(const char * procname)1214 __eglMustCastToProperFunctionPointerType eglGetProcAddressImpl(const char *procname)
1215 {
1216     if (FILTER_EXTENSIONS(procname)) {
1217         return nullptr;
1218     }
1219 
1220     __eglMustCastToProperFunctionPointerType addr;
1221     addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap));
1222     if (addr) return addr;
1223 
1224     addr = findBuiltinWrapper(procname);
1225     if (addr) return addr;
1226 
1227     // this protects accesses to sGLExtensionMap, sGLExtensionSlot, and sGLExtensionSlotMap
1228     pthread_mutex_lock(&sExtensionMapMutex);
1229 
1230     /*
1231      * Since eglGetProcAddress() is not associated to anything, it needs
1232      * to return a function pointer that "works" regardless of what
1233      * the current context is.
1234      *
1235      * For this reason, we return a "forwarder", a small stub that takes
1236      * care of calling the function associated with the context
1237      * currently bound.
1238      *
1239      * We first look for extensions we've already resolved, if we're seeing
1240      * this extension for the first time, we go through all our
1241      * implementations and call eglGetProcAddress() and record the
1242      * result in the appropriate implementation hooks and return the
1243      * address of the forwarder corresponding to that hook set.
1244      *
1245      */
1246 
1247     const std::string name(procname);
1248     auto& extensionMap = sGLExtensionMap;
1249     auto& extensionSlotMap = sGLExtensionSlotMap;
1250     egl_connection_t* const cnx = &gEGLImpl;
1251     LayerLoader& layer_loader(LayerLoader::getInstance());
1252 
1253     // See if we've already looked up this extension
1254     auto pos = extensionMap.find(name);
1255     addr = (pos != extensionMap.end()) ? pos->second : nullptr;
1256 
1257     if (!addr) {
1258         // This is the first time we've looked this function up
1259         // Ensure we have room to track it
1260         const int slot = sGLExtensionSlot;
1261         if (slot < MAX_NUMBER_OF_GL_EXTENSIONS) {
1262 
1263             if (cnx->dso && cnx->egl.eglGetProcAddress) {
1264 
1265                 // Extensions are independent of the bound context
1266                 addr = cnx->egl.eglGetProcAddress(procname);
1267                 if (addr) {
1268 
1269                     // purposefully track the bottom of the stack in extensionMap
1270                     extensionMap[name] = addr;
1271 
1272                     // Apply layers
1273                     addr = layer_loader.ApplyLayers(procname, addr);
1274 
1275                     // Track the top most entry point return the extension forwarder
1276                     cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
1277                     cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] = addr;
1278                     addr = gExtensionForwarders[slot];
1279 
1280                     // Remember the slot for this extension
1281                     extensionSlotMap[name] = slot;
1282 
1283                     // Increment the global extension index
1284                     sGLExtensionSlot++;
1285                 }
1286             }
1287         } else {
1288             // The extension forwarder has a fixed number of slots
1289             ALOGE("no more slots for eglGetProcAddress(\"%s\")", procname);
1290         }
1291 
1292     } else {
1293         // We tracked an address, so we've seen this func before
1294         // Look up the slot for this extension
1295         auto slot_pos = extensionSlotMap.find(name);
1296         int ext_slot = (slot_pos != extensionSlotMap.end()) ? slot_pos->second : -1;
1297         if (ext_slot < 0) {
1298             // Something has gone wrong, this should not happen
1299             ALOGE("No extension slot found for %s", procname);
1300             return nullptr;
1301         }
1302 
1303         // We tracked the bottom of the stack, so re-apply layers since
1304         // more layers might have been enabled
1305         addr = layer_loader.ApplyLayers(procname, addr);
1306 
1307         // Track the top most entry point and return the extension forwarder
1308         cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[ext_slot] =
1309         cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[ext_slot] = addr;
1310         addr = gExtensionForwarders[ext_slot];
1311     }
1312 
1313     pthread_mutex_unlock(&sExtensionMapMutex);
1314     return addr;
1315 }
1316 
1317 class FrameCompletionThread {
1318 public:
1319 
queueSync(EGLSyncKHR sync)1320     static void queueSync(EGLSyncKHR sync) {
1321         static FrameCompletionThread thread;
1322 
1323         char name[64];
1324 
1325         std::lock_guard<std::mutex> lock(thread.mMutex);
1326         snprintf(name, sizeof(name), "kicked off frame %u", (unsigned int)thread.mFramesQueued);
1327         ATRACE_NAME(name);
1328 
1329         thread.mQueue.push_back(sync);
1330         thread.mCondition.notify_one();
1331         thread.mFramesQueued++;
1332         ATRACE_INT("GPU Frames Outstanding", int32_t(thread.mQueue.size()));
1333     }
1334 
1335 private:
1336 
FrameCompletionThread()1337     FrameCompletionThread() : mFramesQueued(0), mFramesCompleted(0) {
1338         std::thread thread(&FrameCompletionThread::loop, this);
1339         thread.detach();
1340     }
1341 
1342 #pragma clang diagnostic push
1343 #pragma clang diagnostic ignored "-Wmissing-noreturn"
loop()1344     void loop() {
1345         while (true) {
1346             threadLoop();
1347         }
1348     }
1349 #pragma clang diagnostic pop
1350 
threadLoop()1351     void threadLoop() {
1352         EGLSyncKHR sync;
1353         uint32_t frameNum;
1354         {
1355             std::unique_lock<std::mutex> lock(mMutex);
1356             while (mQueue.empty()) {
1357                 mCondition.wait(lock);
1358             }
1359             sync = mQueue[0];
1360             frameNum = mFramesCompleted;
1361         }
1362         EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1363         {
1364             char name[64];
1365             snprintf(name, sizeof(name), "waiting for frame %u", (unsigned int)frameNum);
1366             ATRACE_NAME(name);
1367 
1368             EGLint result = eglClientWaitSyncKHR(dpy, sync, 0, EGL_FOREVER_KHR);
1369             if (result == EGL_FALSE) {
1370                 ALOGE("FrameCompletion: error waiting for fence: %#x", eglGetError());
1371             } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
1372                 ALOGE("FrameCompletion: timeout waiting for fence");
1373             }
1374             eglDestroySyncKHR(dpy, sync);
1375         }
1376         {
1377             std::lock_guard<std::mutex> lock(mMutex);
1378             mQueue.pop_front();
1379             mFramesCompleted++;
1380             ATRACE_INT("GPU Frames Outstanding", int32_t(mQueue.size()));
1381         }
1382     }
1383 
1384     uint32_t mFramesQueued;
1385     uint32_t mFramesCompleted;
1386     std::deque<EGLSyncKHR> mQueue;
1387     std::condition_variable mCondition;
1388     std::mutex mMutex;
1389 };
1390 
eglSwapBuffersWithDamageKHRImpl(EGLDisplay dpy,EGLSurface draw,EGLint * rects,EGLint n_rects)1391 EGLBoolean eglSwapBuffersWithDamageKHRImpl(EGLDisplay dpy, EGLSurface draw,
1392         EGLint *rects, EGLint n_rects)
1393 {
1394     const egl_display_ptr dp = validate_display(dpy);
1395     if (!dp) return EGL_FALSE;
1396 
1397     SurfaceRef _s(dp.get(), draw);
1398     if (!_s.get())
1399         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1400 
1401     egl_surface_t* const s = get_surface(draw);
1402 
1403     if (CC_UNLIKELY(dp->traceGpuCompletion)) {
1404         EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr);
1405         if (sync != EGL_NO_SYNC_KHR) {
1406             FrameCompletionThread::queueSync(sync);
1407         }
1408     }
1409 
1410     if (CC_UNLIKELY(dp->finishOnSwap)) {
1411         uint32_t pixel;
1412         egl_context_t * const c = get_context( egl_tls_t::getContext() );
1413         if (c) {
1414             // glReadPixels() ensures that the frame is complete
1415             s->cnx->hooks[c->version]->gl.glReadPixels(0,0,1,1,
1416                     GL_RGBA,GL_UNSIGNED_BYTE,&pixel);
1417         }
1418     }
1419 
1420     if (s->cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
1421         if (!sendSurfaceMetadata(s)) {
1422             native_window_api_disconnect(s->getNativeWindow(), NATIVE_WINDOW_API_EGL);
1423             return setError(EGL_BAD_NATIVE_WINDOW, (EGLBoolean)EGL_FALSE);
1424         }
1425     }
1426 
1427     if (n_rects == 0) {
1428         return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1429     }
1430 
1431     std::vector<android_native_rect_t> androidRects((size_t)n_rects);
1432     for (int r = 0; r < n_rects; ++r) {
1433         int offset = r * 4;
1434         int x = rects[offset];
1435         int y = rects[offset + 1];
1436         int width = rects[offset + 2];
1437         int height = rects[offset + 3];
1438         android_native_rect_t androidRect;
1439         androidRect.left = x;
1440         androidRect.top = y + height;
1441         androidRect.right = x + width;
1442         androidRect.bottom = y;
1443         androidRects.push_back(androidRect);
1444     }
1445     if (s->cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
1446         native_window_set_surface_damage(s->getNativeWindow(), androidRects.data(),
1447                                          androidRects.size());
1448     }
1449 
1450     if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
1451         return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface,
1452                 rects, n_rects);
1453     } else {
1454         return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1455     }
1456 }
1457 
eglSwapBuffersImpl(EGLDisplay dpy,EGLSurface surface)1458 EGLBoolean eglSwapBuffersImpl(EGLDisplay dpy, EGLSurface surface)
1459 {
1460     return eglSwapBuffersWithDamageKHRImpl(dpy, surface, nullptr, 0);
1461 }
1462 
eglCopyBuffersImpl(EGLDisplay dpy,EGLSurface surface,NativePixmapType target)1463 EGLBoolean eglCopyBuffersImpl(  EGLDisplay dpy, EGLSurface surface,
1464                                 NativePixmapType target)
1465 {
1466     const egl_display_ptr dp = validate_display(dpy);
1467     if (!dp) return EGL_FALSE;
1468 
1469     SurfaceRef _s(dp.get(), surface);
1470     if (!_s.get())
1471         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1472 
1473     egl_surface_t const * const s = get_surface(surface);
1474     return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
1475 }
1476 
eglQueryStringImpl(EGLDisplay dpy,EGLint name)1477 const char* eglQueryStringImpl(EGLDisplay dpy, EGLint name)
1478 {
1479     if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
1480         // Return list of client extensions
1481         return gClientExtensionString;
1482     }
1483 
1484     const egl_display_ptr dp = validate_display(dpy);
1485     if (!dp) return (const char *) nullptr;
1486 
1487     switch (name) {
1488         case EGL_VENDOR:
1489             return dp->getVendorString();
1490         case EGL_VERSION:
1491             return dp->getVersionString();
1492         case EGL_EXTENSIONS:
1493             return dp->getExtensionString();
1494         case EGL_CLIENT_APIS:
1495             return dp->getClientApiString();
1496         default:
1497             break;
1498     }
1499     return setError(EGL_BAD_PARAMETER, (const char *)nullptr);
1500 }
1501 
eglQueryStringImplementationANDROIDImpl(EGLDisplay dpy,EGLint name)1502 EGLAPI const char* eglQueryStringImplementationANDROIDImpl(EGLDisplay dpy, EGLint name)
1503 {
1504     const egl_display_ptr dp = validate_display(dpy);
1505     if (!dp) return (const char *) nullptr;
1506 
1507     switch (name) {
1508         case EGL_VENDOR:
1509             return dp->disp.queryString.vendor;
1510         case EGL_VERSION:
1511             return dp->disp.queryString.version;
1512         case EGL_EXTENSIONS:
1513             return dp->disp.queryString.extensions;
1514         case EGL_CLIENT_APIS:
1515             return dp->disp.queryString.clientApi;
1516         default:
1517             break;
1518     }
1519     return setError(EGL_BAD_PARAMETER, (const char *)nullptr);
1520 }
1521 
1522 // ----------------------------------------------------------------------------
1523 // EGL 1.1
1524 // ----------------------------------------------------------------------------
1525 
eglSurfaceAttribImpl(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint value)1526 EGLBoolean eglSurfaceAttribImpl(
1527         EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
1528 {
1529     const egl_display_ptr dp = validate_display(dpy);
1530     if (!dp) return EGL_FALSE;
1531 
1532     SurfaceRef _s(dp.get(), surface);
1533     if (!_s.get())
1534         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1535 
1536     egl_surface_t * const s = get_surface(surface);
1537 
1538     if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) {
1539         if (!s->getNativeWindow()) {
1540             setError(EGL_BAD_SURFACE, EGL_FALSE);
1541         }
1542         int err = native_window_set_auto_refresh(s->getNativeWindow(), value != 0);
1543         return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1544     }
1545 
1546     if (attribute == EGL_TIMESTAMPS_ANDROID) {
1547         if (!s->getNativeWindow()) {
1548             return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1549         }
1550         int err = native_window_enable_frame_timestamps(s->getNativeWindow(), value != 0);
1551         return (err == 0) ? EGL_TRUE : setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1552     }
1553 
1554     if (s->setSmpte2086Attribute(attribute, value)) {
1555         return EGL_TRUE;
1556     } else if (s->setCta8613Attribute(attribute, value)) {
1557         return EGL_TRUE;
1558     } else if (s->cnx->egl.eglSurfaceAttrib) {
1559         return s->cnx->egl.eglSurfaceAttrib(
1560                 dp->disp.dpy, s->surface, attribute, value);
1561     }
1562     return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1563 }
1564 
eglBindTexImageImpl(EGLDisplay dpy,EGLSurface surface,EGLint buffer)1565 EGLBoolean eglBindTexImageImpl(
1566         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1567 {
1568     const egl_display_ptr dp = validate_display(dpy);
1569     if (!dp) return EGL_FALSE;
1570 
1571     SurfaceRef _s(dp.get(), surface);
1572     if (!_s.get())
1573         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1574 
1575     egl_surface_t const * const s = get_surface(surface);
1576     if (s->cnx->egl.eglBindTexImage) {
1577         return s->cnx->egl.eglBindTexImage(
1578                 dp->disp.dpy, s->surface, buffer);
1579     }
1580     return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1581 }
1582 
eglReleaseTexImageImpl(EGLDisplay dpy,EGLSurface surface,EGLint buffer)1583 EGLBoolean eglReleaseTexImageImpl(
1584         EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1585 {
1586     const egl_display_ptr dp = validate_display(dpy);
1587     if (!dp) return EGL_FALSE;
1588 
1589     SurfaceRef _s(dp.get(), surface);
1590     if (!_s.get())
1591         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1592 
1593     egl_surface_t const * const s = get_surface(surface);
1594     if (s->cnx->egl.eglReleaseTexImage) {
1595         return s->cnx->egl.eglReleaseTexImage(
1596                 dp->disp.dpy, s->surface, buffer);
1597     }
1598     return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1599 }
1600 
eglSwapIntervalImpl(EGLDisplay dpy,EGLint interval)1601 EGLBoolean eglSwapIntervalImpl(EGLDisplay dpy, EGLint interval)
1602 {
1603     const egl_display_ptr dp = validate_display(dpy);
1604     if (!dp) return EGL_FALSE;
1605 
1606     EGLBoolean res = EGL_TRUE;
1607     egl_connection_t* const cnx = &gEGLImpl;
1608     if (cnx->dso && cnx->egl.eglSwapInterval) {
1609         res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
1610     }
1611 
1612     return res;
1613 }
1614 
1615 
1616 // ----------------------------------------------------------------------------
1617 // EGL 1.2
1618 // ----------------------------------------------------------------------------
1619 
eglWaitClientImpl(void)1620 EGLBoolean eglWaitClientImpl(void)
1621 {
1622     egl_connection_t* const cnx = &gEGLImpl;
1623     if (!cnx->dso)
1624         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1625 
1626     EGLBoolean res;
1627     if (cnx->egl.eglWaitClient) {
1628         res = cnx->egl.eglWaitClient();
1629     } else {
1630         res = cnx->egl.eglWaitGL();
1631     }
1632     return res;
1633 }
1634 
eglBindAPIImpl(EGLenum api)1635 EGLBoolean eglBindAPIImpl(EGLenum api)
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 
eglQueryAPIImpl(void)1646 EGLenum eglQueryAPIImpl(void)
1647 {
1648     egl_connection_t* const cnx = &gEGLImpl;
1649     if (cnx->dso && cnx->egl.eglQueryAPI) {
1650         return cnx->egl.eglQueryAPI();
1651     }
1652 
1653     // or, it can only be OpenGL ES
1654     return EGL_OPENGL_ES_API;
1655 }
1656 
eglReleaseThreadImpl(void)1657 EGLBoolean eglReleaseThreadImpl(void)
1658 {
1659     egl_connection_t* const cnx = &gEGLImpl;
1660     if (cnx->dso && cnx->egl.eglReleaseThread) {
1661         cnx->egl.eglReleaseThread();
1662     }
1663 
1664     // If there is context bound to the thread, release it
1665     egl_display_t::loseCurrent(get_context(getContext()));
1666 
1667     egl_tls_t::clearTLS();
1668     return EGL_TRUE;
1669 }
1670 
eglCreatePbufferFromClientBufferImpl(EGLDisplay dpy,EGLenum buftype,EGLClientBuffer buffer,EGLConfig config,const EGLint * attrib_list)1671 EGLSurface eglCreatePbufferFromClientBufferImpl(
1672           EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
1673           EGLConfig config, const EGLint *attrib_list)
1674 {
1675     egl_connection_t* cnx = nullptr;
1676     const egl_display_ptr dp = validate_display_connection(dpy, cnx);
1677     if (!dp) return EGL_FALSE;
1678     if (cnx->egl.eglCreatePbufferFromClientBuffer) {
1679         return cnx->egl.eglCreatePbufferFromClientBuffer(
1680                 dp->disp.dpy, buftype, buffer, config, attrib_list);
1681     }
1682     return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
1683 }
1684 
1685 // ----------------------------------------------------------------------------
1686 // EGL_EGLEXT_VERSION 3
1687 // ----------------------------------------------------------------------------
1688 
eglLockSurfaceKHRImpl(EGLDisplay dpy,EGLSurface surface,const EGLint * attrib_list)1689 EGLBoolean eglLockSurfaceKHRImpl(EGLDisplay dpy, EGLSurface surface,
1690         const EGLint *attrib_list)
1691 {
1692     const egl_display_ptr dp = validate_display(dpy);
1693     if (!dp) return EGL_FALSE;
1694 
1695     SurfaceRef _s(dp.get(), surface);
1696     if (!_s.get())
1697         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1698 
1699     egl_surface_t const * const s = get_surface(surface);
1700     if (s->cnx->egl.eglLockSurfaceKHR) {
1701         return s->cnx->egl.eglLockSurfaceKHR(
1702                 dp->disp.dpy, s->surface, attrib_list);
1703     }
1704     return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1705 }
1706 
eglUnlockSurfaceKHRImpl(EGLDisplay dpy,EGLSurface surface)1707 EGLBoolean eglUnlockSurfaceKHRImpl(EGLDisplay dpy, EGLSurface surface)
1708 {
1709     const egl_display_ptr dp = validate_display(dpy);
1710     if (!dp) return EGL_FALSE;
1711 
1712     SurfaceRef _s(dp.get(), surface);
1713     if (!_s.get())
1714         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1715 
1716     egl_surface_t const * const s = get_surface(surface);
1717     if (s->cnx->egl.eglUnlockSurfaceKHR) {
1718         return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
1719     }
1720     return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1721 }
1722 
1723 // Note: EGLImageKHR and EGLImage are the same thing so no need
1724 // to templatize that.
1725 template <typename AttrType, typename FuncType>
eglCreateImageTmpl(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const AttrType * attrib_list,FuncType eglCreateImageFunc)1726 EGLImageKHR eglCreateImageTmpl(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1727                                EGLClientBuffer buffer, const AttrType* attrib_list,
1728                                FuncType eglCreateImageFunc) {
1729     const egl_display_ptr dp = validate_display(dpy);
1730     if (!dp) return EGL_NO_IMAGE_KHR;
1731 
1732     std::vector<AttrType> strippedAttribs;
1733     if (needsAndroidPEglMitigation()) {
1734         // Mitigation for Android P vendor partitions: eglImageCreateKHR should accept
1735         // EGL_GL_COLORSPACE_LINEAR_KHR, EGL_GL_COLORSPACE_SRGB_KHR and
1736         // EGL_GL_COLORSPACE_DEFAULT_EXT if EGL_EXT_image_gl_colorspace is supported,
1737         // but some drivers don't like the DEFAULT value and generate an error.
1738         for (const AttrType *attr = attrib_list; attr && attr[0] != EGL_NONE; attr += 2) {
1739             if (attr[0] == EGL_GL_COLORSPACE_KHR &&
1740                 dp->haveExtension("EGL_EXT_image_gl_colorspace")) {
1741                 if (attr[1] != EGL_GL_COLORSPACE_LINEAR_KHR &&
1742                     attr[1] != EGL_GL_COLORSPACE_SRGB_KHR) {
1743                     continue;
1744                 }
1745             }
1746             strippedAttribs.push_back(attr[0]);
1747             strippedAttribs.push_back(attr[1]);
1748         }
1749         strippedAttribs.push_back(EGL_NONE);
1750     }
1751 
1752     ContextRef _c(dp.get(), ctx);
1753     egl_context_t* const c = _c.get();
1754 
1755     EGLImageKHR result = EGL_NO_IMAGE_KHR;
1756     egl_connection_t* const cnx = &gEGLImpl;
1757     if (cnx->dso && eglCreateImageFunc) {
1758         result = eglCreateImageFunc(dp->disp.dpy, c ? c->context : EGL_NO_CONTEXT, target, buffer,
1759                                     needsAndroidPEglMitigation() ? strippedAttribs.data() : attrib_list);
1760     }
1761     return result;
1762 }
1763 
1764 typedef EGLImage(EGLAPIENTRYP PFNEGLCREATEIMAGE)(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1765                                                  EGLClientBuffer buffer,
1766                                                  const EGLAttrib* attrib_list);
1767 
eglCreateImageKHRImpl(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)1768 EGLImageKHR eglCreateImageKHRImpl(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1769                                   EGLClientBuffer buffer, const EGLint* attrib_list) {
1770     return eglCreateImageTmpl<EGLint, PFNEGLCREATEIMAGEKHRPROC>(dpy, ctx, target, buffer,
1771                                                                 attrib_list,
1772                                                                 gEGLImpl.egl.eglCreateImageKHR);
1773 }
1774 
eglCreateImageImpl(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLAttrib * attrib_list)1775 EGLImage eglCreateImageImpl(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer,
1776                             const EGLAttrib* attrib_list) {
1777     egl_connection_t* const cnx = &gEGLImpl;
1778     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1779         if (cnx->egl.eglCreateImage) {
1780             return eglCreateImageTmpl<EGLAttrib, PFNEGLCREATEIMAGE>(dpy, ctx, target, buffer,
1781                                                                     attrib_list,
1782                                                                     cnx->egl.eglCreateImage);
1783         }
1784         // driver doesn't support native function, return EGL_BAD_DISPLAY
1785         ALOGE("Driver indicates EGL 1.5 support, but does not have eglCreateImage");
1786         return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE);
1787     }
1788 
1789     std::vector<EGLint> convertedAttribs;
1790     convertAttribs(attrib_list, convertedAttribs);
1791     return eglCreateImageTmpl<EGLint, PFNEGLCREATEIMAGEKHRPROC>(dpy, ctx, target, buffer,
1792                                                                 convertedAttribs.data(),
1793                                                                 gEGLImpl.egl.eglCreateImageKHR);
1794 }
1795 
eglDestroyImageTmpl(EGLDisplay dpy,EGLImageKHR img,PFNEGLDESTROYIMAGEKHRPROC destroyImageFunc)1796 EGLBoolean eglDestroyImageTmpl(EGLDisplay dpy, EGLImageKHR img,
1797                                PFNEGLDESTROYIMAGEKHRPROC destroyImageFunc) {
1798     const egl_display_ptr dp = validate_display(dpy);
1799     if (!dp) return EGL_FALSE;
1800 
1801     EGLBoolean result = EGL_FALSE;
1802     egl_connection_t* const cnx = &gEGLImpl;
1803     if (cnx->dso && destroyImageFunc) {
1804         result = destroyImageFunc(dp->disp.dpy, img);
1805     }
1806     return result;
1807 }
1808 
eglDestroyImageKHRImpl(EGLDisplay dpy,EGLImageKHR img)1809 EGLBoolean eglDestroyImageKHRImpl(EGLDisplay dpy, EGLImageKHR img) {
1810     return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImageKHR);
1811 }
1812 
eglDestroyImageImpl(EGLDisplay dpy,EGLImageKHR img)1813 EGLBoolean eglDestroyImageImpl(EGLDisplay dpy, EGLImageKHR img) {
1814     egl_connection_t* const cnx = &gEGLImpl;
1815     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1816         if (cnx->egl.eglDestroyImage) {
1817             return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImage);
1818         }
1819         // driver doesn't support native function, return EGL_BAD_DISPLAY
1820         ALOGE("Driver indicates EGL 1.5 support, but does not have eglDestroyImage");
1821         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
1822     }
1823 
1824     return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImageKHR);
1825 }
1826 
1827 // ----------------------------------------------------------------------------
1828 // EGL_EGLEXT_VERSION 5
1829 // ----------------------------------------------------------------------------
1830 
1831 // NOTE: EGLSyncKHR and EGLSync are identical, no need to templatize
1832 template <typename AttrType, typename FuncType>
eglCreateSyncTmpl(EGLDisplay dpy,EGLenum type,const AttrType * attrib_list,FuncType eglCreateSyncFunc)1833 EGLSyncKHR eglCreateSyncTmpl(EGLDisplay dpy, EGLenum type, const AttrType* attrib_list,
1834                              FuncType eglCreateSyncFunc) {
1835     const egl_display_ptr dp = validate_display(dpy);
1836     if (!dp) return EGL_NO_SYNC_KHR;
1837 
1838     egl_connection_t* const cnx = &gEGLImpl;
1839     EGLSyncKHR result = EGL_NO_SYNC_KHR;
1840     if (cnx->dso && eglCreateSyncFunc) {
1841         result = eglCreateSyncFunc(dp->disp.dpy, type, attrib_list);
1842     }
1843     return result;
1844 }
1845 
1846 typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATESYNC)(EGLDisplay dpy, EGLenum type,
1847                                                   const EGLAttrib* attrib_list);
1848 
eglCreateSyncKHRImpl(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list)1849 EGLSyncKHR eglCreateSyncKHRImpl(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) {
1850     return eglCreateSyncTmpl<EGLint, PFNEGLCREATESYNCKHRPROC>(dpy, type, attrib_list,
1851                                                               gEGLImpl.egl.eglCreateSyncKHR);
1852 }
1853 
eglCreateSyncImpl(EGLDisplay dpy,EGLenum type,const EGLAttrib * attrib_list)1854 EGLSync eglCreateSyncImpl(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list) {
1855     egl_connection_t* const cnx = &gEGLImpl;
1856     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1857         if (cnx->egl.eglCreateSync) {
1858             return eglCreateSyncTmpl<EGLAttrib, PFNEGLCREATESYNC>(dpy, type, attrib_list,
1859                                                                   cnx->egl.eglCreateSync);
1860         }
1861         // driver doesn't support native function, return EGL_BAD_DISPLAY
1862         ALOGE("Driver indicates EGL 1.5 support, but does not have eglCreateSync");
1863         return setError(EGL_BAD_DISPLAY, EGL_NO_SYNC);
1864     }
1865 
1866     std::vector<EGLint> convertedAttribs;
1867     convertAttribs(attrib_list, convertedAttribs);
1868     return eglCreateSyncTmpl<EGLint, PFNEGLCREATESYNCKHRPROC>(dpy, type, convertedAttribs.data(),
1869                                                               cnx->egl.eglCreateSyncKHR);
1870 }
1871 
eglDestroySyncTmpl(EGLDisplay dpy,EGLSyncKHR sync,PFNEGLDESTROYSYNCKHRPROC eglDestroySyncFunc)1872 EGLBoolean eglDestroySyncTmpl(EGLDisplay dpy, EGLSyncKHR sync,
1873                               PFNEGLDESTROYSYNCKHRPROC eglDestroySyncFunc) {
1874     const egl_display_ptr dp = validate_display(dpy);
1875     if (!dp) return EGL_FALSE;
1876 
1877     EGLBoolean result = EGL_FALSE;
1878     egl_connection_t* const cnx = &gEGLImpl;
1879     if (cnx->dso && eglDestroySyncFunc) {
1880         result = eglDestroySyncFunc(dp->disp.dpy, sync);
1881     }
1882     return result;
1883 }
1884 
eglDestroySyncKHRImpl(EGLDisplay dpy,EGLSyncKHR sync)1885 EGLBoolean eglDestroySyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync) {
1886     return eglDestroySyncTmpl(dpy, sync, gEGLImpl.egl.eglDestroySyncKHR);
1887 }
1888 
eglDestroySyncImpl(EGLDisplay dpy,EGLSyncKHR sync)1889 EGLBoolean eglDestroySyncImpl(EGLDisplay dpy, EGLSyncKHR sync) {
1890     egl_connection_t* const cnx = &gEGLImpl;
1891     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1892         if (cnx->egl.eglDestroySync) {
1893             return eglDestroySyncTmpl(dpy, sync, cnx->egl.eglDestroySync);
1894         }
1895         ALOGE("Driver indicates EGL 1.5 support, but does not have eglDestroySync");
1896         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
1897     }
1898 
1899     return eglDestroySyncTmpl(dpy, sync, cnx->egl.eglDestroySyncKHR);
1900 }
1901 
eglSignalSyncKHRImpl(EGLDisplay dpy,EGLSyncKHR sync,EGLenum mode)1902 EGLBoolean eglSignalSyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
1903     const egl_display_ptr dp = validate_display(dpy);
1904     if (!dp) return EGL_FALSE;
1905 
1906     EGLBoolean result = EGL_FALSE;
1907     egl_connection_t* const cnx = &gEGLImpl;
1908     if (cnx->dso && gEGLImpl.egl.eglSignalSyncKHR) {
1909         result = gEGLImpl.egl.eglSignalSyncKHR(dp->disp.dpy, sync, mode);
1910     }
1911     return result;
1912 }
1913 
eglClientWaitSyncTmpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags,EGLTimeKHR timeout,PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncFunc)1914 EGLint eglClientWaitSyncTmpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout,
1915                              PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncFunc) {
1916     const egl_display_ptr dp = validate_display(dpy);
1917     if (!dp) return EGL_FALSE;
1918 
1919     EGLint result = EGL_FALSE;
1920     egl_connection_t* const cnx = &gEGLImpl;
1921     if (cnx->dso && eglClientWaitSyncFunc) {
1922         result = eglClientWaitSyncFunc(dp->disp.dpy, sync, flags, timeout);
1923     }
1924     return result;
1925 }
1926 
eglClientWaitSyncKHRImpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags,EGLTimeKHR timeout)1927 EGLint eglClientWaitSyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
1928     egl_connection_t* const cnx = &gEGLImpl;
1929     return eglClientWaitSyncTmpl(dpy, sync, flags, timeout, cnx->egl.eglClientWaitSyncKHR);
1930 }
1931 
eglClientWaitSyncImpl(EGLDisplay dpy,EGLSync sync,EGLint flags,EGLTimeKHR timeout)1932 EGLint eglClientWaitSyncImpl(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTimeKHR timeout) {
1933     egl_connection_t* const cnx = &gEGLImpl;
1934     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1935         if (cnx->egl.eglClientWaitSync) {
1936             return eglClientWaitSyncTmpl(dpy, sync, flags, timeout, cnx->egl.eglClientWaitSync);
1937         }
1938         ALOGE("Driver indicates EGL 1.5 support, but does not have eglClientWaitSync");
1939         return setError(EGL_BAD_DISPLAY, (EGLint)EGL_FALSE);
1940     }
1941 
1942     return eglClientWaitSyncTmpl(dpy, sync, flags, timeout, cnx->egl.eglClientWaitSyncKHR);
1943 }
1944 
1945 template <typename AttrType, typename FuncType>
eglGetSyncAttribTmpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint attribute,AttrType * value,FuncType eglGetSyncAttribFunc)1946 EGLBoolean eglGetSyncAttribTmpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, AttrType* value,
1947                                 FuncType eglGetSyncAttribFunc) {
1948     const egl_display_ptr dp = validate_display(dpy);
1949     if (!dp) return EGL_FALSE;
1950 
1951     EGLBoolean result = EGL_FALSE;
1952     egl_connection_t* const cnx = &gEGLImpl;
1953     if (cnx->dso && eglGetSyncAttribFunc) {
1954         result = eglGetSyncAttribFunc(dp->disp.dpy, sync, attribute, value);
1955     }
1956     return result;
1957 }
1958 
1959 typedef EGLBoolean(EGLAPIENTRYP PFNEGLGETSYNCATTRIB)(EGLDisplay dpy, EGLSync sync, EGLint attribute,
1960                                                      EGLAttrib* value);
1961 
eglGetSyncAttribImpl(EGLDisplay dpy,EGLSync sync,EGLint attribute,EGLAttrib * value)1962 EGLBoolean eglGetSyncAttribImpl(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value) {
1963     egl_connection_t* const cnx = &gEGLImpl;
1964     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1965         if (cnx->egl.eglGetSyncAttrib) {
1966             return eglGetSyncAttribTmpl<EGLAttrib, PFNEGLGETSYNCATTRIB>(dpy, sync, attribute, value,
1967                                                                         cnx->egl.eglGetSyncAttrib);
1968         }
1969         ALOGE("Driver indicates EGL 1.5 support, but does not have eglGetSyncAttrib");
1970         return setError(EGL_BAD_DISPLAY, (EGLint)EGL_FALSE);
1971     }
1972 
1973     // Fallback to KHR, ask for EGLint attribute and cast back to EGLAttrib
1974     EGLint attribValue;
1975     EGLBoolean ret =
1976             eglGetSyncAttribTmpl<EGLint, PFNEGLGETSYNCATTRIBKHRPROC>(dpy, sync, attribute,
1977                                                                      &attribValue,
1978                                                                      gEGLImpl.egl
1979                                                                              .eglGetSyncAttribKHR);
1980     if (ret) {
1981         *value = static_cast<EGLAttrib>(attribValue);
1982     }
1983     return ret;
1984 }
1985 
eglGetSyncAttribKHRImpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint attribute,EGLint * value)1986 EGLBoolean eglGetSyncAttribKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute,
1987                                    EGLint* value) {
1988     return eglGetSyncAttribTmpl<EGLint, PFNEGLGETSYNCATTRIBKHRPROC>(dpy, sync, attribute, value,
1989                                                                     gEGLImpl.egl
1990                                                                             .eglGetSyncAttribKHR);
1991 }
1992 
eglCreateStreamKHRImpl(EGLDisplay dpy,const EGLint * attrib_list)1993 EGLStreamKHR eglCreateStreamKHRImpl(EGLDisplay dpy, const EGLint *attrib_list)
1994 {
1995     const egl_display_ptr dp = validate_display(dpy);
1996     if (!dp) return EGL_NO_STREAM_KHR;
1997 
1998     EGLStreamKHR result = EGL_NO_STREAM_KHR;
1999     egl_connection_t* const cnx = &gEGLImpl;
2000     if (cnx->dso && cnx->egl.eglCreateStreamKHR) {
2001         result = cnx->egl.eglCreateStreamKHR(
2002                 dp->disp.dpy, attrib_list);
2003     }
2004     return result;
2005 }
2006 
eglDestroyStreamKHRImpl(EGLDisplay dpy,EGLStreamKHR stream)2007 EGLBoolean eglDestroyStreamKHRImpl(EGLDisplay dpy, EGLStreamKHR stream)
2008 {
2009     const egl_display_ptr dp = validate_display(dpy);
2010     if (!dp) return EGL_FALSE;
2011 
2012     EGLBoolean result = EGL_FALSE;
2013     egl_connection_t* const cnx = &gEGLImpl;
2014     if (cnx->dso && cnx->egl.eglDestroyStreamKHR) {
2015         result = cnx->egl.eglDestroyStreamKHR(
2016                 dp->disp.dpy, stream);
2017     }
2018     return result;
2019 }
2020 
eglStreamAttribKHRImpl(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint value)2021 EGLBoolean eglStreamAttribKHRImpl(EGLDisplay dpy, EGLStreamKHR stream,
2022         EGLenum attribute, EGLint value)
2023 {
2024     const egl_display_ptr dp = validate_display(dpy);
2025     if (!dp) return EGL_FALSE;
2026 
2027     EGLBoolean result = EGL_FALSE;
2028     egl_connection_t* const cnx = &gEGLImpl;
2029     if (cnx->dso && cnx->egl.eglStreamAttribKHR) {
2030         result = cnx->egl.eglStreamAttribKHR(
2031                 dp->disp.dpy, stream, attribute, value);
2032     }
2033     return result;
2034 }
2035 
eglQueryStreamKHRImpl(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint * value)2036 EGLBoolean eglQueryStreamKHRImpl(EGLDisplay dpy, EGLStreamKHR stream,
2037         EGLenum attribute, EGLint *value)
2038 {
2039     const egl_display_ptr dp = validate_display(dpy);
2040     if (!dp) return EGL_FALSE;
2041 
2042     EGLBoolean result = EGL_FALSE;
2043     egl_connection_t* const cnx = &gEGLImpl;
2044     if (cnx->dso && cnx->egl.eglQueryStreamKHR) {
2045         result = cnx->egl.eglQueryStreamKHR(
2046                 dp->disp.dpy, stream, attribute, value);
2047     }
2048     return result;
2049 }
2050 
eglQueryStreamu64KHRImpl(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLuint64KHR * value)2051 EGLBoolean eglQueryStreamu64KHRImpl(EGLDisplay dpy, EGLStreamKHR stream,
2052         EGLenum attribute, EGLuint64KHR *value)
2053 {
2054     const egl_display_ptr dp = validate_display(dpy);
2055     if (!dp) return EGL_FALSE;
2056 
2057     EGLBoolean result = EGL_FALSE;
2058     egl_connection_t* const cnx = &gEGLImpl;
2059     if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) {
2060         result = cnx->egl.eglQueryStreamu64KHR(
2061                 dp->disp.dpy, stream, attribute, value);
2062     }
2063     return result;
2064 }
2065 
eglQueryStreamTimeKHRImpl(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLTimeKHR * value)2066 EGLBoolean eglQueryStreamTimeKHRImpl(EGLDisplay dpy, EGLStreamKHR stream,
2067         EGLenum attribute, EGLTimeKHR *value)
2068 {
2069     const egl_display_ptr dp = validate_display(dpy);
2070     if (!dp) return EGL_FALSE;
2071 
2072     EGLBoolean result = EGL_FALSE;
2073     egl_connection_t* const cnx = &gEGLImpl;
2074     if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) {
2075         result = cnx->egl.eglQueryStreamTimeKHR(
2076                 dp->disp.dpy, stream, attribute, value);
2077     }
2078     return result;
2079 }
2080 
eglCreateStreamProducerSurfaceKHRImpl(EGLDisplay dpy,EGLConfig config,EGLStreamKHR stream,const EGLint * attrib_list)2081 EGLSurface eglCreateStreamProducerSurfaceKHRImpl(EGLDisplay dpy, EGLConfig config,
2082         EGLStreamKHR stream, const EGLint *attrib_list)
2083 {
2084     egl_display_ptr dp = validate_display(dpy);
2085     if (!dp) return EGL_NO_SURFACE;
2086 
2087     egl_connection_t* const cnx = &gEGLImpl;
2088     if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
2089         EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
2090                 dp->disp.dpy, config, stream, attrib_list);
2091         if (surface != EGL_NO_SURFACE) {
2092             egl_surface_t* s = new egl_surface_t(dp.get(), config, nullptr, surface,
2093                                                  EGL_GL_COLORSPACE_LINEAR_KHR, cnx);
2094             return s;
2095         }
2096     }
2097     return EGL_NO_SURFACE;
2098 }
2099 
eglStreamConsumerGLTextureExternalKHRImpl(EGLDisplay dpy,EGLStreamKHR stream)2100 EGLBoolean eglStreamConsumerGLTextureExternalKHRImpl(EGLDisplay dpy,
2101         EGLStreamKHR stream)
2102 {
2103     const egl_display_ptr dp = validate_display(dpy);
2104     if (!dp) return EGL_FALSE;
2105 
2106     EGLBoolean result = EGL_FALSE;
2107     egl_connection_t* const cnx = &gEGLImpl;
2108     if (cnx->dso && cnx->egl.eglStreamConsumerGLTextureExternalKHR) {
2109         result = cnx->egl.eglStreamConsumerGLTextureExternalKHR(
2110                 dp->disp.dpy, stream);
2111     }
2112     return result;
2113 }
2114 
eglStreamConsumerAcquireKHRImpl(EGLDisplay dpy,EGLStreamKHR stream)2115 EGLBoolean eglStreamConsumerAcquireKHRImpl(EGLDisplay dpy,
2116         EGLStreamKHR stream)
2117 {
2118     const egl_display_ptr dp = validate_display(dpy);
2119     if (!dp) return EGL_FALSE;
2120 
2121     EGLBoolean result = EGL_FALSE;
2122     egl_connection_t* const cnx = &gEGLImpl;
2123     if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) {
2124         result = cnx->egl.eglStreamConsumerAcquireKHR(
2125                 dp->disp.dpy, stream);
2126     }
2127     return result;
2128 }
2129 
eglStreamConsumerReleaseKHRImpl(EGLDisplay dpy,EGLStreamKHR stream)2130 EGLBoolean eglStreamConsumerReleaseKHRImpl(EGLDisplay dpy,
2131         EGLStreamKHR stream)
2132 {
2133     const egl_display_ptr dp = validate_display(dpy);
2134     if (!dp) return EGL_FALSE;
2135 
2136     EGLBoolean result = EGL_FALSE;
2137     egl_connection_t* const cnx = &gEGLImpl;
2138     if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) {
2139         result = cnx->egl.eglStreamConsumerReleaseKHR(
2140                 dp->disp.dpy, stream);
2141     }
2142     return result;
2143 }
2144 
eglGetStreamFileDescriptorKHRImpl(EGLDisplay dpy,EGLStreamKHR stream)2145 EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHRImpl(
2146         EGLDisplay dpy, EGLStreamKHR stream)
2147 {
2148     const egl_display_ptr dp = validate_display(dpy);
2149     if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR;
2150 
2151     EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR;
2152     egl_connection_t* const cnx = &gEGLImpl;
2153     if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) {
2154         result = cnx->egl.eglGetStreamFileDescriptorKHR(
2155                 dp->disp.dpy, stream);
2156     }
2157     return result;
2158 }
2159 
eglCreateStreamFromFileDescriptorKHRImpl(EGLDisplay dpy,EGLNativeFileDescriptorKHR file_descriptor)2160 EGLStreamKHR eglCreateStreamFromFileDescriptorKHRImpl(
2161         EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor)
2162 {
2163     const egl_display_ptr dp = validate_display(dpy);
2164     if (!dp) return EGL_NO_STREAM_KHR;
2165 
2166     EGLStreamKHR result = EGL_NO_STREAM_KHR;
2167     egl_connection_t* const cnx = &gEGLImpl;
2168     if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) {
2169         result = cnx->egl.eglCreateStreamFromFileDescriptorKHR(
2170                 dp->disp.dpy, file_descriptor);
2171     }
2172     return result;
2173 }
2174 
2175 // ----------------------------------------------------------------------------
2176 // EGL_EGLEXT_VERSION 15
2177 // ----------------------------------------------------------------------------
2178 
2179 // Need to template function type because return type is different
2180 template <typename ReturnType, typename FuncType>
eglWaitSyncTmpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags,FuncType eglWaitSyncFunc)2181 ReturnType eglWaitSyncTmpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags,
2182                            FuncType eglWaitSyncFunc) {
2183     const egl_display_ptr dp = validate_display(dpy);
2184     if (!dp) return EGL_FALSE;
2185     ReturnType result = EGL_FALSE;
2186     egl_connection_t* const cnx = &gEGLImpl;
2187     if (cnx->dso && eglWaitSyncFunc) {
2188         result = eglWaitSyncFunc(dp->disp.dpy, sync, flags);
2189     }
2190     return result;
2191 }
2192 
2193 typedef EGLBoolean(EGLAPIENTRYP PFNEGLWAITSYNC)(EGLDisplay dpy, EGLSync sync, EGLint flags);
2194 
eglWaitSyncKHRImpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags)2195 EGLint eglWaitSyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
2196     egl_connection_t* const cnx = &gEGLImpl;
2197     return eglWaitSyncTmpl<EGLint, PFNEGLWAITSYNCKHRPROC>(dpy, sync, flags,
2198                                                           cnx->egl.eglWaitSyncKHR);
2199 }
2200 
eglWaitSyncImpl(EGLDisplay dpy,EGLSync sync,EGLint flags)2201 EGLBoolean eglWaitSyncImpl(EGLDisplay dpy, EGLSync sync, EGLint flags) {
2202     egl_connection_t* const cnx = &gEGLImpl;
2203     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
2204         if (cnx->egl.eglWaitSync) {
2205             return eglWaitSyncTmpl<EGLBoolean, PFNEGLWAITSYNC>(dpy, sync, flags,
2206                                                                cnx->egl.eglWaitSync);
2207         }
2208         return setError(EGL_BAD_DISPLAY, (EGLint)EGL_FALSE);
2209     }
2210 
2211     return static_cast<EGLBoolean>(
2212             eglWaitSyncTmpl<EGLint, PFNEGLWAITSYNCKHRPROC>(dpy, sync, flags,
2213                                                            cnx->egl.eglWaitSyncKHR));
2214 }
2215 
2216 // ----------------------------------------------------------------------------
2217 // ANDROID extensions
2218 // ----------------------------------------------------------------------------
2219 
eglDupNativeFenceFDANDROIDImpl(EGLDisplay dpy,EGLSyncKHR sync)2220 EGLint eglDupNativeFenceFDANDROIDImpl(EGLDisplay dpy, EGLSyncKHR sync)
2221 {
2222     const egl_display_ptr dp = validate_display(dpy);
2223     if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID;
2224 
2225     EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
2226     egl_connection_t* const cnx = &gEGLImpl;
2227     if (cnx->dso && cnx->egl.eglDupNativeFenceFDANDROID) {
2228         result = cnx->egl.eglDupNativeFenceFDANDROID(dp->disp.dpy, sync);
2229     }
2230     return result;
2231 }
2232 
eglPresentationTimeANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLnsecsANDROID time)2233 EGLBoolean eglPresentationTimeANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
2234         EGLnsecsANDROID time)
2235 {
2236     const egl_display_ptr dp = validate_display(dpy);
2237     if (!dp) {
2238         return EGL_FALSE;
2239     }
2240 
2241     SurfaceRef _s(dp.get(), surface);
2242     if (!_s.get()) {
2243         setError(EGL_BAD_SURFACE, EGL_FALSE);
2244         return EGL_FALSE;
2245     }
2246 
2247     egl_surface_t const * const s = get_surface(surface);
2248     native_window_set_buffers_timestamp(s->getNativeWindow(), time);
2249 
2250     return EGL_TRUE;
2251 }
2252 
eglGetNativeClientBufferANDROIDImpl(const AHardwareBuffer * buffer)2253 EGLClientBuffer eglGetNativeClientBufferANDROIDImpl(const AHardwareBuffer *buffer) {
2254     // AHardwareBuffer_to_ANativeWindowBuffer is a platform-only symbol and thus
2255     // this function cannot be implemented when this libEGL is built for
2256     // vendors.
2257 #ifndef __ANDROID_VNDK__
2258     if (!buffer) return setError(EGL_BAD_PARAMETER, (EGLClientBuffer) nullptr);
2259     return const_cast<ANativeWindowBuffer *>(AHardwareBuffer_to_ANativeWindowBuffer(buffer));
2260 #else
2261     return setError(EGL_BAD_PARAMETER, (EGLClientBuffer) nullptr);
2262 #endif
2263 }
2264 
2265 // ----------------------------------------------------------------------------
2266 // NVIDIA extensions
2267 // ----------------------------------------------------------------------------
eglGetSystemTimeFrequencyNVImpl()2268 EGLuint64NV eglGetSystemTimeFrequencyNVImpl()
2269 {
2270     EGLuint64NV ret = 0;
2271     egl_connection_t* const cnx = &gEGLImpl;
2272 
2273     if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
2274         return cnx->egl.eglGetSystemTimeFrequencyNV();
2275     }
2276 
2277     return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
2278 }
2279 
eglGetSystemTimeNVImpl()2280 EGLuint64NV eglGetSystemTimeNVImpl()
2281 {
2282     EGLuint64NV ret = 0;
2283     egl_connection_t* const cnx = &gEGLImpl;
2284 
2285     if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
2286         return cnx->egl.eglGetSystemTimeNV();
2287     }
2288 
2289     return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
2290 }
2291 
2292 // ----------------------------------------------------------------------------
2293 // Partial update extension
2294 // ----------------------------------------------------------------------------
eglSetDamageRegionKHRImpl(EGLDisplay dpy,EGLSurface surface,EGLint * rects,EGLint n_rects)2295 EGLBoolean eglSetDamageRegionKHRImpl(EGLDisplay dpy, EGLSurface surface,
2296         EGLint *rects, EGLint n_rects)
2297 {
2298     const egl_display_ptr dp = validate_display(dpy);
2299     if (!dp) {
2300         setError(EGL_BAD_DISPLAY, EGL_FALSE);
2301         return EGL_FALSE;
2302     }
2303 
2304     SurfaceRef _s(dp.get(), surface);
2305     if (!_s.get()) {
2306         setError(EGL_BAD_SURFACE, EGL_FALSE);
2307         return EGL_FALSE;
2308     }
2309 
2310     egl_surface_t const * const s = get_surface(surface);
2311     if (s->cnx->egl.eglSetDamageRegionKHR) {
2312         return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface,
2313                 rects, n_rects);
2314     }
2315 
2316     return EGL_FALSE;
2317 }
2318 
eglGetNextFrameIdANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLuint64KHR * frameId)2319 EGLBoolean eglGetNextFrameIdANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
2320             EGLuint64KHR *frameId) {
2321     const egl_display_ptr dp = validate_display(dpy);
2322     if (!dp) {
2323         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2324     }
2325 
2326     SurfaceRef _s(dp.get(), surface);
2327     if (!_s.get()) {
2328         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2329     }
2330 
2331     egl_surface_t const * const s = get_surface(surface);
2332 
2333     if (!s->getNativeWindow()) {
2334         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2335     }
2336 
2337     uint64_t nextFrameId = 0;
2338     int ret = native_window_get_next_frame_id(s->getNativeWindow(), &nextFrameId);
2339 
2340     if (ret != 0) {
2341         // This should not happen. Return an error that is not in the spec
2342         // so it's obvious something is very wrong.
2343         ALOGE("eglGetNextFrameId: Unexpected error.");
2344         return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2345     }
2346 
2347     *frameId = nextFrameId;
2348     return EGL_TRUE;
2349 }
2350 
eglGetCompositorTimingANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values)2351 EGLBoolean eglGetCompositorTimingANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
2352         EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values)
2353 {
2354     const egl_display_ptr dp = validate_display(dpy);
2355     if (!dp) {
2356         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2357     }
2358 
2359     SurfaceRef _s(dp.get(), surface);
2360     if (!_s.get()) {
2361         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2362     }
2363 
2364     egl_surface_t const * const s = get_surface(surface);
2365 
2366     if (!s->getNativeWindow()) {
2367         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2368     }
2369 
2370     nsecs_t* compositeDeadline = nullptr;
2371     nsecs_t* compositeInterval = nullptr;
2372     nsecs_t* compositeToPresentLatency = nullptr;
2373 
2374     for (int i = 0; i < numTimestamps; i++) {
2375         switch (names[i]) {
2376             case EGL_COMPOSITE_DEADLINE_ANDROID:
2377                 compositeDeadline = &values[i];
2378                 break;
2379             case EGL_COMPOSITE_INTERVAL_ANDROID:
2380                 compositeInterval = &values[i];
2381                 break;
2382             case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2383                 compositeToPresentLatency = &values[i];
2384                 break;
2385             default:
2386                 return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2387         }
2388     }
2389 
2390     int ret = native_window_get_compositor_timing(s->getNativeWindow(),
2391             compositeDeadline, compositeInterval, compositeToPresentLatency);
2392 
2393     switch (ret) {
2394       case 0:
2395         return EGL_TRUE;
2396       case -ENOSYS:
2397         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2398       default:
2399         // This should not happen. Return an error that is not in the spec
2400         // so it's obvious something is very wrong.
2401         ALOGE("eglGetCompositorTiming: Unexpected error.");
2402         return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2403     }
2404 }
2405 
eglGetCompositorTimingSupportedANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLint name)2406 EGLBoolean eglGetCompositorTimingSupportedANDROIDImpl(
2407         EGLDisplay dpy, EGLSurface surface, EGLint name)
2408 {
2409     const egl_display_ptr dp = validate_display(dpy);
2410     if (!dp) {
2411         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2412     }
2413 
2414     SurfaceRef _s(dp.get(), surface);
2415     if (!_s.get()) {
2416         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2417     }
2418 
2419     egl_surface_t const * const s = get_surface(surface);
2420 
2421     ANativeWindow* window = s->getNativeWindow();
2422     if (!window) {
2423         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2424     }
2425 
2426     switch (name) {
2427         case EGL_COMPOSITE_DEADLINE_ANDROID:
2428         case EGL_COMPOSITE_INTERVAL_ANDROID:
2429         case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2430             return EGL_TRUE;
2431         default:
2432             return EGL_FALSE;
2433     }
2434 }
2435 
eglGetFrameTimestampsANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values)2436 EGLBoolean eglGetFrameTimestampsANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
2437         EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps,
2438         EGLnsecsANDROID *values)
2439 {
2440     const egl_display_ptr dp = validate_display(dpy);
2441     if (!dp) {
2442         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2443     }
2444 
2445     SurfaceRef _s(dp.get(), surface);
2446     if (!_s.get()) {
2447         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2448     }
2449 
2450     egl_surface_t const * const s = get_surface(surface);
2451 
2452     if (!s->getNativeWindow()) {
2453         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2454     }
2455 
2456     nsecs_t* requestedPresentTime = nullptr;
2457     nsecs_t* acquireTime = nullptr;
2458     nsecs_t* latchTime = nullptr;
2459     nsecs_t* firstRefreshStartTime = nullptr;
2460     nsecs_t* gpuCompositionDoneTime = nullptr;
2461     nsecs_t* lastRefreshStartTime = nullptr;
2462     nsecs_t* displayPresentTime = nullptr;
2463     nsecs_t* dequeueReadyTime = nullptr;
2464     nsecs_t* releaseTime = nullptr;
2465 
2466     for (int i = 0; i < numTimestamps; i++) {
2467         switch (timestamps[i]) {
2468             case EGL_REQUESTED_PRESENT_TIME_ANDROID:
2469                 requestedPresentTime = &values[i];
2470                 break;
2471             case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2472                 acquireTime = &values[i];
2473                 break;
2474             case EGL_COMPOSITION_LATCH_TIME_ANDROID:
2475                 latchTime = &values[i];
2476                 break;
2477             case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
2478                 firstRefreshStartTime = &values[i];
2479                 break;
2480             case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
2481                 lastRefreshStartTime = &values[i];
2482                 break;
2483             case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
2484                 gpuCompositionDoneTime = &values[i];
2485                 break;
2486             case EGL_DISPLAY_PRESENT_TIME_ANDROID:
2487                 displayPresentTime = &values[i];
2488                 break;
2489             case EGL_DEQUEUE_READY_TIME_ANDROID:
2490                 dequeueReadyTime = &values[i];
2491                 break;
2492             case EGL_READS_DONE_TIME_ANDROID:
2493                 releaseTime = &values[i];
2494                 break;
2495             default:
2496                 return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2497         }
2498     }
2499 
2500     int ret = native_window_get_frame_timestamps(s->getNativeWindow(), frameId,
2501             requestedPresentTime, acquireTime, latchTime, firstRefreshStartTime,
2502             lastRefreshStartTime, gpuCompositionDoneTime, displayPresentTime,
2503             dequeueReadyTime, releaseTime);
2504 
2505     switch (ret) {
2506         case 0:
2507             return EGL_TRUE;
2508         case -ENOENT:
2509             return setError(EGL_BAD_ACCESS, (EGLBoolean)EGL_FALSE);
2510         case -ENOSYS:
2511             return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2512         case -EINVAL:
2513             return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2514         default:
2515             // This should not happen. Return an error that is not in the spec
2516             // so it's obvious something is very wrong.
2517             ALOGE("eglGetFrameTimestamps: Unexpected error.");
2518             return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2519     }
2520 }
2521 
eglGetFrameTimestampSupportedANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLint timestamp)2522 EGLBoolean eglGetFrameTimestampSupportedANDROIDImpl(
2523         EGLDisplay dpy, EGLSurface surface, EGLint timestamp)
2524 {
2525     const egl_display_ptr dp = validate_display(dpy);
2526     if (!dp) {
2527         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2528     }
2529 
2530     SurfaceRef _s(dp.get(), surface);
2531     if (!_s.get()) {
2532         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2533     }
2534 
2535     egl_surface_t const * const s = get_surface(surface);
2536 
2537     ANativeWindow* window = s->getNativeWindow();
2538     if (!window) {
2539         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2540     }
2541 
2542     switch (timestamp) {
2543         case EGL_COMPOSITE_DEADLINE_ANDROID:
2544         case EGL_COMPOSITE_INTERVAL_ANDROID:
2545         case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2546         case EGL_REQUESTED_PRESENT_TIME_ANDROID:
2547         case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2548         case EGL_COMPOSITION_LATCH_TIME_ANDROID:
2549         case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
2550         case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
2551         case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
2552         case EGL_DEQUEUE_READY_TIME_ANDROID:
2553         case EGL_READS_DONE_TIME_ANDROID:
2554             return EGL_TRUE;
2555         case EGL_DISPLAY_PRESENT_TIME_ANDROID: {
2556             int value = 0;
2557             window->query(window,
2558                     NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT, &value);
2559             return value == 0 ? EGL_FALSE : EGL_TRUE;
2560         }
2561         default:
2562             return EGL_FALSE;
2563     }
2564 }
2565 
glGetStringImpl(GLenum name)2566 const GLubyte * glGetStringImpl(GLenum name) {
2567     const GLubyte * ret = egl_get_string_for_current_context(name);
2568     if (ret == NULL) {
2569         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
2570         if(_c) ret = _c->glGetString(name);
2571     }
2572     return ret;
2573 }
2574 
glGetStringiImpl(GLenum name,GLuint index)2575 const GLubyte * glGetStringiImpl(GLenum name, GLuint index) {
2576     const GLubyte * ret = egl_get_string_for_current_context(name, index);
2577     if (ret == NULL) {
2578         gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
2579         if(_c) ret = _c->glGetStringi(name, index);
2580     }
2581     return ret;
2582 }
2583 
glGetBooleanvImpl(GLenum pname,GLboolean * data)2584 void glGetBooleanvImpl(GLenum pname, GLboolean * data) {
2585     if (pname == GL_NUM_EXTENSIONS) {
2586         int num_exts = egl_get_num_extensions_for_current_context();
2587         if (num_exts >= 0) {
2588             *data = num_exts > 0 ? GL_TRUE : GL_FALSE;
2589             return;
2590         }
2591     }
2592 
2593     gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
2594     if (_c) _c->glGetBooleanv(pname, data);
2595 }
2596 
glGetFloatvImpl(GLenum pname,GLfloat * data)2597 void glGetFloatvImpl(GLenum pname, GLfloat * data) {
2598     if (pname == GL_NUM_EXTENSIONS) {
2599         int num_exts = egl_get_num_extensions_for_current_context();
2600         if (num_exts >= 0) {
2601             *data = (GLfloat)num_exts;
2602             return;
2603         }
2604     }
2605 
2606     gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
2607     if (_c) _c->glGetFloatv(pname, data);
2608 }
2609 
glGetIntegervImpl(GLenum pname,GLint * data)2610 void glGetIntegervImpl(GLenum pname, GLint * data) {
2611     if (pname == GL_NUM_EXTENSIONS) {
2612         int num_exts = egl_get_num_extensions_for_current_context();
2613         if (num_exts >= 0) {
2614             *data = (GLint)num_exts;
2615             return;
2616         }
2617     }
2618 
2619     gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
2620     if (_c) _c->glGetIntegerv(pname, data);
2621 }
2622 
glGetInteger64vImpl(GLenum pname,GLint64 * data)2623 void glGetInteger64vImpl(GLenum pname, GLint64 * data) {
2624     if (pname == GL_NUM_EXTENSIONS) {
2625         int num_exts = egl_get_num_extensions_for_current_context();
2626         if (num_exts >= 0) {
2627             *data = (GLint64)num_exts;
2628             return;
2629         }
2630     }
2631 
2632     gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl;
2633     if (_c) _c->glGetInteger64v(pname, data);
2634 }
2635 
2636 struct implementation_map_t {
2637     const char* name;
2638     EGLFuncPointer address;
2639 };
2640 
2641 static const implementation_map_t sPlatformImplMap[] = {
2642         // clang-format off
2643     { "eglGetDisplay", (EGLFuncPointer)&eglGetDisplayImpl },
2644     { "eglGetPlatformDisplay", (EGLFuncPointer)&eglGetPlatformDisplayImpl },
2645     { "eglInitialize", (EGLFuncPointer)&eglInitializeImpl },
2646     { "eglTerminate", (EGLFuncPointer)&eglTerminateImpl },
2647     { "eglGetConfigs", (EGLFuncPointer)&eglGetConfigsImpl },
2648     { "eglChooseConfig", (EGLFuncPointer)&eglChooseConfigImpl },
2649     { "eglGetConfigAttrib", (EGLFuncPointer)&eglGetConfigAttribImpl },
2650     { "eglCreateWindowSurface", (EGLFuncPointer)&eglCreateWindowSurfaceImpl },
2651     { "eglCreatePixmapSurface", (EGLFuncPointer)&eglCreatePixmapSurfaceImpl },
2652     { "eglCreatePlatformWindowSurface", (EGLFuncPointer)&eglCreatePlatformWindowSurfaceImpl },
2653     { "eglCreatePlatformPixmapSurface", (EGLFuncPointer)&eglCreatePlatformPixmapSurfaceImpl },
2654     { "eglCreatePbufferSurface", (EGLFuncPointer)&eglCreatePbufferSurfaceImpl },
2655     { "eglDestroySurface", (EGLFuncPointer)&eglDestroySurfaceImpl },
2656     { "eglQuerySurface", (EGLFuncPointer)&eglQuerySurfaceImpl },
2657     { "eglBeginFrame", (EGLFuncPointer)&eglBeginFrameImpl },
2658     { "eglCreateContext", (EGLFuncPointer)&eglCreateContextImpl },
2659     { "eglDestroyContext", (EGLFuncPointer)&eglDestroyContextImpl },
2660     { "eglMakeCurrent", (EGLFuncPointer)&eglMakeCurrentImpl },
2661     { "eglQueryContext", (EGLFuncPointer)&eglQueryContextImpl },
2662     { "eglGetCurrentContext", (EGLFuncPointer)&eglGetCurrentContextImpl },
2663     { "eglGetCurrentSurface", (EGLFuncPointer)&eglGetCurrentSurfaceImpl },
2664     { "eglGetCurrentDisplay", (EGLFuncPointer)&eglGetCurrentDisplayImpl },
2665     { "eglWaitGL", (EGLFuncPointer)&eglWaitGLImpl },
2666     { "eglWaitNative", (EGLFuncPointer)&eglWaitNativeImpl },
2667     { "eglGetError", (EGLFuncPointer)&eglGetErrorImpl },
2668     { "eglSwapBuffersWithDamageKHR", (EGLFuncPointer)&eglSwapBuffersWithDamageKHRImpl },
2669     { "eglGetProcAddress", (EGLFuncPointer)&eglGetProcAddressImpl },
2670     { "eglSwapBuffers", (EGLFuncPointer)&eglSwapBuffersImpl },
2671     { "eglCopyBuffers", (EGLFuncPointer)&eglCopyBuffersImpl },
2672     { "eglQueryString", (EGLFuncPointer)&eglQueryStringImpl },
2673     { "eglQueryStringImplementationANDROID", (EGLFuncPointer)&eglQueryStringImplementationANDROIDImpl },
2674     { "eglSurfaceAttrib", (EGLFuncPointer)&eglSurfaceAttribImpl },
2675     { "eglBindTexImage", (EGLFuncPointer)&eglBindTexImageImpl },
2676     { "eglReleaseTexImage", (EGLFuncPointer)&eglReleaseTexImageImpl },
2677     { "eglSwapInterval", (EGLFuncPointer)&eglSwapIntervalImpl },
2678     { "eglWaitClient", (EGLFuncPointer)&eglWaitClientImpl },
2679     { "eglBindAPI", (EGLFuncPointer)&eglBindAPIImpl },
2680     { "eglQueryAPI", (EGLFuncPointer)&eglQueryAPIImpl },
2681     { "eglReleaseThread", (EGLFuncPointer)&eglReleaseThreadImpl },
2682     { "eglCreatePbufferFromClientBuffer", (EGLFuncPointer)&eglCreatePbufferFromClientBufferImpl },
2683     { "eglLockSurfaceKHR", (EGLFuncPointer)&eglLockSurfaceKHRImpl },
2684     { "eglUnlockSurfaceKHR", (EGLFuncPointer)&eglUnlockSurfaceKHRImpl },
2685     { "eglCreateImageKHR", (EGLFuncPointer)&eglCreateImageKHRImpl },
2686     { "eglDestroyImageKHR", (EGLFuncPointer)&eglDestroyImageKHRImpl },
2687     { "eglCreateImage", (EGLFuncPointer)&eglCreateImageImpl },
2688     { "eglDestroyImage", (EGLFuncPointer)&eglDestroyImageImpl },
2689     { "eglCreateSync", (EGLFuncPointer)&eglCreateSyncImpl },
2690     { "eglDestroySync", (EGLFuncPointer)&eglDestroySyncImpl },
2691     { "eglClientWaitSync", (EGLFuncPointer)&eglClientWaitSyncImpl },
2692     { "eglGetSyncAttrib", (EGLFuncPointer)&eglGetSyncAttribImpl },
2693     { "eglCreateSyncKHR", (EGLFuncPointer)&eglCreateSyncKHRImpl },
2694     { "eglDestroySyncKHR", (EGLFuncPointer)&eglDestroySyncKHRImpl },
2695     { "eglSignalSyncKHR", (EGLFuncPointer)&eglSignalSyncKHRImpl },
2696     { "eglClientWaitSyncKHR", (EGLFuncPointer)&eglClientWaitSyncKHRImpl },
2697     { "eglGetSyncAttribKHR", (EGLFuncPointer)&eglGetSyncAttribKHRImpl },
2698     { "eglCreateStreamKHR", (EGLFuncPointer)&eglCreateStreamKHRImpl },
2699     { "eglDestroyStreamKHR", (EGLFuncPointer)&eglDestroyStreamKHRImpl },
2700     { "eglStreamAttribKHR", (EGLFuncPointer)&eglStreamAttribKHRImpl },
2701     { "eglQueryStreamKHR", (EGLFuncPointer)&eglQueryStreamKHRImpl },
2702     { "eglQueryStreamu64KHR", (EGLFuncPointer)&eglQueryStreamu64KHRImpl },
2703     { "eglQueryStreamTimeKHR", (EGLFuncPointer)&eglQueryStreamTimeKHRImpl },
2704     { "eglCreateStreamProducerSurfaceKHR", (EGLFuncPointer)&eglCreateStreamProducerSurfaceKHRImpl },
2705     { "eglStreamConsumerGLTextureExternalKHR", (EGLFuncPointer)&eglStreamConsumerGLTextureExternalKHRImpl },
2706     { "eglStreamConsumerAcquireKHR", (EGLFuncPointer)&eglStreamConsumerAcquireKHRImpl },
2707     { "eglStreamConsumerReleaseKHR", (EGLFuncPointer)&eglStreamConsumerReleaseKHRImpl },
2708     { "eglGetStreamFileDescriptorKHR", (EGLFuncPointer)&eglGetStreamFileDescriptorKHRImpl },
2709     { "eglCreateStreamFromFileDescriptorKHR", (EGLFuncPointer)&eglCreateStreamFromFileDescriptorKHRImpl },
2710     { "eglWaitSync", (EGLFuncPointer)&eglWaitSyncImpl },
2711     { "eglWaitSyncKHR", (EGLFuncPointer)&eglWaitSyncKHRImpl },
2712     { "eglDupNativeFenceFDANDROID", (EGLFuncPointer)&eglDupNativeFenceFDANDROIDImpl },
2713     { "eglPresentationTimeANDROID", (EGLFuncPointer)&eglPresentationTimeANDROIDImpl },
2714     { "eglGetNativeClientBufferANDROID", (EGLFuncPointer)&eglGetNativeClientBufferANDROIDImpl },
2715     { "eglGetSystemTimeFrequencyNV", (EGLFuncPointer)&eglGetSystemTimeFrequencyNVImpl },
2716     { "eglGetSystemTimeNV", (EGLFuncPointer)&eglGetSystemTimeNVImpl },
2717     { "eglSetDamageRegionKHR", (EGLFuncPointer)&eglSetDamageRegionKHRImpl },
2718     { "eglGetNextFrameIdANDROID", (EGLFuncPointer)&eglGetNextFrameIdANDROIDImpl },
2719     { "eglGetCompositorTimingANDROID", (EGLFuncPointer)&eglGetCompositorTimingANDROIDImpl },
2720     { "eglGetCompositorTimingSupportedANDROID", (EGLFuncPointer)&eglGetCompositorTimingSupportedANDROIDImpl },
2721     { "eglGetFrameTimestampsANDROID", (EGLFuncPointer)&eglGetFrameTimestampsANDROIDImpl },
2722     { "eglGetFrameTimestampSupportedANDROID", (EGLFuncPointer)&eglGetFrameTimestampSupportedANDROIDImpl },
2723     { "glGetString", (EGLFuncPointer)&glGetStringImpl },
2724     { "glGetStringi", (EGLFuncPointer)&glGetStringiImpl },
2725     { "glGetBooleanv", (EGLFuncPointer)&glGetBooleanvImpl },
2726     { "glGetFloatv", (EGLFuncPointer)&glGetFloatvImpl },
2727     { "glGetIntegerv", (EGLFuncPointer)&glGetIntegervImpl },
2728     { "glGetInteger64v", (EGLFuncPointer)&glGetInteger64vImpl },
2729         // clang-format on
2730 };
2731 
FindPlatformImplAddr(const char * name)2732 EGLFuncPointer FindPlatformImplAddr(const char* name)
2733 {
2734     static const bool DEBUG = false;
2735 
2736     if (name == nullptr) {
2737         ALOGV("FindPlatformImplAddr called with null name");
2738         return nullptr;
2739     }
2740 
2741     for (int i = 0; i < NELEM(sPlatformImplMap); i++) {
2742         if (sPlatformImplMap[i].name == nullptr) {
2743             ALOGV("FindPlatformImplAddr found nullptr for sPlatformImplMap[%i].name (%s)", i, name);
2744             return nullptr;
2745         }
2746         if (!strcmp(name, sPlatformImplMap[i].name)) {
2747             ALOGV("FindPlatformImplAddr found %llu for sPlatformImplMap[%i].address (%s)", (unsigned long long)sPlatformImplMap[i].address, i, name);
2748             return sPlatformImplMap[i].address;
2749         }
2750     }
2751 
2752     ALOGV("FindPlatformImplAddr did not find an entry for %s", name);
2753     return nullptr;
2754 }
2755 } // namespace android
2756