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