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