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