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