• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "EglOsApi.h"
18 
19 #include "aemu/base/system/System.h"
20 #include "aemu/base/SharedLibrary.h"
21 #include "host-common/logging.h"
22 #include "host-common/opengl/misc.h"
23 #include "GLcommon/GLLibrary.h"
24 #include "ShaderCache.h"
25 
26 #ifdef ANDROID
27 #include <android/native_window.h>
28 #endif
29 
30 #ifdef __linux__
31 #include "X11Support.h"
32 #include "X11ErrorHandler.h"
33 #endif
34 
35 #ifdef __QNX__
36 #include "screen/screen.h"
37 #endif
38 
39 #include <EGL/egl.h>
40 #include <EGL/eglext.h>
41 #include <GLES2/gl2.h>
42 #include <cstring>
43 #include <memory>
44 #include <vector>
45 
46 #define DEBUG 0
47 #if DEBUG
48 #define D(...) fprintf(stderr, __VA_ARGS__);
49 #define CHECK_EGL_ERR                                                 \
50     {                                                                 \
51         EGLint err = mDispatcher.eglGetError();                       \
52         if (err != EGL_SUCCESS)                                       \
53             D("%s: %s %d get egl error %d\n", __FUNCTION__, __FILE__, \
54               __LINE__, err);                                         \
55     }
56 #else
57 #define D(...) ((void)0);
58 #define CHECK_EGL_ERR ((void)0);
59 #endif
60 
61 #if defined(__WIN32) || defined(_MSC_VER)
62 
63 static const char* kEGLLibName = "libEGL.dll";
64 static const char* kGLES2LibName = "libGLESv2.dll";
65 
66 #elif defined(__linux__)
67 
68 
69 static const char* kEGLLibName = "libEGL.so";
70 static const char* kGLES2LibName = "libGLESv2.so";
71 
72 static const char* kEGLLibNameAlt = "libEGL.so.1";
73 static const char* kGLES2LibNameAlt = "libGLESv2.so.2";
74 
75 #elif defined(__QNX__)
76 
77 static const char* kEGLLibName = "libEGL.so";
78 static const char* kGLES2LibName = "libGLESv2.so";
79 
80 #else // __APPLE__
81 
82 #include "MacNative.h"
83 
84 static const char* kEGLLibName = "libEGL.dylib";
85 static const char* kGLES2LibName = "libGLESv2.dylib";
86 
87 #endif // __APPLE__
88 
89 // List of EGL functions of interest to probe with GetProcAddress()
90 #define LIST_EGL_FUNCTIONS(X)                                                  \
91     X(void*, eglGetProcAddress,                                           \
92       (const char* procname))                                                  \
93     X(const char*, eglQueryString,                                             \
94       (EGLDisplay dpy, EGLint id))                                             \
95     X(EGLDisplay, eglGetPlatformDisplay,                                    \
96       (EGLenum platform, void *native_display, const EGLAttrib *attrib_list))  \
97     X(EGLDisplay, eglGetPlatformDisplayEXT,                                    \
98       (EGLenum platform, void *native_display, const EGLint *attrib_list))     \
99     X(EGLBoolean, eglBindAPI,                                    \
100       (EGLenum api)) \
101     X(EGLBoolean, eglChooseConfig,                                             \
102       (EGLDisplay display, EGLint const* attrib_list, EGLConfig* configs,      \
103        EGLint config_size, EGLint* num_config))                                \
104     X(EGLContext, eglCreateContext,                                            \
105       (EGLDisplay display, EGLConfig config, EGLContext share_context,         \
106        EGLint const* attrib_list))                                             \
107     X(EGLSurface, eglCreatePbufferSurface,                                     \
108       (EGLDisplay display, EGLConfig config, EGLint const* attrib_list))       \
109     X(EGLBoolean, eglDestroyContext, (EGLDisplay display, EGLContext context)) \
110     X(EGLBoolean, eglDestroySurface, (EGLDisplay display, EGLSurface surface)) \
111     X(EGLBoolean, eglGetConfigAttrib,                                          \
112       (EGLDisplay display, EGLConfig config, EGLint attribute,                 \
113        EGLint * value))                                                        \
114     X(EGLDisplay, eglGetDisplay, (NativeDisplayType native_display))           \
115     X(EGLint, eglGetError, (void))                                             \
116     X(EGLBoolean, eglInitialize,                                               \
117       (EGLDisplay display, EGLint * major, EGLint * minor))                    \
118     X(EGLBoolean, eglMakeCurrent,                                              \
119       (EGLDisplay display, EGLSurface draw, EGLSurface read,                   \
120        EGLContext context))                                                    \
121     X(EGLBoolean, eglSwapBuffers, (EGLDisplay display, EGLSurface surface))    \
122     X(EGLSurface, eglCreateWindowSurface,                                      \
123       (EGLDisplay display, EGLConfig config,                                   \
124        EGLNativeWindowType native_window, EGLint const* attrib_list))          \
125     X(EGLBoolean, eglSwapInterval,                                             \
126       (EGLDisplay display, EGLint interval))                                   \
127     X(void, eglSetBlobCacheFuncsANDROID, (EGLDisplay display,                  \
128       EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get))                   \
129     X(EGLImage, eglCreateImageKHR, (EGLDisplay dpy,                            \
130       EGLContext ctx, EGLenum target, EGLClientBuffer buffer,                  \
131       const EGLint *attrib_list))                                              \
132     X(EGLBoolean, eglDestroyImageKHR, (EGLDisplay dpy, EGLImage image))        \
133     X(EGLImage, eglCreateImage, (EGLDisplay dpy,                               \
134       EGLContext ctx, EGLenum target, EGLClientBuffer buffer,                  \
135       const EGLAttrib *attrib_list))                                           \
136     X(EGLBoolean, eglDestroyImage, (EGLDisplay dpy, EGLImage image))           \
137     X(EGLBoolean, eglReleaseThread, (void))                                    \
138     X(EGLint, eglDebugMessageControlKHR,                                       \
139       (EGLDEBUGPROCKHR callback, const EGLAttrib * attrib_list))               \
140 
141 namespace {
142 using namespace EglOS;
143 
144 class EglOsEglDispatcher {
145 public:
146 #define DECLARE_EGL_POINTER(return_type, function_name, signature) \
147     return_type(EGLAPIENTRY* function_name) signature = nullptr;
148     LIST_EGL_FUNCTIONS(DECLARE_EGL_POINTER);
149 
EglOsEglDispatcher()150     EglOsEglDispatcher() {
151         D("loading %s\n", kEGLLibName);
152         char error[256];
153         mLib = android::base::SharedLibrary::open(kEGLLibName, error, sizeof(error));
154         if (!mLib) {
155 #ifdef __linux__
156             ERR("%s: Could not open EGL library %s [%s]. Trying again with [%s]", __FUNCTION__,
157                 kEGLLibName, error, kEGLLibNameAlt);
158             mLib = android::base::SharedLibrary::open(kEGLLibNameAlt, error, sizeof(error));
159             if (!mLib) {
160                 ERR("%s: Could not open EGL library %s [%s]", __FUNCTION__,
161                     kEGLLibNameAlt, error);
162             }
163 #else
164             ERR("%s: Could not open EGL library %s [%s]", __FUNCTION__,
165                 kEGLLibName, error);
166 #endif
167         }
168 
169 #define LOAD_EGL_POINTER(return_type, function_name, signature)        \
170     this->function_name =                                              \
171             reinterpret_cast<return_type(GL_APIENTRY*) signature>(     \
172                     mLib->findSymbol(#function_name));                 \
173     if (!this->function_name) {                                        \
174         this->function_name =                                          \
175                 reinterpret_cast<return_type(GL_APIENTRY*) signature>( \
176                         this->eglGetProcAddress(#function_name));      \
177     } \
178     if (!this->function_name) {                                        \
179         D("%s: Could not find %s in underlying EGL library\n",         \
180           __FUNCTION__,                                                \
181           #function_name);                                             \
182     }
183 
184         LIST_EGL_FUNCTIONS(LOAD_EGL_POINTER);
185     }
186     ~EglOsEglDispatcher() = default;
187 
188 private:
189     android::base::SharedLibrary* mLib = nullptr;
190 };
191 
192 class EglOsGlLibrary : public GlLibrary {
193 public:
EglOsGlLibrary()194     EglOsGlLibrary() {
195         char error[256];
196         mLib = android::base::SharedLibrary::open(kGLES2LibName, error, sizeof(error));
197         if (!mLib) {
198 #ifdef __linux__
199             ERR("%s: Could not open GL library %s [%s]. Trying again with [%s]", __FUNCTION__,
200                 kGLES2LibName, error, kGLES2LibNameAlt);
201             mLib = android::base::SharedLibrary::open(kGLES2LibNameAlt, error, sizeof(error));
202             if (!mLib) {
203                 ERR("%s: Could not open GL library %s [%s]", __FUNCTION__,
204                     kGLES2LibNameAlt, error);
205             }
206 #else
207             ERR("%s: Could not open GL library %s [%s]", __FUNCTION__,
208                 kGLES2LibName, error);
209 #endif
210         }
211     }
findSymbol(const char * name)212     GlFunctionPointer findSymbol(const char* name) {
213         if (!mLib) {
214             return NULL;
215         }
216         return reinterpret_cast<GlFunctionPointer>(mLib->findSymbol(name));
217     }
218     ~EglOsGlLibrary() = default;
219 
220 private:
221     android::base::SharedLibrary* mLib = nullptr;
222 };
223 
224 class EglOsEglPixelFormat : public EglOS::PixelFormat {
225 public:
EglOsEglPixelFormat(EGLConfig configId,EGLint clientCtxVer)226     EglOsEglPixelFormat(EGLConfig configId, EGLint clientCtxVer)
227         : mConfigId(configId), mClientCtxVer(clientCtxVer) {}
clone()228     PixelFormat* clone() {
229         return new EglOsEglPixelFormat(mConfigId, mClientCtxVer);
230     }
231     EGLConfig mConfigId;
232     EGLint mClientCtxVer;
233 #ifdef __APPLE__
234     int mRedSize = 0;
235     int mGreenSize = 0;
236     int mBlueSize = 0;
237 #endif // __APPLE__
238 };
239 
240 class EglOsEglContext : public EglOS::Context {
241 public:
EglOsEglContext(EglOsEglDispatcher * dispatcher,EGLDisplay display,EGLContext context)242     EglOsEglContext(EglOsEglDispatcher* dispatcher,
243                     EGLDisplay display,
244                     EGLContext context) :
245         mDispatcher(dispatcher),
246         mDisplay(display),
247         mNativeCtx(context) { }
248 
~EglOsEglContext()249     virtual ~EglOsEglContext() {
250         D("%s %p\n", __FUNCTION__, mNativeCtx);
251         if (!mDispatcher->eglDestroyContext(mDisplay, mNativeCtx)) {
252             // TODO: print a better error message
253         }
254     }
255 
context() const256     EGLContext context() const {
257         return mNativeCtx;
258     }
259 
getNative()260     virtual void* getNative() { return (void*)mNativeCtx; }
261 private:
262     EglOsEglDispatcher* mDispatcher = nullptr;
263     EGLDisplay mDisplay;
264     EGLContext mNativeCtx;
265 };
266 
267 class EglOsEglSurface : public EglOS::Surface {
268 public:
EglOsEglSurface(SurfaceType type,EGLSurface eglSurface,EGLNativeWindowType win=0)269     EglOsEglSurface(SurfaceType type,
270                     EGLSurface eglSurface,
271                     EGLNativeWindowType win = 0)
272         : EglOS::Surface(type), mHndl(eglSurface), mWin(win) {}
getHndl()273     EGLSurface getHndl() { return mHndl; }
getWin()274     EGLNativeWindowType getWin() { return mWin; }
275 
276 private:
277     EGLSurface mHndl;
278     EGLNativeWindowType mWin;
279 };
280 
281 class EglOsEglDisplay : public EglOS::Display {
282 public:
283     EglOsEglDisplay(bool nullEgl);
284     ~EglOsEglDisplay();
285     virtual EglOS::GlesVersion getMaxGlesVersion();
286     virtual const char* getExtensionString();
287     virtual const char* getVendorString();
288     virtual EGLImage createImageKHR(
289             EGLDisplay dpy,
290             EGLContext ctx,
291             EGLenum target,
292             EGLClientBuffer buffer,
293             const EGLint *attrib_list);
294     virtual EGLBoolean destroyImageKHR(
295             EGLDisplay dpy,
296             EGLImage image);
297     virtual EGLDisplay getNative();
298     void queryConfigs(int renderableType,
299                       AddConfigCallback* addConfigFunc,
300                       void* addConfigOpaque);
301     virtual std::shared_ptr<Context>
302     createContext(EGLint profileMask,
303                   const PixelFormat* pixelFormat,
304                   Context* sharedContext) override;
305     Surface* createPbufferSurface(const PixelFormat* pixelFormat,
306                                   const PbufferInfo* info);
307     Surface* createWindowSurface(PixelFormat* pf, EGLNativeWindowType win);
308     bool releasePbuffer(Surface* pb);
309     bool makeCurrent(Surface* read, Surface* draw, Context* context);
310     EGLBoolean releaseThread();
311     void swapBuffers(Surface* srfc);
312     bool isValidNativeWin(Surface* win);
313     bool isValidNativeWin(EGLNativeWindowType win);
314     bool checkWindowPixelFormatMatch(EGLNativeWindowType win,
315                                      const PixelFormat* pixelFormat,
316                                      unsigned int* width,
317                                      unsigned int* height);
eglGetProcAddress(const char * func)318     void* eglGetProcAddress(const char* func) {
319         return mDispatcher.eglGetProcAddress(func);
320     }
321 
eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,const EGLAttrib * attribs)322     EGLint eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, const EGLAttrib* attribs) {
323         return mDispatcher.eglDebugMessageControlKHR(callback, attribs);
324     }
325 
326 private:
327     bool mVerbose = false;
328     EGLDisplay mDisplay = EGL_NO_DISPLAY;
329     EglOsEglDispatcher mDispatcher;
330     bool mHeadless = false;
331     std::string mClientExts;
332     std::string mVendor;
333     GlesVersion mGlesVersion;
334 
335 #ifdef __linux__
336     ::Display* mGlxDisplay = nullptr;
337 #endif // __linux__
338 };
339 
EglOsEglDisplay(bool nullEgl)340 EglOsEglDisplay::EglOsEglDisplay(bool nullEgl) {
341     mVerbose = android::base::getEnvironmentVariable("ANDROID_EMUGL_VERBOSE") == "1";
342 
343     if (nullEgl) {
344 #ifdef EGL_ANGLE_platform_angle
345         const EGLAttrib attr[] = {
346             EGL_PLATFORM_ANGLE_TYPE_ANGLE,
347             EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE,
348             EGL_NONE
349         };
350 
351         mDisplay = mDispatcher.eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
352             (void*)EGL_DEFAULT_DISPLAY,
353             attr);
354 
355         if (mDisplay == EGL_NO_DISPLAY) {
356             fprintf(stderr, "%s: no display found that supports null backend\n", __func__);
357         }
358 #else
359         fprintf(stderr, "EGL Null display not compiled, falling back to default display\n");
360 #endif
361     } else if (android::base::getEnvironmentVariable("ANDROID_EMUGL_EXPERIMENTAL_FAST_PATH") == "1") {
362 #ifdef EGL_ANGLE_platform_angle
363         const EGLAttrib attr[] = {
364             EGL_PLATFORM_ANGLE_TYPE_ANGLE,
365             EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
366             EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
367             EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
368             EGL_NONE
369         };
370 
371         mDisplay = mDispatcher.eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
372             (void*)EGL_DEFAULT_DISPLAY,
373             attr);
374 
375         if (mDisplay == EGL_NO_DISPLAY) {
376             fprintf(stderr, "%s: no display found that supports the requested extensions\n", __func__);
377         }
378 #endif
379     }
380 
381     if (mDisplay == EGL_NO_DISPLAY)
382         mDisplay = mDispatcher.eglGetDisplay(EGL_DEFAULT_DISPLAY);
383 
384     mDispatcher.eglInitialize(mDisplay, nullptr, nullptr);
385     mDispatcher.eglSwapInterval(mDisplay, 0);
386     auto clientExts = mDispatcher.eglQueryString(mDisplay, EGL_EXTENSIONS);
387     auto vendor = mDispatcher.eglQueryString(mDisplay, EGL_VENDOR);
388 
389     if (mVerbose) {
390         fprintf(stderr, "%s: client exts: [%s]\n", __func__, clientExts);
391     }
392 
393     if (clientExts) {
394         mClientExts = clientExts;
395     }
396 
397     if (vendor) {
398         mVendor = vendor;
399     }
400 
401     mDispatcher.eglBindAPI(EGL_OPENGL_ES_API);
402     CHECK_EGL_ERR
403 
404     mHeadless = android::base::getEnvironmentVariable("ANDROID_EMU_HEADLESS") == "1";
405 
406 #ifdef ANDROID
407     mGlxDisplay = nullptr;
408 #elif defined(__linux__)
409     if (mHeadless) mGlxDisplay = nullptr;
410     else mGlxDisplay = getX11Api()->XOpenDisplay(0);
411 #endif // __linux__
412 
413     if (clientExts != nullptr && emugl::hasExtension(clientExts, "EGL_ANDROID_blob_cache")) {
414         mDispatcher.eglSetBlobCacheFuncsANDROID(mDisplay, SetBlob, GetBlob);
415     }
416 
417     mGlesVersion = GlesVersion::ES2;
418 
419     static const EGLint gles3ConfigAttribs[] =
420         { EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
421           EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT, EGL_NONE };
422 
423     static const EGLint pbufAttribs[] =
424         { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
425 
426     static const EGLint gles31Attribs[] =
427        { EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
428          EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE };
429 
430     static const EGLint gles30Attribs[] =
431        { EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
432          EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE };
433 
434     EGLConfig config;
435 
436     int numConfigs;
437     if (mDispatcher.eglChooseConfig(
438             mDisplay, gles3ConfigAttribs, &config, 1, &numConfigs) &&
439         numConfigs != 0) {
440         EGLSurface surface = mDispatcher.eglCreatePbufferSurface(mDisplay,
441                 config, pbufAttribs);
442         if (surface != EGL_NO_SURFACE) {
443             EGLContext ctx = mDispatcher.eglCreateContext(mDisplay,
444                     config, EGL_NO_CONTEXT, gles31Attribs);
445 
446             if (ctx != EGL_NO_CONTEXT) {
447                 mGlesVersion = GlesVersion::ES31;
448             } else {
449                 ctx = mDispatcher.eglCreateContext(mDisplay, config,
450                         EGL_NO_CONTEXT, gles30Attribs);
451                 if (ctx != EGL_NO_CONTEXT) {
452                     mGlesVersion = GlesVersion::ES30;
453                 }
454             }
455             mDispatcher.eglDestroySurface(mDisplay, surface);
456             if (ctx != EGL_NO_CONTEXT) {
457                 mDispatcher.eglDestroyContext(mDisplay, ctx);
458             }
459         }
460     }
461 };
462 
~EglOsEglDisplay()463 EglOsEglDisplay::~EglOsEglDisplay() {
464 #ifdef ANDROID
465 #elif defined(__linux__)
466     if (mGlxDisplay) getX11Api()->XCloseDisplay(mGlxDisplay);
467 #endif // __linux__
468 }
469 
getMaxGlesVersion()470 EglOS::GlesVersion EglOsEglDisplay::getMaxGlesVersion() {
471     // Maximum GLES3.1
472     // GLES3.2 will also need some more autogen + enums if anyone is interested.
473     return mGlesVersion;
474 }
475 
getExtensionString()476 const char* EglOsEglDisplay::getExtensionString() {
477     return mClientExts.c_str();
478 }
479 
getVendorString()480 const char* EglOsEglDisplay::getVendorString() {
481     return mVendor.c_str();
482 }
483 
createImageKHR(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)484 EGLImage EglOsEglDisplay::createImageKHR(
485         EGLDisplay dpy,
486         EGLContext ctx,
487         EGLenum target,
488         EGLClientBuffer buffer,
489         const EGLint *attrib_list) {
490     if (mDispatcher.eglCreateImageKHR) {
491         return mDispatcher.eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
492     } else {
493         return EGL_NO_IMAGE_KHR;
494     }
495 }
496 
destroyImageKHR(EGLDisplay dpy,EGLImage image)497 EGLBoolean EglOsEglDisplay::destroyImageKHR(
498         EGLDisplay dpy,
499         EGLImage image) {
500     if (mDispatcher.eglDestroyImage) {
501         return mDispatcher.eglDestroyImageKHR(dpy, image);
502     } else {
503         return EGL_FALSE;
504     }
505 }
506 
getNative()507 EGLDisplay EglOsEglDisplay::getNative() {
508     return mDisplay;
509 }
510 
queryConfigs(int renderableType,AddConfigCallback * addConfigFunc,void * addConfigOpaque)511 void EglOsEglDisplay::queryConfigs(int renderableType,
512                                    AddConfigCallback* addConfigFunc,
513                                    void* addConfigOpaque) {
514     D("%s\n", __FUNCTION__);
515     // ANGLE does not support GLES1 uses core profile engine.
516     // Querying underlying EGL with a conservative set of bits.
517     renderableType &= ~EGL_OPENGL_ES_BIT;
518 
519     const EGLint framebuffer_config_attributes[] = {
520         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
521         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
522         EGL_RED_SIZE, 1,
523         EGL_GREEN_SIZE, 1,
524         EGL_BLUE_SIZE, 1,
525         EGL_ALPHA_SIZE, 0,
526         EGL_NONE,
527     };
528 
529     EGLint numConfigs = 0;
530     mDispatcher.eglChooseConfig(mDisplay, framebuffer_config_attributes, nullptr, 0, &numConfigs);
531     CHECK_EGL_ERR
532     std::unique_ptr<EGLConfig[]> configs(new EGLConfig[numConfigs]);
533     mDispatcher.eglChooseConfig(mDisplay, framebuffer_config_attributes, configs.get(), numConfigs,
534                                 &numConfigs);
535     CHECK_EGL_ERR
536 
537     if (mVerbose) {
538         fprintf(stderr, "%s: num configs: %d\n", __func__, numConfigs);
539     }
540 
541     for (int i = 0; i < numConfigs; i++) {
542         const EGLConfig cfg = configs.get()[i];
543         ConfigInfo configInfo;
544         // We do not have recordable_android
545         configInfo.recordable_android = 0;
546         EGLint _renderableType;
547         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_RENDERABLE_TYPE,
548                                        &_renderableType);
549         // We do emulate GLES1
550         configInfo.renderable_type = _renderableType | EGL_OPENGL_ES_BIT;
551 
552         configInfo.frmt = new EglOsEglPixelFormat(cfg, _renderableType);
553         D("config %p renderable type 0x%x\n", cfg, _renderableType);
554 
555         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_RED_SIZE,
556                                        &configInfo.red_size);
557         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_GREEN_SIZE,
558                                        &configInfo.green_size);
559         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_BLUE_SIZE,
560                                        &configInfo.blue_size);
561         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_ALPHA_SIZE,
562                                        &configInfo.alpha_size);
563 
564         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_CONFIG_CAVEAT,
565                                        (EGLint*)&configInfo.caveat);
566         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_DEPTH_SIZE,
567                                        &configInfo.depth_size);
568         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_LEVEL,
569                                        &configInfo.frame_buffer_level);
570 
571         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_MAX_PBUFFER_WIDTH,
572                                        &configInfo.max_pbuffer_width);
573         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_MAX_PBUFFER_HEIGHT,
574                                        &configInfo.max_pbuffer_height);
575         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_MAX_PBUFFER_PIXELS,
576                                        &configInfo.max_pbuffer_size);
577 
578         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_NATIVE_RENDERABLE,
579                                        (EGLint*)&configInfo.native_renderable);
580         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_NATIVE_VISUAL_ID,
581                                        &configInfo.native_visual_id);
582         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_NATIVE_VISUAL_TYPE,
583                                        &configInfo.native_visual_type);
584 
585         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_SAMPLES,
586                                        &configInfo.samples_per_pixel);
587         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_STENCIL_SIZE,
588                                        &configInfo.stencil_size);
589 
590         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_SURFACE_TYPE,
591                                        &configInfo.surface_type);
592         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_TRANSPARENT_TYPE,
593                                        (EGLint*)&configInfo.transparent_type);
594         mDispatcher.eglGetConfigAttrib(mDisplay, cfg, EGL_TRANSPARENT_RED_VALUE,
595                                        &configInfo.trans_red_val);
596         mDispatcher.eglGetConfigAttrib(mDisplay, cfg,
597                                        EGL_TRANSPARENT_GREEN_VALUE,
598                                        &configInfo.trans_green_val);
599         mDispatcher.eglGetConfigAttrib(mDisplay, cfg,
600                                        EGL_TRANSPARENT_BLUE_VALUE,
601                                        &configInfo.trans_blue_val);
602         CHECK_EGL_ERR
603 #ifdef __APPLE__
604         ((EglOsEglPixelFormat*)configInfo.frmt)->mRedSize = configInfo.red_size;
605         ((EglOsEglPixelFormat*)configInfo.frmt)->mGreenSize = configInfo.green_size;
606         ((EglOsEglPixelFormat*)configInfo.frmt)->mBlueSize = configInfo.blue_size;
607 #endif // __APPLE__
608         addConfigFunc(addConfigOpaque, &configInfo);
609     }
610     D("Host gets %d configs\n", numConfigs);
611 }
612 
613 std::shared_ptr<Context>
createContext(EGLint profileMask,const PixelFormat * pixelFormat,Context * sharedContext)614 EglOsEglDisplay::createContext(EGLint profileMask,
615                                const PixelFormat* pixelFormat,
616                                Context* sharedContext) {
617     (void)profileMask;
618 
619     D("%s\n", __FUNCTION__);
620     const EglOsEglPixelFormat* format = (const EglOsEglPixelFormat*)pixelFormat;
621     D("with config %p\n", format->mConfigId);
622 
623     // Always GLES3
624     std::vector<EGLint> attributes = { EGL_CONTEXT_CLIENT_VERSION, 3 };
625     auto exts = mDispatcher.eglQueryString(mDisplay, EGL_EXTENSIONS);
626     auto vendor = mDispatcher.eglQueryString(mDisplay, EGL_VENDOR);
627 
628     // TODO (b/207426737): remove Imagination-specific workaround
629     bool disable_robustness = vendor && (strcmp(vendor, "Imagination Technologies") == 0);
630 
631     bool disableValidation = android::base::getEnvironmentVariable("ANDROID_EMUGL_EGL_VALIDATION") == "0";
632     if (exts != nullptr && emugl::hasExtension(exts, "EGL_KHR_create_context_no_error") && disableValidation) {
633         attributes.push_back(EGL_CONTEXT_OPENGL_NO_ERROR_KHR);
634         attributes.push_back(EGL_TRUE);
635     }
636 
637     if (exts != nullptr && emugl::hasExtension(exts, "EGL_EXT_create_context_robustness") && !disable_robustness) {
638         attributes.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT);
639         attributes.push_back(EGL_LOSE_CONTEXT_ON_RESET_EXT);
640     }
641     attributes.push_back(EGL_NONE);
642 
643     // TODO: support GLES3.1
644     EglOsEglContext* nativeSharedCtx = (EglOsEglContext*)sharedContext;
645     EGLContext newNativeCtx = mDispatcher.eglCreateContext(
646             mDisplay, format->mConfigId,
647             nativeSharedCtx ? nativeSharedCtx->context() : nullptr,
648             attributes.data());
649     CHECK_EGL_ERR
650     std::shared_ptr<Context> res =
651         std::make_shared<EglOsEglContext>(
652             &mDispatcher, mDisplay, newNativeCtx);
653     D("%s done\n", __FUNCTION__);
654     return res;
655 }
656 
createPbufferSurface(const PixelFormat * pixelFormat,const PbufferInfo * info)657 Surface* EglOsEglDisplay::createPbufferSurface(const PixelFormat* pixelFormat,
658                                                const PbufferInfo* info) {
659     // D("%s\n", __FUNCTION__);
660     // const EglOsEglPixelFormat* format = (const EglOsEglPixelFormat*)pixelFormat;
661     // EGLint attrib[] = {EGL_WIDTH,
662     //                    info->width,
663     //                    EGL_HEIGHT,
664     //                    info->height,
665     //                    EGL_LARGEST_PBUFFER,
666     //                    info->largest,
667     //                    EGL_TEXTURE_FORMAT,
668     //                    info->format,
669     //                    EGL_TEXTURE_TARGET,
670     //                    info->target,
671     //                    EGL_MIPMAP_TEXTURE,
672     //                    info->hasMipmap,
673     //                    EGL_NONE};
674     // EGLSurface surface = mDispatcher.eglCreatePbufferSurface(
675     //         mDisplay, format->mConfigId, attrib);
676     // CHECK_EGL_ERR
677     // if (surface == EGL_NO_SURFACE) {
678     //     D("create pbuffer surface failed\n");
679     //     return nullptr;
680     // }
681     // return new EglOsEglSurface(EglOS::Surface::PBUFFER, surface);
682     return new EglOsEglSurface(EglOS::Surface::PBUFFER, 0);
683 }
684 
createWindowSurface(PixelFormat * pf,EGLNativeWindowType win)685 Surface* EglOsEglDisplay::createWindowSurface(PixelFormat* pf,
686                                               EGLNativeWindowType win) {
687     D("%s\n", __FUNCTION__);
688     std::vector<EGLint> surface_attribs;
689     auto exts = mDispatcher.eglQueryString(mDisplay, EGL_EXTENSIONS);
690     if (exts != nullptr && emugl::hasExtension(exts, "EGL_ANGLE_direct_composition")) {
691 #ifdef EGL_ANGLE_direct_composition
692         surface_attribs.push_back(EGL_DIRECT_COMPOSITION_ANGLE);
693         surface_attribs.push_back(EGL_TRUE);
694 #endif
695     }
696     surface_attribs.push_back(EGL_NONE);
697 #ifdef __APPLE__
698     win = nsGetLayer(win);
699 #endif
700     EGLSurface surface = mDispatcher.eglCreateWindowSurface(
701             mDisplay, ((EglOsEglPixelFormat*)pf)->mConfigId, win, surface_attribs.data()
702     );
703     CHECK_EGL_ERR
704     if (surface == EGL_NO_SURFACE) {
705         D("create window surface failed\n");
706         return nullptr;
707     }
708     return new EglOsEglSurface(EglOS::Surface::WINDOW, surface, win);
709 }
710 
releasePbuffer(Surface * pb)711 bool EglOsEglDisplay::releasePbuffer(Surface* pb) {
712     D("%s\n", __FUNCTION__);
713     if (!pb)
714         return false;
715     EglOsEglSurface* surface = (EglOsEglSurface*)pb;
716 
717     if (!surface->getHndl()) {
718         delete surface;
719         return true;
720     }
721 
722     bool ret = mDispatcher.eglDestroySurface(mDisplay, surface->getHndl());
723     CHECK_EGL_ERR
724     D("%s done\n", __FUNCTION__);
725     delete surface;
726     return ret;
727 }
728 
makeCurrent(Surface * read,Surface * draw,Context * context)729 bool EglOsEglDisplay::makeCurrent(Surface* read,
730                                   Surface* draw,
731                                   Context* context) {
732     D("%s\n", __FUNCTION__);
733     EglOsEglSurface* readSfc = (EglOsEglSurface*)read;
734     EglOsEglSurface* drawSfc = (EglOsEglSurface*)draw;
735     EglOsEglContext* ctx = (EglOsEglContext*)context;
736     if (ctx && !readSfc) {
737         D("warning: makeCurrent a context without surface\n");
738         return false;
739     }
740     D("%s %p\n", __FUNCTION__, ctx ? ctx->context() : nullptr);
741     bool ret = mDispatcher.eglMakeCurrent(
742             mDisplay, drawSfc ? drawSfc->getHndl() : EGL_NO_SURFACE,
743             readSfc ? readSfc->getHndl() : EGL_NO_SURFACE,
744             ctx ? ctx->context() : EGL_NO_CONTEXT);
745     if (readSfc) {
746         D("make current surface type %d %d\n", readSfc->type(),
747           drawSfc->type());
748     }
749     D("make current %d\n", ret);
750     CHECK_EGL_ERR
751     return ret;
752 }
753 
swapBuffers(Surface * surface)754 void EglOsEglDisplay::swapBuffers(Surface* surface) {
755     D("%s\n", __FUNCTION__);
756     EglOsEglSurface* sfc = (EglOsEglSurface*)surface;
757     mDispatcher.eglSwapBuffers(mDisplay, sfc->getHndl());
758 }
759 
releaseThread()760 EGLBoolean EglOsEglDisplay::releaseThread() {
761     D("%s\n", __FUNCTION__);
762     return mDispatcher.eglReleaseThread();
763 }
764 
isValidNativeWin(Surface * win)765 bool EglOsEglDisplay::isValidNativeWin(Surface* win) {
766     if (!win) {
767         return false;
768     }
769     EglOsEglSurface* surface = (EglOsEglSurface*)win;
770     return surface->type() == EglOsEglSurface::WINDOW &&
771            isValidNativeWin(surface->getWin());
772 }
773 
isValidNativeWin(EGLNativeWindowType win)774 bool EglOsEglDisplay::isValidNativeWin(EGLNativeWindowType win) {
775 #ifdef _WIN32
776     return IsWindow(win);
777 #elif defined(ANDROID)
778     return true;
779 #elif defined(__linux__)
780     Window root;
781     int t;
782     unsigned int u;
783     X11ErrorHandler handler(mGlxDisplay);
784     return getX11Api()->XGetGeometry(mGlxDisplay, win, &root, &t, &t, &u, &u, &u, &u) != 0;
785 #elif defined(__QNX__)
786     int size[2];
787     return screen_get_window_property_iv(win, SCREEN_PROPERTY_SIZE, size) != -1;
788 #else // __APPLE__
789     unsigned int width, height;
790     return nsGetWinDims(win, &width, &height);
791 #endif // __APPLE__
792 }
793 
checkWindowPixelFormatMatch(EGLNativeWindowType win,const PixelFormat * pixelFormat,unsigned int * width,unsigned int * height)794 bool EglOsEglDisplay::checkWindowPixelFormatMatch(EGLNativeWindowType win,
795                                  const PixelFormat* pixelFormat,
796                                  unsigned int* width,
797                                  unsigned int* height) {
798 #ifdef _WIN32
799     RECT r;
800     if (!GetClientRect(win, &r)) {
801         return false;
802     }
803     *width = r.right - r.left;
804     *height = r.bottom - r.top;
805     return true;
806 #elif defined(ANDROID)
807     *width = ANativeWindow_getWidth((ANativeWindow*)win);
808     *height = ANativeWindow_getHeight((ANativeWindow*)win);
809     return true;
810 #elif defined(__linux__)
811     //TODO: to check what does ATI & NVIDIA enforce on win pixelformat
812     unsigned int depth, border;
813     int x, y;
814     Window root;
815     X11ErrorHandler handler(mGlxDisplay);
816     return getX11Api()->XGetGeometry(
817             mGlxDisplay, win, &root, &x, &y, width, height, &border, &depth);
818 #elif defined(__QNX__)
819     int size[2];
820     if (screen_get_window_property_iv(win, SCREEN_PROPERTY_SIZE, size) == -1) {
821         return false;
822     }
823     *width = size[0];
824     *height = size[1];
825     return true;
826 #else // __APPLE__
827     bool ret = nsGetWinDims(win, width, height);
828 
829     const EglOsEglPixelFormat* format = (EglOsEglPixelFormat*)pixelFormat;
830     int r = format->mRedSize;
831     int g = format->mGreenSize;
832     int b = format->mBlueSize;
833 
834     bool match = nsCheckColor(win, r + g + b);
835 
836     return ret && match;
837 #endif // __APPLE__
838 }
839 
sHostDisplay(bool nullEgl=false)840 static EglOsEglDisplay* sHostDisplay(bool nullEgl = false) {
841     static EglOsEglDisplay* d = new EglOsEglDisplay(nullEgl);
842     return d;
843 }
844 
845 class EglEngine : public EglOS::Engine {
846 public:
EglEngine(bool nullEgl)847  EglEngine(bool nullEgl)
848      :
849 #ifdef __QNX__  // Ensure libEGL is loaded prior to libGLES
850        mDisplay(sHostDisplay(nullEgl)),
851 #endif
852        EglOS::Engine(),
853        mUseNullEgl(nullEgl) {
854  }
855 
856  ~EglEngine() = default;
857 
getDefaultDisplay()858  EglOS::Display* getDefaultDisplay() {
859      D("%s\n", __FUNCTION__);
860      return sHostDisplay(mUseNullEgl);
861  }
getGlLibrary()862  GlLibrary* getGlLibrary() {
863      D("%s\n", __FUNCTION__);
864      return &mGlLib;
865  }
eglGetProcAddress(const char * func)866  void* eglGetProcAddress(const char* func) { return sHostDisplay()->eglGetProcAddress(func); }
createWindowSurface(PixelFormat * pf,EGLNativeWindowType wnd)867  virtual EglOS::Surface* createWindowSurface(PixelFormat* pf, EGLNativeWindowType wnd) {
868      D("%s\n", __FUNCTION__);
869      return sHostDisplay()->createWindowSurface(pf, wnd);
870  }
871 
eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,const EGLAttrib * attribs)872  EGLint eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, const EGLAttrib* attribs) override {
873      return sHostDisplay()->eglDebugMessageControlKHR(callback, attribs);
874  }
875 
876 private:
877 #ifdef __QNX__
878  EglOsEglDisplay* mDisplay;
879 #endif
880  EglOsGlLibrary mGlLib;
881  bool mUseNullEgl;
882 };
883 
884 }  // namespace
885 
sHostEngine(bool nullEgl)886 static EglEngine* sHostEngine(bool nullEgl) {
887     static EglEngine* res = new EglEngine(nullEgl);
888     return res;
889 }
890 
891 namespace EglOS {
getEgl2EglHostInstance(bool nullEgl)892 Engine* getEgl2EglHostInstance(bool nullEgl) {
893     D("%s\n", __FUNCTION__);
894     return sHostEngine(nullEgl);
895 }
896 }  // namespace EglOS
897