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