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