88
99#include " libANGLE/renderer/gl/egl/DisplayEGL.h"
1010
11+ #include " common/debug.h"
12+ #include " libANGLE/Context.h"
13+ #include " libANGLE/Display.h"
1114#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/FunctionsEGLDL.h"
1219#include " libANGLE/renderer/gl/egl/ImageEGL.h"
1320#include " libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h"
1421#include " libANGLE/renderer/gl/egl/RendererEGL.h"
1522#include " libANGLE/renderer/gl/egl/SyncEGL.h"
1623#include " libANGLE/renderer/gl/egl/WindowSurfaceEGL.h"
24+ #include " libANGLE/renderer/gl/renderergl_utils.h"
25+
26+ namespace
27+ {
28+
29+ EGLint ESBitFromPlatformAttrib (const rx::FunctionsEGL *egl, const EGLAttrib platformAttrib)
30+ {
31+ EGLint esBit = EGL_NONE;
32+ switch (platformAttrib)
33+ {
34+ case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
35+ {
36+ esBit = EGL_OPENGL_BIT;
37+ break ;
38+ }
39+
40+ case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
41+ {
42+ static_assert (EGL_OPENGL_ES3_BIT == EGL_OPENGL_ES3_BIT_KHR,
43+ " Extension define must match core" );
44+
45+ gl::Version eglVersion (egl->majorVersion , egl->minorVersion );
46+ esBit = (eglVersion >= gl::Version (1 , 5 ) || egl->hasExtension (" EGL_KHR_create_context" ))
47+ ? EGL_OPENGL_ES3_BIT
48+ : EGL_OPENGL_ES2_BIT;
49+ break ;
50+ }
51+
52+ default :
53+ break ;
54+ }
55+ return esBit;
56+ }
57+
58+ class WorkerContextEGL final : public rx::WorkerContext
59+ {
60+ public:
61+ WorkerContextEGL (EGLContext context, rx::FunctionsEGL *functions, EGLSurface pbuffer);
62+ ~WorkerContextEGL () override ;
63+
64+ bool makeCurrent () override ;
65+ void unmakeCurrent () override ;
66+
67+ private:
68+ EGLContext mContext ;
69+ rx::FunctionsEGL *mFunctions ;
70+ EGLSurface mPbuffer ;
71+ };
72+
73+ WorkerContextEGL::WorkerContextEGL (EGLContext context,
74+ rx::FunctionsEGL *functions,
75+ EGLSurface pbuffer)
76+ : mContext (context), mFunctions (functions), mPbuffer (pbuffer)
77+ {}
78+
79+ WorkerContextEGL::~WorkerContextEGL ()
80+ {
81+ mFunctions ->destroyContext (mContext );
82+ }
83+
84+ bool WorkerContextEGL::makeCurrent ()
85+ {
86+ if (mFunctions ->makeCurrent (mPbuffer , mContext ) == EGL_FALSE)
87+ {
88+ ERR () << " Unable to make the EGL context current." ;
89+ return false ;
90+ }
91+ return true ;
92+ }
93+
94+ void WorkerContextEGL::unmakeCurrent ()
95+ {
96+ mFunctions ->makeCurrent (EGL_NO_SURFACE, EGL_NO_CONTEXT);
97+ }
98+
99+ } // namespace
17100
18101namespace rx
19102{
@@ -113,6 +196,96 @@ egl::Error DisplayEGL::initializeContext(EGLContext shareContext,
113196 return egl::Error (mEGL ->getError (), " eglCreateContext failed" );
114197}
115198
199+ egl::Error DisplayEGL::initialize (egl::Display *display)
200+ {
201+ mDisplayAttributes = display->getAttributeMap ();
202+ mEGL = new FunctionsEGLDL ();
203+
204+ void *eglHandle =
205+ reinterpret_cast <void *>(mDisplayAttributes .get (EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE, 0 ));
206+ ANGLE_TRY (mEGL ->initialize (display->getNativeDisplayId (), " libEGL.so.1" , eglHandle));
207+
208+ gl::Version eglVersion (mEGL ->majorVersion , mEGL ->minorVersion );
209+ if (eglVersion < gl::Version (1 , 4 ))
210+ {
211+ return egl::EglNotInitialized () << " EGL >= 1.4 is required" ;
212+ }
213+
214+ // Only support modern EGL implementation to keep default implementation
215+ // simple.
216+ const char *necessaryExtensions[] = {
217+ " EGL_KHR_no_config_context" ,
218+ " EGL_KHR_surfaceless_context" ,
219+ };
220+
221+ for (const char *ext : necessaryExtensions)
222+ {
223+ if (!mEGL ->hasExtension (ext))
224+ {
225+ return egl::EglNotInitialized () << " need " << ext;
226+ }
227+ }
228+
229+ const EGLAttrib platformAttrib = mDisplayAttributes .get (EGL_PLATFORM_ANGLE_TYPE_ANGLE, 0 );
230+ EGLint esBit = ESBitFromPlatformAttrib (mEGL , platformAttrib);
231+ if (esBit == EGL_NONE)
232+ {
233+ return egl::EglNotInitialized () << " No matching ES Bit" ;
234+ }
235+
236+ std::vector<EGLint> configAttribListBase = {
237+ EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
238+ EGL_CONFIG_CAVEAT, EGL_NONE, EGL_CONFORMANT, esBit,
239+ EGL_RENDERABLE_TYPE, esBit, EGL_NONE};
240+
241+ mConfigAttribList = configAttribListBase;
242+
243+ EGLContext context = EGL_NO_CONTEXT;
244+ native_egl::AttributeVector attribs;
245+ ANGLE_TRY (initializeContext (EGL_NO_CONTEXT, mDisplayAttributes , &context, &attribs));
246+
247+ if (!mEGL ->makeCurrent (EGL_NO_SURFACE, context))
248+ {
249+ return egl::EglNotInitialized () << " Could not make context current." ;
250+ }
251+
252+ std::unique_ptr<FunctionsGL> functionsGL (mEGL ->makeFunctionsGL ());
253+ functionsGL->initialize (mDisplayAttributes );
254+
255+ mRenderer .reset (
256+ new RendererEGL (std::move (functionsGL), mDisplayAttributes , this , context, attribs));
257+ const gl::Version &maxVersion = mRenderer ->getMaxSupportedESVersion ();
258+ if (maxVersion < gl::Version (2 , 0 ))
259+ {
260+ return egl::EglNotInitialized () << " OpenGL ES 2.0 is not supportable." ;
261+ }
262+
263+ ANGLE_TRY (DisplayGL::initialize (display));
264+
265+ return egl::NoError ();
266+ }
267+
268+ void DisplayEGL::terminate ()
269+ {
270+ DisplayGL::terminate ();
271+
272+ EGLBoolean success = mEGL ->makeCurrent (EGL_NO_SURFACE, EGL_NO_CONTEXT);
273+ if (success == EGL_FALSE)
274+ {
275+ ERR () << " eglMakeCurrent error " << egl::Error (mEGL ->getError ());
276+ }
277+
278+ mRenderer .reset ();
279+
280+ egl::Error result = mEGL ->terminate ();
281+ if (result.isError ())
282+ {
283+ ERR () << " eglTerminate error " << result;
284+ }
285+
286+ SafeDelete (mEGL );
287+ }
288+
116289SurfaceImpl *DisplayEGL::createWindowSurface (const egl::SurfaceState &state,
117290 EGLNativeWindowType window,
118291 const egl::AttributeMap &attribs)
@@ -159,6 +332,30 @@ SurfaceImpl *DisplayEGL::createPixmapSurface(const egl::SurfaceState &state,
159332 return nullptr ;
160333}
161334
335+ ContextImpl *DisplayEGL::createContext (const gl::State &state,
336+ gl::ErrorSet *errorSet,
337+ const egl::Config *configuration,
338+ const gl::Context *shareContext,
339+ const egl::AttributeMap &attribs)
340+ {
341+ std::shared_ptr<RendererEGL> renderer;
342+ EGLContext nativeShareContext = EGL_NO_CONTEXT;
343+ if (shareContext)
344+ {
345+ ContextEGL *shareContextEGL = GetImplAs<ContextEGL>(shareContext);
346+ nativeShareContext = shareContextEGL->getContext ();
347+ }
348+
349+ egl::Error error = createRenderer (nativeShareContext, &renderer);
350+ if (error.isError ())
351+ {
352+ ERR () << " Failed to create a shared renderer: " << error.getMessage ();
353+ return nullptr ;
354+ }
355+
356+ return new ContextEGL (state, errorSet, renderer);
357+ }
358+
162359template <typename T>
163360void DisplayEGL::getConfigAttrib (EGLConfig config, EGLint attribute, T *value) const
164361{
@@ -349,6 +546,32 @@ egl::Error DisplayEGL::waitNative(const gl::Context *context, EGLint engine)
349546 return egl::NoError ();
350547}
351548
549+ egl::Error DisplayEGL::makeCurrent (egl::Surface *drawSurface,
550+ egl::Surface *readSurface,
551+ gl::Context *context)
552+ {
553+ EGLSurface newSurface = EGL_NO_SURFACE;
554+ if (drawSurface)
555+ {
556+ SurfaceEGL *drawSurfaceEGL = GetImplAs<SurfaceEGL>(drawSurface);
557+ newSurface = drawSurfaceEGL->getSurface ();
558+ }
559+
560+ EGLContext newContext = EGL_NO_CONTEXT;
561+ if (context)
562+ {
563+ ContextEGL *contextEGL = GetImplAs<ContextEGL>(context);
564+ newContext = contextEGL->getContext ();
565+ }
566+
567+ if (mEGL ->makeCurrent (newSurface, newContext) == EGL_FALSE)
568+ {
569+ return egl::Error (mEGL ->getError (), " eglMakeCurrent failed" );
570+ }
571+
572+ return DisplayGL::makeCurrent (drawSurface, readSurface, context);
573+ }
574+
352575gl::Version DisplayEGL::getMaxSupportedESVersion () const
353576{
354577 return mRenderer ->getMaxSupportedESVersion ();
@@ -416,6 +639,8 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
416639
417640 outExtensions->noConfigContext = mEGL ->hasExtension (" EGL_KHR_no_config_context" );
418641
642+ outExtensions->surfacelessContext = mEGL ->hasExtension (" EGL_KHR_surfaceless_context" );
643+
419644 outExtensions->framebufferTargetANDROID = mEGL ->hasExtension (" EGL_ANDROID_framebuffer_target" );
420645
421646 DisplayGL::generateExtensions (outExtensions);
@@ -441,6 +666,41 @@ egl::Error DisplayEGL::makeCurrentSurfaceless(gl::Context *context)
441666 return egl::NoError ();
442667}
443668
669+ egl::Error DisplayEGL::createRenderer (EGLContext shareContext,
670+ std::shared_ptr<RendererEGL> *outRenderer)
671+ {
672+ EGLContext context = EGL_NO_CONTEXT;
673+ native_egl::AttributeVector attribs;
674+ ANGLE_TRY (initializeContext (shareContext, mDisplayAttributes , &context, &attribs));
675+
676+ if (mEGL ->makeCurrent (EGL_NO_SURFACE, context) == EGL_FALSE)
677+ {
678+ return egl::EglNotInitialized ()
679+ << " eglMakeCurrent failed with " << egl::Error (mEGL ->getError ());
680+ }
681+
682+ std::unique_ptr<FunctionsGL> functionsGL (mEGL ->makeFunctionsGL ());
683+ functionsGL->initialize (mDisplayAttributes );
684+
685+ outRenderer->reset (
686+ new RendererEGL (std::move (functionsGL), mDisplayAttributes , this , context, attribs));
687+
688+ return egl::NoError ();
689+ }
690+
691+ WorkerContext *DisplayEGL::createWorkerContext (std::string *infoLog,
692+ EGLContext sharedContext,
693+ const native_egl::AttributeVector workerAttribs)
694+ {
695+ EGLContext context = mEGL ->createContext (mConfig , sharedContext, workerAttribs.data ());
696+ if (context == EGL_NO_CONTEXT)
697+ {
698+ *infoLog += " Unable to create the EGL context." ;
699+ return nullptr ;
700+ }
701+ return new WorkerContextEGL (context, mEGL , EGL_NO_SURFACE);
702+ }
703+
444704void DisplayEGL::initializeFrontendFeatures (angle::FrontendFeatures *features) const
445705{
446706 mRenderer ->initializeFrontendFeatures (features);
0 commit comments