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