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