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 <dlfcn.h> 20 #include <ctype.h> 21 #include <stdlib.h> 22 #include <string.h> 23 24 #include <hardware/gralloc.h> 25 #include <system/window.h> 26 27 #include <EGL/egl.h> 28 #include <EGL/eglext.h> 29 30 #include <cutils/log.h> 31 #include <cutils/atomic.h> 32 #include <cutils/compiler.h> 33 #include <cutils/properties.h> 34 #include <cutils/memory.h> 35 36 #include <ui/GraphicBuffer.h> 37 38 #include <utils/KeyedVector.h> 39 #include <utils/SortedVector.h> 40 #include <utils/String8.h> 41 #include <utils/Trace.h> 42 43 #include "../egl_impl.h" 44 #include "../hooks.h" 45 46 #include "egl_display.h" 47 #include "egl_object.h" 48 #include "egl_tls.h" 49 #include "egldefs.h" 50 51 using namespace android; 52 53 // This extension has not been ratified yet, so can't be shipped. 54 // Implementation is incomplete and untested. 55 #define ENABLE_EGL_KHR_GL_COLORSPACE 0 56 57 #define ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS 0 58 59 // ---------------------------------------------------------------------------- 60 61 namespace android { 62 63 struct extention_map_t { 64 const char* name; 65 __eglMustCastToProperFunctionPointerType address; 66 }; 67 68 /* 69 * This is the list of EGL extensions exposed to applications. 70 * 71 * Some of them (gBuiltinExtensionString) are implemented entirely in this EGL 72 * wrapper and are always available. 73 * 74 * The rest (gExtensionString) depend on support in the EGL driver, and are 75 * only available if the driver supports them. However, some of these must be 76 * supported because they are used by the Android system itself; these are 77 * listed as mandatory below and are required by the CDD. The system *assumes* 78 * the mandatory extensions are present and may not function properly if some 79 * are missing. 80 * 81 * NOTE: Both strings MUST have a single space as the last character. 82 */ 83 extern char const * const gBuiltinExtensionString = 84 "EGL_KHR_get_all_proc_addresses " 85 "EGL_ANDROID_presentation_time " 86 "EGL_KHR_swap_buffers_with_damage " 87 "EGL_ANDROID_create_native_client_buffer " 88 "EGL_ANDROID_front_buffer_auto_refresh " 89 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS 90 "EGL_ANDROID_get_frame_timestamps " 91 #endif 92 ; 93 extern char const * const gExtensionString = 94 "EGL_KHR_image " // mandatory 95 "EGL_KHR_image_base " // mandatory 96 "EGL_KHR_image_pixmap " 97 "EGL_KHR_lock_surface " 98 #if (ENABLE_EGL_KHR_GL_COLORSPACE != 0) 99 "EGL_KHR_gl_colorspace " 100 #endif 101 "EGL_KHR_gl_texture_2D_image " 102 "EGL_KHR_gl_texture_3D_image " 103 "EGL_KHR_gl_texture_cubemap_image " 104 "EGL_KHR_gl_renderbuffer_image " 105 "EGL_KHR_reusable_sync " 106 "EGL_KHR_fence_sync " 107 "EGL_KHR_create_context " 108 "EGL_KHR_config_attribs " 109 "EGL_KHR_surfaceless_context " 110 "EGL_KHR_stream " 111 "EGL_KHR_stream_fifo " 112 "EGL_KHR_stream_producer_eglsurface " 113 "EGL_KHR_stream_consumer_gltexture " 114 "EGL_KHR_stream_cross_process_fd " 115 "EGL_EXT_create_context_robustness " 116 "EGL_NV_system_time " 117 "EGL_ANDROID_image_native_buffer " // mandatory 118 "EGL_KHR_wait_sync " // strongly recommended 119 "EGL_ANDROID_recordable " // mandatory 120 "EGL_KHR_partial_update " // strongly recommended 121 "EGL_EXT_buffer_age " // strongly recommended with partial_update 122 "EGL_KHR_create_context_no_error " 123 "EGL_KHR_mutable_render_buffer " 124 "EGL_EXT_yuv_surface " 125 "EGL_EXT_protected_content " 126 ; 127 128 // extensions not exposed to applications but used by the ANDROID system 129 // "EGL_ANDROID_blob_cache " // strongly recommended 130 // "EGL_IMG_hibernate_process " // optional 131 // "EGL_ANDROID_native_fence_sync " // strongly recommended 132 // "EGL_ANDROID_framebuffer_target " // mandatory for HWC 1.1 133 // "EGL_ANDROID_image_crop " // optional 134 135 /* 136 * EGL Extensions entry-points exposed to 3rd party applications 137 * (keep in sync with gExtensionString above) 138 * 139 */ 140 static const extention_map_t sExtensionMap[] = { 141 // EGL_KHR_lock_surface 142 { "eglLockSurfaceKHR", 143 (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR }, 144 { "eglUnlockSurfaceKHR", 145 (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR }, 146 147 // EGL_KHR_image, EGL_KHR_image_base 148 { "eglCreateImageKHR", 149 (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR }, 150 { "eglDestroyImageKHR", 151 (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 152 153 // EGL_KHR_reusable_sync, EGL_KHR_fence_sync 154 { "eglCreateSyncKHR", 155 (__eglMustCastToProperFunctionPointerType)&eglCreateSyncKHR }, 156 { "eglDestroySyncKHR", 157 (__eglMustCastToProperFunctionPointerType)&eglDestroySyncKHR }, 158 { "eglClientWaitSyncKHR", 159 (__eglMustCastToProperFunctionPointerType)&eglClientWaitSyncKHR }, 160 { "eglSignalSyncKHR", 161 (__eglMustCastToProperFunctionPointerType)&eglSignalSyncKHR }, 162 { "eglGetSyncAttribKHR", 163 (__eglMustCastToProperFunctionPointerType)&eglGetSyncAttribKHR }, 164 165 // EGL_NV_system_time 166 { "eglGetSystemTimeFrequencyNV", 167 (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV }, 168 { "eglGetSystemTimeNV", 169 (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV }, 170 171 // EGL_KHR_wait_sync 172 { "eglWaitSyncKHR", 173 (__eglMustCastToProperFunctionPointerType)&eglWaitSyncKHR }, 174 175 // EGL_ANDROID_presentation_time 176 { "eglPresentationTimeANDROID", 177 (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID }, 178 179 // EGL_KHR_swap_buffers_with_damage 180 { "eglSwapBuffersWithDamageKHR", 181 (__eglMustCastToProperFunctionPointerType)&eglSwapBuffersWithDamageKHR }, 182 183 // EGL_ANDROID_native_client_buffer 184 { "eglCreateNativeClientBufferANDROID", 185 (__eglMustCastToProperFunctionPointerType)&eglCreateNativeClientBufferANDROID }, 186 187 // EGL_KHR_partial_update 188 { "eglSetDamageRegionKHR", 189 (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR }, 190 191 { "eglCreateStreamKHR", 192 (__eglMustCastToProperFunctionPointerType)&eglCreateStreamKHR }, 193 { "eglDestroyStreamKHR", 194 (__eglMustCastToProperFunctionPointerType)&eglDestroyStreamKHR }, 195 { "eglStreamAttribKHR", 196 (__eglMustCastToProperFunctionPointerType)&eglStreamAttribKHR }, 197 { "eglQueryStreamKHR", 198 (__eglMustCastToProperFunctionPointerType)&eglQueryStreamKHR }, 199 { "eglQueryStreamu64KHR", 200 (__eglMustCastToProperFunctionPointerType)&eglQueryStreamu64KHR }, 201 { "eglQueryStreamTimeKHR", 202 (__eglMustCastToProperFunctionPointerType)&eglQueryStreamTimeKHR }, 203 { "eglCreateStreamProducerSurfaceKHR", 204 (__eglMustCastToProperFunctionPointerType)&eglCreateStreamProducerSurfaceKHR }, 205 { "eglStreamConsumerGLTextureExternalKHR", 206 (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerGLTextureExternalKHR }, 207 { "eglStreamConsumerAcquireKHR", 208 (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerAcquireKHR }, 209 { "eglStreamConsumerReleaseKHR", 210 (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerReleaseKHR }, 211 { "eglGetStreamFileDescriptorKHR", 212 (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR }, 213 { "eglCreateStreamFromFileDescriptorKHR", 214 (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR }, 215 216 // EGL_ANDROID_get_frame_timestamps 217 { "eglGetFrameTimestampsANDROID", 218 (__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampsANDROID }, 219 { "eglQueryTimestampSupportedANDROID", 220 (__eglMustCastToProperFunctionPointerType)&eglQueryTimestampSupportedANDROID }, 221 }; 222 223 /* 224 * These extensions entry-points should not be exposed to applications. 225 * They're used internally by the Android EGL layer. 226 */ 227 #define FILTER_EXTENSIONS(procname) \ 228 (!strcmp((procname), "eglSetBlobCacheFuncsANDROID") || \ 229 !strcmp((procname), "eglHibernateProcessIMG") || \ 230 !strcmp((procname), "eglAwakenProcessIMG") || \ 231 !strcmp((procname), "eglDupNativeFenceFDANDROID")) 232 233 234 235 // accesses protected by sExtensionMapMutex 236 static DefaultKeyedVector<String8, __eglMustCastToProperFunctionPointerType> sGLExtentionMap; 237 static int sGLExtentionSlot = 0; 238 static pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER; 239 240 static void(*findProcAddress(const char* name, 241 const extention_map_t* map, size_t n))() { 242 for (uint32_t i=0 ; i<n ; i++) { 243 if (!strcmp(name, map[i].name)) { 244 return map[i].address; 245 } 246 } 247 return NULL; 248 } 249 250 // ---------------------------------------------------------------------------- 251 252 extern void setGLHooksThreadSpecific(gl_hooks_t const *value); 253 extern EGLBoolean egl_init_drivers(); 254 extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS]; 255 extern gl_hooks_t gHooksTrace; 256 257 } // namespace android; 258 259 260 // ---------------------------------------------------------------------------- 261 262 static inline void clearError() { egl_tls_t::clearError(); } 263 static inline EGLContext getContext() { return egl_tls_t::getContext(); } 264 265 // ---------------------------------------------------------------------------- 266 267 EGLDisplay eglGetDisplay(EGLNativeDisplayType display) 268 { 269 clearError(); 270 271 uintptr_t index = reinterpret_cast<uintptr_t>(display); 272 if (index >= NUM_DISPLAYS) { 273 return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY); 274 } 275 276 if (egl_init_drivers() == EGL_FALSE) { 277 return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY); 278 } 279 280 EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display); 281 return dpy; 282 } 283 284 // ---------------------------------------------------------------------------- 285 // Initialization 286 // ---------------------------------------------------------------------------- 287 288 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 289 { 290 clearError(); 291 292 egl_display_ptr dp = get_display(dpy); 293 if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); 294 295 EGLBoolean res = dp->initialize(major, minor); 296 297 return res; 298 } 299 300 EGLBoolean eglTerminate(EGLDisplay dpy) 301 { 302 // NOTE: don't unload the drivers b/c some APIs can be called 303 // after eglTerminate() has been called. eglTerminate() only 304 // terminates an EGLDisplay, not a EGL itself. 305 306 clearError(); 307 308 egl_display_ptr dp = get_display(dpy); 309 if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); 310 311 EGLBoolean res = dp->terminate(); 312 313 return res; 314 } 315 316 // ---------------------------------------------------------------------------- 317 // configuration 318 // ---------------------------------------------------------------------------- 319 320 EGLBoolean eglGetConfigs( EGLDisplay dpy, 321 EGLConfig *configs, 322 EGLint config_size, EGLint *num_config) 323 { 324 clearError(); 325 326 const egl_display_ptr dp = validate_display(dpy); 327 if (!dp) return EGL_FALSE; 328 329 if (num_config==0) { 330 return setError(EGL_BAD_PARAMETER, EGL_FALSE); 331 } 332 333 EGLBoolean res = EGL_FALSE; 334 *num_config = 0; 335 336 egl_connection_t* const cnx = &gEGLImpl; 337 if (cnx->dso) { 338 res = cnx->egl.eglGetConfigs( 339 dp->disp.dpy, configs, config_size, num_config); 340 } 341 342 return res; 343 } 344 345 EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, 346 EGLConfig *configs, EGLint config_size, 347 EGLint *num_config) 348 { 349 clearError(); 350 351 const egl_display_ptr dp = validate_display(dpy); 352 if (!dp) return EGL_FALSE; 353 354 if (num_config==0) { 355 return setError(EGL_BAD_PARAMETER, EGL_FALSE); 356 } 357 358 EGLBoolean res = EGL_FALSE; 359 *num_config = 0; 360 361 egl_connection_t* const cnx = &gEGLImpl; 362 if (cnx->dso) { 363 if (attrib_list) { 364 char value[PROPERTY_VALUE_MAX]; 365 property_get("debug.egl.force_msaa", value, "false"); 366 367 if (!strcmp(value, "true")) { 368 size_t attribCount = 0; 369 EGLint attrib = attrib_list[0]; 370 371 // Only enable MSAA if the context is OpenGL ES 2.0 and 372 // if no caveat is requested 373 const EGLint *attribRendererable = NULL; 374 const EGLint *attribCaveat = NULL; 375 376 // Count the number of attributes and look for 377 // EGL_RENDERABLE_TYPE and EGL_CONFIG_CAVEAT 378 while (attrib != EGL_NONE) { 379 attrib = attrib_list[attribCount]; 380 switch (attrib) { 381 case EGL_RENDERABLE_TYPE: 382 attribRendererable = &attrib_list[attribCount]; 383 break; 384 case EGL_CONFIG_CAVEAT: 385 attribCaveat = &attrib_list[attribCount]; 386 break; 387 } 388 attribCount++; 389 } 390 391 if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT && 392 (!attribCaveat || attribCaveat[1] != EGL_NONE)) { 393 394 // Insert 2 extra attributes to force-enable MSAA 4x 395 EGLint aaAttribs[attribCount + 4]; 396 aaAttribs[0] = EGL_SAMPLE_BUFFERS; 397 aaAttribs[1] = 1; 398 aaAttribs[2] = EGL_SAMPLES; 399 aaAttribs[3] = 4; 400 401 memcpy(&aaAttribs[4], attrib_list, attribCount * sizeof(EGLint)); 402 403 EGLint numConfigAA; 404 EGLBoolean resAA = cnx->egl.eglChooseConfig( 405 dp->disp.dpy, aaAttribs, configs, config_size, &numConfigAA); 406 407 if (resAA == EGL_TRUE && numConfigAA > 0) { 408 ALOGD("Enabling MSAA 4x"); 409 *num_config = numConfigAA; 410 return resAA; 411 } 412 } 413 } 414 } 415 416 res = cnx->egl.eglChooseConfig( 417 dp->disp.dpy, attrib_list, configs, config_size, num_config); 418 } 419 return res; 420 } 421 422 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, 423 EGLint attribute, EGLint *value) 424 { 425 clearError(); 426 427 egl_connection_t* cnx = NULL; 428 const egl_display_ptr dp = validate_display_connection(dpy, cnx); 429 if (!dp) return EGL_FALSE; 430 431 return cnx->egl.eglGetConfigAttrib( 432 dp->disp.dpy, config, attribute, value); 433 } 434 435 // ---------------------------------------------------------------------------- 436 // surfaces 437 // ---------------------------------------------------------------------------- 438 439 // The EGL_KHR_gl_colorspace spec hasn't been ratified yet, so these haven't 440 // been added to the Khronos egl.h. 441 #define EGL_GL_COLORSPACE_KHR EGL_VG_COLORSPACE 442 #define EGL_GL_COLORSPACE_SRGB_KHR EGL_VG_COLORSPACE_sRGB 443 #define EGL_GL_COLORSPACE_LINEAR_KHR EGL_VG_COLORSPACE_LINEAR 444 445 // Turn linear formats into corresponding sRGB formats when colorspace is 446 // EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear 447 // formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where 448 // the modification isn't possible, the original dataSpace is returned. 449 static android_dataspace modifyBufferDataspace( android_dataspace dataSpace, 450 EGLint colorspace) { 451 if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) { 452 return HAL_DATASPACE_SRGB_LINEAR; 453 } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) { 454 return HAL_DATASPACE_SRGB; 455 } 456 return dataSpace; 457 } 458 459 EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, 460 NativeWindowType window, 461 const EGLint *attrib_list) 462 { 463 clearError(); 464 465 egl_connection_t* cnx = NULL; 466 egl_display_ptr dp = validate_display_connection(dpy, cnx); 467 if (dp) { 468 EGLDisplay iDpy = dp->disp.dpy; 469 470 int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); 471 if (result != OK) { 472 ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) " 473 "failed (%#x) (already connected to another API?)", 474 window, result); 475 return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); 476 } 477 478 // Set the native window's buffers format to match what this config requests. 479 // Whether to use sRGB gamma is not part of the EGLconfig, but is part 480 // of our native format. So if sRGB gamma is requested, we have to 481 // modify the EGLconfig's format before setting the native window's 482 // format. 483 484 // by default, just pick RGBA_8888 485 EGLint format = HAL_PIXEL_FORMAT_RGBA_8888; 486 android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN; 487 488 EGLint a = 0; 489 cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_ALPHA_SIZE, &a); 490 if (a > 0) { 491 // alpha-channel requested, there's really only one suitable format 492 format = HAL_PIXEL_FORMAT_RGBA_8888; 493 } else { 494 EGLint r, g, b; 495 r = g = b = 0; 496 cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_RED_SIZE, &r); 497 cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_GREEN_SIZE, &g); 498 cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_BLUE_SIZE, &b); 499 EGLint colorDepth = r + g + b; 500 if (colorDepth <= 16) { 501 format = HAL_PIXEL_FORMAT_RGB_565; 502 } else { 503 format = HAL_PIXEL_FORMAT_RGBX_8888; 504 } 505 } 506 507 // now select a corresponding sRGB format if needed 508 if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) { 509 for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) { 510 if (*attr == EGL_GL_COLORSPACE_KHR) { 511 if (ENABLE_EGL_KHR_GL_COLORSPACE) { 512 dataSpace = modifyBufferDataspace(dataSpace, *(attr+1)); 513 } else { 514 // Normally we'd pass through unhandled attributes to 515 // the driver. But in case the driver implements this 516 // extension but we're disabling it, we want to prevent 517 // it getting through -- support will be broken without 518 // our help. 519 ALOGE("sRGB window surfaces not supported"); 520 return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); 521 } 522 } 523 } 524 } 525 526 if (format != 0) { 527 int err = native_window_set_buffers_format(window, format); 528 if (err != 0) { 529 ALOGE("error setting native window pixel format: %s (%d)", 530 strerror(-err), err); 531 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 532 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); 533 } 534 } 535 536 if (dataSpace != 0) { 537 int err = native_window_set_buffers_data_space(window, dataSpace); 538 if (err != 0) { 539 ALOGE("error setting native window pixel dataSpace: %s (%d)", 540 strerror(-err), err); 541 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 542 return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); 543 } 544 } 545 546 // the EGL spec requires that a new EGLSurface default to swap interval 547 // 1, so explicitly set that on the window here. 548 ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window); 549 anw->setSwapInterval(anw, 1); 550 551 EGLSurface surface = cnx->egl.eglCreateWindowSurface( 552 iDpy, config, window, attrib_list); 553 if (surface != EGL_NO_SURFACE) { 554 egl_surface_t* s = new egl_surface_t(dp.get(), config, window, 555 surface, cnx); 556 return s; 557 } 558 559 // EGLSurface creation failed 560 native_window_set_buffers_format(window, 0); 561 native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); 562 } 563 return EGL_NO_SURFACE; 564 } 565 566 EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, 567 NativePixmapType pixmap, 568 const EGLint *attrib_list) 569 { 570 clearError(); 571 572 egl_connection_t* cnx = NULL; 573 egl_display_ptr dp = validate_display_connection(dpy, cnx); 574 if (dp) { 575 EGLSurface surface = cnx->egl.eglCreatePixmapSurface( 576 dp->disp.dpy, config, pixmap, attrib_list); 577 if (surface != EGL_NO_SURFACE) { 578 egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, 579 surface, cnx); 580 return s; 581 } 582 } 583 return EGL_NO_SURFACE; 584 } 585 586 EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, 587 const EGLint *attrib_list) 588 { 589 clearError(); 590 591 egl_connection_t* cnx = NULL; 592 egl_display_ptr dp = validate_display_connection(dpy, cnx); 593 if (dp) { 594 EGLSurface surface = cnx->egl.eglCreatePbufferSurface( 595 dp->disp.dpy, config, attrib_list); 596 if (surface != EGL_NO_SURFACE) { 597 egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, 598 surface, cnx); 599 return s; 600 } 601 } 602 return EGL_NO_SURFACE; 603 } 604 605 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) 606 { 607 clearError(); 608 609 const egl_display_ptr dp = validate_display(dpy); 610 if (!dp) return EGL_FALSE; 611 612 SurfaceRef _s(dp.get(), surface); 613 if (!_s.get()) 614 return setError(EGL_BAD_SURFACE, EGL_FALSE); 615 616 egl_surface_t * const s = get_surface(surface); 617 EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface); 618 if (result == EGL_TRUE) { 619 _s.terminate(); 620 } 621 return result; 622 } 623 624 EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface, 625 EGLint attribute, EGLint *value) 626 { 627 clearError(); 628 629 const egl_display_ptr dp = validate_display(dpy); 630 if (!dp) return EGL_FALSE; 631 632 SurfaceRef _s(dp.get(), surface); 633 if (!_s.get()) 634 return setError(EGL_BAD_SURFACE, EGL_FALSE); 635 636 egl_surface_t const * const s = get_surface(surface); 637 return s->cnx->egl.eglQuerySurface( 638 dp->disp.dpy, s->surface, attribute, value); 639 } 640 641 void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) { 642 ATRACE_CALL(); 643 clearError(); 644 645 const egl_display_ptr dp = validate_display(dpy); 646 if (!dp) { 647 return; 648 } 649 650 SurfaceRef _s(dp.get(), surface); 651 if (!_s.get()) { 652 setError(EGL_BAD_SURFACE, EGL_FALSE); 653 return; 654 } 655 } 656 657 // ---------------------------------------------------------------------------- 658 // Contexts 659 // ---------------------------------------------------------------------------- 660 661 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, 662 EGLContext share_list, const EGLint *attrib_list) 663 { 664 clearError(); 665 666 egl_connection_t* cnx = NULL; 667 const egl_display_ptr dp = validate_display_connection(dpy, cnx); 668 if (dp) { 669 if (share_list != EGL_NO_CONTEXT) { 670 if (!ContextRef(dp.get(), share_list).get()) { 671 return setError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT); 672 } 673 egl_context_t* const c = get_context(share_list); 674 share_list = c->context; 675 } 676 EGLContext context = cnx->egl.eglCreateContext( 677 dp->disp.dpy, config, share_list, attrib_list); 678 if (context != EGL_NO_CONTEXT) { 679 // figure out if it's a GLESv1 or GLESv2 680 int version = 0; 681 if (attrib_list) { 682 while (*attrib_list != EGL_NONE) { 683 GLint attr = *attrib_list++; 684 GLint value = *attrib_list++; 685 if (attr == EGL_CONTEXT_CLIENT_VERSION) { 686 if (value == 1) { 687 version = egl_connection_t::GLESv1_INDEX; 688 } else if (value == 2 || value == 3) { 689 version = egl_connection_t::GLESv2_INDEX; 690 } 691 } 692 }; 693 } 694 egl_context_t* c = new egl_context_t(dpy, context, config, cnx, 695 version); 696 return c; 697 } 698 } 699 return EGL_NO_CONTEXT; 700 } 701 702 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) 703 { 704 clearError(); 705 706 const egl_display_ptr dp = validate_display(dpy); 707 if (!dp) 708 return EGL_FALSE; 709 710 ContextRef _c(dp.get(), ctx); 711 if (!_c.get()) 712 return setError(EGL_BAD_CONTEXT, EGL_FALSE); 713 714 egl_context_t * const c = get_context(ctx); 715 EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context); 716 if (result == EGL_TRUE) { 717 _c.terminate(); 718 } 719 return result; 720 } 721 722 EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, 723 EGLSurface read, EGLContext ctx) 724 { 725 clearError(); 726 727 egl_display_ptr dp = validate_display(dpy); 728 if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); 729 730 // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not 731 // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is 732 // a valid but uninitialized display. 733 if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) || 734 (draw != EGL_NO_SURFACE) ) { 735 if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, EGL_FALSE); 736 } 737 738 // get a reference to the object passed in 739 ContextRef _c(dp.get(), ctx); 740 SurfaceRef _d(dp.get(), draw); 741 SurfaceRef _r(dp.get(), read); 742 743 // validate the context (if not EGL_NO_CONTEXT) 744 if ((ctx != EGL_NO_CONTEXT) && !_c.get()) { 745 // EGL_NO_CONTEXT is valid 746 return setError(EGL_BAD_CONTEXT, EGL_FALSE); 747 } 748 749 // these are the underlying implementation's object 750 EGLContext impl_ctx = EGL_NO_CONTEXT; 751 EGLSurface impl_draw = EGL_NO_SURFACE; 752 EGLSurface impl_read = EGL_NO_SURFACE; 753 754 // these are our objects structs passed in 755 egl_context_t * c = NULL; 756 egl_surface_t const * d = NULL; 757 egl_surface_t const * r = NULL; 758 759 // these are the current objects structs 760 egl_context_t * cur_c = get_context(getContext()); 761 762 if (ctx != EGL_NO_CONTEXT) { 763 c = get_context(ctx); 764 impl_ctx = c->context; 765 } else { 766 // no context given, use the implementation of the current context 767 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) { 768 // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT); 769 return setError(EGL_BAD_MATCH, EGL_FALSE); 770 } 771 if (cur_c == NULL) { 772 // no current context 773 // not an error, there is just no current context. 774 return EGL_TRUE; 775 } 776 } 777 778 // retrieve the underlying implementation's draw EGLSurface 779 if (draw != EGL_NO_SURFACE) { 780 if (!_d.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); 781 d = get_surface(draw); 782 impl_draw = d->surface; 783 } 784 785 // retrieve the underlying implementation's read EGLSurface 786 if (read != EGL_NO_SURFACE) { 787 if (!_r.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); 788 r = get_surface(read); 789 impl_read = r->surface; 790 } 791 792 793 EGLBoolean result = dp->makeCurrent(c, cur_c, 794 draw, read, ctx, 795 impl_draw, impl_read, impl_ctx); 796 797 if (result == EGL_TRUE) { 798 if (c) { 799 setGLHooksThreadSpecific(c->cnx->hooks[c->version]); 800 egl_tls_t::setContext(ctx); 801 _c.acquire(); 802 _r.acquire(); 803 _d.acquire(); 804 } else { 805 setGLHooksThreadSpecific(&gHooksNoContext); 806 egl_tls_t::setContext(EGL_NO_CONTEXT); 807 } 808 } else { 809 // this will ALOGE the error 810 egl_connection_t* const cnx = &gEGLImpl; 811 result = setError(cnx->egl.eglGetError(), EGL_FALSE); 812 } 813 return result; 814 } 815 816 817 EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx, 818 EGLint attribute, EGLint *value) 819 { 820 clearError(); 821 822 const egl_display_ptr dp = validate_display(dpy); 823 if (!dp) return EGL_FALSE; 824 825 ContextRef _c(dp.get(), ctx); 826 if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE); 827 828 egl_context_t * const c = get_context(ctx); 829 return c->cnx->egl.eglQueryContext( 830 dp->disp.dpy, c->context, attribute, value); 831 832 } 833 834 EGLContext eglGetCurrentContext(void) 835 { 836 // could be called before eglInitialize(), but we wouldn't have a context 837 // then, and this function would correctly return EGL_NO_CONTEXT. 838 839 clearError(); 840 841 EGLContext ctx = getContext(); 842 return ctx; 843 } 844 845 EGLSurface eglGetCurrentSurface(EGLint readdraw) 846 { 847 // could be called before eglInitialize(), but we wouldn't have a context 848 // then, and this function would correctly return EGL_NO_SURFACE. 849 850 clearError(); 851 852 EGLContext ctx = getContext(); 853 if (ctx) { 854 egl_context_t const * const c = get_context(ctx); 855 if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE); 856 switch (readdraw) { 857 case EGL_READ: return c->read; 858 case EGL_DRAW: return c->draw; 859 default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE); 860 } 861 } 862 return EGL_NO_SURFACE; 863 } 864 865 EGLDisplay eglGetCurrentDisplay(void) 866 { 867 // could be called before eglInitialize(), but we wouldn't have a context 868 // then, and this function would correctly return EGL_NO_DISPLAY. 869 870 clearError(); 871 872 EGLContext ctx = getContext(); 873 if (ctx) { 874 egl_context_t const * const c = get_context(ctx); 875 if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE); 876 return c->dpy; 877 } 878 return EGL_NO_DISPLAY; 879 } 880 881 EGLBoolean eglWaitGL(void) 882 { 883 clearError(); 884 885 egl_connection_t* const cnx = &gEGLImpl; 886 if (!cnx->dso) 887 return setError(EGL_BAD_CONTEXT, EGL_FALSE); 888 889 return cnx->egl.eglWaitGL(); 890 } 891 892 EGLBoolean eglWaitNative(EGLint engine) 893 { 894 clearError(); 895 896 egl_connection_t* const cnx = &gEGLImpl; 897 if (!cnx->dso) 898 return setError(EGL_BAD_CONTEXT, EGL_FALSE); 899 900 return cnx->egl.eglWaitNative(engine); 901 } 902 903 EGLint eglGetError(void) 904 { 905 EGLint err = EGL_SUCCESS; 906 egl_connection_t* const cnx = &gEGLImpl; 907 if (cnx->dso) { 908 err = cnx->egl.eglGetError(); 909 } 910 if (err == EGL_SUCCESS) { 911 err = egl_tls_t::getError(); 912 } 913 return err; 914 } 915 916 static __eglMustCastToProperFunctionPointerType findBuiltinWrapper( 917 const char* procname) { 918 const egl_connection_t* cnx = &gEGLImpl; 919 void* proc = NULL; 920 921 proc = dlsym(cnx->libEgl, procname); 922 if (proc) return (__eglMustCastToProperFunctionPointerType)proc; 923 924 proc = dlsym(cnx->libGles2, procname); 925 if (proc) return (__eglMustCastToProperFunctionPointerType)proc; 926 927 proc = dlsym(cnx->libGles1, procname); 928 if (proc) return (__eglMustCastToProperFunctionPointerType)proc; 929 930 return NULL; 931 } 932 933 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) 934 { 935 // eglGetProcAddress() could be the very first function called 936 // in which case we must make sure we've initialized ourselves, this 937 // happens the first time egl_get_display() is called. 938 939 clearError(); 940 941 if (egl_init_drivers() == EGL_FALSE) { 942 setError(EGL_BAD_PARAMETER, NULL); 943 return NULL; 944 } 945 946 if (FILTER_EXTENSIONS(procname)) { 947 return NULL; 948 } 949 950 __eglMustCastToProperFunctionPointerType addr; 951 addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap)); 952 if (addr) return addr; 953 954 addr = findBuiltinWrapper(procname); 955 if (addr) return addr; 956 957 // this protects accesses to sGLExtentionMap and sGLExtentionSlot 958 pthread_mutex_lock(&sExtensionMapMutex); 959 960 /* 961 * Since eglGetProcAddress() is not associated to anything, it needs 962 * to return a function pointer that "works" regardless of what 963 * the current context is. 964 * 965 * For this reason, we return a "forwarder", a small stub that takes 966 * care of calling the function associated with the context 967 * currently bound. 968 * 969 * We first look for extensions we've already resolved, if we're seeing 970 * this extension for the first time, we go through all our 971 * implementations and call eglGetProcAddress() and record the 972 * result in the appropriate implementation hooks and return the 973 * address of the forwarder corresponding to that hook set. 974 * 975 */ 976 977 const String8 name(procname); 978 addr = sGLExtentionMap.valueFor(name); 979 const int slot = sGLExtentionSlot; 980 981 ALOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS, 982 "no more slots for eglGetProcAddress(\"%s\")", 983 procname); 984 985 if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) { 986 bool found = false; 987 988 egl_connection_t* const cnx = &gEGLImpl; 989 if (cnx->dso && cnx->egl.eglGetProcAddress) { 990 // Extensions are independent of the bound context 991 addr = 992 cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] = 993 cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] = 994 cnx->egl.eglGetProcAddress(procname); 995 if (addr) found = true; 996 } 997 998 if (found) { 999 addr = gExtensionForwarders[slot]; 1000 sGLExtentionMap.add(name, addr); 1001 sGLExtentionSlot++; 1002 } 1003 } 1004 1005 pthread_mutex_unlock(&sExtensionMapMutex); 1006 return addr; 1007 } 1008 1009 class FrameCompletionThread : public Thread { 1010 public: 1011 1012 static void queueSync(EGLSyncKHR sync) { 1013 static sp<FrameCompletionThread> thread(new FrameCompletionThread); 1014 static bool running = false; 1015 if (!running) { 1016 thread->run("GPUFrameCompletion"); 1017 running = true; 1018 } 1019 { 1020 Mutex::Autolock lock(thread->mMutex); 1021 ScopedTrace st(ATRACE_TAG, String8::format("kicked off frame %d", 1022 thread->mFramesQueued).string()); 1023 thread->mQueue.push_back(sync); 1024 thread->mCondition.signal(); 1025 thread->mFramesQueued++; 1026 ATRACE_INT("GPU Frames Outstanding", thread->mQueue.size()); 1027 } 1028 } 1029 1030 private: 1031 FrameCompletionThread() : mFramesQueued(0), mFramesCompleted(0) {} 1032 1033 virtual bool threadLoop() { 1034 EGLSyncKHR sync; 1035 uint32_t frameNum; 1036 { 1037 Mutex::Autolock lock(mMutex); 1038 while (mQueue.isEmpty()) { 1039 mCondition.wait(mMutex); 1040 } 1041 sync = mQueue[0]; 1042 frameNum = mFramesCompleted; 1043 } 1044 EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 1045 { 1046 ScopedTrace st(ATRACE_TAG, String8::format("waiting for frame %d", 1047 frameNum).string()); 1048 EGLint result = eglClientWaitSyncKHR(dpy, sync, 0, EGL_FOREVER_KHR); 1049 if (result == EGL_FALSE) { 1050 ALOGE("FrameCompletion: error waiting for fence: %#x", eglGetError()); 1051 } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 1052 ALOGE("FrameCompletion: timeout waiting for fence"); 1053 } 1054 eglDestroySyncKHR(dpy, sync); 1055 } 1056 { 1057 Mutex::Autolock lock(mMutex); 1058 mQueue.removeAt(0); 1059 mFramesCompleted++; 1060 ATRACE_INT("GPU Frames Outstanding", mQueue.size()); 1061 } 1062 return true; 1063 } 1064 1065 uint32_t mFramesQueued; 1066 uint32_t mFramesCompleted; 1067 Vector<EGLSyncKHR> mQueue; 1068 Condition mCondition; 1069 Mutex mMutex; 1070 }; 1071 1072 EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw, 1073 EGLint *rects, EGLint n_rects) 1074 { 1075 ATRACE_CALL(); 1076 clearError(); 1077 1078 const egl_display_ptr dp = validate_display(dpy); 1079 if (!dp) return EGL_FALSE; 1080 1081 SurfaceRef _s(dp.get(), draw); 1082 if (!_s.get()) 1083 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1084 1085 egl_surface_t const * const s = get_surface(draw); 1086 1087 if (CC_UNLIKELY(dp->traceGpuCompletion)) { 1088 EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); 1089 if (sync != EGL_NO_SYNC_KHR) { 1090 FrameCompletionThread::queueSync(sync); 1091 } 1092 } 1093 1094 if (CC_UNLIKELY(dp->finishOnSwap)) { 1095 uint32_t pixel; 1096 egl_context_t * const c = get_context( egl_tls_t::getContext() ); 1097 if (c) { 1098 // glReadPixels() ensures that the frame is complete 1099 s->cnx->hooks[c->version]->gl.glReadPixels(0,0,1,1, 1100 GL_RGBA,GL_UNSIGNED_BYTE,&pixel); 1101 } 1102 } 1103 1104 if (n_rects == 0) { 1105 return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface); 1106 } 1107 1108 Vector<android_native_rect_t> androidRects; 1109 for (int r = 0; r < n_rects; ++r) { 1110 int offset = r * 4; 1111 int x = rects[offset]; 1112 int y = rects[offset + 1]; 1113 int width = rects[offset + 2]; 1114 int height = rects[offset + 3]; 1115 android_native_rect_t androidRect; 1116 androidRect.left = x; 1117 androidRect.top = y + height; 1118 androidRect.right = x + width; 1119 androidRect.bottom = y; 1120 androidRects.push_back(androidRect); 1121 } 1122 native_window_set_surface_damage(s->win.get(), androidRects.array(), 1123 androidRects.size()); 1124 1125 if (s->cnx->egl.eglSwapBuffersWithDamageKHR) { 1126 return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface, 1127 rects, n_rects); 1128 } else { 1129 return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface); 1130 } 1131 } 1132 1133 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) 1134 { 1135 return eglSwapBuffersWithDamageKHR(dpy, surface, NULL, 0); 1136 } 1137 1138 EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface, 1139 NativePixmapType target) 1140 { 1141 clearError(); 1142 1143 const egl_display_ptr dp = validate_display(dpy); 1144 if (!dp) return EGL_FALSE; 1145 1146 SurfaceRef _s(dp.get(), surface); 1147 if (!_s.get()) 1148 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1149 1150 egl_surface_t const * const s = get_surface(surface); 1151 return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target); 1152 } 1153 1154 const char* eglQueryString(EGLDisplay dpy, EGLint name) 1155 { 1156 clearError(); 1157 1158 const egl_display_ptr dp = validate_display(dpy); 1159 if (!dp) return (const char *) NULL; 1160 1161 switch (name) { 1162 case EGL_VENDOR: 1163 return dp->getVendorString(); 1164 case EGL_VERSION: 1165 return dp->getVersionString(); 1166 case EGL_EXTENSIONS: 1167 return dp->getExtensionString(); 1168 case EGL_CLIENT_APIS: 1169 return dp->getClientApiString(); 1170 } 1171 return setError(EGL_BAD_PARAMETER, (const char *)0); 1172 } 1173 1174 EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name) 1175 { 1176 clearError(); 1177 1178 const egl_display_ptr dp = validate_display(dpy); 1179 if (!dp) return (const char *) NULL; 1180 1181 switch (name) { 1182 case EGL_VENDOR: 1183 return dp->disp.queryString.vendor; 1184 case EGL_VERSION: 1185 return dp->disp.queryString.version; 1186 case EGL_EXTENSIONS: 1187 return dp->disp.queryString.extensions; 1188 case EGL_CLIENT_APIS: 1189 return dp->disp.queryString.clientApi; 1190 } 1191 return setError(EGL_BAD_PARAMETER, (const char *)0); 1192 } 1193 1194 // ---------------------------------------------------------------------------- 1195 // EGL 1.1 1196 // ---------------------------------------------------------------------------- 1197 1198 EGLBoolean eglSurfaceAttrib( 1199 EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) 1200 { 1201 clearError(); 1202 1203 const egl_display_ptr dp = validate_display(dpy); 1204 if (!dp) return EGL_FALSE; 1205 1206 SurfaceRef _s(dp.get(), surface); 1207 if (!_s.get()) 1208 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1209 1210 egl_surface_t * const s = get_surface(surface); 1211 1212 if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) { 1213 int err = native_window_set_auto_refresh(s->win.get(), 1214 value ? true : false); 1215 return (err == NO_ERROR) ? EGL_TRUE : 1216 setError(EGL_BAD_SURFACE, EGL_FALSE); 1217 } 1218 1219 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS 1220 if (attribute == EGL_TIMESTAMPS_ANDROID) { 1221 s->enableTimestamps = value; 1222 return EGL_TRUE; 1223 } 1224 #endif 1225 1226 if (s->cnx->egl.eglSurfaceAttrib) { 1227 return s->cnx->egl.eglSurfaceAttrib( 1228 dp->disp.dpy, s->surface, attribute, value); 1229 } 1230 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1231 } 1232 1233 EGLBoolean eglBindTexImage( 1234 EGLDisplay dpy, EGLSurface surface, EGLint buffer) 1235 { 1236 clearError(); 1237 1238 const egl_display_ptr dp = validate_display(dpy); 1239 if (!dp) return EGL_FALSE; 1240 1241 SurfaceRef _s(dp.get(), surface); 1242 if (!_s.get()) 1243 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1244 1245 egl_surface_t const * const s = get_surface(surface); 1246 if (s->cnx->egl.eglBindTexImage) { 1247 return s->cnx->egl.eglBindTexImage( 1248 dp->disp.dpy, s->surface, buffer); 1249 } 1250 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1251 } 1252 1253 EGLBoolean eglReleaseTexImage( 1254 EGLDisplay dpy, EGLSurface surface, EGLint buffer) 1255 { 1256 clearError(); 1257 1258 const egl_display_ptr dp = validate_display(dpy); 1259 if (!dp) return EGL_FALSE; 1260 1261 SurfaceRef _s(dp.get(), surface); 1262 if (!_s.get()) 1263 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1264 1265 egl_surface_t const * const s = get_surface(surface); 1266 if (s->cnx->egl.eglReleaseTexImage) { 1267 return s->cnx->egl.eglReleaseTexImage( 1268 dp->disp.dpy, s->surface, buffer); 1269 } 1270 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1271 } 1272 1273 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) 1274 { 1275 clearError(); 1276 1277 const egl_display_ptr dp = validate_display(dpy); 1278 if (!dp) return EGL_FALSE; 1279 1280 EGLBoolean res = EGL_TRUE; 1281 egl_connection_t* const cnx = &gEGLImpl; 1282 if (cnx->dso && cnx->egl.eglSwapInterval) { 1283 res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval); 1284 } 1285 1286 return res; 1287 } 1288 1289 1290 // ---------------------------------------------------------------------------- 1291 // EGL 1.2 1292 // ---------------------------------------------------------------------------- 1293 1294 EGLBoolean eglWaitClient(void) 1295 { 1296 clearError(); 1297 1298 egl_connection_t* const cnx = &gEGLImpl; 1299 if (!cnx->dso) 1300 return setError(EGL_BAD_CONTEXT, EGL_FALSE); 1301 1302 EGLBoolean res; 1303 if (cnx->egl.eglWaitClient) { 1304 res = cnx->egl.eglWaitClient(); 1305 } else { 1306 res = cnx->egl.eglWaitGL(); 1307 } 1308 return res; 1309 } 1310 1311 EGLBoolean eglBindAPI(EGLenum api) 1312 { 1313 clearError(); 1314 1315 if (egl_init_drivers() == EGL_FALSE) { 1316 return setError(EGL_BAD_PARAMETER, EGL_FALSE); 1317 } 1318 1319 // bind this API on all EGLs 1320 EGLBoolean res = EGL_TRUE; 1321 egl_connection_t* const cnx = &gEGLImpl; 1322 if (cnx->dso && cnx->egl.eglBindAPI) { 1323 res = cnx->egl.eglBindAPI(api); 1324 } 1325 return res; 1326 } 1327 1328 EGLenum eglQueryAPI(void) 1329 { 1330 clearError(); 1331 1332 if (egl_init_drivers() == EGL_FALSE) { 1333 return setError(EGL_BAD_PARAMETER, EGL_FALSE); 1334 } 1335 1336 egl_connection_t* const cnx = &gEGLImpl; 1337 if (cnx->dso && cnx->egl.eglQueryAPI) { 1338 return cnx->egl.eglQueryAPI(); 1339 } 1340 1341 // or, it can only be OpenGL ES 1342 return EGL_OPENGL_ES_API; 1343 } 1344 1345 EGLBoolean eglReleaseThread(void) 1346 { 1347 clearError(); 1348 1349 // If there is context bound to the thread, release it 1350 egl_display_t::loseCurrent(get_context(getContext())); 1351 1352 egl_connection_t* const cnx = &gEGLImpl; 1353 if (cnx->dso && cnx->egl.eglReleaseThread) { 1354 cnx->egl.eglReleaseThread(); 1355 } 1356 egl_tls_t::clearTLS(); 1357 return EGL_TRUE; 1358 } 1359 1360 EGLSurface eglCreatePbufferFromClientBuffer( 1361 EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, 1362 EGLConfig config, const EGLint *attrib_list) 1363 { 1364 clearError(); 1365 1366 egl_connection_t* cnx = NULL; 1367 const egl_display_ptr dp = validate_display_connection(dpy, cnx); 1368 if (!dp) return EGL_FALSE; 1369 if (cnx->egl.eglCreatePbufferFromClientBuffer) { 1370 return cnx->egl.eglCreatePbufferFromClientBuffer( 1371 dp->disp.dpy, buftype, buffer, config, attrib_list); 1372 } 1373 return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE); 1374 } 1375 1376 // ---------------------------------------------------------------------------- 1377 // EGL_EGLEXT_VERSION 3 1378 // ---------------------------------------------------------------------------- 1379 1380 EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, 1381 const EGLint *attrib_list) 1382 { 1383 clearError(); 1384 1385 const egl_display_ptr dp = validate_display(dpy); 1386 if (!dp) return EGL_FALSE; 1387 1388 SurfaceRef _s(dp.get(), surface); 1389 if (!_s.get()) 1390 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1391 1392 egl_surface_t const * const s = get_surface(surface); 1393 if (s->cnx->egl.eglLockSurfaceKHR) { 1394 return s->cnx->egl.eglLockSurfaceKHR( 1395 dp->disp.dpy, s->surface, attrib_list); 1396 } 1397 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1398 } 1399 1400 EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface) 1401 { 1402 clearError(); 1403 1404 const egl_display_ptr dp = validate_display(dpy); 1405 if (!dp) return EGL_FALSE; 1406 1407 SurfaceRef _s(dp.get(), surface); 1408 if (!_s.get()) 1409 return setError(EGL_BAD_SURFACE, EGL_FALSE); 1410 1411 egl_surface_t const * const s = get_surface(surface); 1412 if (s->cnx->egl.eglUnlockSurfaceKHR) { 1413 return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface); 1414 } 1415 return setError(EGL_BAD_DISPLAY, EGL_FALSE); 1416 } 1417 1418 EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, 1419 EGLClientBuffer buffer, const EGLint *attrib_list) 1420 { 1421 clearError(); 1422 1423 const egl_display_ptr dp = validate_display(dpy); 1424 if (!dp) return EGL_NO_IMAGE_KHR; 1425 1426 ContextRef _c(dp.get(), ctx); 1427 egl_context_t * const c = _c.get(); 1428 1429 EGLImageKHR result = EGL_NO_IMAGE_KHR; 1430 egl_connection_t* const cnx = &gEGLImpl; 1431 if (cnx->dso && cnx->egl.eglCreateImageKHR) { 1432 result = cnx->egl.eglCreateImageKHR( 1433 dp->disp.dpy, 1434 c ? c->context : EGL_NO_CONTEXT, 1435 target, buffer, attrib_list); 1436 } 1437 return result; 1438 } 1439 1440 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) 1441 { 1442 clearError(); 1443 1444 const egl_display_ptr dp = validate_display(dpy); 1445 if (!dp) return EGL_FALSE; 1446 1447 EGLBoolean result = EGL_FALSE; 1448 egl_connection_t* const cnx = &gEGLImpl; 1449 if (cnx->dso && cnx->egl.eglDestroyImageKHR) { 1450 result = cnx->egl.eglDestroyImageKHR(dp->disp.dpy, img); 1451 } 1452 return result; 1453 } 1454 1455 // ---------------------------------------------------------------------------- 1456 // EGL_EGLEXT_VERSION 5 1457 // ---------------------------------------------------------------------------- 1458 1459 1460 EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) 1461 { 1462 clearError(); 1463 1464 const egl_display_ptr dp = validate_display(dpy); 1465 if (!dp) return EGL_NO_SYNC_KHR; 1466 1467 EGLSyncKHR result = EGL_NO_SYNC_KHR; 1468 egl_connection_t* const cnx = &gEGLImpl; 1469 if (cnx->dso && cnx->egl.eglCreateSyncKHR) { 1470 result = cnx->egl.eglCreateSyncKHR(dp->disp.dpy, type, attrib_list); 1471 } 1472 return result; 1473 } 1474 1475 EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) 1476 { 1477 clearError(); 1478 1479 const egl_display_ptr dp = validate_display(dpy); 1480 if (!dp) return EGL_FALSE; 1481 1482 EGLBoolean result = EGL_FALSE; 1483 egl_connection_t* const cnx = &gEGLImpl; 1484 if (cnx->dso && cnx->egl.eglDestroySyncKHR) { 1485 result = cnx->egl.eglDestroySyncKHR(dp->disp.dpy, sync); 1486 } 1487 return result; 1488 } 1489 1490 EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) { 1491 clearError(); 1492 1493 const egl_display_ptr dp = validate_display(dpy); 1494 if (!dp) return EGL_FALSE; 1495 1496 EGLBoolean result = EGL_FALSE; 1497 egl_connection_t* const cnx = &gEGLImpl; 1498 if (cnx->dso && cnx->egl.eglSignalSyncKHR) { 1499 result = cnx->egl.eglSignalSyncKHR( 1500 dp->disp.dpy, sync, mode); 1501 } 1502 return result; 1503 } 1504 1505 EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, 1506 EGLint flags, EGLTimeKHR timeout) 1507 { 1508 clearError(); 1509 1510 const egl_display_ptr dp = validate_display(dpy); 1511 if (!dp) return EGL_FALSE; 1512 1513 EGLBoolean result = EGL_FALSE; 1514 egl_connection_t* const cnx = &gEGLImpl; 1515 if (cnx->dso && cnx->egl.eglClientWaitSyncKHR) { 1516 result = cnx->egl.eglClientWaitSyncKHR( 1517 dp->disp.dpy, sync, flags, timeout); 1518 } 1519 return result; 1520 } 1521 1522 EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, 1523 EGLint attribute, EGLint *value) 1524 { 1525 clearError(); 1526 1527 const egl_display_ptr dp = validate_display(dpy); 1528 if (!dp) return EGL_FALSE; 1529 1530 EGLBoolean result = EGL_FALSE; 1531 egl_connection_t* const cnx = &gEGLImpl; 1532 if (cnx->dso && cnx->egl.eglGetSyncAttribKHR) { 1533 result = cnx->egl.eglGetSyncAttribKHR( 1534 dp->disp.dpy, sync, attribute, value); 1535 } 1536 return result; 1537 } 1538 1539 EGLStreamKHR eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list) 1540 { 1541 clearError(); 1542 1543 const egl_display_ptr dp = validate_display(dpy); 1544 if (!dp) return EGL_NO_STREAM_KHR; 1545 1546 EGLStreamKHR result = EGL_NO_STREAM_KHR; 1547 egl_connection_t* const cnx = &gEGLImpl; 1548 if (cnx->dso && cnx->egl.eglCreateStreamKHR) { 1549 result = cnx->egl.eglCreateStreamKHR( 1550 dp->disp.dpy, attrib_list); 1551 } 1552 return result; 1553 } 1554 1555 EGLBoolean eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) 1556 { 1557 clearError(); 1558 1559 const egl_display_ptr dp = validate_display(dpy); 1560 if (!dp) return EGL_FALSE; 1561 1562 EGLBoolean result = EGL_FALSE; 1563 egl_connection_t* const cnx = &gEGLImpl; 1564 if (cnx->dso && cnx->egl.eglDestroyStreamKHR) { 1565 result = cnx->egl.eglDestroyStreamKHR( 1566 dp->disp.dpy, stream); 1567 } 1568 return result; 1569 } 1570 1571 EGLBoolean eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream, 1572 EGLenum attribute, EGLint value) 1573 { 1574 clearError(); 1575 1576 const egl_display_ptr dp = validate_display(dpy); 1577 if (!dp) return EGL_FALSE; 1578 1579 EGLBoolean result = EGL_FALSE; 1580 egl_connection_t* const cnx = &gEGLImpl; 1581 if (cnx->dso && cnx->egl.eglStreamAttribKHR) { 1582 result = cnx->egl.eglStreamAttribKHR( 1583 dp->disp.dpy, stream, attribute, value); 1584 } 1585 return result; 1586 } 1587 1588 EGLBoolean eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream, 1589 EGLenum attribute, EGLint *value) 1590 { 1591 clearError(); 1592 1593 const egl_display_ptr dp = validate_display(dpy); 1594 if (!dp) return EGL_FALSE; 1595 1596 EGLBoolean result = EGL_FALSE; 1597 egl_connection_t* const cnx = &gEGLImpl; 1598 if (cnx->dso && cnx->egl.eglQueryStreamKHR) { 1599 result = cnx->egl.eglQueryStreamKHR( 1600 dp->disp.dpy, stream, attribute, value); 1601 } 1602 return result; 1603 } 1604 1605 EGLBoolean eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream, 1606 EGLenum attribute, EGLuint64KHR *value) 1607 { 1608 clearError(); 1609 1610 const egl_display_ptr dp = validate_display(dpy); 1611 if (!dp) return EGL_FALSE; 1612 1613 EGLBoolean result = EGL_FALSE; 1614 egl_connection_t* const cnx = &gEGLImpl; 1615 if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) { 1616 result = cnx->egl.eglQueryStreamu64KHR( 1617 dp->disp.dpy, stream, attribute, value); 1618 } 1619 return result; 1620 } 1621 1622 EGLBoolean eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream, 1623 EGLenum attribute, EGLTimeKHR *value) 1624 { 1625 clearError(); 1626 1627 const egl_display_ptr dp = validate_display(dpy); 1628 if (!dp) return EGL_FALSE; 1629 1630 EGLBoolean result = EGL_FALSE; 1631 egl_connection_t* const cnx = &gEGLImpl; 1632 if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) { 1633 result = cnx->egl.eglQueryStreamTimeKHR( 1634 dp->disp.dpy, stream, attribute, value); 1635 } 1636 return result; 1637 } 1638 1639 EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, 1640 EGLStreamKHR stream, const EGLint *attrib_list) 1641 { 1642 clearError(); 1643 1644 egl_display_ptr dp = validate_display(dpy); 1645 if (!dp) return EGL_NO_SURFACE; 1646 1647 egl_connection_t* const cnx = &gEGLImpl; 1648 if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) { 1649 EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR( 1650 dp->disp.dpy, config, stream, attrib_list); 1651 if (surface != EGL_NO_SURFACE) { 1652 egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, 1653 surface, cnx); 1654 return s; 1655 } 1656 } 1657 return EGL_NO_SURFACE; 1658 } 1659 1660 EGLBoolean eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, 1661 EGLStreamKHR stream) 1662 { 1663 clearError(); 1664 1665 const egl_display_ptr dp = validate_display(dpy); 1666 if (!dp) return EGL_FALSE; 1667 1668 EGLBoolean result = EGL_FALSE; 1669 egl_connection_t* const cnx = &gEGLImpl; 1670 if (cnx->dso && cnx->egl.eglStreamConsumerGLTextureExternalKHR) { 1671 result = cnx->egl.eglStreamConsumerGLTextureExternalKHR( 1672 dp->disp.dpy, stream); 1673 } 1674 return result; 1675 } 1676 1677 EGLBoolean eglStreamConsumerAcquireKHR(EGLDisplay dpy, 1678 EGLStreamKHR stream) 1679 { 1680 clearError(); 1681 1682 const egl_display_ptr dp = validate_display(dpy); 1683 if (!dp) return EGL_FALSE; 1684 1685 EGLBoolean result = EGL_FALSE; 1686 egl_connection_t* const cnx = &gEGLImpl; 1687 if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) { 1688 result = cnx->egl.eglStreamConsumerAcquireKHR( 1689 dp->disp.dpy, stream); 1690 } 1691 return result; 1692 } 1693 1694 EGLBoolean eglStreamConsumerReleaseKHR(EGLDisplay dpy, 1695 EGLStreamKHR stream) 1696 { 1697 clearError(); 1698 1699 const egl_display_ptr dp = validate_display(dpy); 1700 if (!dp) return EGL_FALSE; 1701 1702 EGLBoolean result = EGL_FALSE; 1703 egl_connection_t* const cnx = &gEGLImpl; 1704 if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) { 1705 result = cnx->egl.eglStreamConsumerReleaseKHR( 1706 dp->disp.dpy, stream); 1707 } 1708 return result; 1709 } 1710 1711 EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR( 1712 EGLDisplay dpy, EGLStreamKHR stream) 1713 { 1714 clearError(); 1715 1716 const egl_display_ptr dp = validate_display(dpy); 1717 if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR; 1718 1719 EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR; 1720 egl_connection_t* const cnx = &gEGLImpl; 1721 if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) { 1722 result = cnx->egl.eglGetStreamFileDescriptorKHR( 1723 dp->disp.dpy, stream); 1724 } 1725 return result; 1726 } 1727 1728 EGLStreamKHR eglCreateStreamFromFileDescriptorKHR( 1729 EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor) 1730 { 1731 clearError(); 1732 1733 const egl_display_ptr dp = validate_display(dpy); 1734 if (!dp) return EGL_NO_STREAM_KHR; 1735 1736 EGLStreamKHR result = EGL_NO_STREAM_KHR; 1737 egl_connection_t* const cnx = &gEGLImpl; 1738 if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) { 1739 result = cnx->egl.eglCreateStreamFromFileDescriptorKHR( 1740 dp->disp.dpy, file_descriptor); 1741 } 1742 return result; 1743 } 1744 1745 // ---------------------------------------------------------------------------- 1746 // EGL_EGLEXT_VERSION 15 1747 // ---------------------------------------------------------------------------- 1748 1749 EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) { 1750 clearError(); 1751 const egl_display_ptr dp = validate_display(dpy); 1752 if (!dp) return EGL_FALSE; 1753 EGLint result = EGL_FALSE; 1754 egl_connection_t* const cnx = &gEGLImpl; 1755 if (cnx->dso && cnx->egl.eglWaitSyncKHR) { 1756 result = cnx->egl.eglWaitSyncKHR(dp->disp.dpy, sync, flags); 1757 } 1758 return result; 1759 } 1760 1761 // ---------------------------------------------------------------------------- 1762 // ANDROID extensions 1763 // ---------------------------------------------------------------------------- 1764 1765 EGLint eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync) 1766 { 1767 clearError(); 1768 1769 const egl_display_ptr dp = validate_display(dpy); 1770 if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID; 1771 1772 EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID; 1773 egl_connection_t* const cnx = &gEGLImpl; 1774 if (cnx->dso && cnx->egl.eglDupNativeFenceFDANDROID) { 1775 result = cnx->egl.eglDupNativeFenceFDANDROID(dp->disp.dpy, sync); 1776 } 1777 return result; 1778 } 1779 1780 EGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface, 1781 EGLnsecsANDROID time) 1782 { 1783 clearError(); 1784 1785 const egl_display_ptr dp = validate_display(dpy); 1786 if (!dp) { 1787 return EGL_FALSE; 1788 } 1789 1790 SurfaceRef _s(dp.get(), surface); 1791 if (!_s.get()) { 1792 setError(EGL_BAD_SURFACE, EGL_FALSE); 1793 return EGL_FALSE; 1794 } 1795 1796 egl_surface_t const * const s = get_surface(surface); 1797 native_window_set_buffers_timestamp(s->win.get(), time); 1798 1799 return EGL_TRUE; 1800 } 1801 1802 EGLClientBuffer eglCreateNativeClientBufferANDROID(const EGLint *attrib_list) 1803 { 1804 clearError(); 1805 1806 int usage = 0; 1807 uint32_t width = 0; 1808 uint32_t height = 0; 1809 uint32_t format = 0; 1810 uint32_t red_size = 0; 1811 uint32_t green_size = 0; 1812 uint32_t blue_size = 0; 1813 uint32_t alpha_size = 0; 1814 1815 #define GET_NONNEGATIVE_VALUE(case_name, target) \ 1816 case case_name: \ 1817 if (value >= 0) { \ 1818 target = value; \ 1819 } else { \ 1820 return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0); \ 1821 } \ 1822 break 1823 1824 if (attrib_list) { 1825 while (*attrib_list != EGL_NONE) { 1826 GLint attr = *attrib_list++; 1827 GLint value = *attrib_list++; 1828 switch (attr) { 1829 GET_NONNEGATIVE_VALUE(EGL_WIDTH, width); 1830 GET_NONNEGATIVE_VALUE(EGL_HEIGHT, height); 1831 GET_NONNEGATIVE_VALUE(EGL_RED_SIZE, red_size); 1832 GET_NONNEGATIVE_VALUE(EGL_GREEN_SIZE, green_size); 1833 GET_NONNEGATIVE_VALUE(EGL_BLUE_SIZE, blue_size); 1834 GET_NONNEGATIVE_VALUE(EGL_ALPHA_SIZE, alpha_size); 1835 case EGL_NATIVE_BUFFER_USAGE_ANDROID: 1836 if (value & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID) { 1837 usage |= GRALLOC_USAGE_PROTECTED; 1838 } 1839 if (value & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID) { 1840 usage |= GRALLOC_USAGE_HW_RENDER; 1841 } 1842 if (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID) { 1843 usage |= GRALLOC_USAGE_HW_TEXTURE; 1844 } 1845 // The buffer must be used for either a texture or a 1846 // renderbuffer. 1847 if ((value & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID) && 1848 (value & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)) { 1849 return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0); 1850 } 1851 break; 1852 default: 1853 return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0); 1854 } 1855 } 1856 } 1857 #undef GET_NONNEGATIVE_VALUE 1858 1859 // Validate format. 1860 if (red_size == 8 && green_size == 8 && blue_size == 8) { 1861 if (alpha_size == 8) { 1862 format = HAL_PIXEL_FORMAT_RGBA_8888; 1863 } else { 1864 format = HAL_PIXEL_FORMAT_RGB_888; 1865 } 1866 } else if (red_size == 5 && green_size == 6 && blue_size == 5 && 1867 alpha_size == 0) { 1868 format = HAL_PIXEL_FORMAT_RGB_565; 1869 } else { 1870 ALOGE("Invalid native pixel format { r=%d, g=%d, b=%d, a=%d }", 1871 red_size, green_size, blue_size, alpha_size); 1872 return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0); 1873 } 1874 1875 GraphicBuffer* gBuffer = new GraphicBuffer(width, height, format, usage, 1876 std::string("[eglCreateNativeClientBufferANDROID pid ") + 1877 std::to_string(getpid()) + ']'); 1878 const status_t err = gBuffer->initCheck(); 1879 if (err != NO_ERROR) { 1880 ALOGE("Unable to create native buffer { w=%d, h=%d, f=%d, u=%#x }: %#x", 1881 width, height, format, usage, err); 1882 // Destroy the buffer. 1883 sp<GraphicBuffer> holder(gBuffer); 1884 return setError(EGL_BAD_ALLOC, (EGLClientBuffer)0); 1885 } 1886 ALOGD("Created new native buffer %p { w=%d, h=%d, f=%d, u=%#x }", 1887 gBuffer, width, height, format, usage); 1888 return static_cast<EGLClientBuffer>(gBuffer->getNativeBuffer()); 1889 } 1890 1891 // ---------------------------------------------------------------------------- 1892 // NVIDIA extensions 1893 // ---------------------------------------------------------------------------- 1894 EGLuint64NV eglGetSystemTimeFrequencyNV() 1895 { 1896 clearError(); 1897 1898 if (egl_init_drivers() == EGL_FALSE) { 1899 return setError(EGL_BAD_PARAMETER, EGL_FALSE); 1900 } 1901 1902 EGLuint64NV ret = 0; 1903 egl_connection_t* const cnx = &gEGLImpl; 1904 1905 if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) { 1906 return cnx->egl.eglGetSystemTimeFrequencyNV(); 1907 } 1908 1909 return setErrorQuiet(EGL_BAD_DISPLAY, 0); 1910 } 1911 1912 EGLuint64NV eglGetSystemTimeNV() 1913 { 1914 clearError(); 1915 1916 if (egl_init_drivers() == EGL_FALSE) { 1917 return setError(EGL_BAD_PARAMETER, EGL_FALSE); 1918 } 1919 1920 EGLuint64NV ret = 0; 1921 egl_connection_t* const cnx = &gEGLImpl; 1922 1923 if (cnx->dso && cnx->egl.eglGetSystemTimeNV) { 1924 return cnx->egl.eglGetSystemTimeNV(); 1925 } 1926 1927 return setErrorQuiet(EGL_BAD_DISPLAY, 0); 1928 } 1929 1930 // ---------------------------------------------------------------------------- 1931 // Partial update extension 1932 // ---------------------------------------------------------------------------- 1933 EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface, 1934 EGLint *rects, EGLint n_rects) 1935 { 1936 clearError(); 1937 1938 const egl_display_ptr dp = validate_display(dpy); 1939 if (!dp) { 1940 setError(EGL_BAD_DISPLAY, EGL_FALSE); 1941 return EGL_FALSE; 1942 } 1943 1944 SurfaceRef _s(dp.get(), surface); 1945 if (!_s.get()) { 1946 setError(EGL_BAD_SURFACE, EGL_FALSE); 1947 return EGL_FALSE; 1948 } 1949 1950 egl_surface_t const * const s = get_surface(surface); 1951 if (s->cnx->egl.eglSetDamageRegionKHR) { 1952 return s->cnx->egl.eglSetDamageRegionKHR(dp->disp.dpy, s->surface, 1953 rects, n_rects); 1954 } 1955 1956 return EGL_FALSE; 1957 } 1958 1959 EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, 1960 EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, 1961 EGLnsecsANDROID *values) 1962 { 1963 clearError(); 1964 1965 const egl_display_ptr dp = validate_display(dpy); 1966 if (!dp) { 1967 setError(EGL_BAD_DISPLAY, EGL_FALSE); 1968 return EGL_FALSE; 1969 } 1970 1971 SurfaceRef _s(dp.get(), surface); 1972 if (!_s.get()) { 1973 setError(EGL_BAD_SURFACE, EGL_FALSE); 1974 return EGL_FALSE; 1975 } 1976 1977 egl_surface_t const * const s = get_surface(surface); 1978 1979 if (!s->enableTimestamps) { 1980 setError(EGL_BAD_SURFACE, EGL_FALSE); 1981 return EGL_FALSE; 1982 } 1983 1984 nsecs_t* postedTime = nullptr; 1985 nsecs_t* acquireTime = nullptr; 1986 nsecs_t* refreshStartTime = nullptr; 1987 nsecs_t* GLCompositionDoneTime = nullptr; 1988 nsecs_t* displayRetireTime = nullptr; 1989 nsecs_t* releaseTime = nullptr; 1990 1991 for (int i = 0; i < numTimestamps; i++) { 1992 switch (timestamps[i]) { 1993 case EGL_QUEUE_TIME_ANDROID: 1994 postedTime = &values[i]; 1995 break; 1996 case EGL_RENDERING_COMPLETE_TIME_ANDROID: 1997 acquireTime = &values[i]; 1998 break; 1999 case EGL_COMPOSITION_START_TIME_ANDROID: 2000 refreshStartTime = &values[i]; 2001 break; 2002 case EGL_COMPOSITION_FINISHED_TIME_ANDROID: 2003 GLCompositionDoneTime = &values[i]; 2004 break; 2005 case EGL_DISPLAY_RETIRE_TIME_ANDROID: 2006 displayRetireTime = &values[i]; 2007 break; 2008 case EGL_READS_DONE_TIME_ANDROID: 2009 releaseTime = &values[i]; 2010 break; 2011 default: 2012 setError(EGL_BAD_PARAMETER, EGL_FALSE); 2013 return EGL_FALSE; 2014 } 2015 } 2016 2017 status_t ret = native_window_get_frame_timestamps(s->win.get(), framesAgo, 2018 postedTime, acquireTime, refreshStartTime, GLCompositionDoneTime, 2019 displayRetireTime, releaseTime); 2020 2021 if (ret != NO_ERROR) { 2022 setError(EGL_BAD_ACCESS, EGL_FALSE); 2023 return EGL_FALSE; 2024 } 2025 2026 return EGL_TRUE; 2027 } 2028 2029 EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, 2030 EGLint timestamp) 2031 { 2032 clearError(); 2033 2034 const egl_display_ptr dp = validate_display(dpy); 2035 if (!dp) { 2036 setError(EGL_BAD_DISPLAY, EGL_FALSE); 2037 return EGL_FALSE; 2038 } 2039 2040 SurfaceRef _s(dp.get(), surface); 2041 if (!_s.get()) { 2042 setError(EGL_BAD_SURFACE, EGL_FALSE); 2043 return EGL_FALSE; 2044 } 2045 2046 switch (timestamp) { 2047 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS 2048 case EGL_QUEUE_TIME_ANDROID: 2049 case EGL_RENDERING_COMPLETE_TIME_ANDROID: 2050 case EGL_COMPOSITION_START_TIME_ANDROID: 2051 case EGL_COMPOSITION_FINISHED_TIME_ANDROID: 2052 case EGL_DISPLAY_RETIRE_TIME_ANDROID: 2053 case EGL_READS_DONE_TIME_ANDROID: 2054 return EGL_TRUE; 2055 #endif 2056 default: 2057 return EGL_FALSE; 2058 } 2059 } 2060