• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // DisplayEGL.cpp: Common across EGL parts of platform specific egl::Display implementations
8 
9 #include "libANGLE/renderer/gl/egl/DisplayEGL.h"
10 
11 #include "common/debug.h"
12 #include "libANGLE/Context.h"
13 #include "libANGLE/Display.h"
14 #include "libANGLE/Surface.h"
15 #include "libANGLE/renderer/gl/ContextGL.h"
16 #include "libANGLE/renderer/gl/RendererGL.h"
17 #include "libANGLE/renderer/gl/egl/ContextEGL.h"
18 #include "libANGLE/renderer/gl/egl/DmaBufImageSiblingEGL.h"
19 #include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h"
20 #include "libANGLE/renderer/gl/egl/ImageEGL.h"
21 #include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h"
22 #include "libANGLE/renderer/gl/egl/RendererEGL.h"
23 #include "libANGLE/renderer/gl/egl/SyncEGL.h"
24 #include "libANGLE/renderer/gl/egl/WindowSurfaceEGL.h"
25 #include "libANGLE/renderer/gl/renderergl_utils.h"
26 
27 namespace
28 {
29 
ESBitFromPlatformAttrib(const rx::FunctionsEGL * egl,const EGLAttrib platformAttrib)30 EGLint ESBitFromPlatformAttrib(const rx::FunctionsEGL *egl, const EGLAttrib platformAttrib)
31 {
32     EGLint esBit = EGL_NONE;
33     switch (platformAttrib)
34     {
35         case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
36         {
37             esBit = EGL_OPENGL_BIT;
38             break;
39         }
40 
41         case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
42         {
43             static_assert(EGL_OPENGL_ES3_BIT == EGL_OPENGL_ES3_BIT_KHR,
44                           "Extension define must match core");
45 
46             gl::Version eglVersion(egl->majorVersion, egl->minorVersion);
47             esBit = (eglVersion >= gl::Version(1, 5) || egl->hasExtension("EGL_KHR_create_context"))
48                         ? EGL_OPENGL_ES3_BIT
49                         : EGL_OPENGL_ES2_BIT;
50             break;
51         }
52 
53         default:
54             break;
55     }
56     return esBit;
57 }
58 
59 class WorkerContextEGL final : public rx::WorkerContext
60 {
61   public:
62     WorkerContextEGL(EGLContext context, rx::FunctionsEGL *functions, EGLSurface pbuffer);
63     ~WorkerContextEGL() override;
64 
65     bool makeCurrent() override;
66     void unmakeCurrent() override;
67 
68   private:
69     EGLContext mContext;
70     rx::FunctionsEGL *mFunctions;
71     EGLSurface mPbuffer;
72 };
73 
WorkerContextEGL(EGLContext context,rx::FunctionsEGL * functions,EGLSurface pbuffer)74 WorkerContextEGL::WorkerContextEGL(EGLContext context,
75                                    rx::FunctionsEGL *functions,
76                                    EGLSurface pbuffer)
77     : mContext(context), mFunctions(functions), mPbuffer(pbuffer)
78 {}
79 
~WorkerContextEGL()80 WorkerContextEGL::~WorkerContextEGL()
81 {
82     mFunctions->destroyContext(mContext);
83 }
84 
makeCurrent()85 bool WorkerContextEGL::makeCurrent()
86 {
87     if (mFunctions->makeCurrent(mPbuffer, mContext) == EGL_FALSE)
88     {
89         ERR() << "Unable to make the EGL context current.";
90         return false;
91     }
92     return true;
93 }
94 
unmakeCurrent()95 void WorkerContextEGL::unmakeCurrent()
96 {
97     mFunctions->makeCurrent(EGL_NO_SURFACE, EGL_NO_CONTEXT);
98 }
99 
100 }  // namespace
101 
102 namespace rx
103 {
104 
DisplayEGL(const egl::DisplayState & state)105 DisplayEGL::DisplayEGL(const egl::DisplayState &state)
106     : DisplayGL(state), mRenderer(nullptr), mEGL(nullptr), mConfig(EGL_NO_CONFIG_KHR)
107 {}
108 
~DisplayEGL()109 DisplayEGL::~DisplayEGL() {}
110 
createImage(const egl::ImageState & state,const gl::Context * context,EGLenum target,const egl::AttributeMap & attribs)111 ImageImpl *DisplayEGL::createImage(const egl::ImageState &state,
112                                    const gl::Context *context,
113                                    EGLenum target,
114                                    const egl::AttributeMap &attribs)
115 {
116     return new ImageEGL(state, context, target, attribs, mEGL);
117 }
118 
createSync(const egl::AttributeMap & attribs)119 EGLSyncImpl *DisplayEGL::createSync(const egl::AttributeMap &attribs)
120 {
121     return new SyncEGL(attribs, mEGL);
122 }
123 
getVendorString() const124 std::string DisplayEGL::getVendorString() const
125 {
126     const char *vendor = mEGL->queryString(EGL_VENDOR);
127     ASSERT(vendor);
128     return vendor;
129 }
130 
initializeContext(EGLContext shareContext,const egl::AttributeMap & eglAttributes,EGLContext * outContext,native_egl::AttributeVector * outAttribs) const131 egl::Error DisplayEGL::initializeContext(EGLContext shareContext,
132                                          const egl::AttributeMap &eglAttributes,
133                                          EGLContext *outContext,
134                                          native_egl::AttributeVector *outAttribs) const
135 {
136     gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
137 
138     EGLint requestedMajor =
139         eglAttributes.getAsInt(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE);
140     EGLint requestedMinor =
141         eglAttributes.getAsInt(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE);
142     bool initializeRequested = requestedMajor != EGL_DONT_CARE && requestedMinor != EGL_DONT_CARE;
143 
144     static_assert(EGL_CONTEXT_MAJOR_VERSION == EGL_CONTEXT_MAJOR_VERSION_KHR,
145                   "Major Version define should match");
146     static_assert(EGL_CONTEXT_MINOR_VERSION == EGL_CONTEXT_MINOR_VERSION_KHR,
147                   "Minor Version define should match");
148 
149     std::vector<native_egl::AttributeVector> contextAttribLists;
150     if (eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_create_context"))
151     {
152         if (initializeRequested)
153         {
154             contextAttribLists.push_back({EGL_CONTEXT_MAJOR_VERSION, requestedMajor,
155                                           EGL_CONTEXT_MINOR_VERSION, requestedMinor, EGL_NONE});
156         }
157         else
158         {
159             // clang-format off
160             const gl::Version esVersionsFrom2_0[] = {
161                 gl::Version(3, 2),
162                 gl::Version(3, 1),
163                 gl::Version(3, 0),
164                 gl::Version(2, 0),
165             };
166             // clang-format on
167 
168             for (const auto &version : esVersionsFrom2_0)
169             {
170                 contextAttribLists.push_back(
171                     {EGL_CONTEXT_MAJOR_VERSION, static_cast<EGLint>(version.major),
172                      EGL_CONTEXT_MINOR_VERSION, static_cast<EGLint>(version.minor), EGL_NONE});
173             }
174         }
175     }
176     else
177     {
178         if (initializeRequested && (requestedMajor != 2 || requestedMinor != 0))
179         {
180             return egl::EglBadAttribute() << "Unsupported requested context version";
181         }
182         contextAttribLists.push_back({EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE});
183     }
184 
185     EGLContext context = EGL_NO_CONTEXT;
186     for (const auto &attribList : contextAttribLists)
187     {
188         context = mEGL->createContext(mConfig, shareContext, attribList.data());
189         if (context != EGL_NO_CONTEXT)
190         {
191             *outContext = context;
192             *outAttribs = attribList;
193             return egl::NoError();
194         }
195     }
196 
197     return egl::Error(mEGL->getError(), "eglCreateContext failed");
198 }
199 
initialize(egl::Display * display)200 egl::Error DisplayEGL::initialize(egl::Display *display)
201 {
202     mDisplayAttributes = display->getAttributeMap();
203     mEGL               = new FunctionsEGLDL();
204 
205     void *eglHandle =
206         reinterpret_cast<void *>(mDisplayAttributes.get(EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE, 0));
207     ANGLE_TRY(mEGL->initialize(display->getNativeDisplayId(), "libEGL.so.1", eglHandle));
208 
209     gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
210     if (eglVersion < gl::Version(1, 4))
211     {
212         return egl::EglNotInitialized() << "EGL >= 1.4 is required";
213     }
214 
215     // Only support modern EGL implementation to keep default implementation
216     // simple.
217     const char *necessaryExtensions[] = {
218         "EGL_KHR_no_config_context",
219         "EGL_KHR_surfaceless_context",
220     };
221 
222     for (const char *ext : necessaryExtensions)
223     {
224         if (!mEGL->hasExtension(ext))
225         {
226             return egl::EglNotInitialized() << "need " << ext;
227         }
228     }
229 
230     const EGLAttrib platformAttrib = mDisplayAttributes.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, 0);
231     EGLint esBit                   = ESBitFromPlatformAttrib(mEGL, platformAttrib);
232     if (esBit == EGL_NONE)
233     {
234         return egl::EglNotInitialized() << "No matching ES Bit";
235     }
236 
237     std::vector<EGLint> configAttribListBase = {
238         EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
239         EGL_CONFIG_CAVEAT,     EGL_NONE,       EGL_CONFORMANT,   esBit,
240         EGL_RENDERABLE_TYPE,   esBit,          EGL_NONE};
241 
242     mConfigAttribList = configAttribListBase;
243 
244     EGLContext context = EGL_NO_CONTEXT;
245     native_egl::AttributeVector attribs;
246     ANGLE_TRY(initializeContext(EGL_NO_CONTEXT, mDisplayAttributes, &context, &attribs));
247 
248     if (!mEGL->makeCurrent(EGL_NO_SURFACE, context))
249     {
250         return egl::EglNotInitialized() << "Could not make context current.";
251     }
252 
253     std::unique_ptr<FunctionsGL> functionsGL(mEGL->makeFunctionsGL());
254     functionsGL->initialize(mDisplayAttributes);
255 
256     mRenderer.reset(
257         new RendererEGL(std::move(functionsGL), mDisplayAttributes, this, context, attribs));
258     const gl::Version &maxVersion = mRenderer->getMaxSupportedESVersion();
259     if (maxVersion < gl::Version(2, 0))
260     {
261         return egl::EglNotInitialized() << "OpenGL ES 2.0 is not supportable.";
262     }
263 
264     ANGLE_TRY(DisplayGL::initialize(display));
265 
266     return egl::NoError();
267 }
268 
terminate()269 void DisplayEGL::terminate()
270 {
271     DisplayGL::terminate();
272 
273     EGLBoolean success = mEGL->makeCurrent(EGL_NO_SURFACE, EGL_NO_CONTEXT);
274     if (success == EGL_FALSE)
275     {
276         ERR() << "eglMakeCurrent error " << egl::Error(mEGL->getError());
277     }
278 
279     mRenderer.reset();
280 
281     egl::Error result = mEGL->terminate();
282     if (result.isError())
283     {
284         ERR() << "eglTerminate error " << result;
285     }
286 
287     SafeDelete(mEGL);
288 }
289 
createWindowSurface(const egl::SurfaceState & state,EGLNativeWindowType window,const egl::AttributeMap & attribs)290 SurfaceImpl *DisplayEGL::createWindowSurface(const egl::SurfaceState &state,
291                                              EGLNativeWindowType window,
292                                              const egl::AttributeMap &attribs)
293 {
294     EGLConfig config;
295     EGLint numConfig;
296     EGLBoolean success;
297 
298     const EGLint configAttribList[] = {EGL_CONFIG_ID, mConfigIds[state.config->configID], EGL_NONE};
299     success                         = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
300     ASSERT(success && numConfig == 1);
301 
302     return new WindowSurfaceEGL(state, mEGL, config, window);
303 }
304 
createPbufferSurface(const egl::SurfaceState & state,const egl::AttributeMap & attribs)305 SurfaceImpl *DisplayEGL::createPbufferSurface(const egl::SurfaceState &state,
306                                               const egl::AttributeMap &attribs)
307 {
308     EGLConfig config;
309     EGLint numConfig;
310     EGLBoolean success;
311 
312     const EGLint configAttribList[] = {EGL_CONFIG_ID, mConfigIds[state.config->configID], EGL_NONE};
313     success                         = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
314     ASSERT(success && numConfig == 1);
315 
316     return new PbufferSurfaceEGL(state, mEGL, config);
317 }
318 
createPbufferFromClientBuffer(const egl::SurfaceState & state,EGLenum buftype,EGLClientBuffer clientBuffer,const egl::AttributeMap & attribs)319 SurfaceImpl *DisplayEGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
320                                                        EGLenum buftype,
321                                                        EGLClientBuffer clientBuffer,
322                                                        const egl::AttributeMap &attribs)
323 {
324     UNIMPLEMENTED();
325     return nullptr;
326 }
327 
createPixmapSurface(const egl::SurfaceState & state,NativePixmapType nativePixmap,const egl::AttributeMap & attribs)328 SurfaceImpl *DisplayEGL::createPixmapSurface(const egl::SurfaceState &state,
329                                              NativePixmapType nativePixmap,
330                                              const egl::AttributeMap &attribs)
331 {
332     UNIMPLEMENTED();
333     return nullptr;
334 }
335 
createContext(const gl::State & state,gl::ErrorSet * errorSet,const egl::Config * configuration,const gl::Context * shareContext,const egl::AttributeMap & attribs)336 ContextImpl *DisplayEGL::createContext(const gl::State &state,
337                                        gl::ErrorSet *errorSet,
338                                        const egl::Config *configuration,
339                                        const gl::Context *shareContext,
340                                        const egl::AttributeMap &attribs)
341 {
342     std::shared_ptr<RendererEGL> renderer;
343     EGLContext nativeShareContext = EGL_NO_CONTEXT;
344     if (shareContext)
345     {
346         ContextEGL *shareContextEGL = GetImplAs<ContextEGL>(shareContext);
347         nativeShareContext          = shareContextEGL->getContext();
348     }
349 
350     egl::Error error = createRenderer(nativeShareContext, &renderer);
351     if (error.isError())
352     {
353         ERR() << "Failed to create a shared renderer: " << error.getMessage();
354         return nullptr;
355     }
356 
357     return new ContextEGL(state, errorSet, renderer);
358 }
359 
360 template <typename T>
getConfigAttrib(EGLConfig config,EGLint attribute,T * value) const361 void DisplayEGL::getConfigAttrib(EGLConfig config, EGLint attribute, T *value) const
362 {
363     EGLint tmp;
364     EGLBoolean success = mEGL->getConfigAttrib(config, attribute, &tmp);
365     ASSERT(success == EGL_TRUE);
366     *value = tmp;
367 }
368 
369 template <typename T, typename U>
getConfigAttribIfExtension(EGLConfig config,EGLint attribute,T * value,const char * extension,const U & defaultValue) const370 void DisplayEGL::getConfigAttribIfExtension(EGLConfig config,
371                                             EGLint attribute,
372                                             T *value,
373                                             const char *extension,
374                                             const U &defaultValue) const
375 {
376     if (mEGL->hasExtension(extension))
377     {
378         getConfigAttrib(config, attribute, value);
379     }
380     else
381     {
382         *value = static_cast<T>(defaultValue);
383     }
384 }
385 
generateConfigs()386 egl::ConfigSet DisplayEGL::generateConfigs()
387 {
388     egl::ConfigSet configSet;
389     mConfigIds.clear();
390 
391     EGLint numConfigs;
392     EGLBoolean success = mEGL->chooseConfig(mConfigAttribList.data(), nullptr, 0, &numConfigs);
393     ASSERT(success == EGL_TRUE && numConfigs > 0);
394 
395     std::vector<EGLConfig> configs(numConfigs);
396     EGLint numConfigs2;
397     success =
398         mEGL->chooseConfig(mConfigAttribList.data(), configs.data(), numConfigs, &numConfigs2);
399     ASSERT(success == EGL_TRUE && numConfigs2 == numConfigs);
400 
401     for (int i = 0; i < numConfigs; i++)
402     {
403         egl::Config config;
404 
405         getConfigAttrib(configs[i], EGL_BUFFER_SIZE, &config.bufferSize);
406         getConfigAttrib(configs[i], EGL_RED_SIZE, &config.redSize);
407         getConfigAttrib(configs[i], EGL_GREEN_SIZE, &config.greenSize);
408         getConfigAttrib(configs[i], EGL_BLUE_SIZE, &config.blueSize);
409         getConfigAttrib(configs[i], EGL_LUMINANCE_SIZE, &config.luminanceSize);
410         getConfigAttrib(configs[i], EGL_ALPHA_SIZE, &config.alphaSize);
411         getConfigAttrib(configs[i], EGL_ALPHA_MASK_SIZE, &config.alphaMaskSize);
412         getConfigAttrib(configs[i], EGL_BIND_TO_TEXTURE_RGB, &config.bindToTextureRGB);
413         getConfigAttrib(configs[i], EGL_BIND_TO_TEXTURE_RGBA, &config.bindToTextureRGBA);
414         getConfigAttrib(configs[i], EGL_COLOR_BUFFER_TYPE, &config.colorBufferType);
415         getConfigAttrib(configs[i], EGL_CONFIG_CAVEAT, &config.configCaveat);
416         getConfigAttrib(configs[i], EGL_CONFIG_ID, &config.configID);
417         getConfigAttrib(configs[i], EGL_CONFORMANT, &config.conformant);
418         getConfigAttrib(configs[i], EGL_DEPTH_SIZE, &config.depthSize);
419         getConfigAttrib(configs[i], EGL_LEVEL, &config.level);
420         getConfigAttrib(configs[i], EGL_MAX_PBUFFER_WIDTH, &config.maxPBufferWidth);
421         getConfigAttrib(configs[i], EGL_MAX_PBUFFER_HEIGHT, &config.maxPBufferHeight);
422         getConfigAttrib(configs[i], EGL_MAX_PBUFFER_PIXELS, &config.maxPBufferPixels);
423         getConfigAttrib(configs[i], EGL_MAX_SWAP_INTERVAL, &config.maxSwapInterval);
424         getConfigAttrib(configs[i], EGL_MIN_SWAP_INTERVAL, &config.minSwapInterval);
425         getConfigAttrib(configs[i], EGL_NATIVE_RENDERABLE, &config.nativeRenderable);
426         getConfigAttrib(configs[i], EGL_NATIVE_VISUAL_ID, &config.nativeVisualID);
427         getConfigAttrib(configs[i], EGL_NATIVE_VISUAL_TYPE, &config.nativeVisualType);
428         getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE, &config.renderableType);
429         getConfigAttrib(configs[i], EGL_SAMPLE_BUFFERS, &config.sampleBuffers);
430         getConfigAttrib(configs[i], EGL_SAMPLES, &config.samples);
431         getConfigAttrib(configs[i], EGL_STENCIL_SIZE, &config.stencilSize);
432         getConfigAttrib(configs[i], EGL_SURFACE_TYPE, &config.surfaceType);
433         getConfigAttrib(configs[i], EGL_TRANSPARENT_TYPE, &config.transparentType);
434         getConfigAttrib(configs[i], EGL_TRANSPARENT_RED_VALUE, &config.transparentRedValue);
435         getConfigAttrib(configs[i], EGL_TRANSPARENT_GREEN_VALUE, &config.transparentGreenValue);
436         getConfigAttrib(configs[i], EGL_TRANSPARENT_BLUE_VALUE, &config.transparentBlueValue);
437         getConfigAttribIfExtension(configs[i], EGL_COLOR_COMPONENT_TYPE_EXT,
438                                    &config.colorComponentType, "EGL_EXT_pixel_format_float",
439                                    EGL_COLOR_COMPONENT_TYPE_FIXED_EXT);
440 
441         if (config.colorBufferType == EGL_RGB_BUFFER)
442         {
443             ASSERT(config.colorComponentType == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT);
444             if (config.redSize == 8 && config.greenSize == 8 && config.blueSize == 8 &&
445                 config.alphaSize == 8)
446             {
447                 config.renderTargetFormat = GL_RGBA8;
448             }
449             else if (config.redSize == 8 && config.greenSize == 8 && config.blueSize == 8 &&
450                      config.alphaSize == 0)
451             {
452                 config.renderTargetFormat = GL_RGB8;
453             }
454             else if (config.redSize == 5 && config.greenSize == 6 && config.blueSize == 5 &&
455                      config.alphaSize == 0)
456             {
457                 config.renderTargetFormat = GL_RGB565;
458             }
459             else if (config.redSize == 5 && config.greenSize == 5 && config.blueSize == 5 &&
460                      config.alphaSize == 1)
461             {
462                 config.renderTargetFormat = GL_RGB5_A1;
463             }
464             else if (config.redSize == 4 && config.greenSize == 4 && config.blueSize == 4 &&
465                      config.alphaSize == 4)
466             {
467                 config.renderTargetFormat = GL_RGBA4;
468             }
469             else
470             {
471                 ERR() << "RGBA(" << config.redSize << "," << config.greenSize << ","
472                       << config.blueSize << "," << config.alphaSize << ") not handled";
473                 UNREACHABLE();
474             }
475         }
476         else
477         {
478             UNREACHABLE();
479         }
480 
481         if (config.depthSize == 0 && config.stencilSize == 0)
482         {
483             config.depthStencilFormat = GL_ZERO;
484         }
485         else if (config.depthSize == 16 && config.stencilSize == 0)
486         {
487             config.depthStencilFormat = GL_DEPTH_COMPONENT16;
488         }
489         else if (config.depthSize == 24 && config.stencilSize == 0)
490         {
491             config.depthStencilFormat = GL_DEPTH_COMPONENT24;
492         }
493         else if (config.depthSize == 24 && config.stencilSize == 8)
494         {
495             config.depthStencilFormat = GL_DEPTH24_STENCIL8;
496         }
497         else if (config.depthSize == 0 && config.stencilSize == 8)
498         {
499             config.depthStencilFormat = GL_STENCIL_INDEX8;
500         }
501         else
502         {
503             UNREACHABLE();
504         }
505 
506         config.matchNativePixmap  = EGL_NONE;
507         config.optimalOrientation = 0;
508 
509         int internalId         = configSet.add(config);
510         mConfigIds[internalId] = config.configID;
511     }
512 
513     return configSet;
514 }
515 
testDeviceLost()516 bool DisplayEGL::testDeviceLost()
517 {
518     return false;
519 }
520 
restoreLostDevice(const egl::Display * display)521 egl::Error DisplayEGL::restoreLostDevice(const egl::Display *display)
522 {
523     UNIMPLEMENTED();
524     return egl::NoError();
525 }
526 
isValidNativeWindow(EGLNativeWindowType window) const527 bool DisplayEGL::isValidNativeWindow(EGLNativeWindowType window) const
528 {
529     return true;
530 }
531 
createDevice()532 DeviceImpl *DisplayEGL::createDevice()
533 {
534     UNIMPLEMENTED();
535     return nullptr;
536 }
537 
waitClient(const gl::Context * context)538 egl::Error DisplayEGL::waitClient(const gl::Context *context)
539 {
540     UNIMPLEMENTED();
541     return egl::NoError();
542 }
543 
waitNative(const gl::Context * context,EGLint engine)544 egl::Error DisplayEGL::waitNative(const gl::Context *context, EGLint engine)
545 {
546     UNIMPLEMENTED();
547     return egl::NoError();
548 }
549 
makeCurrent(egl::Surface * drawSurface,egl::Surface * readSurface,gl::Context * context)550 egl::Error DisplayEGL::makeCurrent(egl::Surface *drawSurface,
551                                    egl::Surface *readSurface,
552                                    gl::Context *context)
553 {
554     EGLSurface newSurface = EGL_NO_SURFACE;
555     if (drawSurface)
556     {
557         SurfaceEGL *drawSurfaceEGL = GetImplAs<SurfaceEGL>(drawSurface);
558         newSurface                 = drawSurfaceEGL->getSurface();
559     }
560 
561     EGLContext newContext = EGL_NO_CONTEXT;
562     if (context)
563     {
564         ContextEGL *contextEGL = GetImplAs<ContextEGL>(context);
565         newContext             = contextEGL->getContext();
566     }
567 
568     if (mEGL->makeCurrent(newSurface, newContext) == EGL_FALSE)
569     {
570         return egl::Error(mEGL->getError(), "eglMakeCurrent failed");
571     }
572 
573     return DisplayGL::makeCurrent(drawSurface, readSurface, context);
574 }
575 
getMaxSupportedESVersion() const576 gl::Version DisplayEGL::getMaxSupportedESVersion() const
577 {
578     return mRenderer->getMaxSupportedESVersion();
579 }
580 
destroyNativeContext(EGLContext context)581 void DisplayEGL::destroyNativeContext(EGLContext context)
582 {
583     mEGL->destroyContext(context);
584 }
585 
generateExtensions(egl::DisplayExtensions * outExtensions) const586 void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
587 {
588     gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
589 
590     outExtensions->createContextRobustness =
591         mEGL->hasExtension("EGL_EXT_create_context_robustness");
592 
593     outExtensions->postSubBuffer    = false;  // Since SurfaceEGL::postSubBuffer is not implemented
594     outExtensions->presentationTime = mEGL->hasExtension("EGL_ANDROID_presentation_time");
595 
596     // Contexts are virtualized so textures can be shared globally
597     outExtensions->displayTextureShareGroup = true;
598 
599     // We will fallback to regular swap if swapBuffersWithDamage isn't
600     // supported, so indicate support here to keep validation happy.
601     outExtensions->swapBuffersWithDamage = true;
602 
603     outExtensions->image     = mEGL->hasExtension("EGL_KHR_image");
604     outExtensions->imageBase = mEGL->hasExtension("EGL_KHR_image_base");
605     // Pixmaps are not supported in ANGLE's EGL implementation.
606     // outExtensions->imagePixmap = mEGL->hasExtension("EGL_KHR_image_pixmap");
607     outExtensions->glTexture2DImage      = mEGL->hasExtension("EGL_KHR_gl_texture_2D_image");
608     outExtensions->glTextureCubemapImage = mEGL->hasExtension("EGL_KHR_gl_texture_cubemap_image");
609     outExtensions->glTexture3DImage      = mEGL->hasExtension("EGL_KHR_gl_texture_3D_image");
610     outExtensions->glRenderbufferImage   = mEGL->hasExtension("EGL_KHR_gl_renderbuffer_image");
611     outExtensions->pixelFormatFloat      = mEGL->hasExtension("EGL_EXT_pixel_format_float");
612 
613     outExtensions->glColorspace = mEGL->hasExtension("EGL_KHR_gl_colorspace");
614     if (outExtensions->glColorspace)
615     {
616         outExtensions->glColorspaceDisplayP3Linear =
617             mEGL->hasExtension("EGL_EXT_gl_colorspace_display_p3_linear");
618         outExtensions->glColorspaceDisplayP3 =
619             mEGL->hasExtension("EGL_EXT_gl_colorspace_display_p3");
620         outExtensions->glColorspaceScrgb = mEGL->hasExtension("EGL_EXT_gl_colorspace_scrgb");
621         outExtensions->glColorspaceScrgbLinear =
622             mEGL->hasExtension("EGL_EXT_gl_colorspace_scrgb_linear");
623         outExtensions->glColorspaceDisplayP3Passthrough =
624             mEGL->hasExtension("EGL_EXT_gl_colorspace_display_p3_passthrough");
625         outExtensions->imageGlColorspace = mEGL->hasExtension("EGL_EXT_image_gl_colorspace");
626     }
627 
628     outExtensions->imageNativeBuffer = mEGL->hasExtension("EGL_ANDROID_image_native_buffer");
629 
630     outExtensions->getFrameTimestamps = mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps");
631 
632     outExtensions->fenceSync =
633         eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_fence_sync");
634     outExtensions->waitSync =
635         eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_wait_sync");
636 
637     outExtensions->getNativeClientBufferANDROID =
638         mEGL->hasExtension("EGL_ANDROID_get_native_client_buffer");
639 
640     outExtensions->nativeFenceSyncANDROID = mEGL->hasExtension("EGL_ANDROID_native_fence_sync");
641 
642     outExtensions->noConfigContext = mEGL->hasExtension("EGL_KHR_no_config_context");
643 
644     outExtensions->surfacelessContext = mEGL->hasExtension("EGL_KHR_surfaceless_context");
645 
646     outExtensions->framebufferTargetANDROID = mEGL->hasExtension("EGL_ANDROID_framebuffer_target");
647 
648     outExtensions->imageDmaBufImportEXT = mEGL->hasExtension("EGL_EXT_image_dma_buf_import");
649 
650     outExtensions->imageDmaBufImportModifiersEXT =
651         mEGL->hasExtension("EGL_EXT_image_dma_buf_import_modifiers");
652 
653     DisplayGL::generateExtensions(outExtensions);
654 }
655 
generateCaps(egl::Caps * outCaps) const656 void DisplayEGL::generateCaps(egl::Caps *outCaps) const
657 {
658     outCaps->textureNPOT = true;  // Since we request GLES >= 2
659 }
660 
setBlobCacheFuncs(EGLSetBlobFuncANDROID set,EGLGetBlobFuncANDROID get)661 void DisplayEGL::setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get)
662 {
663     if (mEGL->hasExtension("EGL_ANDROID_blob_cache"))
664     {
665         mEGL->setBlobCacheFuncsANDROID(set, get);
666     }
667 }
668 
makeCurrentSurfaceless(gl::Context * context)669 egl::Error DisplayEGL::makeCurrentSurfaceless(gl::Context *context)
670 {
671     // Nothing to do because EGL always uses the same context and the previous surface can be left
672     // current.
673     return egl::NoError();
674 }
675 
createRenderer(EGLContext shareContext,std::shared_ptr<RendererEGL> * outRenderer)676 egl::Error DisplayEGL::createRenderer(EGLContext shareContext,
677                                       std::shared_ptr<RendererEGL> *outRenderer)
678 {
679     EGLContext context = EGL_NO_CONTEXT;
680     native_egl::AttributeVector attribs;
681     ANGLE_TRY(initializeContext(shareContext, mDisplayAttributes, &context, &attribs));
682 
683     if (mEGL->makeCurrent(EGL_NO_SURFACE, context) == EGL_FALSE)
684     {
685         return egl::EglNotInitialized()
686                << "eglMakeCurrent failed with " << egl::Error(mEGL->getError());
687     }
688 
689     std::unique_ptr<FunctionsGL> functionsGL(mEGL->makeFunctionsGL());
690     functionsGL->initialize(mDisplayAttributes);
691 
692     outRenderer->reset(
693         new RendererEGL(std::move(functionsGL), mDisplayAttributes, this, context, attribs));
694 
695     return egl::NoError();
696 }
697 
createWorkerContext(std::string * infoLog,EGLContext sharedContext,const native_egl::AttributeVector workerAttribs)698 WorkerContext *DisplayEGL::createWorkerContext(std::string *infoLog,
699                                                EGLContext sharedContext,
700                                                const native_egl::AttributeVector workerAttribs)
701 {
702     EGLContext context = mEGL->createContext(mConfig, sharedContext, workerAttribs.data());
703     if (context == EGL_NO_CONTEXT)
704     {
705         *infoLog += "Unable to create the EGL context.";
706         return nullptr;
707     }
708     return new WorkerContextEGL(context, mEGL, EGL_NO_SURFACE);
709 }
710 
initializeFrontendFeatures(angle::FrontendFeatures * features) const711 void DisplayEGL::initializeFrontendFeatures(angle::FrontendFeatures *features) const
712 {
713     mRenderer->initializeFrontendFeatures(features);
714 }
715 
populateFeatureList(angle::FeatureList * features)716 void DisplayEGL::populateFeatureList(angle::FeatureList *features)
717 {
718     mRenderer->getFeatures().populateFeatureList(features);
719 }
720 
validateImageClientBuffer(const gl::Context * context,EGLenum target,EGLClientBuffer clientBuffer,const egl::AttributeMap & attribs) const721 egl::Error DisplayEGL::validateImageClientBuffer(const gl::Context *context,
722                                                  EGLenum target,
723                                                  EGLClientBuffer clientBuffer,
724                                                  const egl::AttributeMap &attribs) const
725 {
726     switch (target)
727     {
728         case EGL_LINUX_DMA_BUF_EXT:
729             return egl::NoError();
730 
731         default:
732             return DisplayGL::validateImageClientBuffer(context, target, clientBuffer, attribs);
733     }
734 }
735 
createExternalImageSibling(const gl::Context * context,EGLenum target,EGLClientBuffer buffer,const egl::AttributeMap & attribs)736 ExternalImageSiblingImpl *DisplayEGL::createExternalImageSibling(const gl::Context *context,
737                                                                  EGLenum target,
738                                                                  EGLClientBuffer buffer,
739                                                                  const egl::AttributeMap &attribs)
740 {
741     switch (target)
742     {
743         case EGL_LINUX_DMA_BUF_EXT:
744             ASSERT(context == nullptr);
745             ASSERT(buffer == nullptr);
746             return new DmaBufImageSiblingEGL(attribs);
747 
748         default:
749             return DisplayGL::createExternalImageSibling(context, target, buffer, attribs);
750     }
751 }
752 
753 }  // namespace rx
754