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