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