diff options
| author | 2018-11-27 22:49:37 -0800 | |
|---|---|---|
| committer | 2018-11-27 22:49:37 -0800 | |
| commit | a5e9f1b0d17dc149f399cb0b477844f05193cdbb (patch) | |
| tree | 8f85c4827485784b48178057657e61a8e599b81c | |
| parent | b49bb9150a4abc1561ea6b13b79a6ea86d6e81f2 (diff) | |
[RenderEngine] Make use of EGL_KHR_surfaceless_context.
Per
https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_surfaceless_context.txt,
when EGL_KHR_surfaceless_context is present, we can make the context current
without specifying draw and read surface, thus we no longer need to create a
1x1 buffer surface.
BUG: 35315015
Test: Build, flash, boot.
Change-Id: Ia5f19cf0f9561bb660708b5a2ae0187593422210
| -rw-r--r-- | libs/renderengine/gl/GLES20RenderEngine.cpp | 92 | ||||
| -rw-r--r-- | libs/renderengine/gl/GLES20RenderEngine.h | 4 | ||||
| -rw-r--r-- | libs/renderengine/gl/GLExtensions.cpp | 3 | ||||
| -rw-r--r-- | libs/renderengine/gl/GLExtensions.h | 47 |
4 files changed, 86 insertions, 60 deletions
diff --git a/libs/renderengine/gl/GLES20RenderEngine.cpp b/libs/renderengine/gl/GLES20RenderEngine.cpp index d35762d447..b10b52bad8 100644 --- a/libs/renderengine/gl/GLES20RenderEngine.cpp +++ b/libs/renderengine/gl/GLES20RenderEngine.cpp @@ -240,60 +240,29 @@ std::unique_ptr<GLES20RenderEngine> GLES20RenderEngine::create(int hwcFormat, config = chooseEglConfig(display, hwcFormat, /*logConfig*/ true); } - EGLint renderableType = 0; - if (config == EGL_NO_CONFIG) { - renderableType = EGL_OPENGL_ES2_BIT; - } else if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) { - LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE"); - } - EGLint contextClientVersion = 0; - if (renderableType & EGL_OPENGL_ES2_BIT) { - contextClientVersion = 2; - } else if (renderableType & EGL_OPENGL_ES_BIT) { - contextClientVersion = 1; - } else { - LOG_ALWAYS_FATAL("no supported EGL_RENDERABLE_TYPEs"); - } - - std::vector<EGLint> contextAttributes; - contextAttributes.reserve(6); - contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION); - contextAttributes.push_back(contextClientVersion); bool useContextPriority = extensions.hasContextPriority() && (featureFlags & RenderEngine::USE_HIGH_PRIORITY_CONTEXT); - if (useContextPriority) { - contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); - contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); - } - contextAttributes.push_back(EGL_NONE); - - EGLContext ctxt = eglCreateContext(display, config, nullptr, contextAttributes.data()); + EGLContext ctxt = createEglContext(display, config, EGL_NO_CONTEXT, useContextPriority); // if can't create a GL context, we can only abort. LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed"); - // now figure out what version of GL did we actually get - // NOTE: a dummy surface is not needed if KHR_create_context is supported - // TODO(alecmouri): don't create this surface if EGL_KHR_surfaceless_context - // is supported. - - EGLConfig dummyConfig = config; - if (dummyConfig == EGL_NO_CONFIG) { - dummyConfig = chooseEglConfig(display, hwcFormat, /*logConfig*/ true); + EGLSurface dummy = EGL_NO_SURFACE; + if (!extensions.hasSurfacelessContext()) { + dummy = createDummyEglPbufferSurface(display, config, hwcFormat); + LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer"); } - EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE}; - EGLSurface dummy = eglCreatePbufferSurface(display, dummyConfig, attribs); - LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer"); + EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt); LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current"); extensions.initWithGLStrings(glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION), glGetString(GL_EXTENSIONS)); + // now figure out what version of GL did we actually get GlesVersion version = parseGlesVersion(extensions.getVersion()); // initialize the renderer while GL is current - std::unique_ptr<GLES20RenderEngine> engine; switch (version) { case GLES_VERSION_1_0: @@ -908,6 +877,53 @@ GLES20RenderEngine::GlesVersion GLES20RenderEngine::parseGlesVersion(const char* return GLES_VERSION_1_0; } +EGLContext GLES20RenderEngine::createEglContext(EGLDisplay display, EGLConfig config, + EGLContext shareContext, bool useContextPriority) { + EGLint renderableType = 0; + if (config == EGL_NO_CONFIG) { + renderableType = EGL_OPENGL_ES2_BIT; + } else if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) { + LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE"); + } + EGLint contextClientVersion = 0; + if (renderableType & EGL_OPENGL_ES2_BIT) { + contextClientVersion = 2; + } else if (renderableType & EGL_OPENGL_ES_BIT) { + contextClientVersion = 1; + } else { + LOG_ALWAYS_FATAL("no supported EGL_RENDERABLE_TYPEs"); + } + + std::vector<EGLint> contextAttributes; + contextAttributes.reserve(5); + contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION); + contextAttributes.push_back(contextClientVersion); + if (useContextPriority) { + contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); + contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); + } + contextAttributes.push_back(EGL_NONE); + + return eglCreateContext(display, config, shareContext, contextAttributes.data()); +} + +EGLSurface GLES20RenderEngine::createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config, + int hwcFormat) { + EGLConfig dummyConfig = config; + if (dummyConfig == EGL_NO_CONFIG) { + dummyConfig = chooseEglConfig(display, hwcFormat, /*logConfig*/ true); + } + std::vector<EGLint> attributes; + attributes.reserve(5); + attributes.push_back(EGL_WIDTH); + attributes.push_back(1); + attributes.push_back(EGL_HEIGHT); + attributes.push_back(1); + attributes.push_back(EGL_NONE); + + return eglCreatePbufferSurface(display, dummyConfig, attributes.data()); +} + bool GLES20RenderEngine::isHdrDataSpace(const Dataspace dataSpace) const { const Dataspace standard = static_cast<Dataspace>(dataSpace & Dataspace::STANDARD_MASK); const Dataspace transfer = static_cast<Dataspace>(dataSpace & Dataspace::TRANSFER_MASK); diff --git a/libs/renderengine/gl/GLES20RenderEngine.h b/libs/renderengine/gl/GLES20RenderEngine.h index 6c50938863..77dba626a0 100644 --- a/libs/renderengine/gl/GLES20RenderEngine.h +++ b/libs/renderengine/gl/GLES20RenderEngine.h @@ -112,6 +112,10 @@ private: }; static GlesVersion parseGlesVersion(const char* str); + static EGLContext createEglContext(EGLDisplay display, EGLConfig config, + EGLContext shareContext, bool useContextPriority); + static EGLSurface createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config, + int hwcFormat); // A data space is considered HDR data space if it has BT2020 color space // with PQ or HLG transfer function. diff --git a/libs/renderengine/gl/GLExtensions.cpp b/libs/renderengine/gl/GLExtensions.cpp index 784693bdfa..ce83dd576b 100644 --- a/libs/renderengine/gl/GLExtensions.cpp +++ b/libs/renderengine/gl/GLExtensions.cpp @@ -112,6 +112,9 @@ void GLExtensions::initWithEGLStrings(char const* eglVersion, char const* eglExt if (extensionSet.hasExtension("EGL_IMG_context_priority")) { mHasContextPriority = true; } + if (extensionSet.hasExtension("EGL_KHR_surfaceless_context")) { + mHasSurfacelessContext = true; + } } char const* GLExtensions::getEGLVersion() const { diff --git a/libs/renderengine/gl/GLExtensions.h b/libs/renderengine/gl/GLExtensions.h index 382c23a583..2a654d5356 100644 --- a/libs/renderengine/gl/GLExtensions.h +++ b/libs/renderengine/gl/GLExtensions.h @@ -32,6 +32,30 @@ namespace renderengine { namespace gl { class GLExtensions : public Singleton<GLExtensions> { +public: + bool hasNoConfigContext() const { return mHasNoConfigContext; } + bool hasNativeFenceSync() const { return mHasNativeFenceSync; } + bool hasFenceSync() const { return mHasFenceSync; } + bool hasWaitSync() const { return mHasWaitSync; } + bool hasProtectedContent() const { return mHasProtectedContent; } + bool hasContextPriority() const { return mHasContextPriority; } + bool hasSurfacelessContext() const { return mHasSurfacelessContext; } + + void initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version, + GLubyte const* extensions); + char const* getVendor() const; + char const* getRenderer() const; + char const* getVersion() const; + char const* getExtensions() const; + + void initWithEGLStrings(char const* eglVersion, char const* eglExtensions); + char const* getEGLVersion() const; + char const* getEGLExtensions() const; + +protected: + GLExtensions() = default; + +private: friend class Singleton<GLExtensions>; bool mHasNoConfigContext = false; @@ -40,6 +64,7 @@ class GLExtensions : public Singleton<GLExtensions> { bool mHasWaitSync = false; bool mHasProtectedContent = false; bool mHasContextPriority = false; + bool mHasSurfacelessContext = false; String8 mVendor; String8 mRenderer; @@ -51,28 +76,6 @@ class GLExtensions : public Singleton<GLExtensions> { GLExtensions(const GLExtensions&); GLExtensions& operator=(const GLExtensions&); - -protected: - GLExtensions() = default; - -public: - bool hasNoConfigContext() const { return mHasNoConfigContext; } - bool hasNativeFenceSync() const { return mHasNativeFenceSync; } - bool hasFenceSync() const { return mHasFenceSync; } - bool hasWaitSync() const { return mHasWaitSync; } - bool hasProtectedContent() const { return mHasProtectedContent; } - bool hasContextPriority() const { return mHasContextPriority; } - - void initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version, - GLubyte const* extensions); - char const* getVendor() const; - char const* getRenderer() const; - char const* getVersion() const; - char const* getExtensions() const; - - void initWithEGLStrings(char const* eglVersion, char const* eglExtensions); - char const* getEGLVersion() const; - char const* getEGLExtensions() const; }; } // namespace gl |