Home | History | Annotate | Download | only in EGL
      1 /*
      2  ** Copyright 2018, The Android Open Source Project
      3  **
      4  ** Licensed under the Apache License, Version 2.0 (the "License");
      5  ** you may not use this file except in compliance with the License.
      6  ** You may obtain a copy of the License at
      7  **
      8  **     http://www.apache.org/licenses/LICENSE-2.0
      9  **
     10  ** Unless required by applicable law or agreed to in writing, software
     11  ** distributed under the License is distributed on an "AS IS" BASIS,
     12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 
     17 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
     18 
     19 #include <EGL/egl.h>
     20 #include <EGL/eglext.h>
     21 
     22 #include "../egl_impl.h"
     23 
     24 #include "egl_layers.h"
     25 #include "egl_platform_entries.h"
     26 #include "egl_tls.h"
     27 #include "egl_trace.h"
     28 
     29 using namespace android;
     30 
     31 namespace android {
     32 
     33 extern EGLBoolean egl_init_drivers();
     34 
     35 } // namespace android
     36 
     37 static inline void clearError() {
     38     egl_tls_t::clearError();
     39 }
     40 
     41 EGLDisplay eglGetDisplay(EGLNativeDisplayType display) {
     42     ATRACE_CALL();
     43     clearError();
     44 
     45     if (egl_init_drivers() == EGL_FALSE) {
     46         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
     47     }
     48 
     49     // Call down the chain, which usually points directly to the impl
     50     // but may also be routed through layers
     51     egl_connection_t* const cnx = &gEGLImpl;
     52     return cnx->platform.eglGetDisplay(display);
     53 }
     54 
     55 EGLDisplay eglGetPlatformDisplay(EGLenum platform, EGLNativeDisplayType display,
     56                                  const EGLAttrib* attrib_list) {
     57     ATRACE_CALL();
     58     clearError();
     59 
     60     if (egl_init_drivers() == EGL_FALSE) {
     61         return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
     62     }
     63 
     64     // Call down the chain, which usually points directly to the impl
     65     // but may also be routed through layers
     66     egl_connection_t* const cnx = &gEGLImpl;
     67     return cnx->platform.eglGetPlatformDisplay(platform, display, attrib_list);
     68 }
     69 
     70 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) {
     71     clearError();
     72 
     73     egl_connection_t* const cnx = &gEGLImpl;
     74     return cnx->platform.eglInitialize(dpy, major, minor);
     75 }
     76 
     77 EGLBoolean eglTerminate(EGLDisplay dpy) {
     78     clearError();
     79 
     80     egl_connection_t* const cnx = &gEGLImpl;
     81     return cnx->platform.eglTerminate(dpy);
     82 }
     83 
     84 EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size,
     85                          EGLint* num_config) {
     86     clearError();
     87 
     88     egl_connection_t* const cnx = &gEGLImpl;
     89     return cnx->platform.eglGetConfigs(dpy, configs, config_size, num_config);
     90 }
     91 
     92 EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs,
     93                            EGLint config_size, EGLint* num_config) {
     94     clearError();
     95 
     96     egl_connection_t* const cnx = &gEGLImpl;
     97     return cnx->platform.eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
     98 }
     99 
    100 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) {
    101     clearError();
    102 
    103     egl_connection_t* const cnx = &gEGLImpl;
    104     return cnx->platform.eglGetConfigAttrib(dpy, config, attribute, value);
    105 }
    106 
    107 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window,
    108                                   const EGLint* attrib_list) {
    109     clearError();
    110 
    111     egl_connection_t* const cnx = &gEGLImpl;
    112     return cnx->platform.eglCreateWindowSurface(dpy, config, window, attrib_list);
    113 }
    114 
    115 EGLSurface eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void* native_window,
    116                                           const EGLAttrib* attrib_list) {
    117     clearError();
    118 
    119     egl_connection_t* const cnx = &gEGLImpl;
    120     return cnx->platform.eglCreatePlatformWindowSurface(dpy, config, native_window, attrib_list);
    121 }
    122 
    123 EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap,
    124                                   const EGLint* attrib_list) {
    125     clearError();
    126 
    127     egl_connection_t* const cnx = &gEGLImpl;
    128     return cnx->platform.eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
    129 }
    130 
    131 EGLSurface eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void* native_pixmap,
    132                                           const EGLAttrib* attrib_list) {
    133     clearError();
    134 
    135     egl_connection_t* const cnx = &gEGLImpl;
    136     return cnx->platform.eglCreatePlatformPixmapSurface(dpy, config, native_pixmap, attrib_list);
    137 }
    138 
    139 EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) {
    140     clearError();
    141 
    142     egl_connection_t* const cnx = &gEGLImpl;
    143     return cnx->platform.eglCreatePbufferSurface(dpy, config, attrib_list);
    144 }
    145 
    146 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) {
    147     clearError();
    148 
    149     egl_connection_t* const cnx = &gEGLImpl;
    150     return cnx->platform.eglDestroySurface(dpy, surface);
    151 }
    152 
    153 EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value) {
    154     clearError();
    155 
    156     egl_connection_t* const cnx = &gEGLImpl;
    157     return cnx->platform.eglQuerySurface(dpy, surface, attribute, value);
    158 }
    159 
    160 void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
    161     ATRACE_CALL();
    162     clearError();
    163 
    164     egl_connection_t* const cnx = &gEGLImpl;
    165     cnx->platform.eglBeginFrame(dpy, surface);
    166 }
    167 
    168 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
    169                             const EGLint* attrib_list) {
    170     clearError();
    171 
    172     egl_connection_t* const cnx = &gEGLImpl;
    173     return cnx->platform.eglCreateContext(dpy, config, share_list, attrib_list);
    174 }
    175 
    176 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
    177     clearError();
    178 
    179     egl_connection_t* const cnx = &gEGLImpl;
    180     return cnx->platform.eglDestroyContext(dpy, ctx);
    181 }
    182 
    183 EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) {
    184     clearError();
    185 
    186     egl_connection_t* const cnx = &gEGLImpl;
    187     return cnx->platform.eglMakeCurrent(dpy, draw, read, ctx);
    188 }
    189 
    190 EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) {
    191     clearError();
    192 
    193     egl_connection_t* const cnx = &gEGLImpl;
    194     return cnx->platform.eglQueryContext(dpy, ctx, attribute, value);
    195 }
    196 
    197 EGLContext eglGetCurrentContext(void) {
    198     clearError();
    199 
    200     egl_connection_t* const cnx = &gEGLImpl;
    201     return cnx->platform.eglGetCurrentContext();
    202 }
    203 
    204 EGLSurface eglGetCurrentSurface(EGLint readdraw) {
    205     clearError();
    206 
    207     egl_connection_t* const cnx = &gEGLImpl;
    208     return cnx->platform.eglGetCurrentSurface(readdraw);
    209 }
    210 
    211 EGLDisplay eglGetCurrentDisplay(void) {
    212     clearError();
    213 
    214     egl_connection_t* const cnx = &gEGLImpl;
    215     return cnx->platform.eglGetCurrentDisplay();
    216 }
    217 
    218 EGLBoolean eglWaitGL(void) {
    219     clearError();
    220 
    221     egl_connection_t* const cnx = &gEGLImpl;
    222     return cnx->platform.eglWaitGL();
    223 }
    224 
    225 EGLBoolean eglWaitNative(EGLint engine) {
    226     clearError();
    227 
    228     egl_connection_t* const cnx = &gEGLImpl;
    229     return cnx->platform.eglWaitNative(engine);
    230 }
    231 
    232 EGLint eglGetError(void) {
    233     egl_connection_t* const cnx = &gEGLImpl;
    234     return cnx->platform.eglGetError();
    235 }
    236 
    237 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char* procname) {
    238     // eglGetProcAddress() could be the very first function called
    239     // in which case we must make sure we've initialized ourselves, this
    240     // happens the first time egl_get_display() is called.
    241 
    242     clearError();
    243 
    244     if (egl_init_drivers() == EGL_FALSE) {
    245         setError(EGL_BAD_PARAMETER, NULL);
    246         return nullptr;
    247     }
    248 
    249     egl_connection_t* const cnx = &gEGLImpl;
    250     return cnx->platform.eglGetProcAddress(procname);
    251 }
    252 
    253 EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw, EGLint* rects,
    254                                        EGLint n_rects) {
    255     ATRACE_CALL();
    256     clearError();
    257 
    258     egl_connection_t* const cnx = &gEGLImpl;
    259     return cnx->platform.eglSwapBuffersWithDamageKHR(dpy, draw, rects, n_rects);
    260 }
    261 
    262 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
    263     ATRACE_CALL();
    264     clearError();
    265 
    266     egl_connection_t* const cnx = &gEGLImpl;
    267     return cnx->platform.eglSwapBuffers(dpy, surface);
    268 }
    269 
    270 EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target) {
    271     clearError();
    272 
    273     egl_connection_t* const cnx = &gEGLImpl;
    274     return cnx->platform.eglCopyBuffers(dpy, surface, target);
    275 }
    276 
    277 const char* eglQueryString(EGLDisplay dpy, EGLint name) {
    278     clearError();
    279 
    280     egl_connection_t* const cnx = &gEGLImpl;
    281     return cnx->platform.eglQueryString(dpy, name);
    282 }
    283 
    284 extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name) {
    285     clearError();
    286 
    287     egl_connection_t* const cnx = &gEGLImpl;
    288     return cnx->platform.eglQueryStringImplementationANDROID(dpy, name);
    289 }
    290 
    291 EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) {
    292     clearError();
    293 
    294     egl_connection_t* const cnx = &gEGLImpl;
    295     return cnx->platform.eglSurfaceAttrib(dpy, surface, attribute, value);
    296 }
    297 
    298 EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
    299     clearError();
    300 
    301     egl_connection_t* const cnx = &gEGLImpl;
    302     return cnx->platform.eglBindTexImage(dpy, surface, buffer);
    303 }
    304 
    305 EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
    306     clearError();
    307 
    308     egl_connection_t* const cnx = &gEGLImpl;
    309     return cnx->platform.eglReleaseTexImage(dpy, surface, buffer);
    310 }
    311 
    312 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) {
    313     clearError();
    314 
    315     egl_connection_t* const cnx = &gEGLImpl;
    316     return cnx->platform.eglSwapInterval(dpy, interval);
    317 }
    318 
    319 EGLBoolean eglWaitClient(void) {
    320     clearError();
    321 
    322     egl_connection_t* const cnx = &gEGLImpl;
    323     return cnx->platform.eglWaitClient();
    324 }
    325 
    326 EGLBoolean eglBindAPI(EGLenum api) {
    327     clearError();
    328 
    329     if (egl_init_drivers() == EGL_FALSE) {
    330         return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
    331     }
    332 
    333     egl_connection_t* const cnx = &gEGLImpl;
    334     return cnx->platform.eglBindAPI(api);
    335 }
    336 
    337 EGLenum eglQueryAPI(void) {
    338     clearError();
    339 
    340     if (egl_init_drivers() == EGL_FALSE) {
    341         return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
    342     }
    343 
    344     egl_connection_t* const cnx = &gEGLImpl;
    345     return cnx->platform.eglQueryAPI();
    346 }
    347 
    348 EGLBoolean eglReleaseThread(void) {
    349     clearError();
    350 
    351     egl_connection_t* const cnx = &gEGLImpl;
    352     return cnx->platform.eglReleaseThread();
    353 }
    354 
    355 EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
    356                                             EGLConfig config, const EGLint* attrib_list) {
    357     clearError();
    358 
    359     egl_connection_t* const cnx = &gEGLImpl;
    360     return cnx->platform.eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config,
    361                                                           attrib_list);
    362 }
    363 
    364 EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, const EGLint* attrib_list) {
    365     clearError();
    366 
    367     egl_connection_t* const cnx = &gEGLImpl;
    368     return cnx->platform.eglLockSurfaceKHR(dpy, surface, attrib_list);
    369 }
    370 
    371 EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface) {
    372     clearError();
    373 
    374     egl_connection_t* const cnx = &gEGLImpl;
    375     return cnx->platform.eglUnlockSurfaceKHR(dpy, surface);
    376 }
    377 
    378 EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
    379                               EGLClientBuffer buffer, const EGLint* attrib_list) {
    380     clearError();
    381 
    382     egl_connection_t* const cnx = &gEGLImpl;
    383     return cnx->platform.eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
    384 }
    385 
    386 EGLImage eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer,
    387                         const EGLAttrib* attrib_list) {
    388     clearError();
    389 
    390     egl_connection_t* const cnx = &gEGLImpl;
    391     return cnx->platform.eglCreateImage(dpy, ctx, target, buffer, attrib_list);
    392 }
    393 
    394 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) {
    395     clearError();
    396 
    397     egl_connection_t* const cnx = &gEGLImpl;
    398     return cnx->platform.eglDestroyImageKHR(dpy, img);
    399 }
    400 
    401 EGLBoolean eglDestroyImage(EGLDisplay dpy, EGLImageKHR img) {
    402     clearError();
    403 
    404     egl_connection_t* const cnx = &gEGLImpl;
    405     return cnx->platform.eglDestroyImage(dpy, img);
    406 }
    407 
    408 // ----------------------------------------------------------------------------
    409 // EGL_EGLEXT_VERSION 5
    410 // ----------------------------------------------------------------------------
    411 
    412 EGLSyncKHR eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib* attrib_list) {
    413     clearError();
    414 
    415     egl_connection_t* const cnx = &gEGLImpl;
    416     return cnx->platform.eglCreateSync(dpy, type, attrib_list);
    417 }
    418 
    419 EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) {
    420     clearError();
    421 
    422     egl_connection_t* const cnx = &gEGLImpl;
    423     return cnx->platform.eglCreateSyncKHR(dpy, type, attrib_list);
    424 }
    425 
    426 EGLBoolean eglDestroySync(EGLDisplay dpy, EGLSyncKHR sync) {
    427     clearError();
    428 
    429     egl_connection_t* const cnx = &gEGLImpl;
    430     return cnx->platform.eglDestroySync(dpy, sync);
    431 }
    432 
    433 EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) {
    434     clearError();
    435 
    436     egl_connection_t* const cnx = &gEGLImpl;
    437     return cnx->platform.eglDestroySyncKHR(dpy, sync);
    438 }
    439 
    440 EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
    441     clearError();
    442 
    443     egl_connection_t* const cnx = &gEGLImpl;
    444     return cnx->platform.eglSignalSyncKHR(dpy, sync, mode);
    445 }
    446 
    447 EGLint eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTimeKHR timeout) {
    448     clearError();
    449 
    450     egl_connection_t* const cnx = &gEGLImpl;
    451     return cnx->platform.eglClientWaitSyncKHR(dpy, sync, flags, timeout);
    452 }
    453 
    454 EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
    455     clearError();
    456 
    457     egl_connection_t* const cnx = &gEGLImpl;
    458     return cnx->platform.eglClientWaitSyncKHR(dpy, sync, flags, timeout);
    459 }
    460 
    461 EGLBoolean eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib* value) {
    462     clearError();
    463 
    464     egl_connection_t* const cnx = &gEGLImpl;
    465     return cnx->platform.eglGetSyncAttrib(dpy, sync, attribute, value);
    466 }
    467 
    468 EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint* value) {
    469     clearError();
    470 
    471     egl_connection_t* const cnx = &gEGLImpl;
    472     return cnx->platform.eglGetSyncAttribKHR(dpy, sync, attribute, value);
    473 }
    474 
    475 EGLStreamKHR eglCreateStreamKHR(EGLDisplay dpy, const EGLint* attrib_list) {
    476     clearError();
    477 
    478     egl_connection_t* const cnx = &gEGLImpl;
    479     return cnx->platform.eglCreateStreamKHR(dpy, attrib_list);
    480 }
    481 
    482 EGLBoolean eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) {
    483     clearError();
    484 
    485     egl_connection_t* const cnx = &gEGLImpl;
    486     return cnx->platform.eglDestroyStreamKHR(dpy, stream);
    487 }
    488 
    489 EGLBoolean eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
    490                               EGLint value) {
    491     clearError();
    492 
    493     egl_connection_t* const cnx = &gEGLImpl;
    494     return cnx->platform.eglStreamAttribKHR(dpy, stream, attribute, value);
    495 }
    496 
    497 EGLBoolean eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
    498                              EGLint* value) {
    499     clearError();
    500 
    501     egl_connection_t* const cnx = &gEGLImpl;
    502     return cnx->platform.eglQueryStreamKHR(dpy, stream, attribute, value);
    503 }
    504 
    505 EGLBoolean eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
    506                                 EGLuint64KHR* value) {
    507     clearError();
    508 
    509     egl_connection_t* const cnx = &gEGLImpl;
    510     return cnx->platform.eglQueryStreamu64KHR(dpy, stream, attribute, value);
    511 }
    512 
    513 EGLBoolean eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
    514                                  EGLTimeKHR* value) {
    515     clearError();
    516 
    517     egl_connection_t* const cnx = &gEGLImpl;
    518     return cnx->platform.eglQueryStreamTimeKHR(dpy, stream, attribute, value);
    519 }
    520 
    521 EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream,
    522                                              const EGLint* attrib_list) {
    523     clearError();
    524 
    525     egl_connection_t* const cnx = &gEGLImpl;
    526     return cnx->platform.eglCreateStreamProducerSurfaceKHR(dpy, config, stream, attrib_list);
    527 }
    528 
    529 EGLBoolean eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream) {
    530     clearError();
    531 
    532     egl_connection_t* const cnx = &gEGLImpl;
    533     return cnx->platform.eglStreamConsumerGLTextureExternalKHR(dpy, stream);
    534 }
    535 
    536 EGLBoolean eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream) {
    537     clearError();
    538 
    539     egl_connection_t* const cnx = &gEGLImpl;
    540     return cnx->platform.eglStreamConsumerAcquireKHR(dpy, stream);
    541 }
    542 
    543 EGLBoolean eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream) {
    544     clearError();
    545 
    546     egl_connection_t* const cnx = &gEGLImpl;
    547     return cnx->platform.eglStreamConsumerReleaseKHR(dpy, stream);
    548 }
    549 
    550 EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR(EGLDisplay dpy, EGLStreamKHR stream) {
    551     clearError();
    552 
    553     egl_connection_t* const cnx = &gEGLImpl;
    554     return cnx->platform.eglGetStreamFileDescriptorKHR(dpy, stream);
    555 }
    556 
    557 EGLStreamKHR eglCreateStreamFromFileDescriptorKHR(EGLDisplay dpy,
    558                                                   EGLNativeFileDescriptorKHR file_descriptor) {
    559     clearError();
    560 
    561     egl_connection_t* const cnx = &gEGLImpl;
    562     return cnx->platform.eglCreateStreamFromFileDescriptorKHR(dpy, file_descriptor);
    563 }
    564 
    565 EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
    566     clearError();
    567     egl_connection_t* const cnx = &gEGLImpl;
    568     return cnx->platform.eglWaitSyncKHR(dpy, sync, flags);
    569 }
    570 
    571 EGLBoolean eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) {
    572     clearError();
    573     egl_connection_t* const cnx = &gEGLImpl;
    574     return cnx->platform.eglWaitSync(dpy, sync, flags);
    575 }
    576 
    577 EGLint eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync) {
    578     clearError();
    579 
    580     egl_connection_t* const cnx = &gEGLImpl;
    581     return cnx->platform.eglDupNativeFenceFDANDROID(dpy, sync);
    582 }
    583 
    584 EGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time) {
    585     clearError();
    586 
    587     egl_connection_t* const cnx = &gEGLImpl;
    588     return cnx->platform.eglPresentationTimeANDROID(dpy, surface, time);
    589 }
    590 
    591 EGLClientBuffer eglGetNativeClientBufferANDROID(const AHardwareBuffer* buffer) {
    592     clearError();
    593     egl_connection_t* const cnx = &gEGLImpl;
    594     return cnx->platform.eglGetNativeClientBufferANDROID(buffer);
    595 }
    596 
    597 EGLuint64NV eglGetSystemTimeFrequencyNV() {
    598     clearError();
    599 
    600     if (egl_init_drivers() == EGL_FALSE) {
    601         return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
    602     }
    603 
    604     egl_connection_t* const cnx = &gEGLImpl;
    605     return cnx->platform.eglGetSystemTimeFrequencyNV();
    606 }
    607 
    608 EGLuint64NV eglGetSystemTimeNV() {
    609     clearError();
    610 
    611     if (egl_init_drivers() == EGL_FALSE) {
    612         return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
    613     }
    614 
    615     egl_connection_t* const cnx = &gEGLImpl;
    616     return cnx->platform.eglGetSystemTimeNV();
    617 }
    618 
    619 EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface, EGLint* rects,
    620                                  EGLint n_rects) {
    621     clearError();
    622 
    623     egl_connection_t* const cnx = &gEGLImpl;
    624     return cnx->platform.eglSetDamageRegionKHR(dpy, surface, rects, n_rects);
    625 }
    626 
    627 EGLBoolean eglGetNextFrameIdANDROID(EGLDisplay dpy, EGLSurface surface, EGLuint64KHR* frameId) {
    628     clearError();
    629 
    630     egl_connection_t* const cnx = &gEGLImpl;
    631     return cnx->platform.eglGetNextFrameIdANDROID(dpy, surface, frameId);
    632 }
    633 
    634 EGLBoolean eglGetCompositorTimingANDROID(EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps,
    635                                          const EGLint* names, EGLnsecsANDROID* values) {
    636     clearError();
    637 
    638     egl_connection_t* const cnx = &gEGLImpl;
    639     return cnx->platform.eglGetCompositorTimingANDROID(dpy, surface, numTimestamps, names, values);
    640 }
    641 
    642 EGLBoolean eglGetCompositorTimingSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint name) {
    643     clearError();
    644 
    645     egl_connection_t* const cnx = &gEGLImpl;
    646     return cnx->platform.eglGetCompositorTimingSupportedANDROID(dpy, surface, name);
    647 }
    648 
    649 EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId,
    650                                         EGLint numTimestamps, const EGLint* timestamps,
    651                                         EGLnsecsANDROID* values) {
    652     clearError();
    653 
    654     egl_connection_t* const cnx = &gEGLImpl;
    655     return cnx->platform.eglGetFrameTimestampsANDROID(dpy, surface, frameId, numTimestamps,
    656                                                       timestamps, values);
    657 }
    658 
    659 EGLBoolean eglGetFrameTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface,
    660                                                 EGLint timestamp) {
    661     clearError();
    662 
    663     egl_connection_t* const cnx = &gEGLImpl;
    664     return cnx->platform.eglGetFrameTimestampSupportedANDROID(dpy, surface, timestamp);
    665 }
    666