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