Home | History | Annotate | Download | only in egl
      1 /*
      2 * Copyright (C) 2011 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 #include <assert.h>
     18 #include "HostConnection.h"
     19 #include "ThreadInfo.h"
     20 #include "eglDisplay.h"
     21 #include "eglSync.h"
     22 #include "egl_ftable.h"
     23 #include <cutils/log.h>
     24 #include <cutils/properties.h>
     25 #include "goldfish_sync.h"
     26 #include "gralloc_cb.h"
     27 #include "GLClientState.h"
     28 #include "GLSharedGroup.h"
     29 #include "eglContext.h"
     30 #include "ClientAPIExts.h"
     31 #include "EGLImage.h"
     32 #include "ProcessPipe.h"
     33 
     34 #include "GLEncoder.h"
     35 #ifdef WITH_GLES2
     36 #include "GL2Encoder.h"
     37 #endif
     38 
     39 #include <GLES3/gl31.h>
     40 
     41 #if PLATFORM_SDK_VERSION < 18
     42 #define override
     43 #endif
     44 
     45 #if PLATFORM_SDK_VERSION >= 16
     46 #include <system/window.h>
     47 #else // PLATFORM_SDK_VERSION >= 16
     48 #include <private/ui/android_natives_priv.h>
     49 #endif // PLATFORM_SDK_VERSION >= 16
     50 
     51 #if PLATFORM_SDK_VERSION <= 16
     52 #define queueBuffer_DEPRECATED queueBuffer
     53 #define dequeueBuffer_DEPRECATED dequeueBuffer
     54 #define cancelBuffer_DEPRECATED cancelBuffer
     55 #endif // PLATFORM_SDK_VERSION <= 16
     56 
     57 #define DEBUG_EGL 0
     58 
     59 #if DEBUG_EGL
     60 #define DPRINT(fmt,...) ALOGD("%s: " fmt, __FUNCTION__, ##__VA_ARGS__);
     61 #else
     62 #define DPRINT(...)
     63 #endif
     64 
     65 template<typename T>
     66 static T setErrorFunc(GLint error, T returnValue) {
     67     getEGLThreadInfo()->eglError = error;
     68     return returnValue;
     69 }
     70 
     71 const char *  eglStrError(EGLint err)
     72 {
     73     switch (err){
     74         case EGL_SUCCESS:           return "EGL_SUCCESS";
     75         case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
     76         case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
     77         case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
     78         case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
     79         case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
     80         case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
     81         case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
     82         case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
     83         case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
     84         case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
     85         case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
     86         case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
     87         case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
     88         case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
     89         default: return "UNKNOWN";
     90     }
     91 }
     92 
     93 #define LOG_EGL_ERRORS 1
     94 
     95 #ifdef LOG_EGL_ERRORS
     96 
     97 #define setErrorReturn(error, retVal)     \
     98     {                                                \
     99         ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, error, eglStrError(error));     \
    100         return setErrorFunc(error, retVal);            \
    101     }
    102 
    103 #define RETURN_ERROR(ret,err)           \
    104     ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, err, eglStrError(err));    \
    105     getEGLThreadInfo()->eglError = err;    \
    106     return ret;
    107 
    108 #else //!LOG_EGL_ERRORS
    109 
    110 #define setErrorReturn(error, retVal) return setErrorFunc(error, retVal);
    111 
    112 #define RETURN_ERROR(ret,err)           \
    113     getEGLThreadInfo()->eglError = err; \
    114     return ret;
    115 
    116 #endif //LOG_EGL_ERRORS
    117 
    118 #define VALIDATE_CONFIG(cfg,ret) \
    119     if(((intptr_t)(cfg)<0)||((intptr_t)(cfg)>s_display.getNumConfigs())) { \
    120         RETURN_ERROR(ret,EGL_BAD_CONFIG); \
    121     }
    122 
    123 #define VALIDATE_DISPLAY(dpy,ret) \
    124     if ((dpy) != (EGLDisplay)&s_display) { \
    125         RETURN_ERROR(ret, EGL_BAD_DISPLAY);    \
    126     }
    127 
    128 #define VALIDATE_DISPLAY_INIT(dpy,ret) \
    129     VALIDATE_DISPLAY(dpy, ret)    \
    130     if (!s_display.initialized()) {        \
    131         RETURN_ERROR(ret, EGL_NOT_INITIALIZED);    \
    132     }
    133 
    134 #define DEFINE_HOST_CONNECTION \
    135     HostConnection *hostCon = HostConnection::get(); \
    136     ExtendedRCEncoderContext *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
    137 
    138 #define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \
    139     HostConnection *hostCon = HostConnection::get(); \
    140     if (!hostCon) { \
    141         ALOGE("egl: Failed to get host connection\n"); \
    142         return ret; \
    143     } \
    144     ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
    145     if (!rcEnc) { \
    146         ALOGE("egl: Failed to get renderControl encoder context\n"); \
    147         return ret; \
    148     }
    149 
    150 #define DEFINE_AND_VALIDATE_HOST_CONNECTION_FOR_TLS(ret, tls) \
    151     HostConnection *hostCon = HostConnection::getWithThreadInfo(tls); \
    152     if (!hostCon) { \
    153         ALOGE("egl: Failed to get host connection\n"); \
    154         return ret; \
    155     } \
    156     ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
    157     if (!rcEnc) { \
    158         ALOGE("egl: Failed to get renderControl encoder context\n"); \
    159         return ret; \
    160     }
    161 
    162 #define VALIDATE_CONTEXT_RETURN(context,ret)  \
    163     if (!(context)) {                         \
    164         RETURN_ERROR(ret,EGL_BAD_CONTEXT);    \
    165     }
    166 
    167 #define VALIDATE_SURFACE_RETURN(surface, ret)    \
    168     if ((surface) != EGL_NO_SURFACE) {    \
    169         egl_surface_t* s( static_cast<egl_surface_t*>(surface) );    \
    170         if (s->dpy != (EGLDisplay)&s_display)    \
    171             setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE);    \
    172     }
    173 
    174 // The one and only supported display object.
    175 static eglDisplay s_display;
    176 
    177 // Extra defines not in the official EGL spec yet,
    178 // but required in Android CTS.
    179 
    180 #define EGL_TIMESTAMPS_ANDROID 0x314D
    181 
    182 EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx, int maj, int min) :
    183     dpy(dpy),
    184     config(config),
    185     read(EGL_NO_SURFACE),
    186     draw(EGL_NO_SURFACE),
    187     shareCtx(shareCtx),
    188     rcContext(0),
    189     versionString(NULL),
    190     majorVersion(maj),
    191     minorVersion(min),
    192     vendorString(NULL) ,
    193     rendererString(NULL),
    194     shaderVersionString(NULL),
    195     extensionString(NULL),
    196     deletePending(0),
    197     goldfishSyncFd(-1)
    198 {
    199 
    200     DEFINE_HOST_CONNECTION;
    201     switch (rcEnc->getGLESMaxVersion()) {
    202         case GLES_MAX_VERSION_3_0:
    203             deviceMajorVersion = 3;
    204             deviceMinorVersion = 0;
    205             break;
    206         case GLES_MAX_VERSION_3_1:
    207             deviceMajorVersion = 3;
    208             deviceMinorVersion = 1;
    209             break;
    210         case GLES_MAX_VERSION_3_2:
    211             deviceMajorVersion = 3;
    212             deviceMinorVersion = 2;
    213             break;
    214         default:
    215             deviceMajorVersion = 2;
    216             deviceMinorVersion = 0;
    217             break;
    218     }
    219 
    220     flags = 0;
    221     clientState = new GLClientState(majorVersion, minorVersion);
    222      if (shareCtx)
    223         sharedGroup = shareCtx->getSharedGroup();
    224     else
    225         sharedGroup = GLSharedGroupPtr(new GLSharedGroup());
    226     assert(dpy == (EGLDisplay)&s_display);
    227     s_display.onCreateContext((EGLContext)this);
    228 };
    229 
    230 int EGLContext_t::getGoldfishSyncFd() {
    231     if (goldfishSyncFd < 0) {
    232         goldfishSyncFd = goldfish_sync_open();
    233     }
    234     return goldfishSyncFd;
    235 }
    236 
    237 EGLContext_t::~EGLContext_t()
    238 {
    239     if (goldfishSyncFd > 0) {
    240         goldfish_sync_close(goldfishSyncFd);
    241         goldfishSyncFd = -1;
    242     }
    243     assert(dpy == (EGLDisplay)&s_display);
    244     s_display.onDestroyContext((EGLContext)this);
    245     delete clientState;
    246     delete [] versionString;
    247     delete [] vendorString;
    248     delete [] rendererString;
    249     delete [] shaderVersionString;
    250     delete [] extensionString;
    251 }
    252 
    253 // ----------------------------------------------------------------------------
    254 //egl_surface_t
    255 
    256 //we don't need to handle depth since it's handled when window created on the host
    257 
    258 struct egl_surface_t {
    259 
    260     EGLDisplay          dpy;
    261     EGLConfig           config;
    262 
    263 
    264     egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType);
    265     virtual     ~egl_surface_t();
    266 
    267     virtual     void        setSwapInterval(int interval) = 0;
    268     virtual     EGLBoolean  swapBuffers() = 0;
    269 
    270     EGLint      getSwapBehavior() const;
    271     uint32_t    getRcSurface()   { return rcSurface; }
    272     EGLint      getSurfaceType() { return surfaceType; }
    273 
    274     EGLint      getWidth(){ return width; }
    275     EGLint      getHeight(){ return height; }
    276     EGLint      getNativeWidth(){ return nativeWidth; }
    277     EGLint      getNativeHeight(){ return nativeHeight; }
    278     void        setTextureFormat(EGLint _texFormat) { texFormat = _texFormat; }
    279     EGLint      getTextureFormat() { return texFormat; }
    280     void        setTextureTarget(EGLint _texTarget) { texTarget = _texTarget; }
    281     EGLint      getTextureTarget() { return texTarget; }
    282 
    283     virtual     void setCollectingTimestamps(EGLint collect) { }
    284     virtual     EGLint isCollectingTimestamps() const { return EGL_FALSE; }
    285 
    286 private:
    287     //
    288     //Surface attributes
    289     //
    290     EGLint      width;
    291     EGLint      height;
    292     EGLint      texFormat;
    293     EGLint      texTarget;
    294 
    295     // Width of the actual window being presented (not the EGL texture)
    296     // Give it some default values.
    297     int nativeWidth;
    298     int nativeHeight;
    299 
    300 protected:
    301     void        setWidth(EGLint w)  { width = w;  }
    302     void        setHeight(EGLint h) { height = h; }
    303     void        setNativeWidth(int w)  { nativeWidth = w;  }
    304     void        setNativeHeight(int h) { nativeHeight = h; }
    305 
    306     EGLint      surfaceType;
    307     uint32_t    rcSurface; //handle to surface created via remote control
    308 };
    309 
    310 egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType)
    311     : dpy(dpy), config(config), surfaceType(surfaceType), rcSurface(0)
    312 {
    313     width = 0;
    314     height = 0;
    315     // prevent div by 0 in EGL_(HORIZONTAL|VERTICAL)_RESOLUTION queries.
    316     nativeWidth = 1;
    317     nativeHeight = 1;
    318     texFormat = EGL_NO_TEXTURE;
    319     texTarget = EGL_NO_TEXTURE;
    320     assert(dpy == (EGLDisplay)&s_display);
    321     s_display.onCreateSurface((EGLSurface)this);
    322 }
    323 
    324 EGLint egl_surface_t::getSwapBehavior() const {
    325     return EGL_BUFFER_PRESERVED;
    326 }
    327 
    328 egl_surface_t::~egl_surface_t()
    329 {
    330     assert(dpy == (EGLDisplay)&s_display);
    331     s_display.onDestroySurface((EGLSurface)this);
    332 }
    333 
    334 // ----------------------------------------------------------------------------
    335 // egl_window_surface_t
    336 
    337 struct egl_window_surface_t : public egl_surface_t {
    338     static egl_window_surface_t* create(
    339             EGLDisplay dpy, EGLConfig config, EGLint surfType,
    340             ANativeWindow* window);
    341 
    342     virtual ~egl_window_surface_t();
    343 
    344     virtual void       setSwapInterval(int interval);
    345     virtual EGLBoolean swapBuffers();
    346 
    347     virtual     void        setCollectingTimestamps(EGLint collect)
    348         override { collectingTimestamps = (collect == EGL_TRUE) ? true : false; }
    349     virtual     EGLint isCollectingTimestamps() const override { return collectingTimestamps ? EGL_TRUE : EGL_FALSE; }
    350 
    351 
    352 private:
    353     egl_window_surface_t(
    354             EGLDisplay dpy, EGLConfig config, EGLint surfType,
    355             ANativeWindow* window);
    356     EGLBoolean init();
    357 
    358     ANativeWindow*              nativeWindow;
    359     android_native_buffer_t*    buffer;
    360     bool collectingTimestamps;
    361 };
    362 
    363 egl_window_surface_t::egl_window_surface_t (
    364         EGLDisplay dpy, EGLConfig config, EGLint surfType,
    365         ANativeWindow* window)
    366 :   egl_surface_t(dpy, config, surfType),
    367     nativeWindow(window),
    368     buffer(NULL),
    369     collectingTimestamps(false)
    370 {
    371     // keep a reference on the window
    372     nativeWindow->common.incRef(&nativeWindow->common);
    373 }
    374 
    375 
    376 EGLBoolean egl_window_surface_t::init()
    377 {
    378     if (nativeWindow->dequeueBuffer_DEPRECATED(nativeWindow, &buffer) != NO_ERROR) {
    379         setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
    380     }
    381     setWidth(buffer->width);
    382     setHeight(buffer->height);
    383 
    384     int nativeWidth, nativeHeight;
    385           nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &nativeWidth);
    386           nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &nativeHeight);
    387 
    388     setNativeWidth(nativeWidth);
    389     setNativeHeight(nativeHeight);
    390 
    391     DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
    392     rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config,
    393             getWidth(), getHeight());
    394     if (!rcSurface) {
    395         ALOGE("rcCreateWindowSurface returned 0");
    396         return EGL_FALSE;
    397     }
    398     rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
    399             ((cb_handle_t*)(buffer->handle))->hostHandle);
    400 
    401     return EGL_TRUE;
    402 }
    403 
    404 egl_window_surface_t* egl_window_surface_t::create(
    405         EGLDisplay dpy, EGLConfig config, EGLint surfType,
    406         ANativeWindow* window)
    407 {
    408     egl_window_surface_t* wnd = new egl_window_surface_t(
    409             dpy, config, surfType, window);
    410     if (wnd && !wnd->init()) {
    411         delete wnd;
    412         wnd = NULL;
    413     }
    414     return wnd;
    415 }
    416 
    417 egl_window_surface_t::~egl_window_surface_t() {
    418     DEFINE_HOST_CONNECTION;
    419     if (rcSurface && rcEnc) {
    420         rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
    421     }
    422     if (buffer) {
    423         nativeWindow->cancelBuffer_DEPRECATED(nativeWindow, buffer);
    424     }
    425     nativeWindow->common.decRef(&nativeWindow->common);
    426 }
    427 
    428 void egl_window_surface_t::setSwapInterval(int interval)
    429 {
    430     nativeWindow->setSwapInterval(nativeWindow, interval);
    431 }
    432 
    433 // createNativeSync() creates an OpenGL sync object on the host
    434 // using rcCreateSyncKHR. If necessary, a native fence FD will
    435 // also be created through the goldfish sync device.
    436 // Returns a handle to the host-side FenceSync object.
    437 static uint64_t createNativeSync(EGLenum type,
    438                                  const EGLint* attrib_list,
    439                                  int num_actual_attribs,
    440                                  bool destroy_when_signaled,
    441                                  int fd_in,
    442                                  int* fd_out) {
    443     DEFINE_HOST_CONNECTION;
    444 
    445     uint64_t sync_handle;
    446     uint64_t thread_handle;
    447 
    448     EGLint* actual_attribs =
    449         (EGLint*)(num_actual_attribs == 0 ? NULL : attrib_list);
    450 
    451     rcEnc->rcCreateSyncKHR(rcEnc, type,
    452                            actual_attribs,
    453                            num_actual_attribs * sizeof(EGLint),
    454                            destroy_when_signaled,
    455                            &sync_handle,
    456                            &thread_handle);
    457 
    458     if (type == EGL_SYNC_NATIVE_FENCE_ANDROID && fd_in < 0) {
    459         int queue_work_err =
    460             goldfish_sync_queue_work(
    461                     getEGLThreadInfo()->currentContext->getGoldfishSyncFd(),
    462                     sync_handle,
    463                     thread_handle,
    464                     fd_out);
    465 
    466         DPRINT("got native fence fd=%d queue_work_err=%d",
    467                *fd_out, queue_work_err);
    468     }
    469 
    470     return sync_handle;
    471 }
    472 
    473 // createGoldfishOpenGLNativeSync() is for creating host-only sync objects
    474 // that are needed by only this goldfish opengl driver,
    475 // such as in swapBuffers().
    476 // The guest will not see any of these, and these sync objects will be
    477 // destroyed on the host when signaled.
    478 // A native fence FD is possibly returned.
    479 static void createGoldfishOpenGLNativeSync(int* fd_out) {
    480     createNativeSync(EGL_SYNC_NATIVE_FENCE_ANDROID,
    481                      NULL /* empty attrib list */,
    482                      0 /* 0 attrib count */,
    483                      true /* destroy when signaled. this is host-only
    484                              and there will only be one waiter */,
    485                      -1 /* we want a new fd */,
    486                      fd_out);
    487 }
    488 
    489 EGLBoolean egl_window_surface_t::swapBuffers()
    490 {
    491 
    492     DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
    493 
    494     // Follow up flushWindowColorBuffer with a fence command.
    495     // When the fence command finishes,
    496     // we're sure that the buffer on the host
    497     // has been blitted.
    498     //
    499     // |presentFenceFd| guards the presentation of the
    500     // current frame with a goldfish sync fence fd.
    501     //
    502     // When |presentFenceFd| is signaled, the recipient
    503     // of the buffer that was sent through queueBuffer
    504     // can be sure that the buffer is current.
    505     //
    506     // If we don't take care of this synchronization,
    507     // an old frame can be processed by surfaceflinger,
    508     // resulting in out of order frames.
    509 
    510     int presentFenceFd = -1;
    511 
    512     if (buffer == NULL) {
    513         ALOGE("egl_window_surface_t::swapBuffers called with NULL buffer");
    514         setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
    515     }
    516 
    517 #if PLATFORM_SDK_VERSION <= 16
    518     rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface);
    519     // equivalent to glFinish if no native sync
    520     eglWaitClient();
    521     nativeWindow->queueBuffer(nativeWindow, buffer);
    522 #else
    523     if (rcEnc->hasNativeSync()) {
    524         rcEnc->rcFlushWindowColorBufferAsync(rcEnc, rcSurface);
    525         createGoldfishOpenGLNativeSync(&presentFenceFd);
    526     } else {
    527         rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface);
    528         // equivalent to glFinish if no native sync
    529         eglWaitClient();
    530     }
    531 
    532     DPRINT("queueBuffer with fence %d", presentFenceFd);
    533     nativeWindow->queueBuffer(nativeWindow, buffer, presentFenceFd);
    534 #endif
    535 
    536     DPRINT("calling dequeueBuffer...");
    537 
    538 #if PLATFORM_SDK_VERSION <= 16
    539     if (nativeWindow->dequeueBuffer(nativeWindow, &buffer)) {
    540         buffer = NULL;
    541         setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
    542     }
    543 #else
    544     int acquireFenceFd = -1;
    545     if (nativeWindow->dequeueBuffer(nativeWindow, &buffer, &acquireFenceFd)) {
    546         buffer = NULL;
    547         setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
    548     }
    549 
    550     DPRINT("dequeueBuffer with fence %d", acquireFenceFd);
    551 
    552     if (acquireFenceFd > 0) {
    553         close(acquireFenceFd);
    554     }
    555 #endif
    556 
    557     rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
    558             ((cb_handle_t *)(buffer->handle))->hostHandle);
    559 
    560     setWidth(buffer->width);
    561     setHeight(buffer->height);
    562 
    563     return EGL_TRUE;
    564 }
    565 
    566 // ----------------------------------------------------------------------------
    567 //egl_pbuffer_surface_t
    568 
    569 struct egl_pbuffer_surface_t : public egl_surface_t {
    570     static egl_pbuffer_surface_t* create(EGLDisplay dpy, EGLConfig config,
    571             EGLint surfType, int32_t w, int32_t h, GLenum pixelFormat);
    572 
    573     virtual ~egl_pbuffer_surface_t();
    574 
    575     virtual void       setSwapInterval(int interval) { (void)interval; }
    576     virtual EGLBoolean swapBuffers() { return EGL_TRUE; }
    577 
    578     uint32_t getRcColorBuffer() { return rcColorBuffer; }
    579 
    580 private:
    581     egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfType,
    582             int32_t w, int32_t h);
    583     EGLBoolean init(GLenum format);
    584 
    585     uint32_t rcColorBuffer;
    586 };
    587 
    588 egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config,
    589         EGLint surfType, int32_t w, int32_t h)
    590 :   egl_surface_t(dpy, config, surfType),
    591     rcColorBuffer(0)
    592 {
    593     setWidth(w);
    594     setHeight(h);
    595 }
    596 
    597 egl_pbuffer_surface_t::~egl_pbuffer_surface_t()
    598 {
    599     DEFINE_HOST_CONNECTION;
    600     if (rcEnc) {
    601         if (rcColorBuffer) rcEnc->rcCloseColorBuffer(rcEnc, rcColorBuffer);
    602         if (rcSurface)     rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
    603     }
    604 }
    605 
    606 EGLBoolean egl_pbuffer_surface_t::init(GLenum pixelFormat)
    607 {
    608     DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
    609 
    610     rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config,
    611             getWidth(), getHeight());
    612     if (!rcSurface) {
    613         ALOGE("rcCreateWindowSurface returned 0");
    614         return EGL_FALSE;
    615     }
    616 
    617     rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(), pixelFormat);
    618     if (!rcColorBuffer) {
    619         ALOGE("rcCreateColorBuffer returned 0");
    620         return EGL_FALSE;
    621     }
    622 
    623     rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, rcColorBuffer);
    624 
    625     return EGL_TRUE;
    626 }
    627 
    628 egl_pbuffer_surface_t* egl_pbuffer_surface_t::create(EGLDisplay dpy,
    629         EGLConfig config, EGLint surfType, int32_t w, int32_t h,
    630         GLenum pixelFormat)
    631 {
    632     egl_pbuffer_surface_t* pb = new egl_pbuffer_surface_t(dpy, config, surfType,
    633             w, h);
    634     if (pb && !pb->init(pixelFormat)) {
    635         delete pb;
    636         pb = NULL;
    637     }
    638     return pb;
    639 }
    640 
    641 static const char *getGLString(int glEnum)
    642 {
    643     EGLThreadInfo *tInfo = getEGLThreadInfo();
    644     if (!tInfo || !tInfo->currentContext) {
    645         return NULL;
    646     }
    647 
    648     const char** strPtr = NULL;
    649 
    650 #define GL_VENDOR                         0x1F00
    651 #define GL_RENDERER                       0x1F01
    652 #define GL_VERSION                        0x1F02
    653 #define GL_SHADING_LANGUAGE_VERSION       0x8B8C
    654 #define GL_EXTENSIONS                     0x1F03
    655 
    656     switch(glEnum) {
    657         case GL_VERSION:
    658             strPtr = &tInfo->currentContext->versionString;
    659             break;
    660         case GL_VENDOR:
    661             strPtr = &tInfo->currentContext->vendorString;
    662             break;
    663         case GL_RENDERER:
    664             strPtr = &tInfo->currentContext->rendererString;
    665             break;
    666         case GL_SHADING_LANGUAGE_VERSION:
    667             strPtr = &tInfo->currentContext->shaderVersionString;
    668             break;
    669         case GL_EXTENSIONS:
    670             strPtr = &tInfo->currentContext->extensionString;
    671             break;
    672     }
    673 
    674     if (!strPtr) {
    675         return NULL;
    676     }
    677 
    678     //
    679     // first query of that string - need to query host
    680     //
    681     DEFINE_AND_VALIDATE_HOST_CONNECTION(NULL);
    682     char *hostStr = NULL;
    683     int n = rcEnc->rcGetGLString(rcEnc, glEnum, NULL, 0);
    684     if (n < 0) {
    685         hostStr = new char[-n+1];
    686         n = rcEnc->rcGetGLString(rcEnc, glEnum, hostStr, -n);
    687         if (n <= 0) {
    688             delete [] hostStr;
    689             hostStr = NULL;
    690         }
    691     }
    692 
    693     //
    694     // keep the string in the context and return its value
    695     //
    696     *strPtr = hostStr;
    697     return hostStr;
    698 }
    699 
    700 // ----------------------------------------------------------------------------
    701 
    702 static EGLClient_eglInterface s_eglIface = {
    703     getThreadInfo: getEGLThreadInfo,
    704     getGLString: getGLString
    705 };
    706 
    707 #define DBG_FUNC DBG("%s\n", __FUNCTION__)
    708 EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
    709 {
    710     //
    711     // we support only EGL_DEFAULT_DISPLAY.
    712     //
    713     if (display_id != EGL_DEFAULT_DISPLAY) {
    714         return EGL_NO_DISPLAY;
    715     }
    716 
    717     return (EGLDisplay)&s_display;
    718 }
    719 
    720 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
    721 {
    722     VALIDATE_DISPLAY(dpy,EGL_FALSE);
    723 
    724     if (!s_display.initialize(&s_eglIface)) {
    725         return EGL_FALSE;
    726     }
    727     if (major!=NULL)
    728         *major = s_display.getVersionMajor();
    729     if (minor!=NULL)
    730         *minor = s_display.getVersionMinor();
    731     return EGL_TRUE;
    732 }
    733 
    734 EGLBoolean eglTerminate(EGLDisplay dpy)
    735 {
    736     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
    737 
    738     s_display.terminate();
    739     return EGL_TRUE;
    740 }
    741 
    742 EGLint eglGetError()
    743 {
    744     EGLint error = getEGLThreadInfo()->eglError;
    745     getEGLThreadInfo()->eglError = EGL_SUCCESS;
    746     return error;
    747 }
    748 
    749 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
    750 {
    751     // search in EGL function table
    752     for (int i=0; i<egl_num_funcs; i++) {
    753         if (!strcmp(egl_funcs_by_name[i].name, procname)) {
    754             return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc;
    755         }
    756     }
    757 
    758     // look in gles client api's extensions table
    759     return (__eglMustCastToProperFunctionPointerType)ClientAPIExts::getProcAddress(procname);
    760 
    761     // Fail - function not found.
    762     return NULL;
    763 }
    764 
    765 const char* eglQueryString(EGLDisplay dpy, EGLint name)
    766 {
    767     VALIDATE_DISPLAY_INIT(dpy, NULL);
    768 
    769     return s_display.queryString(name);
    770 }
    771 
    772 EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
    773 {
    774     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
    775 
    776     if(!num_config) {
    777         RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
    778     }
    779 
    780     GLint numConfigs = s_display.getNumConfigs();
    781     if (!configs) {
    782         *num_config = numConfigs;
    783         return EGL_TRUE;
    784     }
    785 
    786     EGLint i;
    787     for (i = 0 ; i < numConfigs && i < config_size ; i++) {
    788         *configs++ = (EGLConfig)(uintptr_t)i;
    789     }
    790     *num_config = i;
    791     return EGL_TRUE;
    792 }
    793 
    794 EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
    795 {
    796     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
    797 
    798     if (!num_config) {
    799         setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
    800     }
    801 
    802     int attribs_size = 0;
    803     if (attrib_list) {
    804         const EGLint * attrib_p = attrib_list;
    805         while (attrib_p[0] != EGL_NONE) {
    806             attribs_size += 2;
    807             attrib_p += 2;
    808         }
    809         attribs_size++; //for the terminating EGL_NONE
    810     }
    811 
    812     // API 19 passes EGL_SWAP_BEHAVIOR_PRESERVED_BIT to surface type,
    813     // while the host never supports it.
    814     // We remove the bit here.
    815     EGLint* local_attrib_list = NULL;
    816     if (PLATFORM_SDK_VERSION <= 19) {
    817         local_attrib_list = new EGLint[attribs_size];
    818         memcpy(local_attrib_list, attrib_list, attribs_size * sizeof(EGLint));
    819         EGLint* local_attrib_p = local_attrib_list;
    820         while (local_attrib_p[0] != EGL_NONE) {
    821             if (local_attrib_p[0] == EGL_SURFACE_TYPE) {
    822                 local_attrib_p[1] &= ~(EGLint)EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
    823             }
    824             local_attrib_p += 2;
    825         }
    826     }
    827 
    828     uint32_t* tempConfigs[config_size];
    829     DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
    830     *num_config = rcEnc->rcChooseConfig(rcEnc,
    831             local_attrib_list ? local_attrib_list:(EGLint*)attrib_list,
    832             attribs_size * sizeof(EGLint), (uint32_t*)tempConfigs, config_size);
    833 
    834     if (local_attrib_list) delete [] local_attrib_list;
    835     if (*num_config <= 0) {
    836         EGLint err = -(*num_config);
    837         *num_config = 0;
    838         switch (err) {
    839             case EGL_BAD_ATTRIBUTE:
    840                 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE);
    841             default:
    842                 return EGL_FALSE;
    843         }
    844     }
    845 
    846     if (configs!=NULL) {
    847         EGLint i=0;
    848         for (i=0;i<(*num_config);i++) {
    849              *((uintptr_t*)configs+i) = *((uint32_t*)tempConfigs+i);
    850         }
    851     }
    852 
    853     return EGL_TRUE;
    854 }
    855 
    856 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
    857 {
    858     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
    859     VALIDATE_CONFIG(config, EGL_FALSE);
    860 
    861     if (s_display.getConfigAttrib(config, attribute, value))
    862     {
    863         return EGL_TRUE;
    864     }
    865     else
    866     {
    867         ALOGD("%s: bad attrib 0x%x", __FUNCTION__, attribute);
    868         RETURN_ERROR(EGL_FALSE, EGL_BAD_ATTRIBUTE);
    869     }
    870 }
    871 
    872 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
    873 {
    874     (void)attrib_list;
    875 
    876     VALIDATE_DISPLAY_INIT(dpy, NULL);
    877     VALIDATE_CONFIG(config, EGL_FALSE);
    878     if (win == 0) {
    879         setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
    880     }
    881 
    882     EGLint surfaceType;
    883     if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)    return EGL_FALSE;
    884 
    885     if (!(surfaceType & EGL_WINDOW_BIT)) {
    886         setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
    887     }
    888 
    889     if (static_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
    890         setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
    891     }
    892 
    893     egl_surface_t* surface = egl_window_surface_t::create(
    894             &s_display, config, EGL_WINDOW_BIT, static_cast<ANativeWindow*>(win));
    895     if (!surface) {
    896         setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
    897     }
    898 
    899     return surface;
    900 }
    901 
    902 EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
    903 {
    904     VALIDATE_DISPLAY_INIT(dpy, NULL);
    905     VALIDATE_CONFIG(config, EGL_FALSE);
    906 
    907     EGLint surfaceType;
    908     if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)    return EGL_FALSE;
    909 
    910     if (!(surfaceType & EGL_PBUFFER_BIT)) {
    911         setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
    912     }
    913 
    914     int32_t w = 0;
    915     int32_t h = 0;
    916     EGLint texFormat = EGL_NO_TEXTURE;
    917     EGLint texTarget = EGL_NO_TEXTURE;
    918     while (attrib_list[0] != EGL_NONE) {
    919         switch (attrib_list[0]) {
    920             case EGL_WIDTH:
    921                 w = attrib_list[1];
    922                 if (w < 0) setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
    923                 break;
    924             case EGL_HEIGHT:
    925                 h = attrib_list[1];
    926                 if (h < 0) setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
    927                 break;
    928             case EGL_TEXTURE_FORMAT:
    929                 texFormat = attrib_list[1];
    930                 break;
    931             case EGL_TEXTURE_TARGET:
    932                 texTarget = attrib_list[1];
    933                 break;
    934             // the followings are not supported
    935             case EGL_LARGEST_PBUFFER:
    936             case EGL_MIPMAP_TEXTURE:
    937             case EGL_VG_ALPHA_FORMAT:
    938             case EGL_VG_COLORSPACE:
    939                 break;
    940             default:
    941                 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
    942         };
    943         attrib_list+=2;
    944     }
    945     if (((texFormat == EGL_NO_TEXTURE)&&(texTarget != EGL_NO_TEXTURE)) ||
    946         ((texFormat != EGL_NO_TEXTURE)&&(texTarget == EGL_NO_TEXTURE))) {
    947         setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
    948     }
    949     // TODO: check EGL_TEXTURE_FORMAT - need to support eglBindTexImage
    950 
    951     GLenum pixelFormat;
    952     if (s_display.getConfigGLPixelFormat(config, &pixelFormat) == EGL_FALSE)
    953         setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
    954 
    955     egl_surface_t* surface = egl_pbuffer_surface_t::create(dpy, config,
    956             EGL_PBUFFER_BIT, w, h, pixelFormat);
    957     if (!surface) {
    958         setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
    959     }
    960 
    961     //setup attributes
    962     surface->setTextureFormat(texFormat);
    963     surface->setTextureTarget(texTarget);
    964 
    965     return surface;
    966 }
    967 
    968 EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
    969 {
    970     //XXX: Pixmap not supported. The host cannot render to a pixmap resource
    971     //     located on host. In order to support Pixmaps we should either punt
    972     //     to s/w rendering -or- let the host render to a buffer that will be
    973     //     copied back to guest at some sync point. None of those methods not
    974     //     implemented and pixmaps are not used with OpenGL anyway ...
    975     VALIDATE_CONFIG(config, EGL_FALSE);
    976     (void)dpy;
    977     (void)pixmap;
    978     (void)attrib_list;
    979     return EGL_NO_SURFACE;
    980 }
    981 
    982 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
    983 {
    984     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
    985     VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
    986 
    987     egl_surface_t* surface(static_cast<egl_surface_t*>(eglSurface));
    988     delete surface;
    989 
    990     return EGL_TRUE;
    991 }
    992 
    993 static float s_getNativeDpi() {
    994     float nativeDPI = 560.0f;
    995     const char* dpiPropName = "qemu.sf.lcd_density";
    996     char dpiProp[PROPERTY_VALUE_MAX];
    997     if (property_get(dpiPropName, dpiProp, NULL) > 0) {
    998         nativeDPI = atof(dpiProp);
    999     }
   1000     return nativeDPI;
   1001 }
   1002 
   1003 EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribute, EGLint *value)
   1004 {
   1005     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
   1006     VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
   1007 
   1008     egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
   1009 
   1010     // Parameters involved in queries of EGL_(HORIZONTAL|VERTICAL)_RESOLUTION
   1011     float currWidth, currHeight, scaledResolution, effectiveSurfaceDPI;
   1012     EGLBoolean ret = EGL_TRUE;
   1013     switch (attribute) {
   1014         case EGL_CONFIG_ID:
   1015             ret = s_display.getConfigAttrib(surface->config, EGL_CONFIG_ID, value);
   1016             break;
   1017         case EGL_WIDTH:
   1018             *value = surface->getWidth();
   1019             break;
   1020         case EGL_HEIGHT:
   1021             *value = surface->getHeight();
   1022             break;
   1023         case EGL_TEXTURE_FORMAT:
   1024             if (surface->getSurfaceType() & EGL_PBUFFER_BIT) {
   1025                 *value = surface->getTextureFormat();
   1026             }
   1027             break;
   1028         case EGL_TEXTURE_TARGET:
   1029             if (surface->getSurfaceType() & EGL_PBUFFER_BIT) {
   1030                 *value = surface->getTextureTarget();
   1031             }
   1032             break;
   1033         case EGL_SWAP_BEHAVIOR:
   1034         {
   1035             EGLint surfaceType;
   1036             ret = s_display.getConfigAttrib(surface->config, EGL_SURFACE_TYPE,
   1037                     &surfaceType);
   1038             if (ret == EGL_TRUE) {
   1039                 if (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) {
   1040                     *value = EGL_BUFFER_PRESERVED;
   1041                 } else {
   1042                     *value = EGL_BUFFER_DESTROYED;
   1043                 }
   1044             }
   1045             break;
   1046         }
   1047         case EGL_LARGEST_PBUFFER:
   1048             // not modified for a window or pixmap surface
   1049             // and we ignore it when creating a PBuffer surface (default is EGL_FALSE)
   1050             if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = EGL_FALSE;
   1051             break;
   1052         case EGL_MIPMAP_TEXTURE:
   1053             // not modified for a window or pixmap surface
   1054             // and we ignore it when creating a PBuffer surface (default is 0)
   1055             if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = false;
   1056             break;
   1057         case EGL_MIPMAP_LEVEL:
   1058             // not modified for a window or pixmap surface
   1059             // and we ignore it when creating a PBuffer surface (default is 0)
   1060             if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = 0;
   1061             break;
   1062         case EGL_MULTISAMPLE_RESOLVE:
   1063             // ignored when creating the surface, return default
   1064             *value = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
   1065             break;
   1066         case EGL_HORIZONTAL_RESOLUTION:
   1067             // pixel/mm * EGL_DISPLAY_SCALING
   1068             // TODO: get the DPI from avd config
   1069             currWidth = surface->getWidth();
   1070             scaledResolution = currWidth / surface->getNativeWidth();
   1071             effectiveSurfaceDPI =
   1072                 scaledResolution * s_getNativeDpi() * EGL_DISPLAY_SCALING;
   1073             *value = (EGLint)(effectiveSurfaceDPI);
   1074             break;
   1075         case EGL_VERTICAL_RESOLUTION:
   1076             // pixel/mm * EGL_DISPLAY_SCALING
   1077             // TODO: get the real DPI from avd config
   1078             currHeight = surface->getHeight();
   1079             scaledResolution = currHeight / surface->getNativeHeight();
   1080             effectiveSurfaceDPI =
   1081                 scaledResolution * s_getNativeDpi() * EGL_DISPLAY_SCALING;
   1082             *value = (EGLint)(effectiveSurfaceDPI);
   1083             break;
   1084         case EGL_PIXEL_ASPECT_RATIO:
   1085             // w / h * EGL_DISPLAY_SCALING
   1086             // Please don't ask why * EGL_DISPLAY_SCALING, the document says it
   1087             *value = 1 * EGL_DISPLAY_SCALING;
   1088             break;
   1089         case EGL_RENDER_BUFFER:
   1090             switch (surface->getSurfaceType()) {
   1091                 case EGL_PBUFFER_BIT:
   1092                     *value = EGL_BACK_BUFFER;
   1093                     break;
   1094                 case EGL_PIXMAP_BIT:
   1095                     *value = EGL_SINGLE_BUFFER;
   1096                     break;
   1097                 case EGL_WINDOW_BIT:
   1098                     // ignored when creating the surface, return default
   1099                     *value = EGL_BACK_BUFFER;
   1100                     break;
   1101                 default:
   1102                     ALOGE("eglQuerySurface %x unknown surface type %x",
   1103                             attribute, surface->getSurfaceType());
   1104                     ret = setErrorFunc(EGL_BAD_ATTRIBUTE, EGL_FALSE);
   1105                     break;
   1106             }
   1107             break;
   1108         case EGL_VG_COLORSPACE:
   1109             // ignored when creating the surface, return default
   1110             *value = EGL_VG_COLORSPACE_sRGB;
   1111             break;
   1112         case EGL_VG_ALPHA_FORMAT:
   1113             // ignored when creating the surface, return default
   1114             *value = EGL_VG_ALPHA_FORMAT_NONPRE;
   1115             break;
   1116         case EGL_TIMESTAMPS_ANDROID:
   1117             *value = surface->isCollectingTimestamps();
   1118             break;
   1119         //TODO: complete other attributes
   1120         default:
   1121             ALOGE("eglQuerySurface %x  EGL_BAD_ATTRIBUTE", attribute);
   1122             ret = setErrorFunc(EGL_BAD_ATTRIBUTE, EGL_FALSE);
   1123             break;
   1124     }
   1125 
   1126     return ret;
   1127 }
   1128 
   1129 EGLBoolean eglBindAPI(EGLenum api)
   1130 {
   1131     if (api != EGL_OPENGL_ES_API)
   1132         setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
   1133     return EGL_TRUE;
   1134 }
   1135 
   1136 EGLenum eglQueryAPI()
   1137 {
   1138     return EGL_OPENGL_ES_API;
   1139 }
   1140 
   1141 EGLBoolean eglWaitClient()
   1142 {
   1143     return eglWaitGL();
   1144 }
   1145 
   1146 // We may need to trigger this directly from the TLS destructor.
   1147 static EGLBoolean s_eglReleaseThreadImpl(EGLThreadInfo* tInfo) {
   1148     if (!tInfo) return EGL_TRUE;
   1149 
   1150     tInfo->eglError = EGL_SUCCESS;
   1151     EGLContext_t* context = tInfo->currentContext;
   1152 
   1153     if (!context) return EGL_TRUE;
   1154 
   1155     // The following code is doing pretty much the same thing as
   1156     // eglMakeCurrent(&s_display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE)
   1157     // with the only issue that we do not require a valid display here.
   1158     DEFINE_AND_VALIDATE_HOST_CONNECTION_FOR_TLS(EGL_FALSE, tInfo);
   1159     // We are going to call makeCurrent on the null context and surface
   1160     // anyway once we are on the host, so skip rcMakeCurrent here.
   1161     // rcEnc->rcMakeCurrent(rcEnc, 0, 0, 0);
   1162     context->flags &= ~EGLContext_t::IS_CURRENT;
   1163     if (context->deletePending) {
   1164         if (context->rcContext) {
   1165             rcEnc->rcDestroyContext(rcEnc, context->rcContext);
   1166             context->rcContext = 0;
   1167         }
   1168         delete context;
   1169     }
   1170     tInfo->currentContext = 0;
   1171 
   1172     return EGL_TRUE;
   1173 }
   1174 
   1175 EGLBoolean eglReleaseThread()
   1176 {
   1177     return s_eglReleaseThreadImpl(getEGLThreadInfo());
   1178 }
   1179 
   1180 EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
   1181 {
   1182     //TODO
   1183     (void)dpy;
   1184     (void)buftype;
   1185     (void)buffer;
   1186     (void)config;
   1187     (void)attrib_list;
   1188     ALOGW("%s not implemented", __FUNCTION__);
   1189     return 0;
   1190 }
   1191 
   1192 EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
   1193 {
   1194     // Right now we don't do anything when using host GPU.
   1195     // This is purely just to pass the data through
   1196     // without issuing a warning. We may benefit from validating the
   1197     // display and surface for debug purposes.
   1198     // TODO: Find cases where we actually need to do something.
   1199     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
   1200     VALIDATE_SURFACE_RETURN(surface, EGL_FALSE);
   1201     if (surface == EGL_NO_SURFACE) {
   1202         setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
   1203     }
   1204 
   1205     (void)value;
   1206 
   1207     egl_surface_t* p_surface( static_cast<egl_surface_t*>(surface) );
   1208     switch (attribute) {
   1209     case EGL_MIPMAP_LEVEL:
   1210         return true;
   1211     case EGL_MULTISAMPLE_RESOLVE:
   1212     {
   1213         if (value == EGL_MULTISAMPLE_RESOLVE_BOX) {
   1214             EGLint surface_type;
   1215             s_display.getConfigAttrib(p_surface->config, EGL_SURFACE_TYPE, &surface_type);
   1216             if (0 == (surface_type & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)) {
   1217                 setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
   1218             }
   1219         }
   1220         return true;
   1221     }
   1222     case EGL_SWAP_BEHAVIOR:
   1223         if (value == EGL_BUFFER_PRESERVED) {
   1224             EGLint surface_type;
   1225             s_display.getConfigAttrib(p_surface->config, EGL_SURFACE_TYPE, &surface_type);
   1226             if (0 == (surface_type & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)) {
   1227                 setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
   1228             }
   1229         }
   1230         return true;
   1231     case EGL_TIMESTAMPS_ANDROID:
   1232         ALOGD("%s: set frame timestamps collecting %d\n", __func__, value);
   1233         p_surface->setCollectingTimestamps(value);
   1234         return true;
   1235     default:
   1236         ALOGW("%s: attr=0x%x not implemented", __FUNCTION__, attribute);
   1237         setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE);
   1238     }
   1239     return false;
   1240 }
   1241 
   1242 EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface eglSurface, EGLint buffer)
   1243 {
   1244     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
   1245     VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
   1246     if (eglSurface == EGL_NO_SURFACE) {
   1247         setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
   1248     }
   1249 
   1250     if (buffer != EGL_BACK_BUFFER) {
   1251         setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
   1252     }
   1253 
   1254     egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
   1255 
   1256     if (surface->getTextureFormat() == EGL_NO_TEXTURE) {
   1257         setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
   1258     }
   1259 
   1260     if (!(surface->getSurfaceType() & EGL_PBUFFER_BIT)) {
   1261         setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
   1262     }
   1263 
   1264     //It's now safe to cast to pbuffer surface
   1265     egl_pbuffer_surface_t* pbSurface = (egl_pbuffer_surface_t*)surface;
   1266 
   1267     DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
   1268     rcEnc->rcBindTexture(rcEnc, pbSurface->getRcColorBuffer());
   1269 
   1270     return GL_TRUE;
   1271 }
   1272 
   1273 EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
   1274 {
   1275     //TODO
   1276     (void)dpy;
   1277     (void)surface;
   1278     (void)buffer;
   1279     ALOGW("%s not implemented", __FUNCTION__);
   1280     return 0;
   1281 }
   1282 
   1283 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
   1284 {
   1285     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
   1286     DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
   1287 
   1288     EGLContext_t* ctx = getEGLThreadInfo()->currentContext;
   1289     if (!ctx) {
   1290         setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE);
   1291     }
   1292     if (!ctx->draw) {
   1293         setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
   1294     }
   1295     egl_surface_t* draw(static_cast<egl_surface_t*>(ctx->draw));
   1296     draw->setSwapInterval(interval);
   1297 
   1298     rcEnc->rcFBSetSwapInterval(rcEnc, interval); //TODO: implement on the host
   1299 
   1300     return EGL_TRUE;
   1301 }
   1302 
   1303 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
   1304 {
   1305     VALIDATE_DISPLAY_INIT(dpy, EGL_NO_CONTEXT);
   1306     VALIDATE_CONFIG(config, EGL_NO_CONTEXT);
   1307 
   1308     EGLint majorVersion = 1; //default
   1309     EGLint minorVersion = 0;
   1310     EGLint context_flags = 0;
   1311     EGLint profile_mask = 0;
   1312     EGLint reset_notification_strategy = 0;
   1313 
   1314     bool wantedMajorVersion = false;
   1315     bool wantedMinorVersion = false;
   1316 
   1317     while (attrib_list && attrib_list[0] != EGL_NONE) {
   1318            EGLint attrib_val = attrib_list[1];
   1319         switch(attrib_list[0]) {
   1320         case EGL_CONTEXT_MAJOR_VERSION_KHR:
   1321             majorVersion = attrib_val;
   1322             wantedMajorVersion = true;
   1323             break;
   1324         case EGL_CONTEXT_MINOR_VERSION_KHR:
   1325             minorVersion = attrib_val;
   1326             wantedMinorVersion = true;
   1327             break;
   1328         case EGL_CONTEXT_FLAGS_KHR:
   1329             if ((attrib_val | EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) ||
   1330                 (attrib_val | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR)  ||
   1331                 (attrib_val | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) {
   1332                 context_flags = attrib_val;
   1333             } else {
   1334                 RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE);
   1335             }
   1336             break;
   1337         case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
   1338             if ((attrib_val | EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR) ||
   1339                 (attrib_val | EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR)) {
   1340                 profile_mask = attrib_val;
   1341             } else {
   1342                 RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE);
   1343             }
   1344             break;
   1345         case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
   1346             switch (attrib_val) {
   1347             case EGL_NO_RESET_NOTIFICATION_KHR:
   1348             case EGL_LOSE_CONTEXT_ON_RESET_KHR:
   1349                 break;
   1350             default:
   1351                 RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE);
   1352             }
   1353             reset_notification_strategy = attrib_val;
   1354             break;
   1355         default:
   1356             setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
   1357         }
   1358         attrib_list+=2;
   1359     }
   1360 
   1361     // Support up to GLES 3.2 depending on advertised version from the host system.
   1362     DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT);
   1363     if (rcEnc->getGLESMaxVersion() >= GLES_MAX_VERSION_3_0) {
   1364         if (!wantedMajorVersion) {
   1365             majorVersion = 1;
   1366             wantedMinorVersion = false;
   1367         }
   1368 
   1369         if (wantedMajorVersion &&
   1370             majorVersion == 2) {
   1371             majorVersion = 3;
   1372             wantedMinorVersion = false;
   1373         }
   1374 
   1375         if (majorVersion == 3 && !wantedMinorVersion) {
   1376             switch (rcEnc->getGLESMaxVersion()) {
   1377                 case GLES_MAX_VERSION_3_0:
   1378                     minorVersion = 0;
   1379                     break;
   1380                 case GLES_MAX_VERSION_3_1:
   1381                     minorVersion = 1;
   1382                     break;
   1383                 case GLES_MAX_VERSION_3_2:
   1384                     minorVersion = 2;
   1385                     break;
   1386                 default:
   1387                     minorVersion = 0;
   1388                     break;
   1389             }
   1390         }
   1391     } else {
   1392         if (!wantedMajorVersion) {
   1393             majorVersion = 1;
   1394         }
   1395     }
   1396 
   1397     switch (majorVersion) {
   1398     case 1:
   1399     case 2:
   1400         break;
   1401     case 3:
   1402         if (rcEnc->getGLESMaxVersion() < GLES_MAX_VERSION_3_0) {
   1403             ALOGE("%s: EGL_BAD_CONFIG: no ES 3 support", __FUNCTION__);
   1404             setErrorReturn(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
   1405         }
   1406         switch (minorVersion) {
   1407             case 0:
   1408                 break;
   1409             case 1:
   1410                 if (rcEnc->getGLESMaxVersion() < GLES_MAX_VERSION_3_1) {
   1411                     ALOGE("%s: EGL_BAD_CONFIG: no ES 3.1 support", __FUNCTION__);
   1412                     setErrorReturn(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
   1413                 }
   1414                 break;
   1415             case 2:
   1416                 if (rcEnc->getGLESMaxVersion() < GLES_MAX_VERSION_3_2) {
   1417                     ALOGE("%s: EGL_BAD_CONFIG: no ES 3.2 support", __FUNCTION__);
   1418                     setErrorReturn(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
   1419                 }
   1420                 break;
   1421             default:
   1422                 ALOGE("%s: EGL_BAD_CONFIG: Unknown ES version %d.%d",
   1423                       __FUNCTION__, majorVersion, minorVersion);
   1424                 setErrorReturn(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
   1425         }
   1426         break;
   1427     default:
   1428         setErrorReturn(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
   1429     }
   1430 
   1431     uint32_t rcShareCtx = 0;
   1432     EGLContext_t * shareCtx = NULL;
   1433     if (share_context) {
   1434         shareCtx = static_cast<EGLContext_t*>(share_context);
   1435         rcShareCtx = shareCtx->rcContext;
   1436         if (shareCtx->dpy != dpy)
   1437             setErrorReturn(EGL_BAD_MATCH, EGL_NO_CONTEXT);
   1438     }
   1439 
   1440     // We've created EGL context. Disconnecting
   1441     // would be dangerous at this point.
   1442     hostCon->setGrallocOnly(false);
   1443 
   1444     int rcMajorVersion = majorVersion;
   1445     if (majorVersion == 3 && minorVersion == 1) {
   1446         rcMajorVersion = 4;
   1447     }
   1448     if (majorVersion == 3 && minorVersion == 2) {
   1449         rcMajorVersion = 4;
   1450     }
   1451     uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uintptr_t)config, rcShareCtx, rcMajorVersion);
   1452     if (!rcContext) {
   1453         ALOGE("rcCreateContext returned 0");
   1454         setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
   1455     }
   1456 
   1457     EGLContext_t * context = new EGLContext_t(dpy, config, shareCtx, majorVersion, minorVersion);
   1458     ALOGD("%s: %p: maj %d min %d rcv %d", __FUNCTION__, context, majorVersion, minorVersion, rcMajorVersion);
   1459     if (!context) {
   1460         ALOGE("could not alloc egl context!");
   1461         setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
   1462     }
   1463 
   1464     context->rcContext = rcContext;
   1465     return context;
   1466 }
   1467 
   1468 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
   1469 {
   1470     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
   1471     VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE);
   1472 
   1473     EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
   1474 
   1475     if (!context) return EGL_TRUE;
   1476 
   1477     if (getEGLThreadInfo()->currentContext == context) {
   1478         getEGLThreadInfo()->currentContext->deletePending = 1;
   1479         return EGL_TRUE;
   1480     }
   1481 
   1482     if (context->rcContext) {
   1483         DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
   1484         rcEnc->rcDestroyContext(rcEnc, context->rcContext);
   1485         context->rcContext = 0;
   1486     }
   1487 
   1488     delete context;
   1489     return EGL_TRUE;
   1490 }
   1491 
   1492 EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
   1493 {
   1494     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
   1495     VALIDATE_SURFACE_RETURN(draw, EGL_FALSE);
   1496     VALIDATE_SURFACE_RETURN(read, EGL_FALSE);
   1497 
   1498     // Only place to initialize the TLS destructor; any
   1499     // thread can suddenly jump in any eglMakeCurrent
   1500     setTlsDestructor((tlsDtorCallback)s_eglReleaseThreadImpl);
   1501 
   1502     if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT))
   1503         setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
   1504     if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT))
   1505         setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
   1506 
   1507     EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
   1508     uint32_t ctxHandle = (context) ? context->rcContext : 0;
   1509     egl_surface_t * drawSurf = static_cast<egl_surface_t *>(draw);
   1510     uint32_t drawHandle = (drawSurf) ? drawSurf->getRcSurface() : 0;
   1511     egl_surface_t * readSurf = static_cast<egl_surface_t *>(read);
   1512     uint32_t readHandle = (readSurf) ? readSurf->getRcSurface() : 0;
   1513 
   1514     //
   1515     // Nothing to do if no binding change has made
   1516     //
   1517     EGLThreadInfo *tInfo = getEGLThreadInfo();
   1518 
   1519     if (tInfo->currentContext == context &&
   1520         (context == NULL ||
   1521         (context && context->draw == draw && context->read == read))) {
   1522         return EGL_TRUE;
   1523     }
   1524 
   1525     if (tInfo->currentContext && tInfo->currentContext->deletePending) {
   1526         if (tInfo->currentContext != context) {
   1527             EGLContext_t * contextToDelete = tInfo->currentContext;
   1528             tInfo->currentContext = 0;
   1529             eglDestroyContext(dpy, contextToDelete);
   1530         }
   1531     }
   1532 
   1533     if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) {
   1534         // context is current to another thread
   1535         ALOGE("%s: error: EGL_BAD_ACCESS: context %p current to another thread!\n", __FUNCTION__, context);
   1536         setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE);
   1537     }
   1538 
   1539     DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
   1540     if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) {
   1541         ALOGE("rcMakeCurrent returned EGL_FALSE");
   1542         setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE);
   1543     }
   1544 
   1545     //Now make the local bind
   1546     if (context) {
   1547 
   1548         ALOGD("%s: %p: ver %d %d (tinfo %p)", __FUNCTION__, context, context->majorVersion, context->minorVersion, tInfo);
   1549         // This is a nontrivial context.
   1550         // The thread cannot be gralloc-only anymore.
   1551         hostCon->setGrallocOnly(false);
   1552         context->draw = draw;
   1553         context->read = read;
   1554         context->flags |= EGLContext_t::IS_CURRENT;
   1555         GLClientState* contextState =
   1556             context->getClientState();
   1557 
   1558         if (!hostCon->gl2Encoder()->isInitialized()) {
   1559             s_display.gles2_iface()->init();
   1560             hostCon->gl2Encoder()->setInitialized();
   1561             ClientAPIExts::initClientFuncs(s_display.gles2_iface(), 1);
   1562         }
   1563         if (contextState->needsInitFromCaps()) {
   1564             // Need to set the version first if
   1565             // querying caps, or validation will trip incorrectly.
   1566             hostCon->gl2Encoder()->setVersion(
   1567                 context->majorVersion,
   1568                 context->minorVersion,
   1569                 context->deviceMajorVersion,
   1570                 context->deviceMinorVersion);
   1571             // Get caps for indexed buffers from host.
   1572             // Some need a current context.
   1573             int max_transform_feedback_separate_attribs = 0;
   1574             int max_uniform_buffer_bindings = 0;
   1575             int max_atomic_counter_buffer_bindings = 0;
   1576             int max_shader_storage_buffer_bindings = 0;
   1577             int max_vertex_attrib_bindings = 0;
   1578             int max_color_attachments = 1;
   1579             int max_draw_buffers = 1;
   1580             if (context->majorVersion > 2) {
   1581                 s_display.gles2_iface()->getIntegerv(
   1582                         GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_transform_feedback_separate_attribs);
   1583                 s_display.gles2_iface()->getIntegerv(
   1584                         GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uniform_buffer_bindings);
   1585                 if (context->minorVersion > 0) {
   1586                     s_display.gles2_iface()->getIntegerv(
   1587                             GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &max_atomic_counter_buffer_bindings);
   1588                     s_display.gles2_iface()->getIntegerv(
   1589                             GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &max_shader_storage_buffer_bindings);
   1590                     s_display.gles2_iface()->getIntegerv(
   1591                             GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings);
   1592                 }
   1593                 s_display.gles2_iface()->getIntegerv(
   1594                         GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
   1595                 s_display.gles2_iface()->getIntegerv(
   1596                         GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
   1597             }
   1598             contextState->initFromCaps(
   1599                     max_transform_feedback_separate_attribs,
   1600                     max_uniform_buffer_bindings,
   1601                     max_atomic_counter_buffer_bindings,
   1602                     max_shader_storage_buffer_bindings,
   1603                     max_vertex_attrib_bindings,
   1604                     max_color_attachments,
   1605                     max_draw_buffers);
   1606         }
   1607 
   1608         // update the client state, share group, and version
   1609         if (context->majorVersion > 1) {
   1610             hostCon->gl2Encoder()->setClientStateMakeCurrent(
   1611                     contextState,
   1612                     context->majorVersion,
   1613                     context->minorVersion,
   1614                     context->deviceMajorVersion,
   1615                     context->deviceMinorVersion);
   1616             hostCon->gl2Encoder()->setSharedGroup(context->getSharedGroup());
   1617         }
   1618         else {
   1619             hostCon->glEncoder()->setClientState(context->getClientState());
   1620             hostCon->glEncoder()->setSharedGroup(context->getSharedGroup());
   1621         }
   1622     }
   1623     else if (tInfo->currentContext) {
   1624         //release ClientState & SharedGroup
   1625         if (tInfo->currentContext->majorVersion > 1) {
   1626             hostCon->gl2Encoder()->setClientState(NULL);
   1627             hostCon->gl2Encoder()->setSharedGroup(GLSharedGroupPtr(NULL));
   1628         }
   1629         else {
   1630             hostCon->glEncoder()->setClientState(NULL);
   1631             hostCon->glEncoder()->setSharedGroup(GLSharedGroupPtr(NULL));
   1632         }
   1633 
   1634     }
   1635 
   1636     if (tInfo->currentContext)
   1637         tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT;
   1638 
   1639     //Now make current
   1640     tInfo->currentContext = context;
   1641 
   1642     //Check maybe we need to init the encoder, if it's first eglMakeCurrent
   1643     if (tInfo->currentContext) {
   1644         if (tInfo->currentContext->majorVersion  > 1) {
   1645             if (!hostCon->gl2Encoder()->isInitialized()) {
   1646                 s_display.gles2_iface()->init();
   1647                 hostCon->gl2Encoder()->setInitialized();
   1648                 ClientAPIExts::initClientFuncs(s_display.gles2_iface(), 1);
   1649             }
   1650             const char* exts = getGLString(GL_EXTENSIONS);
   1651             if (exts) {
   1652                 hostCon->gl2Encoder()->setExtensions(exts);
   1653             }
   1654         }
   1655         else {
   1656             if (!hostCon->glEncoder()->isInitialized()) {
   1657                 s_display.gles_iface()->init();
   1658                 hostCon->glEncoder()->setInitialized();
   1659                 ClientAPIExts::initClientFuncs(s_display.gles_iface(), 0);
   1660             }
   1661         }
   1662     }
   1663 
   1664     return EGL_TRUE;
   1665 }
   1666 
   1667 EGLContext eglGetCurrentContext()
   1668 {
   1669     return getEGLThreadInfo()->currentContext;
   1670 }
   1671 
   1672 EGLSurface eglGetCurrentSurface(EGLint readdraw)
   1673 {
   1674     EGLContext_t * context = getEGLThreadInfo()->currentContext;
   1675     if (!context)
   1676         return EGL_NO_SURFACE; //not an error
   1677 
   1678     switch (readdraw) {
   1679         case EGL_READ:
   1680             return context->read;
   1681         case EGL_DRAW:
   1682             return context->draw;
   1683         default:
   1684             setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
   1685     }
   1686 }
   1687 
   1688 EGLDisplay eglGetCurrentDisplay()
   1689 {
   1690     EGLContext_t * context = getEGLThreadInfo()->currentContext;
   1691     if (!context)
   1692         return EGL_NO_DISPLAY; //not an error
   1693 
   1694     return context->dpy;
   1695 }
   1696 
   1697 EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
   1698 {
   1699     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
   1700     VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE);
   1701 
   1702     EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
   1703 
   1704     EGLBoolean ret = EGL_TRUE;
   1705     switch (attribute) {
   1706         case EGL_CONFIG_ID:
   1707             ret = s_display.getConfigAttrib(context->config, EGL_CONFIG_ID, value);
   1708             break;
   1709         case EGL_CONTEXT_CLIENT_TYPE:
   1710             *value = EGL_OPENGL_ES_API;
   1711             break;
   1712         case EGL_CONTEXT_CLIENT_VERSION:
   1713             *value = context->majorVersion;
   1714             break;
   1715         case EGL_RENDER_BUFFER:
   1716             if (!context->draw)
   1717                 *value = EGL_NONE;
   1718             else
   1719                 *value = EGL_BACK_BUFFER; //single buffer not supported
   1720             break;
   1721         default:
   1722             ALOGE("eglQueryContext %x  EGL_BAD_ATTRIBUTE", attribute);
   1723             setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE);
   1724             break;
   1725     }
   1726 
   1727     return ret;
   1728 }
   1729 
   1730 EGLBoolean eglWaitGL()
   1731 {
   1732     EGLThreadInfo *tInfo = getEGLThreadInfo();
   1733     if (!tInfo || !tInfo->currentContext) {
   1734         return EGL_FALSE;
   1735     }
   1736 
   1737     if (tInfo->currentContext->majorVersion > 1) {
   1738         s_display.gles2_iface()->finish();
   1739     }
   1740     else {
   1741         s_display.gles_iface()->finish();
   1742     }
   1743 
   1744     return EGL_TRUE;
   1745 }
   1746 
   1747 EGLBoolean eglWaitNative(EGLint engine)
   1748 {
   1749     (void)engine;
   1750     return EGL_TRUE;
   1751 }
   1752 
   1753 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface)
   1754 {
   1755     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
   1756     if (eglSurface == EGL_NO_SURFACE)
   1757         setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
   1758 
   1759     DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
   1760 
   1761     egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface);
   1762     if (d->dpy != dpy)
   1763         setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE);
   1764 
   1765     // post the surface
   1766     EGLBoolean ret = d->swapBuffers();
   1767 
   1768     hostCon->flush();
   1769     return ret;
   1770 }
   1771 
   1772 EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
   1773 {
   1774     //TODO :later
   1775     (void)dpy;
   1776     (void)surface;
   1777     (void)target;
   1778     return 0;
   1779 }
   1780 
   1781 EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
   1782 {
   1783     //TODO later
   1784     (void)display;
   1785     (void)surface;
   1786     (void)attrib_list;
   1787     return 0;
   1788 }
   1789 
   1790 EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
   1791 {
   1792     //TODO later
   1793     (void)display;
   1794     (void)surface;
   1795     return 0;
   1796 }
   1797 
   1798 EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
   1799 {
   1800     (void)attrib_list;
   1801 
   1802     VALIDATE_DISPLAY_INIT(dpy, EGL_NO_IMAGE_KHR);
   1803 
   1804     if (target == EGL_NATIVE_BUFFER_ANDROID) {
   1805         if (ctx != EGL_NO_CONTEXT) {
   1806             setErrorReturn(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
   1807         }
   1808 
   1809         android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
   1810 
   1811         if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
   1812             setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
   1813 
   1814         if (native_buffer->common.version != sizeof(android_native_buffer_t))
   1815             setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
   1816 
   1817         cb_handle_t *cb = (cb_handle_t *)(native_buffer->handle);
   1818 
   1819         switch (cb->format) {
   1820             case HAL_PIXEL_FORMAT_RGBA_8888:
   1821             case HAL_PIXEL_FORMAT_RGBX_8888:
   1822             case HAL_PIXEL_FORMAT_RGB_888:
   1823             case HAL_PIXEL_FORMAT_RGB_565:
   1824             case HAL_PIXEL_FORMAT_YV12:
   1825             case HAL_PIXEL_FORMAT_BGRA_8888:
   1826                 break;
   1827             default:
   1828                 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
   1829         }
   1830 
   1831         native_buffer->common.incRef(&native_buffer->common);
   1832 
   1833         EGLImage_t *image = new EGLImage_t();
   1834         image->dpy = dpy;
   1835         image->target = target;
   1836         image->native_buffer = native_buffer;
   1837 
   1838         return (EGLImageKHR)image;
   1839     }
   1840     else if (target == EGL_GL_TEXTURE_2D_KHR) {
   1841         VALIDATE_CONTEXT_RETURN(ctx, EGL_NO_IMAGE_KHR);
   1842 
   1843         EGLContext_t *context = static_cast<EGLContext_t*>(ctx);
   1844         DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_IMAGE_KHR);
   1845 
   1846         uint32_t ctxHandle = (context) ? context->rcContext : 0;
   1847         GLuint texture = (GLuint)reinterpret_cast<uintptr_t>(buffer);
   1848         uint32_t img = rcEnc->rcCreateClientImage(rcEnc, ctxHandle, target, texture);
   1849         EGLImage_t *image = new EGLImage_t();
   1850         image->dpy = dpy;
   1851         image->target = target;
   1852         image->host_egl_image = img;
   1853 
   1854         return (EGLImageKHR)image;
   1855     }
   1856 
   1857     setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
   1858 }
   1859 
   1860 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
   1861 {
   1862     VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
   1863     EGLImage_t *image = (EGLImage_t*)img;
   1864 
   1865     if (!image || image->dpy != dpy) {
   1866         RETURN_ERROR(EGL_FALSE, EGL_BAD_PARAMETER);
   1867     }
   1868 
   1869     if (image->target == EGL_NATIVE_BUFFER_ANDROID) {
   1870         android_native_buffer_t* native_buffer = image->native_buffer;
   1871 
   1872         if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
   1873             setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
   1874 
   1875         if (native_buffer->common.version != sizeof(android_native_buffer_t))
   1876             setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
   1877 
   1878         native_buffer->common.decRef(&native_buffer->common);
   1879         delete image;
   1880 
   1881         return EGL_TRUE;
   1882     }
   1883     else if (image->target == EGL_GL_TEXTURE_2D_KHR) {
   1884         uint32_t host_egl_image = image->host_egl_image;
   1885         delete image;
   1886         DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
   1887         return rcEnc->rcDestroyClientImage(rcEnc, host_egl_image);
   1888     }
   1889 
   1890     setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
   1891 }
   1892 
   1893 #define FENCE_SYNC_HANDLE (EGLSyncKHR)0xFE4CE
   1894 #define MAX_EGL_SYNC_ATTRIBS 10
   1895 
   1896 EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type,
   1897         const EGLint *attrib_list)
   1898 {
   1899     VALIDATE_DISPLAY(dpy, EGL_NO_SYNC_KHR);
   1900     DPRINT("type for eglCreateSyncKHR: 0x%x", type);
   1901 
   1902     DEFINE_HOST_CONNECTION;
   1903 
   1904     if ((type != EGL_SYNC_FENCE_KHR &&
   1905          type != EGL_SYNC_NATIVE_FENCE_ANDROID) ||
   1906         (type != EGL_SYNC_FENCE_KHR &&
   1907          !rcEnc->hasNativeSync())) {
   1908         setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
   1909     }
   1910 
   1911     EGLThreadInfo *tInfo = getEGLThreadInfo();
   1912     if (!tInfo || !tInfo->currentContext) {
   1913         setErrorReturn(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
   1914     }
   1915 
   1916     int num_actual_attribs = 0;
   1917 
   1918     // If attrib_list is not NULL,
   1919     // ensure attrib_list contains (key, value) pairs
   1920     // followed by a single EGL_NONE.
   1921     // Also validate attribs.
   1922     int inputFenceFd = -1;
   1923     if (attrib_list) {
   1924         for (int i = 0; i < MAX_EGL_SYNC_ATTRIBS; i += 2) {
   1925             if (attrib_list[i] == EGL_NONE) {
   1926                 num_actual_attribs = i;
   1927                 break;
   1928             }
   1929             if (i + 1 == MAX_EGL_SYNC_ATTRIBS) {
   1930                 DPRINT("ERROR: attrib list without EGL_NONE");
   1931                 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
   1932             }
   1933         }
   1934 
   1935         // Validate and input attribs
   1936         for (int i = 0; i < num_actual_attribs; i += 2) {
   1937             if (attrib_list[i] == EGL_SYNC_TYPE_KHR) {
   1938                 DPRINT("ERROR: attrib key = EGL_SYNC_TYPE_KHR");
   1939             }
   1940             if (attrib_list[i] == EGL_SYNC_STATUS_KHR) {
   1941                 DPRINT("ERROR: attrib key = EGL_SYNC_STATUS_KHR");
   1942             }
   1943             if (attrib_list[i] == EGL_SYNC_CONDITION_KHR) {
   1944                 DPRINT("ERROR: attrib key = EGL_SYNC_CONDITION_KHR");
   1945             }
   1946             EGLint attrib_key = attrib_list[i];
   1947             EGLint attrib_val = attrib_list[i + 1];
   1948             if (attrib_key == EGL_SYNC_NATIVE_FENCE_FD_ANDROID) {
   1949                 if (attrib_val != EGL_NO_NATIVE_FENCE_FD_ANDROID) {
   1950                     inputFenceFd = attrib_val;
   1951                 }
   1952             }
   1953             DPRINT("attrib: 0x%x : 0x%x", attrib_key, attrib_val);
   1954         }
   1955     }
   1956 
   1957     uint64_t sync_handle = 0;
   1958     int newFenceFd = -1;
   1959 
   1960     if (rcEnc->hasNativeSync()) {
   1961         sync_handle =
   1962             createNativeSync(type, attrib_list, num_actual_attribs,
   1963                              false /* don't destroy when signaled on the host;
   1964                                       let the guest clean this up,
   1965                                       because the guest called eglCreateSyncKHR. */,
   1966                              inputFenceFd,
   1967                              &newFenceFd);
   1968 
   1969     } else {
   1970         // Just trigger a glFinish if the native sync on host
   1971         // is unavailable.
   1972         eglWaitClient();
   1973     }
   1974 
   1975     EGLSync_t* syncRes = new EGLSync_t(sync_handle);
   1976 
   1977     if (type == EGL_SYNC_NATIVE_FENCE_ANDROID) {
   1978         syncRes->type = EGL_SYNC_NATIVE_FENCE_ANDROID;
   1979 
   1980         if (inputFenceFd < 0) {
   1981             syncRes->android_native_fence_fd = newFenceFd;
   1982         } else {
   1983             DPRINT("has input fence fd %d",
   1984                     inputFenceFd);
   1985             syncRes->android_native_fence_fd = inputFenceFd;
   1986         }
   1987     } else {
   1988         syncRes->type = EGL_SYNC_FENCE_KHR;
   1989         syncRes->android_native_fence_fd = -1;
   1990         if (!rcEnc->hasNativeSync()) {
   1991             syncRes->status = EGL_SIGNALED_KHR;
   1992         }
   1993     }
   1994 
   1995     return (EGLSyncKHR)syncRes;
   1996 }
   1997 
   1998 EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR eglsync)
   1999 {
   2000     (void)dpy;
   2001 
   2002     if (!eglsync) {
   2003         DPRINT("WARNING: null sync object")
   2004         return EGL_TRUE;
   2005     }
   2006 
   2007     EGLSync_t* sync = static_cast<EGLSync_t*>(eglsync);
   2008 
   2009     if (sync && sync->android_native_fence_fd > 0) {
   2010         close(sync->android_native_fence_fd);
   2011         sync->android_native_fence_fd = -1;
   2012     }
   2013 
   2014     if (sync) {
   2015         DEFINE_HOST_CONNECTION;
   2016         if (rcEnc->hasNativeSync()) {
   2017             rcEnc->rcDestroySyncKHR(rcEnc, sync->handle);
   2018         }
   2019         delete sync;
   2020     }
   2021 
   2022     return EGL_TRUE;
   2023 }
   2024 
   2025 EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR eglsync, EGLint flags,
   2026         EGLTimeKHR timeout)
   2027 {
   2028     (void)dpy;
   2029 
   2030     if (!eglsync) {
   2031         DPRINT("WARNING: null sync object");
   2032         return EGL_CONDITION_SATISFIED_KHR;
   2033     }
   2034 
   2035     EGLSync_t* sync = (EGLSync_t*)eglsync;
   2036 
   2037     DPRINT("sync=0x%lx (handle=0x%lx) flags=0x%x timeout=0x%llx",
   2038            sync, sync->handle, flags, timeout);
   2039 
   2040     DEFINE_HOST_CONNECTION;
   2041 
   2042     EGLint retval;
   2043     if (rcEnc->hasNativeSync()) {
   2044         retval = rcEnc->rcClientWaitSyncKHR
   2045             (rcEnc, sync->handle, flags, timeout);
   2046     } else {
   2047         retval = EGL_CONDITION_SATISFIED_KHR;
   2048     }
   2049     EGLint res_status;
   2050     switch (sync->type) {
   2051         case EGL_SYNC_FENCE_KHR:
   2052             res_status = EGL_SIGNALED_KHR;
   2053             break;
   2054         case EGL_SYNC_NATIVE_FENCE_ANDROID:
   2055             res_status = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID;
   2056             break;
   2057         default:
   2058             res_status = EGL_SIGNALED_KHR;
   2059     }
   2060     sync->status = res_status;
   2061     return retval;
   2062 }
   2063 
   2064 EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR eglsync,
   2065         EGLint attribute, EGLint *value)
   2066 {
   2067     (void)dpy;
   2068 
   2069     EGLSync_t* sync = (EGLSync_t*)eglsync;
   2070 
   2071     switch (attribute) {
   2072     case EGL_SYNC_TYPE_KHR:
   2073         *value = sync->type;
   2074         return EGL_TRUE;
   2075     case EGL_SYNC_STATUS_KHR:
   2076         *value = sync->status;
   2077         return EGL_TRUE;
   2078     case EGL_SYNC_CONDITION_KHR:
   2079         *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
   2080         return EGL_TRUE;
   2081     default:
   2082         setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE);
   2083     }
   2084 }
   2085 
   2086 int eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR eglsync) {
   2087     (void)dpy;
   2088 
   2089     DPRINT("call");
   2090 
   2091     EGLSync_t* sync = (EGLSync_t*)eglsync;
   2092     if (sync && sync->android_native_fence_fd > 0) {
   2093         int res = dup(sync->android_native_fence_fd);
   2094         return res;
   2095     } else {
   2096         return -1;
   2097     }
   2098 }
   2099 
   2100 // TODO: Implement EGL_KHR_wait_sync
   2101 EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR eglsync, EGLint flags) {
   2102     (void)dpy;
   2103     (void)eglsync;
   2104     (void)flags;
   2105     return EGL_TRUE;
   2106 }
   2107