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