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