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