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