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         // b/111083885 - If we are presenting EGL 1.4 interface to apps
920         // error out on robust access attributes that are invalid
921         // in EGL 1.4 as the driver may be fine with them but dEQP expects
922         // tests to fail according to spec.
923         if (attrib_list && (cnx->driverVersion < EGL_MAKE_VERSION(1, 5, 0))) {
924             const EGLint* attrib_ptr = attrib_list;
925             while (*attrib_ptr != EGL_NONE) {
926                 GLint attr = *attrib_ptr++;
927                 GLint value = *attrib_ptr++;
928                 if (attr == EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR) {
929                     // We are GL ES context with EGL 1.4, this is an invalid
930                     // attribute
931                     return setError(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
932                 }
933             };
934         }
935         EGLContext context =
936                 cnx->egl.eglCreateContext(dp->disp.dpy, config, share_list, attrib_list);
937         if (context != EGL_NO_CONTEXT) {
938             // figure out if it's a GLESv1 or GLESv2
939             int version = egl_connection_t::GLESv1_INDEX;
940             if (attrib_list) {
941                 while (*attrib_list != EGL_NONE) {
942                     GLint attr = *attrib_list++;
943                     GLint value = *attrib_list++;
944                     if (attr == EGL_CONTEXT_CLIENT_VERSION && (value == 2 || value == 3)) {
945                         version = egl_connection_t::GLESv2_INDEX;
946                     }
947                 };
948             }
949             if (version == egl_connection_t::GLESv1_INDEX) {
950                 android::GraphicsEnv::getInstance().setTargetStats(
951                         android::GpuStatsInfo::Stats::GLES_1_IN_USE);
952             }
953             android::GraphicsEnv::getInstance().setTargetStats(
954                     android::GpuStatsInfo::Stats::CREATED_GLES_CONTEXT);
955             egl_context_t* c = new egl_context_t(dpy, context, config, cnx, version);
956             return c;
957         }
958     }
959     return EGL_NO_CONTEXT;
960 }
961 
eglDestroyContextImpl(EGLDisplay dpy,EGLContext ctx)962 EGLBoolean eglDestroyContextImpl(EGLDisplay dpy, EGLContext ctx) {
963     const egl_display_t* dp = validate_display(dpy);
964     if (!dp) return EGL_FALSE;
965 
966     ContextRef _c(dp, ctx);
967     if (!_c.get()) return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
968 
969     egl_context_t* const c = get_context(ctx);
970     EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
971     if (result == EGL_TRUE) {
972         _c.terminate();
973     }
974     return result;
975 }
976 
eglMakeCurrentImpl(EGLDisplay dpy,EGLSurface draw,EGLSurface read,EGLContext ctx)977 EGLBoolean eglMakeCurrentImpl(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) {
978     egl_display_t* dp = validate_display(dpy);
979     if (!dp) return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
980 
981     // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
982     // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
983     // a valid but uninitialized display.
984     if ((ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) || (draw != EGL_NO_SURFACE)) {
985         if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
986     }
987 
988     // get a reference to the object passed in
989     ContextRef _c(dp, ctx);
990     SurfaceRef _d(dp, draw);
991     SurfaceRef _r(dp, read);
992 
993     // validate the context (if not EGL_NO_CONTEXT)
994     if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
995         // EGL_NO_CONTEXT is valid
996         return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
997     }
998 
999     // these are the underlying implementation's object
1000     EGLContext impl_ctx = EGL_NO_CONTEXT;
1001     EGLSurface impl_draw = EGL_NO_SURFACE;
1002     EGLSurface impl_read = EGL_NO_SURFACE;
1003 
1004     // these are our objects structs passed in
1005     egl_context_t* c = nullptr;
1006     egl_surface_t const* d = nullptr;
1007     egl_surface_t const* r = nullptr;
1008 
1009     // these are the current objects structs
1010     egl_context_t* cur_c = get_context(getContext());
1011 
1012     if (ctx != EGL_NO_CONTEXT) {
1013         c = get_context(ctx);
1014         impl_ctx = c->context;
1015     } else {
1016         // no context given, use the implementation of the current context
1017         if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
1018             // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
1019             return setError(EGL_BAD_MATCH, (EGLBoolean)EGL_FALSE);
1020         }
1021         if (cur_c == nullptr) {
1022             // no current context
1023             // not an error, there is just no current context.
1024             return EGL_TRUE;
1025         }
1026     }
1027 
1028     // retrieve the underlying implementation's draw EGLSurface
1029     if (draw != EGL_NO_SURFACE) {
1030         if (!_d.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1031         d = get_surface(draw);
1032         impl_draw = d->surface;
1033     }
1034 
1035     // retrieve the underlying implementation's read EGLSurface
1036     if (read != EGL_NO_SURFACE) {
1037         if (!_r.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1038         r = get_surface(read);
1039         impl_read = r->surface;
1040     }
1041 
1042     EGLBoolean result = dp->makeCurrent(c, cur_c, draw, read, ctx, impl_draw, impl_read, impl_ctx);
1043 
1044     if (result == EGL_TRUE) {
1045         if (c) {
1046             setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
1047             egl_tls_t::setContext(ctx);
1048             _c.acquire();
1049             _r.acquire();
1050             _d.acquire();
1051         } else {
1052             setGLHooksThreadSpecific(&gHooksNoContext);
1053             egl_tls_t::setContext(EGL_NO_CONTEXT);
1054         }
1055     } else {
1056         // this will ALOGE the error
1057         egl_connection_t* const cnx = &gEGLImpl;
1058         result = setError(cnx->egl.eglGetError(), (EGLBoolean)EGL_FALSE);
1059     }
1060     return result;
1061 }
1062 
eglQueryContextImpl(EGLDisplay dpy,EGLContext ctx,EGLint attribute,EGLint * value)1063 EGLBoolean eglQueryContextImpl(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) {
1064     const egl_display_t* dp = validate_display(dpy);
1065     if (!dp) return EGL_FALSE;
1066 
1067     ContextRef _c(dp, ctx);
1068     if (!_c.get()) return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1069 
1070     egl_context_t* const c = get_context(ctx);
1071     return c->cnx->egl.eglQueryContext(dp->disp.dpy, c->context, attribute, value);
1072 }
1073 
eglGetCurrentContextImpl(void)1074 EGLContext eglGetCurrentContextImpl(void) {
1075     // could be called before eglInitialize(), but we wouldn't have a context
1076     // then, and this function would correctly return EGL_NO_CONTEXT.
1077     EGLContext ctx = getContext();
1078     return ctx;
1079 }
1080 
eglGetCurrentSurfaceImpl(EGLint readdraw)1081 EGLSurface eglGetCurrentSurfaceImpl(EGLint readdraw) {
1082     // could be called before eglInitialize(), but we wouldn't have a context
1083     // then, and this function would correctly return EGL_NO_SURFACE.
1084 
1085     EGLContext ctx = getContext();
1086     if (ctx) {
1087         egl_context_t const* const c = get_context(ctx);
1088         if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
1089         switch (readdraw) {
1090             case EGL_READ:
1091                 return c->read;
1092             case EGL_DRAW:
1093                 return c->draw;
1094             default:
1095                 return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
1096         }
1097     }
1098     return EGL_NO_SURFACE;
1099 }
1100 
eglGetCurrentDisplayImpl(void)1101 EGLDisplay eglGetCurrentDisplayImpl(void) {
1102     // could be called before eglInitialize(), but we wouldn't have a context
1103     // then, and this function would correctly return EGL_NO_DISPLAY.
1104 
1105     EGLContext ctx = getContext();
1106     if (ctx) {
1107         egl_context_t const* const c = get_context(ctx);
1108         if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
1109         return c->dpy;
1110     }
1111     return EGL_NO_DISPLAY;
1112 }
1113 
eglWaitGLImpl(void)1114 EGLBoolean eglWaitGLImpl(void) {
1115     egl_connection_t* const cnx = &gEGLImpl;
1116     if (!cnx->dso) return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1117 
1118     return cnx->egl.eglWaitGL();
1119 }
1120 
eglWaitNativeImpl(EGLint engine)1121 EGLBoolean eglWaitNativeImpl(EGLint engine) {
1122     egl_connection_t* const cnx = &gEGLImpl;
1123     if (!cnx->dso) return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1124 
1125     return cnx->egl.eglWaitNative(engine);
1126 }
1127 
eglGetErrorImpl(void)1128 EGLint eglGetErrorImpl(void) {
1129     EGLint err = EGL_SUCCESS;
1130     egl_connection_t* const cnx = &gEGLImpl;
1131     if (cnx->dso) {
1132         err = cnx->egl.eglGetError();
1133     }
1134     if (err == EGL_SUCCESS) {
1135         err = egl_tls_t::getError();
1136     }
1137     return err;
1138 }
1139 
findBuiltinWrapper(const char * procname)1140 static __eglMustCastToProperFunctionPointerType findBuiltinWrapper(const char* procname) {
1141     const egl_connection_t* cnx = &gEGLImpl;
1142     void* proc = nullptr;
1143 
1144     proc = dlsym(cnx->libEgl, procname);
1145     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1146 
1147     proc = dlsym(cnx->libGles2, procname);
1148     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1149 
1150     proc = dlsym(cnx->libGles1, procname);
1151     if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
1152 
1153     return nullptr;
1154 }
1155 
eglGetProcAddressImpl(const char * procname)1156 __eglMustCastToProperFunctionPointerType eglGetProcAddressImpl(const char* procname) {
1157     if (FILTER_EXTENSIONS(procname)) {
1158         return nullptr;
1159     }
1160 
1161     __eglMustCastToProperFunctionPointerType addr;
1162     addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap));
1163     if (addr) return addr;
1164 
1165     addr = findBuiltinWrapper(procname);
1166     if (addr) return addr;
1167 
1168     // this protects accesses to sGLExtensionMap, sGLExtensionSlot, and sGLExtensionSlotMap
1169     pthread_mutex_lock(&sExtensionMapMutex);
1170 
1171     /*
1172      * Since eglGetProcAddress() is not associated to anything, it needs
1173      * to return a function pointer that "works" regardless of what
1174      * the current context is.
1175      *
1176      * For this reason, we return a "forwarder", a small stub that takes
1177      * care of calling the function associated with the context
1178      * currently bound.
1179      *
1180      * We first look for extensions we've already resolved, if we're seeing
1181      * this extension for the first time, we go through all our
1182      * implementations and call eglGetProcAddress() and record the
1183      * result in the appropriate implementation hooks and return the
1184      * address of the forwarder corresponding to that hook set.
1185      *
1186      */
1187 
1188     const std::string name(procname);
1189     auto& extensionMap = sGLExtensionMap;
1190     auto& extensionSlotMap = sGLExtensionSlotMap;
1191     egl_connection_t* const cnx = &gEGLImpl;
1192     LayerLoader& layer_loader(LayerLoader::getInstance());
1193 
1194     // See if we've already looked up this extension
1195     auto pos = extensionMap.find(name);
1196     addr = (pos != extensionMap.end()) ? pos->second : nullptr;
1197 
1198     if (!addr) {
1199         // This is the first time we've looked this function up
1200         // Ensure we have room to track it
1201         const int slot = sGLExtensionSlot;
1202         if (slot < MAX_NUMBER_OF_GL_EXTENSIONS) {
1203             if (cnx->dso && cnx->egl.eglGetProcAddress) {
1204                 // Extensions are independent of the bound context
1205                 addr = cnx->egl.eglGetProcAddress(procname);
1206                 if (addr) {
1207                     // purposefully track the bottom of the stack in extensionMap
1208                     extensionMap[name] = addr;
1209 
1210                     // Apply layers
1211                     addr = layer_loader.ApplyLayers(procname, addr);
1212 
1213                     // Track the top most entry point return the extension forwarder
1214                     cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
1215                             cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] = addr;
1216                     addr = gExtensionForwarders[slot];
1217 
1218                     // Remember the slot for this extension
1219                     extensionSlotMap[name] = slot;
1220 
1221                     // Increment the global extension index
1222                     sGLExtensionSlot++;
1223                 }
1224             }
1225         } else {
1226             // The extension forwarder has a fixed number of slots
1227             ALOGE("no more slots for eglGetProcAddress(\"%s\")", procname);
1228         }
1229 
1230     } else {
1231         // We tracked an address, so we've seen this func before
1232         // Look up the slot for this extension
1233         auto slot_pos = extensionSlotMap.find(name);
1234         int ext_slot = (slot_pos != extensionSlotMap.end()) ? slot_pos->second : -1;
1235         if (ext_slot < 0) {
1236             // Something has gone wrong, this should not happen
1237             ALOGE("No extension slot found for %s", procname);
1238             return nullptr;
1239         }
1240 
1241         // We tracked the bottom of the stack, so re-apply layers since
1242         // more layers might have been enabled
1243         addr = layer_loader.ApplyLayers(procname, addr);
1244 
1245         // Track the top most entry point and return the extension forwarder
1246         cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[ext_slot] =
1247                 cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[ext_slot] = addr;
1248         addr = gExtensionForwarders[ext_slot];
1249     }
1250 
1251     pthread_mutex_unlock(&sExtensionMapMutex);
1252     return addr;
1253 }
1254 
1255 class FrameCompletionThread {
1256 public:
queueSync(EGLSyncKHR sync)1257     static void queueSync(EGLSyncKHR sync) {
1258         static FrameCompletionThread thread;
1259 
1260         char name[64];
1261 
1262         std::lock_guard<std::mutex> lock(thread.mMutex);
1263         snprintf(name, sizeof(name), "kicked off frame %u", (unsigned int)thread.mFramesQueued);
1264         ATRACE_NAME(name);
1265 
1266         thread.mQueue.push_back(sync);
1267         thread.mCondition.notify_one();
1268         thread.mFramesQueued++;
1269         ATRACE_INT("GPU Frames Outstanding", int32_t(thread.mQueue.size()));
1270     }
1271 
1272 private:
FrameCompletionThread()1273     FrameCompletionThread() : mFramesQueued(0), mFramesCompleted(0) {
1274         std::thread thread(&FrameCompletionThread::loop, this);
1275         thread.detach();
1276     }
1277 
1278 #pragma clang diagnostic push
1279 #pragma clang diagnostic ignored "-Wmissing-noreturn"
loop()1280     void loop() {
1281         while (true) {
1282             threadLoop();
1283         }
1284     }
1285 #pragma clang diagnostic pop
1286 
threadLoop()1287     void threadLoop() {
1288         EGLSyncKHR sync;
1289         uint32_t frameNum;
1290         {
1291             std::unique_lock<std::mutex> lock(mMutex);
1292             while (mQueue.empty()) {
1293                 mCondition.wait(lock);
1294             }
1295             sync = mQueue[0];
1296             frameNum = mFramesCompleted;
1297         }
1298         EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1299         {
1300             char name[64];
1301             snprintf(name, sizeof(name), "waiting for frame %u", (unsigned int)frameNum);
1302             ATRACE_NAME(name);
1303 
1304             EGLint result = eglClientWaitSyncKHR(dpy, sync, 0, EGL_FOREVER_KHR);
1305             if (result == EGL_FALSE) {
1306                 ALOGE("FrameCompletion: error waiting for fence: %#x", eglGetError());
1307             } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
1308                 ALOGE("FrameCompletion: timeout waiting for fence");
1309             }
1310             eglDestroySyncKHR(dpy, sync);
1311         }
1312         {
1313             std::lock_guard<std::mutex> lock(mMutex);
1314             mQueue.pop_front();
1315             mFramesCompleted++;
1316             ATRACE_INT("GPU Frames Outstanding", int32_t(mQueue.size()));
1317         }
1318     }
1319 
1320     uint32_t mFramesQueued;
1321     uint32_t mFramesCompleted;
1322     std::deque<EGLSyncKHR> mQueue;
1323     std::condition_variable mCondition;
1324     std::mutex mMutex;
1325 };
1326 
eglSwapBuffersWithDamageKHRImpl(EGLDisplay dpy,EGLSurface draw,EGLint * rects,EGLint n_rects)1327 EGLBoolean eglSwapBuffersWithDamageKHRImpl(EGLDisplay dpy, EGLSurface draw, EGLint* rects,
1328                                            EGLint n_rects) {
1329     const egl_display_t* dp = validate_display(dpy);
1330     if (!dp) return EGL_FALSE;
1331 
1332     SurfaceRef _s(dp, draw);
1333     if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1334 
1335     if (n_rects < 0 || (n_rects > 0 && rects == NULL))
1336         return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
1337 
1338     egl_surface_t* const s = get_surface(draw);
1339 
1340     if (CC_UNLIKELY(dp->traceGpuCompletion)) {
1341         EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr);
1342         if (sync != EGL_NO_SYNC_KHR) {
1343             FrameCompletionThread::queueSync(sync);
1344         }
1345     }
1346 
1347     if (CC_UNLIKELY(dp->finishOnSwap)) {
1348         uint32_t pixel;
1349         egl_context_t* const c = get_context(egl_tls_t::getContext());
1350         if (c) {
1351             // glReadPixels() ensures that the frame is complete
1352             s->cnx->hooks[c->version]->gl.glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
1353                                                        &pixel);
1354         }
1355     }
1356 
1357     if (!s->cnx->angleLoaded) {
1358         if (!sendSurfaceMetadata(s)) {
1359             native_window_api_disconnect(s->getNativeWindow(), NATIVE_WINDOW_API_EGL);
1360             return setError(EGL_BAD_NATIVE_WINDOW, (EGLBoolean)EGL_FALSE);
1361         }
1362     }
1363 
1364     if (n_rects == 0) {
1365         return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1366     }
1367 
1368     std::vector<android_native_rect_t> androidRects((size_t)n_rects);
1369     for (int r = 0; r < n_rects; ++r) {
1370         int offset = r * 4;
1371         int x = rects[offset];
1372         int y = rects[offset + 1];
1373         int width = rects[offset + 2];
1374         int height = rects[offset + 3];
1375         android_native_rect_t androidRect;
1376         androidRect.left = x;
1377         androidRect.top = y + height;
1378         androidRect.right = x + width;
1379         androidRect.bottom = y;
1380         androidRects.push_back(androidRect);
1381     }
1382     if (!s->cnx->angleLoaded) {
1383         native_window_set_surface_damage(s->getNativeWindow(), androidRects.data(),
1384                                          androidRects.size());
1385     }
1386 
1387     if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
1388         return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface, rects, n_rects);
1389     }
1390 
1391     return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
1392 }
1393 
eglSwapBuffersImpl(EGLDisplay dpy,EGLSurface surface)1394 EGLBoolean eglSwapBuffersImpl(EGLDisplay dpy, EGLSurface surface) {
1395     return eglSwapBuffersWithDamageKHRImpl(dpy, surface, nullptr, 0);
1396 }
1397 
eglCopyBuffersImpl(EGLDisplay dpy,EGLSurface surface,NativePixmapType target)1398 EGLBoolean eglCopyBuffersImpl(EGLDisplay dpy, EGLSurface surface, NativePixmapType target) {
1399     const egl_display_t* dp = validate_display(dpy);
1400     if (!dp) return EGL_FALSE;
1401 
1402     SurfaceRef _s(dp, surface);
1403     if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1404 
1405     egl_surface_t const* const s = get_surface(surface);
1406     return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
1407 }
1408 
eglQueryStringImpl(EGLDisplay dpy,EGLint name)1409 const char* eglQueryStringImpl(EGLDisplay dpy, EGLint name) {
1410     if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
1411         // Return list of client extensions
1412         return gClientExtensionString;
1413     }
1414 
1415     const egl_display_t* dp = validate_display(dpy);
1416     if (!dp) return (const char*)nullptr;
1417 
1418     switch (name) {
1419         case EGL_VENDOR:
1420             return dp->getVendorString();
1421         case EGL_VERSION:
1422             return dp->getVersionString();
1423         case EGL_EXTENSIONS:
1424             return dp->getExtensionString();
1425         case EGL_CLIENT_APIS:
1426             return dp->getClientApiString();
1427         default:
1428             break;
1429     }
1430     return setError(EGL_BAD_PARAMETER, (const char*)nullptr);
1431 }
1432 
eglQueryStringImplementationANDROIDImpl(EGLDisplay dpy,EGLint name)1433 EGLAPI const char* eglQueryStringImplementationANDROIDImpl(EGLDisplay dpy, EGLint name) {
1434     const egl_display_t* dp = validate_display(dpy);
1435     if (!dp) return (const char*)nullptr;
1436 
1437     switch (name) {
1438         case EGL_VENDOR:
1439             return dp->disp.queryString.vendor;
1440         case EGL_VERSION:
1441             return dp->disp.queryString.version;
1442         case EGL_EXTENSIONS:
1443             return dp->disp.queryString.extensions;
1444         case EGL_CLIENT_APIS:
1445             return dp->disp.queryString.clientApi;
1446         default:
1447             break;
1448     }
1449     return setError(EGL_BAD_PARAMETER, (const char*)nullptr);
1450 }
1451 
1452 // ----------------------------------------------------------------------------
1453 // EGL 1.1
1454 // ----------------------------------------------------------------------------
1455 
eglSurfaceAttribImpl(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint value)1456 EGLBoolean eglSurfaceAttribImpl(EGLDisplay dpy, EGLSurface surface, EGLint attribute,
1457                                 EGLint value) {
1458     const egl_display_t* dp = validate_display(dpy);
1459     if (!dp) return EGL_FALSE;
1460 
1461     SurfaceRef _s(dp, surface);
1462     if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1463 
1464     egl_surface_t* const s = get_surface(surface);
1465 
1466     if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) {
1467         if (!s->getNativeWindow()) {
1468             setError(EGL_BAD_SURFACE, EGL_FALSE);
1469         }
1470         int err = native_window_set_auto_refresh(s->getNativeWindow(), value != 0);
1471         if (err != 0) {
1472             return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1473         } else if (!s->cnx->angleLoaded) {
1474             return EGL_TRUE;
1475         } // else if ANGLE, fall through to the call to the driver (i.e. ANGLE) below
1476     }
1477 
1478     if (attribute == EGL_TIMESTAMPS_ANDROID) {
1479         if (!s->getNativeWindow()) {
1480             // According to the spec, "if surface is not a window surface this has no
1481             // effect."
1482             return EGL_TRUE;
1483         }
1484         int err = native_window_enable_frame_timestamps(s->getNativeWindow(), value != 0);
1485         if (err != 0) {
1486             return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1487         } else if (!s->cnx->angleLoaded) {
1488             return EGL_TRUE;
1489         } // else if ANGLE, fall through to the call to the driver (i.e. ANGLE) below
1490     }
1491 
1492     if (s->setSmpte2086Attribute(attribute, value)) {
1493         return EGL_TRUE;
1494     } else if (s->setCta8613Attribute(attribute, value)) {
1495         return EGL_TRUE;
1496     } else if (s->cnx->egl.eglSurfaceAttrib) {
1497         return s->cnx->egl.eglSurfaceAttrib(dp->disp.dpy, s->surface, attribute, value);
1498     }
1499     return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1500 }
1501 
eglBindTexImageImpl(EGLDisplay dpy,EGLSurface surface,EGLint buffer)1502 EGLBoolean eglBindTexImageImpl(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
1503     const egl_display_t* dp = validate_display(dpy);
1504     if (!dp) return EGL_FALSE;
1505 
1506     SurfaceRef _s(dp, surface);
1507     if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1508 
1509     egl_surface_t const* const s = get_surface(surface);
1510     if (s->cnx->egl.eglBindTexImage) {
1511         return s->cnx->egl.eglBindTexImage(dp->disp.dpy, s->surface, buffer);
1512     }
1513     return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1514 }
1515 
eglReleaseTexImageImpl(EGLDisplay dpy,EGLSurface surface,EGLint buffer)1516 EGLBoolean eglReleaseTexImageImpl(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
1517     const egl_display_t* dp = validate_display(dpy);
1518     if (!dp) return EGL_FALSE;
1519 
1520     SurfaceRef _s(dp, surface);
1521     if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1522 
1523     egl_surface_t const* const s = get_surface(surface);
1524     if (s->cnx->egl.eglReleaseTexImage) {
1525         return s->cnx->egl.eglReleaseTexImage(dp->disp.dpy, s->surface, buffer);
1526     }
1527     return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1528 }
1529 
eglSwapIntervalImpl(EGLDisplay dpy,EGLint interval)1530 EGLBoolean eglSwapIntervalImpl(EGLDisplay dpy, EGLint interval) {
1531     const egl_display_t* dp = validate_display(dpy);
1532     if (!dp) return EGL_FALSE;
1533 
1534     EGLBoolean res = EGL_TRUE;
1535     egl_connection_t* const cnx = &gEGLImpl;
1536     if (cnx->dso && cnx->egl.eglSwapInterval) {
1537         res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
1538     }
1539 
1540     return res;
1541 }
1542 
1543 // ----------------------------------------------------------------------------
1544 // EGL 1.2
1545 // ----------------------------------------------------------------------------
1546 
eglWaitClientImpl(void)1547 EGLBoolean eglWaitClientImpl(void) {
1548     egl_connection_t* const cnx = &gEGLImpl;
1549     if (!cnx->dso) return setError(EGL_BAD_CONTEXT, (EGLBoolean)EGL_FALSE);
1550 
1551     EGLBoolean res;
1552     if (cnx->egl.eglWaitClient) {
1553         res = cnx->egl.eglWaitClient();
1554     } else {
1555         res = cnx->egl.eglWaitGL();
1556     }
1557     return res;
1558 }
1559 
eglBindAPIImpl(EGLenum api)1560 EGLBoolean eglBindAPIImpl(EGLenum api) {
1561     // bind this API on all EGLs
1562     EGLBoolean res = EGL_TRUE;
1563     egl_connection_t* const cnx = &gEGLImpl;
1564     if (cnx->dso && cnx->egl.eglBindAPI) {
1565         res = cnx->egl.eglBindAPI(api);
1566     }
1567     return res;
1568 }
1569 
eglQueryAPIImpl(void)1570 EGLenum eglQueryAPIImpl(void) {
1571     egl_connection_t* const cnx = &gEGLImpl;
1572     if (cnx->dso && cnx->egl.eglQueryAPI) {
1573         return cnx->egl.eglQueryAPI();
1574     }
1575 
1576     // or, it can only be OpenGL ES
1577     return EGL_OPENGL_ES_API;
1578 }
1579 
eglReleaseThreadImpl(void)1580 EGLBoolean eglReleaseThreadImpl(void) {
1581     egl_connection_t* const cnx = &gEGLImpl;
1582     if (cnx->dso && cnx->egl.eglReleaseThread) {
1583         cnx->egl.eglReleaseThread();
1584     }
1585 
1586     // If there is context bound to the thread, release it
1587     egl_display_t::loseCurrent(get_context(getContext()));
1588 
1589     egl_tls_t::clearTLS();
1590     return EGL_TRUE;
1591 }
1592 
eglCreatePbufferFromClientBufferImpl(EGLDisplay dpy,EGLenum buftype,EGLClientBuffer buffer,EGLConfig config,const EGLint * attrib_list)1593 EGLSurface eglCreatePbufferFromClientBufferImpl(EGLDisplay dpy, EGLenum buftype,
1594                                                 EGLClientBuffer buffer, EGLConfig config,
1595                                                 const EGLint* attrib_list) {
1596     egl_connection_t* cnx = nullptr;
1597     const egl_display_t* dp = validate_display_connection(dpy, &cnx);
1598     if (!dp) return EGL_FALSE;
1599     if (cnx->egl.eglCreatePbufferFromClientBuffer) {
1600         return cnx->egl.eglCreatePbufferFromClientBuffer(dp->disp.dpy, buftype, buffer, config,
1601                                                          attrib_list);
1602     }
1603     return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
1604 }
1605 
1606 // ----------------------------------------------------------------------------
1607 // EGL_EGLEXT_VERSION 3
1608 // ----------------------------------------------------------------------------
1609 
eglLockSurfaceKHRImpl(EGLDisplay dpy,EGLSurface surface,const EGLint * attrib_list)1610 EGLBoolean eglLockSurfaceKHRImpl(EGLDisplay dpy, EGLSurface surface, const EGLint* attrib_list) {
1611     const egl_display_t* dp = validate_display(dpy);
1612     if (!dp) return EGL_FALSE;
1613 
1614     SurfaceRef _s(dp, surface);
1615     if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1616 
1617     egl_surface_t const* const s = get_surface(surface);
1618     if (s->cnx->egl.eglLockSurfaceKHR) {
1619         return s->cnx->egl.eglLockSurfaceKHR(dp->disp.dpy, s->surface, attrib_list);
1620     }
1621     return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1622 }
1623 
eglUnlockSurfaceKHRImpl(EGLDisplay dpy,EGLSurface surface)1624 EGLBoolean eglUnlockSurfaceKHRImpl(EGLDisplay dpy, EGLSurface surface) {
1625     const egl_display_t* dp = validate_display(dpy);
1626     if (!dp) return EGL_FALSE;
1627 
1628     SurfaceRef _s(dp, surface);
1629     if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
1630 
1631     egl_surface_t const* const s = get_surface(surface);
1632     if (s->cnx->egl.eglUnlockSurfaceKHR) {
1633         return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
1634     }
1635     return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
1636 }
1637 
1638 // Note: EGLImageKHR and EGLImage are the same thing so no need
1639 // to templatize that.
1640 template <typename AttrType, typename FuncType>
eglCreateImageTmpl(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const AttrType * attrib_list,FuncType eglCreateImageFunc)1641 EGLImageKHR eglCreateImageTmpl(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1642                                EGLClientBuffer buffer, const AttrType* attrib_list,
1643                                FuncType eglCreateImageFunc) {
1644     const egl_display_t* dp = validate_display(dpy);
1645     if (!dp) return EGL_NO_IMAGE_KHR;
1646 
1647     ContextRef _c(dp, ctx);
1648     egl_context_t* const c = _c.get();
1649 
1650     EGLImageKHR result = EGL_NO_IMAGE_KHR;
1651     egl_connection_t* const cnx = &gEGLImpl;
1652     if (cnx->dso && eglCreateImageFunc) {
1653         result = eglCreateImageFunc(dp->disp.dpy, c ? c->context : EGL_NO_CONTEXT, target, buffer,
1654                                     attrib_list);
1655     }
1656     return result;
1657 }
1658 
1659 typedef EGLImage(EGLAPIENTRYP PFNEGLCREATEIMAGE)(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1660                                                  EGLClientBuffer buffer,
1661                                                  const EGLAttrib* attrib_list);
1662 
eglCreateImageKHRImpl(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)1663 EGLImageKHR eglCreateImageKHRImpl(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1664                                   EGLClientBuffer buffer, const EGLint* attrib_list) {
1665     return eglCreateImageTmpl<EGLint, PFNEGLCREATEIMAGEKHRPROC>(dpy, ctx, target, buffer,
1666                                                                 attrib_list,
1667                                                                 gEGLImpl.egl.eglCreateImageKHR);
1668 }
1669 
eglCreateImageImpl(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLAttrib * attrib_list)1670 EGLImage eglCreateImageImpl(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer,
1671                             const EGLAttrib* attrib_list) {
1672     egl_connection_t* const cnx = &gEGLImpl;
1673     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1674         if (cnx->egl.eglCreateImage) {
1675             return eglCreateImageTmpl<EGLAttrib, PFNEGLCREATEIMAGE>(dpy, ctx, target, buffer,
1676                                                                     attrib_list,
1677                                                                     cnx->egl.eglCreateImage);
1678         }
1679         // driver doesn't support native function, return EGL_BAD_DISPLAY
1680         ALOGE("Driver indicates EGL 1.5 support, but does not have eglCreateImage");
1681         return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE);
1682     }
1683 
1684     std::vector<EGLint> convertedAttribs;
1685     convertAttribs(attrib_list, convertedAttribs);
1686     return eglCreateImageTmpl<EGLint, PFNEGLCREATEIMAGEKHRPROC>(dpy, ctx, target, buffer,
1687                                                                 convertedAttribs.data(),
1688                                                                 gEGLImpl.egl.eglCreateImageKHR);
1689 }
1690 
eglDestroyImageTmpl(EGLDisplay dpy,EGLImageKHR img,PFNEGLDESTROYIMAGEKHRPROC destroyImageFunc)1691 EGLBoolean eglDestroyImageTmpl(EGLDisplay dpy, EGLImageKHR img,
1692                                PFNEGLDESTROYIMAGEKHRPROC destroyImageFunc) {
1693     const egl_display_t* dp = validate_display(dpy);
1694     if (!dp) return EGL_FALSE;
1695 
1696     EGLBoolean result = EGL_FALSE;
1697     egl_connection_t* const cnx = &gEGLImpl;
1698     if (cnx->dso && destroyImageFunc) {
1699         result = destroyImageFunc(dp->disp.dpy, img);
1700     }
1701     return result;
1702 }
1703 
eglDestroyImageKHRImpl(EGLDisplay dpy,EGLImageKHR img)1704 EGLBoolean eglDestroyImageKHRImpl(EGLDisplay dpy, EGLImageKHR img) {
1705     return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImageKHR);
1706 }
1707 
eglDestroyImageImpl(EGLDisplay dpy,EGLImageKHR img)1708 EGLBoolean eglDestroyImageImpl(EGLDisplay dpy, EGLImageKHR img) {
1709     egl_connection_t* const cnx = &gEGLImpl;
1710     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1711         if (cnx->egl.eglDestroyImage) {
1712             return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImage);
1713         }
1714         // driver doesn't support native function, return EGL_BAD_DISPLAY
1715         ALOGE("Driver indicates EGL 1.5 support, but does not have eglDestroyImage");
1716         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
1717     }
1718 
1719     return eglDestroyImageTmpl(dpy, img, gEGLImpl.egl.eglDestroyImageKHR);
1720 }
1721 
1722 // ----------------------------------------------------------------------------
1723 // EGL_EGLEXT_VERSION 5
1724 // ----------------------------------------------------------------------------
1725 
1726 // NOTE: EGLSyncKHR and EGLSync are identical, no need to templatize
1727 template <typename AttrType, typename FuncType>
eglCreateSyncTmpl(EGLDisplay dpy,EGLenum type,const AttrType * attrib_list,FuncType eglCreateSyncFunc)1728 EGLSyncKHR eglCreateSyncTmpl(EGLDisplay dpy, EGLenum type, const AttrType* attrib_list,
1729                              FuncType eglCreateSyncFunc) {
1730     const egl_display_t* dp = validate_display(dpy);
1731     if (!dp) return EGL_NO_SYNC_KHR;
1732 
1733     egl_connection_t* const cnx = &gEGLImpl;
1734     EGLSyncKHR result = EGL_NO_SYNC_KHR;
1735     if (cnx->dso && eglCreateSyncFunc) {
1736         result = eglCreateSyncFunc(dp->disp.dpy, type, attrib_list);
1737     }
1738     return result;
1739 }
1740 
1741 typedef EGLSurface(EGLAPIENTRYP PFNEGLCREATESYNC)(EGLDisplay dpy, EGLenum type,
1742                                                   const EGLAttrib* attrib_list);
1743 
eglCreateSyncKHRImpl(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list)1744 EGLSyncKHR eglCreateSyncKHRImpl(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) {
1745     return eglCreateSyncTmpl<EGLint, PFNEGLCREATESYNCKHRPROC>(dpy, type, attrib_list,
1746                                                               gEGLImpl.egl.eglCreateSyncKHR);
1747 }
1748 
eglCreateSyncImpl(EGLDisplay dpy,EGLenum type,const EGLAttrib * attrib_list)1749 EGLSync eglCreateSyncImpl(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list) {
1750     egl_connection_t* const cnx = &gEGLImpl;
1751     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1752         if (cnx->egl.eglCreateSync) {
1753             return eglCreateSyncTmpl<EGLAttrib, PFNEGLCREATESYNC>(dpy, type, attrib_list,
1754                                                                   cnx->egl.eglCreateSync);
1755         }
1756         // driver doesn't support native function, return EGL_BAD_DISPLAY
1757         ALOGE("Driver indicates EGL 1.5 support, but does not have eglCreateSync");
1758         return setError(EGL_BAD_DISPLAY, EGL_NO_SYNC);
1759     }
1760 
1761     std::vector<EGLint> convertedAttribs;
1762     convertAttribs(attrib_list, convertedAttribs);
1763     return eglCreateSyncTmpl<EGLint, PFNEGLCREATESYNCKHRPROC>(dpy, type, convertedAttribs.data(),
1764                                                               cnx->egl.eglCreateSyncKHR);
1765 }
1766 
eglDestroySyncTmpl(EGLDisplay dpy,EGLSyncKHR sync,PFNEGLDESTROYSYNCKHRPROC eglDestroySyncFunc)1767 EGLBoolean eglDestroySyncTmpl(EGLDisplay dpy, EGLSyncKHR sync,
1768                               PFNEGLDESTROYSYNCKHRPROC eglDestroySyncFunc) {
1769     const egl_display_t* dp = validate_display(dpy);
1770     if (!dp) return EGL_FALSE;
1771 
1772     EGLBoolean result = EGL_FALSE;
1773     egl_connection_t* const cnx = &gEGLImpl;
1774     if (cnx->dso && eglDestroySyncFunc) {
1775         result = eglDestroySyncFunc(dp->disp.dpy, sync);
1776     }
1777     return result;
1778 }
1779 
eglDestroySyncKHRImpl(EGLDisplay dpy,EGLSyncKHR sync)1780 EGLBoolean eglDestroySyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync) {
1781     return eglDestroySyncTmpl(dpy, sync, gEGLImpl.egl.eglDestroySyncKHR);
1782 }
1783 
eglDestroySyncImpl(EGLDisplay dpy,EGLSyncKHR sync)1784 EGLBoolean eglDestroySyncImpl(EGLDisplay dpy, EGLSyncKHR sync) {
1785     egl_connection_t* const cnx = &gEGLImpl;
1786     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1787         if (cnx->egl.eglDestroySync) {
1788             return eglDestroySyncTmpl(dpy, sync, cnx->egl.eglDestroySync);
1789         }
1790         ALOGE("Driver indicates EGL 1.5 support, but does not have eglDestroySync");
1791         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
1792     }
1793 
1794     return eglDestroySyncTmpl(dpy, sync, cnx->egl.eglDestroySyncKHR);
1795 }
1796 
eglSignalSyncKHRImpl(EGLDisplay dpy,EGLSyncKHR sync,EGLenum mode)1797 EGLBoolean eglSignalSyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
1798     const egl_display_t* dp = validate_display(dpy);
1799     if (!dp) return EGL_FALSE;
1800 
1801     EGLBoolean result = EGL_FALSE;
1802     egl_connection_t* const cnx = &gEGLImpl;
1803     if (cnx->dso && gEGLImpl.egl.eglSignalSyncKHR) {
1804         result = gEGLImpl.egl.eglSignalSyncKHR(dp->disp.dpy, sync, mode);
1805     }
1806     return result;
1807 }
1808 
eglClientWaitSyncTmpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags,EGLTimeKHR timeout,PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncFunc)1809 EGLint eglClientWaitSyncTmpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout,
1810                              PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncFunc) {
1811     const egl_display_t* dp = validate_display(dpy);
1812     if (!dp) return EGL_FALSE;
1813 
1814     EGLint result = EGL_FALSE;
1815     egl_connection_t* const cnx = &gEGLImpl;
1816     if (cnx->dso && eglClientWaitSyncFunc) {
1817         result = eglClientWaitSyncFunc(dp->disp.dpy, sync, flags, timeout);
1818     }
1819     return result;
1820 }
1821 
eglClientWaitSyncKHRImpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags,EGLTimeKHR timeout)1822 EGLint eglClientWaitSyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
1823     egl_connection_t* const cnx = &gEGLImpl;
1824     return eglClientWaitSyncTmpl(dpy, sync, flags, timeout, cnx->egl.eglClientWaitSyncKHR);
1825 }
1826 
eglClientWaitSyncImpl(EGLDisplay dpy,EGLSync sync,EGLint flags,EGLTimeKHR timeout)1827 EGLint eglClientWaitSyncImpl(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTimeKHR timeout) {
1828     egl_connection_t* const cnx = &gEGLImpl;
1829     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1830         if (cnx->egl.eglClientWaitSync) {
1831             return eglClientWaitSyncTmpl(dpy, sync, flags, timeout, cnx->egl.eglClientWaitSync);
1832         }
1833         ALOGE("Driver indicates EGL 1.5 support, but does not have eglClientWaitSync");
1834         return setError(EGL_BAD_DISPLAY, (EGLint)EGL_FALSE);
1835     }
1836 
1837     return eglClientWaitSyncTmpl(dpy, sync, flags, timeout, cnx->egl.eglClientWaitSyncKHR);
1838 }
1839 
1840 template <typename AttrType, typename FuncType>
eglGetSyncAttribTmpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint attribute,AttrType * value,FuncType eglGetSyncAttribFunc)1841 EGLBoolean eglGetSyncAttribTmpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, AttrType* value,
1842                                 FuncType eglGetSyncAttribFunc) {
1843     const egl_display_t* dp = validate_display(dpy);
1844     if (!dp) return EGL_FALSE;
1845 
1846     EGLBoolean result = EGL_FALSE;
1847     egl_connection_t* const cnx = &gEGLImpl;
1848     if (cnx->dso && eglGetSyncAttribFunc) {
1849         result = eglGetSyncAttribFunc(dp->disp.dpy, sync, attribute, value);
1850     }
1851     return result;
1852 }
1853 
1854 typedef EGLBoolean(EGLAPIENTRYP PFNEGLGETSYNCATTRIB)(EGLDisplay dpy, EGLSync sync, EGLint attribute,
1855                                                      EGLAttrib* value);
1856 
eglGetSyncAttribImpl(EGLDisplay dpy,EGLSync sync,EGLint attribute,EGLAttrib * value)1857 EGLBoolean eglGetSyncAttribImpl(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value) {
1858     egl_connection_t* const cnx = &gEGLImpl;
1859     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
1860         if (cnx->egl.eglGetSyncAttrib) {
1861             return eglGetSyncAttribTmpl<EGLAttrib, PFNEGLGETSYNCATTRIB>(dpy, sync, attribute, value,
1862                                                                         cnx->egl.eglGetSyncAttrib);
1863         }
1864         ALOGE("Driver indicates EGL 1.5 support, but does not have eglGetSyncAttrib");
1865         return setError(EGL_BAD_DISPLAY, (EGLint)EGL_FALSE);
1866     }
1867 
1868     // Fallback to KHR, ask for EGLint attribute and cast back to EGLAttrib
1869     EGLint attribValue;
1870     EGLBoolean ret =
1871             eglGetSyncAttribTmpl<EGLint, PFNEGLGETSYNCATTRIBKHRPROC>(dpy, sync, attribute,
1872                                                                      &attribValue,
1873                                                                      gEGLImpl.egl
1874                                                                              .eglGetSyncAttribKHR);
1875     if (ret) {
1876         *value = static_cast<EGLAttrib>(attribValue);
1877     }
1878     return ret;
1879 }
1880 
eglGetSyncAttribKHRImpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint attribute,EGLint * value)1881 EGLBoolean eglGetSyncAttribKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute,
1882                                    EGLint* value) {
1883     return eglGetSyncAttribTmpl<EGLint, PFNEGLGETSYNCATTRIBKHRPROC>(dpy, sync, attribute, value,
1884                                                                     gEGLImpl.egl
1885                                                                             .eglGetSyncAttribKHR);
1886 }
1887 
eglCreateStreamKHRImpl(EGLDisplay dpy,const EGLint * attrib_list)1888 EGLStreamKHR eglCreateStreamKHRImpl(EGLDisplay dpy, const EGLint* attrib_list) {
1889     const egl_display_t* dp = validate_display(dpy);
1890     if (!dp) return EGL_NO_STREAM_KHR;
1891 
1892     EGLStreamKHR result = EGL_NO_STREAM_KHR;
1893     egl_connection_t* const cnx = &gEGLImpl;
1894     if (cnx->dso && cnx->egl.eglCreateStreamKHR) {
1895         result = cnx->egl.eglCreateStreamKHR(dp->disp.dpy, attrib_list);
1896     }
1897     return result;
1898 }
1899 
eglDestroyStreamKHRImpl(EGLDisplay dpy,EGLStreamKHR stream)1900 EGLBoolean eglDestroyStreamKHRImpl(EGLDisplay dpy, EGLStreamKHR stream) {
1901     const egl_display_t* dp = validate_display(dpy);
1902     if (!dp) return EGL_FALSE;
1903 
1904     EGLBoolean result = EGL_FALSE;
1905     egl_connection_t* const cnx = &gEGLImpl;
1906     if (cnx->dso && cnx->egl.eglDestroyStreamKHR) {
1907         result = cnx->egl.eglDestroyStreamKHR(dp->disp.dpy, stream);
1908     }
1909     return result;
1910 }
1911 
eglStreamAttribKHRImpl(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint value)1912 EGLBoolean eglStreamAttribKHRImpl(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
1913                                   EGLint value) {
1914     const egl_display_t* dp = validate_display(dpy);
1915     if (!dp) return EGL_FALSE;
1916 
1917     EGLBoolean result = EGL_FALSE;
1918     egl_connection_t* const cnx = &gEGLImpl;
1919     if (cnx->dso && cnx->egl.eglStreamAttribKHR) {
1920         result = cnx->egl.eglStreamAttribKHR(dp->disp.dpy, stream, attribute, value);
1921     }
1922     return result;
1923 }
1924 
eglQueryStreamKHRImpl(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint * value)1925 EGLBoolean eglQueryStreamKHRImpl(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
1926                                  EGLint* value) {
1927     const egl_display_t* dp = validate_display(dpy);
1928     if (!dp) return EGL_FALSE;
1929 
1930     EGLBoolean result = EGL_FALSE;
1931     egl_connection_t* const cnx = &gEGLImpl;
1932     if (cnx->dso && cnx->egl.eglQueryStreamKHR) {
1933         result = cnx->egl.eglQueryStreamKHR(dp->disp.dpy, stream, attribute, value);
1934     }
1935     return result;
1936 }
1937 
eglQueryStreamu64KHRImpl(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLuint64KHR * value)1938 EGLBoolean eglQueryStreamu64KHRImpl(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
1939                                     EGLuint64KHR* value) {
1940     const egl_display_t* dp = validate_display(dpy);
1941     if (!dp) return EGL_FALSE;
1942 
1943     EGLBoolean result = EGL_FALSE;
1944     egl_connection_t* const cnx = &gEGLImpl;
1945     if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) {
1946         result = cnx->egl.eglQueryStreamu64KHR(dp->disp.dpy, stream, attribute, value);
1947     }
1948     return result;
1949 }
1950 
eglQueryStreamTimeKHRImpl(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLTimeKHR * value)1951 EGLBoolean eglQueryStreamTimeKHRImpl(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
1952                                      EGLTimeKHR* value) {
1953     const egl_display_t* dp = validate_display(dpy);
1954     if (!dp) return EGL_FALSE;
1955 
1956     EGLBoolean result = EGL_FALSE;
1957     egl_connection_t* const cnx = &gEGLImpl;
1958     if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) {
1959         result = cnx->egl.eglQueryStreamTimeKHR(dp->disp.dpy, stream, attribute, value);
1960     }
1961     return result;
1962 }
1963 
eglCreateStreamProducerSurfaceKHRImpl(EGLDisplay dpy,EGLConfig config,EGLStreamKHR stream,const EGLint * attrib_list)1964 EGLSurface eglCreateStreamProducerSurfaceKHRImpl(EGLDisplay dpy, EGLConfig config,
1965                                                  EGLStreamKHR stream, const EGLint* attrib_list) {
1966     egl_display_t* dp = validate_display(dpy);
1967     if (!dp) return EGL_NO_SURFACE;
1968 
1969     egl_connection_t* const cnx = &gEGLImpl;
1970     if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
1971         EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(dp->disp.dpy, config,
1972                                                                         stream, attrib_list);
1973         if (surface != EGL_NO_SURFACE) {
1974             egl_surface_t* s = new egl_surface_t(dp, config, nullptr, surface,
1975                                                  EGL_GL_COLORSPACE_LINEAR_KHR, cnx);
1976             return s;
1977         }
1978     }
1979     return EGL_NO_SURFACE;
1980 }
1981 
eglStreamConsumerGLTextureExternalKHRImpl(EGLDisplay dpy,EGLStreamKHR stream)1982 EGLBoolean eglStreamConsumerGLTextureExternalKHRImpl(EGLDisplay dpy, EGLStreamKHR stream) {
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.eglStreamConsumerGLTextureExternalKHR) {
1989         result = cnx->egl.eglStreamConsumerGLTextureExternalKHR(dp->disp.dpy, stream);
1990     }
1991     return result;
1992 }
1993 
eglStreamConsumerAcquireKHRImpl(EGLDisplay dpy,EGLStreamKHR stream)1994 EGLBoolean eglStreamConsumerAcquireKHRImpl(EGLDisplay dpy, EGLStreamKHR stream) {
1995     const egl_display_t* dp = validate_display(dpy);
1996     if (!dp) return EGL_FALSE;
1997 
1998     EGLBoolean result = EGL_FALSE;
1999     egl_connection_t* const cnx = &gEGLImpl;
2000     if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) {
2001         result = cnx->egl.eglStreamConsumerAcquireKHR(dp->disp.dpy, stream);
2002     }
2003     return result;
2004 }
2005 
eglStreamConsumerReleaseKHRImpl(EGLDisplay dpy,EGLStreamKHR stream)2006 EGLBoolean eglStreamConsumerReleaseKHRImpl(EGLDisplay dpy, EGLStreamKHR stream) {
2007     const egl_display_t* dp = validate_display(dpy);
2008     if (!dp) return EGL_FALSE;
2009 
2010     EGLBoolean result = EGL_FALSE;
2011     egl_connection_t* const cnx = &gEGLImpl;
2012     if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) {
2013         result = cnx->egl.eglStreamConsumerReleaseKHR(dp->disp.dpy, stream);
2014     }
2015     return result;
2016 }
2017 
eglGetStreamFileDescriptorKHRImpl(EGLDisplay dpy,EGLStreamKHR stream)2018 EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHRImpl(EGLDisplay dpy, EGLStreamKHR stream) {
2019     const egl_display_t* dp = validate_display(dpy);
2020     if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR;
2021 
2022     EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR;
2023     egl_connection_t* const cnx = &gEGLImpl;
2024     if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) {
2025         result = cnx->egl.eglGetStreamFileDescriptorKHR(dpy, stream);
2026     }
2027     return result;
2028 }
2029 
eglCreateStreamFromFileDescriptorKHRImpl(EGLDisplay dpy,EGLNativeFileDescriptorKHR file_descriptor)2030 EGLStreamKHR eglCreateStreamFromFileDescriptorKHRImpl(EGLDisplay dpy,
2031                                                       EGLNativeFileDescriptorKHR file_descriptor) {
2032     const egl_display_t* dp = validate_display(dpy);
2033     if (!dp) return EGL_NO_STREAM_KHR;
2034 
2035     EGLStreamKHR result = EGL_NO_STREAM_KHR;
2036     egl_connection_t* const cnx = &gEGLImpl;
2037     if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) {
2038         result = cnx->egl.eglCreateStreamFromFileDescriptorKHR(dp->disp.dpy, file_descriptor);
2039     }
2040     return result;
2041 }
2042 
2043 // ----------------------------------------------------------------------------
2044 // EGL_EGLEXT_VERSION 15
2045 // ----------------------------------------------------------------------------
2046 
2047 // Need to template function type because return type is different
2048 template <typename ReturnType, typename FuncType>
eglWaitSyncTmpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags,FuncType eglWaitSyncFunc)2049 ReturnType eglWaitSyncTmpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags,
2050                            FuncType eglWaitSyncFunc) {
2051     const egl_display_t* dp = validate_display(dpy);
2052     if (!dp) return EGL_FALSE;
2053     ReturnType result = EGL_FALSE;
2054     egl_connection_t* const cnx = &gEGLImpl;
2055     if (cnx->dso && eglWaitSyncFunc) {
2056         result = eglWaitSyncFunc(dp->disp.dpy, sync, flags);
2057     }
2058     return result;
2059 }
2060 
2061 typedef EGLBoolean(EGLAPIENTRYP PFNEGLWAITSYNC)(EGLDisplay dpy, EGLSync sync, EGLint flags);
2062 
eglWaitSyncKHRImpl(EGLDisplay dpy,EGLSyncKHR sync,EGLint flags)2063 EGLint eglWaitSyncKHRImpl(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
2064     egl_connection_t* const cnx = &gEGLImpl;
2065     return eglWaitSyncTmpl<EGLint, PFNEGLWAITSYNCKHRPROC>(dpy, sync, flags,
2066                                                           cnx->egl.eglWaitSyncKHR);
2067 }
2068 
eglWaitSyncImpl(EGLDisplay dpy,EGLSync sync,EGLint flags)2069 EGLBoolean eglWaitSyncImpl(EGLDisplay dpy, EGLSync sync, EGLint flags) {
2070     egl_connection_t* const cnx = &gEGLImpl;
2071     if (cnx->driverVersion >= EGL_MAKE_VERSION(1, 5, 0)) {
2072         if (cnx->egl.eglWaitSync) {
2073             return eglWaitSyncTmpl<EGLBoolean, PFNEGLWAITSYNC>(dpy, sync, flags,
2074                                                                cnx->egl.eglWaitSync);
2075         }
2076         return setError(EGL_BAD_DISPLAY, (EGLint)EGL_FALSE);
2077     }
2078 
2079     return static_cast<EGLBoolean>(
2080             eglWaitSyncTmpl<EGLint, PFNEGLWAITSYNCKHRPROC>(dpy, sync, flags,
2081                                                            cnx->egl.eglWaitSyncKHR));
2082 }
2083 
2084 // ----------------------------------------------------------------------------
2085 // ANDROID extensions
2086 // ----------------------------------------------------------------------------
2087 
eglDupNativeFenceFDANDROIDImpl(EGLDisplay dpy,EGLSyncKHR sync)2088 EGLint eglDupNativeFenceFDANDROIDImpl(EGLDisplay dpy, EGLSyncKHR sync) {
2089     const egl_display_t* dp = validate_display(dpy);
2090     if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID;
2091 
2092     EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
2093     egl_connection_t* const cnx = &gEGLImpl;
2094     if (cnx->dso && cnx->egl.eglDupNativeFenceFDANDROID) {
2095         result = cnx->egl.eglDupNativeFenceFDANDROID(dp->disp.dpy, sync);
2096     }
2097     return result;
2098 }
2099 
eglPresentationTimeANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLnsecsANDROID time)2100 EGLBoolean eglPresentationTimeANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
2101                                           EGLnsecsANDROID time) {
2102     const egl_display_t* dp = validate_display(dpy);
2103     if (!dp) {
2104         return EGL_FALSE;
2105     }
2106 
2107     SurfaceRef _s(dp, surface);
2108     if (!_s.get()) {
2109         setError(EGL_BAD_SURFACE, EGL_FALSE);
2110         return EGL_FALSE;
2111     }
2112 
2113     egl_surface_t const* const s = get_surface(surface);
2114     native_window_set_buffers_timestamp(s->getNativeWindow(), time);
2115 
2116     return EGL_TRUE;
2117 }
2118 
eglGetNativeClientBufferANDROIDImpl(const AHardwareBuffer * buffer)2119 EGLClientBuffer eglGetNativeClientBufferANDROIDImpl(const AHardwareBuffer* buffer) {
2120     if (!buffer) return setError(EGL_BAD_PARAMETER, (EGLClientBuffer) nullptr);
2121     return const_cast<ANativeWindowBuffer*>(AHardwareBuffer_to_ANativeWindowBuffer(buffer));
2122 }
2123 
2124 // ----------------------------------------------------------------------------
2125 // NVIDIA extensions
2126 // ----------------------------------------------------------------------------
eglGetSystemTimeFrequencyNVImpl()2127 EGLuint64NV eglGetSystemTimeFrequencyNVImpl() {
2128     EGLuint64NV ret = 0;
2129     egl_connection_t* const cnx = &gEGLImpl;
2130 
2131     if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
2132         return cnx->egl.eglGetSystemTimeFrequencyNV();
2133     }
2134 
2135     return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
2136 }
2137 
eglGetSystemTimeNVImpl()2138 EGLuint64NV eglGetSystemTimeNVImpl() {
2139     EGLuint64NV ret = 0;
2140     egl_connection_t* const cnx = &gEGLImpl;
2141 
2142     if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
2143         return cnx->egl.eglGetSystemTimeNV();
2144     }
2145 
2146     return setErrorQuiet(EGL_BAD_DISPLAY, (EGLuint64NV)0);
2147 }
2148 
2149 // ----------------------------------------------------------------------------
2150 // Partial update extension
2151 // ----------------------------------------------------------------------------
eglSetDamageRegionKHRImpl(EGLDisplay dpy,EGLSurface surface,EGLint * rects,EGLint n_rects)2152 EGLBoolean eglSetDamageRegionKHRImpl(EGLDisplay dpy, EGLSurface surface, EGLint* rects,
2153                                      EGLint n_rects) {
2154     const egl_display_t* dp = validate_display(dpy);
2155     if (!dp) {
2156         setError(EGL_BAD_DISPLAY, EGL_FALSE);
2157         return EGL_FALSE;
2158     }
2159 
2160     SurfaceRef _s(dp, surface);
2161     if (!_s.get()) {
2162         setError(EGL_BAD_SURFACE, EGL_FALSE);
2163         return EGL_FALSE;
2164     }
2165 
2166     egl_surface_t const* const s = get_surface(surface);
2167     if (s->cnx->egl.eglSetDamageRegionKHR) {
2168         return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface, rects, n_rects);
2169     }
2170 
2171     return EGL_FALSE;
2172 }
2173 
eglGetNextFrameIdANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLuint64KHR * frameId)2174 EGLBoolean eglGetNextFrameIdANDROIDImpl(EGLDisplay dpy, EGLSurface surface, EGLuint64KHR* frameId) {
2175     const egl_display_t* dp = validate_display(dpy);
2176     if (!dp) {
2177         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2178     }
2179 
2180     if (!dp->haveExtension("EGL_ANDROID_get_frame_timestamps")) {
2181         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2182     }
2183 
2184     SurfaceRef _s(dp, surface);
2185     if (!_s.get()) {
2186         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2187     }
2188 
2189     egl_surface_t const* const s = get_surface(surface);
2190 
2191     if (!s->getNativeWindow()) {
2192         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2193     }
2194 
2195     uint64_t nextFrameId = 0;
2196     int ret = native_window_get_next_frame_id(s->getNativeWindow(), &nextFrameId);
2197 
2198     if (ret != 0) {
2199         // This should not happen. Return an error that is not in the spec
2200         // so it's obvious something is very wrong.
2201         ALOGE("eglGetNextFrameId: Unexpected error.");
2202         return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2203     }
2204 
2205     *frameId = nextFrameId;
2206     return EGL_TRUE;
2207 }
2208 
eglGetCompositorTimingANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values)2209 EGLBoolean eglGetCompositorTimingANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
2210                                              EGLint numTimestamps, const EGLint* names,
2211                                              EGLnsecsANDROID* values) {
2212     const egl_display_t* dp = validate_display(dpy);
2213     if (!dp) {
2214         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2215     }
2216 
2217     if (!dp->haveExtension("EGL_ANDROID_get_frame_timestamps")) {
2218         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2219     }
2220 
2221     SurfaceRef _s(dp, surface);
2222     if (!_s.get()) {
2223         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2224     }
2225 
2226     egl_surface_t const* const s = get_surface(surface);
2227 
2228     if (!s->getNativeWindow()) {
2229         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2230     }
2231 
2232     nsecs_t* compositeDeadline = nullptr;
2233     nsecs_t* compositeInterval = nullptr;
2234     nsecs_t* compositeToPresentLatency = nullptr;
2235 
2236     for (int i = 0; i < numTimestamps; i++) {
2237         switch (names[i]) {
2238             case EGL_COMPOSITE_DEADLINE_ANDROID:
2239                 compositeDeadline = &values[i];
2240                 break;
2241             case EGL_COMPOSITE_INTERVAL_ANDROID:
2242                 compositeInterval = &values[i];
2243                 break;
2244             case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2245                 compositeToPresentLatency = &values[i];
2246                 break;
2247             default:
2248                 return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2249         }
2250     }
2251 
2252     int ret = native_window_get_compositor_timing(s->getNativeWindow(), compositeDeadline,
2253                                                   compositeInterval, compositeToPresentLatency);
2254 
2255     switch (ret) {
2256         case 0:
2257             return EGL_TRUE;
2258         case -ENOSYS:
2259             return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2260         default:
2261             // This should not happen. Return an error that is not in the spec
2262             // so it's obvious something is very wrong.
2263             ALOGE("eglGetCompositorTiming: Unexpected error.");
2264             return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2265     }
2266 }
2267 
eglGetCompositorTimingSupportedANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLint name)2268 EGLBoolean eglGetCompositorTimingSupportedANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
2269                                                       EGLint name) {
2270     const egl_display_t* dp = validate_display(dpy);
2271     if (!dp) {
2272         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2273     }
2274 
2275     if (!dp->haveExtension("EGL_ANDROID_get_frame_timestamps")) {
2276         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2277     }
2278 
2279     SurfaceRef _s(dp, surface);
2280     if (!_s.get()) {
2281         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2282     }
2283 
2284     egl_surface_t const* const s = get_surface(surface);
2285 
2286     ANativeWindow* window = s->getNativeWindow();
2287     if (!window) {
2288         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2289     }
2290 
2291     switch (name) {
2292         case EGL_COMPOSITE_DEADLINE_ANDROID:
2293         case EGL_COMPOSITE_INTERVAL_ANDROID:
2294         case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2295             return EGL_TRUE;
2296         default:
2297             return EGL_FALSE;
2298     }
2299 }
2300 
eglGetFrameTimestampsANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values)2301 EGLBoolean eglGetFrameTimestampsANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
2302                                             EGLuint64KHR frameId, EGLint numTimestamps,
2303                                             const EGLint* timestamps, EGLnsecsANDROID* values) {
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     if (!s->getNativeWindow()) {
2321         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2322     }
2323 
2324     nsecs_t* requestedPresentTime = nullptr;
2325     nsecs_t* acquireTime = nullptr;
2326     nsecs_t* latchTime = nullptr;
2327     nsecs_t* firstRefreshStartTime = nullptr;
2328     nsecs_t* gpuCompositionDoneTime = nullptr;
2329     nsecs_t* lastRefreshStartTime = nullptr;
2330     nsecs_t* displayPresentTime = nullptr;
2331     nsecs_t* dequeueReadyTime = nullptr;
2332     nsecs_t* releaseTime = nullptr;
2333 
2334     for (int i = 0; i < numTimestamps; i++) {
2335         switch (timestamps[i]) {
2336             case EGL_REQUESTED_PRESENT_TIME_ANDROID:
2337                 requestedPresentTime = &values[i];
2338                 break;
2339             case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2340                 acquireTime = &values[i];
2341                 break;
2342             case EGL_COMPOSITION_LATCH_TIME_ANDROID:
2343                 latchTime = &values[i];
2344                 break;
2345             case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
2346                 firstRefreshStartTime = &values[i];
2347                 break;
2348             case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
2349                 lastRefreshStartTime = &values[i];
2350                 break;
2351             case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
2352                 gpuCompositionDoneTime = &values[i];
2353                 break;
2354             case EGL_DISPLAY_PRESENT_TIME_ANDROID:
2355                 displayPresentTime = &values[i];
2356                 break;
2357             case EGL_DEQUEUE_READY_TIME_ANDROID:
2358                 dequeueReadyTime = &values[i];
2359                 break;
2360             case EGL_READS_DONE_TIME_ANDROID:
2361                 releaseTime = &values[i];
2362                 break;
2363             default:
2364                 return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2365         }
2366     }
2367 
2368     int ret =
2369             native_window_get_frame_timestamps(s->getNativeWindow(), frameId, requestedPresentTime,
2370                                                acquireTime, latchTime, firstRefreshStartTime,
2371                                                lastRefreshStartTime, gpuCompositionDoneTime,
2372                                                displayPresentTime, dequeueReadyTime, releaseTime);
2373 
2374     switch (ret) {
2375         case 0:
2376             return EGL_TRUE;
2377         case -ENOENT:
2378             return setError(EGL_BAD_ACCESS, (EGLBoolean)EGL_FALSE);
2379         case -ENOSYS:
2380             return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2381         case -EINVAL:
2382             return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
2383         default:
2384             // This should not happen. Return an error that is not in the spec
2385             // so it's obvious something is very wrong.
2386             ALOGE("eglGetFrameTimestamps: Unexpected error.");
2387             return setError(EGL_NOT_INITIALIZED, (EGLBoolean)EGL_FALSE);
2388     }
2389 }
2390 
eglGetFrameTimestampSupportedANDROIDImpl(EGLDisplay dpy,EGLSurface surface,EGLint timestamp)2391 EGLBoolean eglGetFrameTimestampSupportedANDROIDImpl(EGLDisplay dpy, EGLSurface surface,
2392                                                     EGLint timestamp) {
2393     const egl_display_t* dp = validate_display(dpy);
2394     if (!dp) {
2395         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2396     }
2397 
2398     if (!dp->haveExtension("EGL_ANDROID_get_frame_timestamps")) {
2399         return setError(EGL_BAD_DISPLAY, (EGLBoolean)EGL_FALSE);
2400     }
2401 
2402     SurfaceRef _s(dp, surface);
2403     if (!_s.get()) {
2404         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2405     }
2406 
2407     egl_surface_t const* const s = get_surface(surface);
2408 
2409     ANativeWindow* window = s->getNativeWindow();
2410     if (!window) {
2411         return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
2412     }
2413 
2414     switch (timestamp) {
2415         case EGL_COMPOSITE_DEADLINE_ANDROID:
2416         case EGL_COMPOSITE_INTERVAL_ANDROID:
2417         case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
2418         case EGL_REQUESTED_PRESENT_TIME_ANDROID:
2419         case EGL_RENDERING_COMPLETE_TIME_ANDROID:
2420         case EGL_COMPOSITION_LATCH_TIME_ANDROID:
2421         case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
2422         case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
2423         case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
2424         case EGL_DEQUEUE_READY_TIME_ANDROID:
2425         case EGL_READS_DONE_TIME_ANDROID:
2426             return EGL_TRUE;
2427         case EGL_DISPLAY_PRESENT_TIME_ANDROID: {
2428             int value = 0;
2429             window->query(window, NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT, &value);
2430             return value == 0 ? EGL_FALSE : EGL_TRUE;
2431         }
2432         default:
2433             return EGL_FALSE;
2434     }
2435 }
2436 
glGetStringImpl(GLenum name)2437 const GLubyte* glGetStringImpl(GLenum name) {
2438     const GLubyte* ret = egl_get_string_for_current_context(name);
2439     if (ret == NULL) {
2440         gl_hooks_t::gl_t const* const _c = &getGlThreadSpecific()->gl;
2441         if (_c) ret = _c->glGetString(name);
2442     }
2443     return ret;
2444 }
2445 
glGetStringiImpl(GLenum name,GLuint index)2446 const GLubyte* glGetStringiImpl(GLenum name, GLuint index) {
2447     const GLubyte* ret = egl_get_string_for_current_context(name, index);
2448     if (ret == NULL) {
2449         gl_hooks_t::gl_t const* const _c = &getGlThreadSpecific()->gl;
2450         if (_c) ret = _c->glGetStringi(name, index);
2451     }
2452     return ret;
2453 }
2454 
glGetBooleanvImpl(GLenum pname,GLboolean * data)2455 void glGetBooleanvImpl(GLenum pname, GLboolean* data) {
2456     if (pname == GL_NUM_EXTENSIONS) {
2457         int num_exts = egl_get_num_extensions_for_current_context();
2458         if (num_exts >= 0) {
2459             *data = num_exts > 0 ? GL_TRUE : GL_FALSE;
2460             return;
2461         }
2462     }
2463 
2464     gl_hooks_t::gl_t const* const _c = &getGlThreadSpecific()->gl;
2465     if (_c) _c->glGetBooleanv(pname, data);
2466 }
2467 
glGetFloatvImpl(GLenum pname,GLfloat * data)2468 void glGetFloatvImpl(GLenum pname, GLfloat* data) {
2469     if (pname == GL_NUM_EXTENSIONS) {
2470         int num_exts = egl_get_num_extensions_for_current_context();
2471         if (num_exts >= 0) {
2472             *data = (GLfloat)num_exts;
2473             return;
2474         }
2475     }
2476 
2477     gl_hooks_t::gl_t const* const _c = &getGlThreadSpecific()->gl;
2478     if (_c) _c->glGetFloatv(pname, data);
2479 }
2480 
glGetIntegervImpl(GLenum pname,GLint * data)2481 void glGetIntegervImpl(GLenum pname, GLint* data) {
2482     if (pname == GL_NUM_EXTENSIONS) {
2483         int num_exts = egl_get_num_extensions_for_current_context();
2484         if (num_exts >= 0) {
2485             *data = (GLint)num_exts;
2486             return;
2487         }
2488     }
2489 
2490     gl_hooks_t::gl_t const* const _c = &getGlThreadSpecific()->gl;
2491     if (_c) _c->glGetIntegerv(pname, data);
2492 }
2493 
glGetInteger64vImpl(GLenum pname,GLint64 * data)2494 void glGetInteger64vImpl(GLenum pname, GLint64* data) {
2495     if (pname == GL_NUM_EXTENSIONS) {
2496         int num_exts = egl_get_num_extensions_for_current_context();
2497         if (num_exts >= 0) {
2498             *data = (GLint64)num_exts;
2499             return;
2500         }
2501     }
2502 
2503     gl_hooks_t::gl_t const* const _c = &getGlThreadSpecific()->gl;
2504     if (_c) _c->glGetInteger64v(pname, data);
2505 }
2506 
2507 struct implementation_map_t {
2508     const char* name;
2509     EGLFuncPointer address;
2510 };
2511 
2512 // clang-format off
2513 static const implementation_map_t sPlatformImplMap[] = {
2514     { "eglGetDisplay", (EGLFuncPointer)&eglGetDisplayImpl },
2515     { "eglGetPlatformDisplay", (EGLFuncPointer)&eglGetPlatformDisplayImpl },
2516     { "eglInitialize", (EGLFuncPointer)&eglInitializeImpl },
2517     { "eglTerminate", (EGLFuncPointer)&eglTerminateImpl },
2518     { "eglGetConfigs", (EGLFuncPointer)&eglGetConfigsImpl },
2519     { "eglChooseConfig", (EGLFuncPointer)&eglChooseConfigImpl },
2520     { "eglGetConfigAttrib", (EGLFuncPointer)&eglGetConfigAttribImpl },
2521     { "eglCreateWindowSurface", (EGLFuncPointer)&eglCreateWindowSurfaceImpl },
2522     { "eglCreatePixmapSurface", (EGLFuncPointer)&eglCreatePixmapSurfaceImpl },
2523     { "eglCreatePlatformWindowSurface", (EGLFuncPointer)&eglCreatePlatformWindowSurfaceImpl },
2524     { "eglCreatePlatformPixmapSurface", (EGLFuncPointer)&eglCreatePlatformPixmapSurfaceImpl },
2525     { "eglCreatePbufferSurface", (EGLFuncPointer)&eglCreatePbufferSurfaceImpl },
2526     { "eglDestroySurface", (EGLFuncPointer)&eglDestroySurfaceImpl },
2527     { "eglQuerySurface", (EGLFuncPointer)&eglQuerySurfaceImpl },
2528     { "eglBeginFrame", (EGLFuncPointer)&eglBeginFrameImpl },
2529     { "eglCreateContext", (EGLFuncPointer)&eglCreateContextImpl },
2530     { "eglDestroyContext", (EGLFuncPointer)&eglDestroyContextImpl },
2531     { "eglMakeCurrent", (EGLFuncPointer)&eglMakeCurrentImpl },
2532     { "eglQueryContext", (EGLFuncPointer)&eglQueryContextImpl },
2533     { "eglGetCurrentContext", (EGLFuncPointer)&eglGetCurrentContextImpl },
2534     { "eglGetCurrentSurface", (EGLFuncPointer)&eglGetCurrentSurfaceImpl },
2535     { "eglGetCurrentDisplay", (EGLFuncPointer)&eglGetCurrentDisplayImpl },
2536     { "eglWaitGL", (EGLFuncPointer)&eglWaitGLImpl },
2537     { "eglWaitNative", (EGLFuncPointer)&eglWaitNativeImpl },
2538     { "eglGetError", (EGLFuncPointer)&eglGetErrorImpl },
2539     { "eglSwapBuffersWithDamageKHR", (EGLFuncPointer)&eglSwapBuffersWithDamageKHRImpl },
2540     { "eglGetProcAddress", (EGLFuncPointer)&eglGetProcAddressImpl },
2541     { "eglSwapBuffers", (EGLFuncPointer)&eglSwapBuffersImpl },
2542     { "eglCopyBuffers", (EGLFuncPointer)&eglCopyBuffersImpl },
2543     { "eglQueryString", (EGLFuncPointer)&eglQueryStringImpl },
2544     { "eglQueryStringImplementationANDROID", (EGLFuncPointer)&eglQueryStringImplementationANDROIDImpl },
2545     { "eglSurfaceAttrib", (EGLFuncPointer)&eglSurfaceAttribImpl },
2546     { "eglBindTexImage", (EGLFuncPointer)&eglBindTexImageImpl },
2547     { "eglReleaseTexImage", (EGLFuncPointer)&eglReleaseTexImageImpl },
2548     { "eglSwapInterval", (EGLFuncPointer)&eglSwapIntervalImpl },
2549     { "eglWaitClient", (EGLFuncPointer)&eglWaitClientImpl },
2550     { "eglBindAPI", (EGLFuncPointer)&eglBindAPIImpl },
2551     { "eglQueryAPI", (EGLFuncPointer)&eglQueryAPIImpl },
2552     { "eglReleaseThread", (EGLFuncPointer)&eglReleaseThreadImpl },
2553     { "eglCreatePbufferFromClientBuffer", (EGLFuncPointer)&eglCreatePbufferFromClientBufferImpl },
2554     { "eglLockSurfaceKHR", (EGLFuncPointer)&eglLockSurfaceKHRImpl },
2555     { "eglUnlockSurfaceKHR", (EGLFuncPointer)&eglUnlockSurfaceKHRImpl },
2556     { "eglCreateImageKHR", (EGLFuncPointer)&eglCreateImageKHRImpl },
2557     { "eglDestroyImageKHR", (EGLFuncPointer)&eglDestroyImageKHRImpl },
2558     { "eglCreateImage", (EGLFuncPointer)&eglCreateImageImpl },
2559     { "eglDestroyImage", (EGLFuncPointer)&eglDestroyImageImpl },
2560     { "eglCreateSync", (EGLFuncPointer)&eglCreateSyncImpl },
2561     { "eglDestroySync", (EGLFuncPointer)&eglDestroySyncImpl },
2562     { "eglClientWaitSync", (EGLFuncPointer)&eglClientWaitSyncImpl },
2563     { "eglGetSyncAttrib", (EGLFuncPointer)&eglGetSyncAttribImpl },
2564     { "eglCreateSyncKHR", (EGLFuncPointer)&eglCreateSyncKHRImpl },
2565     { "eglDestroySyncKHR", (EGLFuncPointer)&eglDestroySyncKHRImpl },
2566     { "eglSignalSyncKHR", (EGLFuncPointer)&eglSignalSyncKHRImpl },
2567     { "eglClientWaitSyncKHR", (EGLFuncPointer)&eglClientWaitSyncKHRImpl },
2568     { "eglGetSyncAttribKHR", (EGLFuncPointer)&eglGetSyncAttribKHRImpl },
2569     { "eglCreateStreamKHR", (EGLFuncPointer)&eglCreateStreamKHRImpl },
2570     { "eglDestroyStreamKHR", (EGLFuncPointer)&eglDestroyStreamKHRImpl },
2571     { "eglStreamAttribKHR", (EGLFuncPointer)&eglStreamAttribKHRImpl },
2572     { "eglQueryStreamKHR", (EGLFuncPointer)&eglQueryStreamKHRImpl },
2573     { "eglQueryStreamu64KHR", (EGLFuncPointer)&eglQueryStreamu64KHRImpl },
2574     { "eglQueryStreamTimeKHR", (EGLFuncPointer)&eglQueryStreamTimeKHRImpl },
2575     { "eglCreateStreamProducerSurfaceKHR", (EGLFuncPointer)&eglCreateStreamProducerSurfaceKHRImpl },
2576     { "eglStreamConsumerGLTextureExternalKHR", (EGLFuncPointer)&eglStreamConsumerGLTextureExternalKHRImpl },
2577     { "eglStreamConsumerAcquireKHR", (EGLFuncPointer)&eglStreamConsumerAcquireKHRImpl },
2578     { "eglStreamConsumerReleaseKHR", (EGLFuncPointer)&eglStreamConsumerReleaseKHRImpl },
2579     { "eglGetStreamFileDescriptorKHR", (EGLFuncPointer)&eglGetStreamFileDescriptorKHRImpl },
2580     { "eglCreateStreamFromFileDescriptorKHR", (EGLFuncPointer)&eglCreateStreamFromFileDescriptorKHRImpl },
2581     { "eglWaitSync", (EGLFuncPointer)&eglWaitSyncImpl },
2582     { "eglWaitSyncKHR", (EGLFuncPointer)&eglWaitSyncKHRImpl },
2583     { "eglDupNativeFenceFDANDROID", (EGLFuncPointer)&eglDupNativeFenceFDANDROIDImpl },
2584     { "eglPresentationTimeANDROID", (EGLFuncPointer)&eglPresentationTimeANDROIDImpl },
2585     { "eglGetNativeClientBufferANDROID", (EGLFuncPointer)&eglGetNativeClientBufferANDROIDImpl },
2586     { "eglGetSystemTimeFrequencyNV", (EGLFuncPointer)&eglGetSystemTimeFrequencyNVImpl },
2587     { "eglGetSystemTimeNV", (EGLFuncPointer)&eglGetSystemTimeNVImpl },
2588     { "eglSetDamageRegionKHR", (EGLFuncPointer)&eglSetDamageRegionKHRImpl },
2589     { "eglGetNextFrameIdANDROID", (EGLFuncPointer)&eglGetNextFrameIdANDROIDImpl },
2590     { "eglGetCompositorTimingANDROID", (EGLFuncPointer)&eglGetCompositorTimingANDROIDImpl },
2591     { "eglGetCompositorTimingSupportedANDROID", (EGLFuncPointer)&eglGetCompositorTimingSupportedANDROIDImpl },
2592     { "eglGetFrameTimestampsANDROID", (EGLFuncPointer)&eglGetFrameTimestampsANDROIDImpl },
2593     { "eglGetFrameTimestampSupportedANDROID", (EGLFuncPointer)&eglGetFrameTimestampSupportedANDROIDImpl },
2594     { "glGetString", (EGLFuncPointer)&glGetStringImpl },
2595     { "glGetStringi", (EGLFuncPointer)&glGetStringiImpl },
2596     { "glGetBooleanv", (EGLFuncPointer)&glGetBooleanvImpl },
2597     { "glGetFloatv", (EGLFuncPointer)&glGetFloatvImpl },
2598     { "glGetIntegerv", (EGLFuncPointer)&glGetIntegervImpl },
2599     { "glGetInteger64v", (EGLFuncPointer)&glGetInteger64vImpl },
2600 };
2601 // clang-format on
2602 
FindPlatformImplAddr(const char * name)2603 EGLFuncPointer FindPlatformImplAddr(const char* name) {
2604     static const bool DEBUG = false;
2605 
2606     if (name == nullptr) {
2607         ALOGV("FindPlatformImplAddr called with null name");
2608         return nullptr;
2609     }
2610 
2611     for (int i = 0; i < NELEM(sPlatformImplMap); i++) {
2612         if (sPlatformImplMap[i].name == nullptr) {
2613             ALOGV("FindPlatformImplAddr found nullptr for sPlatformImplMap[%i].name (%s)", i, name);
2614             return nullptr;
2615         }
2616         if (!strcmp(name, sPlatformImplMap[i].name)) {
2617             ALOGV("FindPlatformImplAddr found %llu for sPlatformImplMap[%i].address (%s)",
2618                   (unsigned long long)sPlatformImplMap[i].address, i, name);
2619             return sPlatformImplMap[i].address;
2620         }
2621     }
2622 
2623     ALOGV("FindPlatformImplAddr did not find an entry for %s", name);
2624     return nullptr;
2625 }
2626 } // namespace android
2627