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