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