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