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