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