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