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