Loading libs/renderengine/gl/GLESRenderEngine.cpp +53 −10 Original line number Diff line number Diff line Loading @@ -222,6 +222,29 @@ static status_t selectEGLConfig(EGLDisplay display, EGLint format, EGLint render return err; } std::optional<RenderEngine::ContextPriority> GLESRenderEngine::createContextPriority( const RenderEngineCreationArgs& args) { if (!GLExtensions::getInstance().hasContextPriority()) { return std::nullopt; } switch (args.contextPriority) { case RenderEngine::ContextPriority::REALTIME: if (gl::GLExtensions::getInstance().hasRealtimePriority()) { return RenderEngine::ContextPriority::REALTIME; } else { ALOGI("Realtime priority unsupported, degrading gracefully to high priority"); return RenderEngine::ContextPriority::HIGH; } case RenderEngine::ContextPriority::HIGH: case RenderEngine::ContextPriority::MEDIUM: case RenderEngine::ContextPriority::LOW: return args.contextPriority; default: return std::nullopt; } } std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCreationArgs& args) { // initialize EGL for the default display EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); Loading @@ -235,6 +258,7 @@ std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCre LOG_ALWAYS_FATAL("eglQueryString(EGL_VERSION) failed"); } // Use the Android impl to grab EGL_NV_context_priority_realtime const auto eglExtensions = eglQueryString(display, EGL_EXTENSIONS); if (!eglExtensions) { checkGlError(__FUNCTION__, __LINE__); Loading @@ -251,17 +275,16 @@ std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCre config = chooseEglConfig(display, args.pixelFormat, /*logConfig*/ true); } bool useContextPriority = extensions.hasContextPriority() && args.contextPriority == ContextPriority::HIGH; const std::optional<RenderEngine::ContextPriority> priority = createContextPriority(args); EGLContext protectedContext = EGL_NO_CONTEXT; if (args.enableProtectedContext && extensions.hasProtectedContent()) { protectedContext = createEglContext(display, config, nullptr, useContextPriority, Protection::PROTECTED); protectedContext = createEglContext(display, config, nullptr, priority, Protection::PROTECTED); ALOGE_IF(protectedContext == EGL_NO_CONTEXT, "Can't create protected context"); } EGLContext ctxt = createEglContext(display, config, protectedContext, useContextPriority, Protection::UNPROTECTED); EGLContext ctxt = createEglContext(display, config, protectedContext, priority, Protection::UNPROTECTED); // if can't create a GL context, we can only abort. LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed"); Loading Loading @@ -311,7 +334,6 @@ std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCre ALOGI("extensions: %s", extensions.getExtensions()); ALOGI("GL_MAX_TEXTURE_SIZE = %zu", engine->getMaxTextureSize()); ALOGI("GL_MAX_VIEWPORT_DIMS = %zu", engine->getMaxViewportDims()); return engine; } Loading Loading @@ -802,6 +824,12 @@ void GLESRenderEngine::unbindExternalTextureBufferInternal(uint64_t bufferId) { ALOGV("Failed to find image for buffer: %" PRIu64, bufferId); } int GLESRenderEngine::getContextPriority() { int value; eglQueryContext(mEGLDisplay, mEGLContext, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &value); return value; } FloatRect GLESRenderEngine::setupLayerCropping(const LayerSettings& layer, Mesh& mesh) { // Translate win by the rounded corners rect coordinates, to have all values in // layer coordinate space. Loading Loading @@ -1617,7 +1645,8 @@ GLESRenderEngine::GlesVersion GLESRenderEngine::parseGlesVersion(const char* str } EGLContext GLESRenderEngine::createEglContext(EGLDisplay display, EGLConfig config, EGLContext shareContext, bool useContextPriority, EGLContext shareContext, std::optional<ContextPriority> contextPriority, Protection protection) { EGLint renderableType = 0; if (config == EGL_NO_CONFIG) { Loading @@ -1640,9 +1669,23 @@ EGLContext GLESRenderEngine::createEglContext(EGLDisplay display, EGLConfig conf contextAttributes.reserve(7); contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION); contextAttributes.push_back(contextClientVersion); if (useContextPriority) { if (contextPriority) { contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); switch (*contextPriority) { case ContextPriority::REALTIME: contextAttributes.push_back(EGL_CONTEXT_PRIORITY_REALTIME_NV); break; case ContextPriority::MEDIUM: contextAttributes.push_back(EGL_CONTEXT_PRIORITY_MEDIUM_IMG); break; case ContextPriority::LOW: contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LOW_IMG); break; case ContextPriority::HIGH: default: contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); break; } } if (protection == Protection::PROTECTED) { contextAttributes.push_back(EGL_PROTECTED_CONTENT_EXT); Loading libs/renderengine/gl/GLESRenderEngine.h +5 −1 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ public: const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence, base::unique_fd* drawFence) override; bool cleanupPostRender(CleanupMode mode) override; int getContextPriority() override; EGLDisplay getEGLDisplay() const { return mEGLDisplay; } // Creates an output image for rendering to Loading Loading @@ -116,8 +117,11 @@ private: static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig); static GlesVersion parseGlesVersion(const char* str); static EGLContext createEglContext(EGLDisplay display, EGLConfig config, EGLContext shareContext, bool useContextPriority, EGLContext shareContext, std::optional<ContextPriority> contextPriority, Protection protection); static std::optional<RenderEngine::ContextPriority> createContextPriority( const RenderEngineCreationArgs& args); static EGLSurface createStubEglPbufferSurface(EGLDisplay display, EGLConfig config, int hwcFormat, Protection protection); std::unique_ptr<Framebuffer> createFramebuffer(); Loading libs/renderengine/gl/GLExtensions.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,10 @@ void GLExtensions::initWithEGLStrings(char const* eglVersion, char const* eglExt if (extensionSet.hasExtension("EGL_KHR_surfaceless_context")) { mHasSurfacelessContext = true; } if (extensionSet.hasExtension("EGL_NV_context_priority_realtime")) { mHasRealtimePriority = true; } } char const* GLExtensions::getEGLVersion() const { Loading libs/renderengine/gl/GLExtensions.h +2 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ public: bool hasContextPriority() const { return mHasContextPriority; } bool hasSurfacelessContext() const { return mHasSurfacelessContext; } bool hasProtectedTexture() const { return mHasProtectedTexture; } bool hasRealtimePriority() const { return mHasRealtimePriority; } void initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version, GLubyte const* extensions); Loading @@ -67,6 +68,7 @@ private: bool mHasContextPriority = false; bool mHasSurfacelessContext = false; bool mHasProtectedTexture = false; bool mHasRealtimePriority = false; String8 mVendor; String8 mRenderer; Loading libs/renderengine/include/renderengine/RenderEngine.h +5 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ public: LOW = 1, MEDIUM = 2, HIGH = 3, REALTIME = 4, }; enum class RenderEngineType { Loading Loading @@ -181,6 +182,10 @@ public: const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0; virtual void cleanFramebufferCache() = 0; // Returns the priority this context was actually created with. Note: this may not be // the same as specified at context creation time, due to implementation limits on the // number of contexts that can be created at a specific priority level in the system. virtual int getContextPriority() = 0; protected: friend class threaded::RenderEngineThreaded; Loading Loading
libs/renderengine/gl/GLESRenderEngine.cpp +53 −10 Original line number Diff line number Diff line Loading @@ -222,6 +222,29 @@ static status_t selectEGLConfig(EGLDisplay display, EGLint format, EGLint render return err; } std::optional<RenderEngine::ContextPriority> GLESRenderEngine::createContextPriority( const RenderEngineCreationArgs& args) { if (!GLExtensions::getInstance().hasContextPriority()) { return std::nullopt; } switch (args.contextPriority) { case RenderEngine::ContextPriority::REALTIME: if (gl::GLExtensions::getInstance().hasRealtimePriority()) { return RenderEngine::ContextPriority::REALTIME; } else { ALOGI("Realtime priority unsupported, degrading gracefully to high priority"); return RenderEngine::ContextPriority::HIGH; } case RenderEngine::ContextPriority::HIGH: case RenderEngine::ContextPriority::MEDIUM: case RenderEngine::ContextPriority::LOW: return args.contextPriority; default: return std::nullopt; } } std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCreationArgs& args) { // initialize EGL for the default display EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); Loading @@ -235,6 +258,7 @@ std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCre LOG_ALWAYS_FATAL("eglQueryString(EGL_VERSION) failed"); } // Use the Android impl to grab EGL_NV_context_priority_realtime const auto eglExtensions = eglQueryString(display, EGL_EXTENSIONS); if (!eglExtensions) { checkGlError(__FUNCTION__, __LINE__); Loading @@ -251,17 +275,16 @@ std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCre config = chooseEglConfig(display, args.pixelFormat, /*logConfig*/ true); } bool useContextPriority = extensions.hasContextPriority() && args.contextPriority == ContextPriority::HIGH; const std::optional<RenderEngine::ContextPriority> priority = createContextPriority(args); EGLContext protectedContext = EGL_NO_CONTEXT; if (args.enableProtectedContext && extensions.hasProtectedContent()) { protectedContext = createEglContext(display, config, nullptr, useContextPriority, Protection::PROTECTED); protectedContext = createEglContext(display, config, nullptr, priority, Protection::PROTECTED); ALOGE_IF(protectedContext == EGL_NO_CONTEXT, "Can't create protected context"); } EGLContext ctxt = createEglContext(display, config, protectedContext, useContextPriority, Protection::UNPROTECTED); EGLContext ctxt = createEglContext(display, config, protectedContext, priority, Protection::UNPROTECTED); // if can't create a GL context, we can only abort. LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed"); Loading Loading @@ -311,7 +334,6 @@ std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCre ALOGI("extensions: %s", extensions.getExtensions()); ALOGI("GL_MAX_TEXTURE_SIZE = %zu", engine->getMaxTextureSize()); ALOGI("GL_MAX_VIEWPORT_DIMS = %zu", engine->getMaxViewportDims()); return engine; } Loading Loading @@ -802,6 +824,12 @@ void GLESRenderEngine::unbindExternalTextureBufferInternal(uint64_t bufferId) { ALOGV("Failed to find image for buffer: %" PRIu64, bufferId); } int GLESRenderEngine::getContextPriority() { int value; eglQueryContext(mEGLDisplay, mEGLContext, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &value); return value; } FloatRect GLESRenderEngine::setupLayerCropping(const LayerSettings& layer, Mesh& mesh) { // Translate win by the rounded corners rect coordinates, to have all values in // layer coordinate space. Loading Loading @@ -1617,7 +1645,8 @@ GLESRenderEngine::GlesVersion GLESRenderEngine::parseGlesVersion(const char* str } EGLContext GLESRenderEngine::createEglContext(EGLDisplay display, EGLConfig config, EGLContext shareContext, bool useContextPriority, EGLContext shareContext, std::optional<ContextPriority> contextPriority, Protection protection) { EGLint renderableType = 0; if (config == EGL_NO_CONFIG) { Loading @@ -1640,9 +1669,23 @@ EGLContext GLESRenderEngine::createEglContext(EGLDisplay display, EGLConfig conf contextAttributes.reserve(7); contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION); contextAttributes.push_back(contextClientVersion); if (useContextPriority) { if (contextPriority) { contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG); switch (*contextPriority) { case ContextPriority::REALTIME: contextAttributes.push_back(EGL_CONTEXT_PRIORITY_REALTIME_NV); break; case ContextPriority::MEDIUM: contextAttributes.push_back(EGL_CONTEXT_PRIORITY_MEDIUM_IMG); break; case ContextPriority::LOW: contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LOW_IMG); break; case ContextPriority::HIGH: default: contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG); break; } } if (protection == Protection::PROTECTED) { contextAttributes.push_back(EGL_PROTECTED_CONTENT_EXT); Loading
libs/renderengine/gl/GLESRenderEngine.h +5 −1 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ public: const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence, base::unique_fd* drawFence) override; bool cleanupPostRender(CleanupMode mode) override; int getContextPriority() override; EGLDisplay getEGLDisplay() const { return mEGLDisplay; } // Creates an output image for rendering to Loading Loading @@ -116,8 +117,11 @@ private: static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig); static GlesVersion parseGlesVersion(const char* str); static EGLContext createEglContext(EGLDisplay display, EGLConfig config, EGLContext shareContext, bool useContextPriority, EGLContext shareContext, std::optional<ContextPriority> contextPriority, Protection protection); static std::optional<RenderEngine::ContextPriority> createContextPriority( const RenderEngineCreationArgs& args); static EGLSurface createStubEglPbufferSurface(EGLDisplay display, EGLConfig config, int hwcFormat, Protection protection); std::unique_ptr<Framebuffer> createFramebuffer(); Loading
libs/renderengine/gl/GLExtensions.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,10 @@ void GLExtensions::initWithEGLStrings(char const* eglVersion, char const* eglExt if (extensionSet.hasExtension("EGL_KHR_surfaceless_context")) { mHasSurfacelessContext = true; } if (extensionSet.hasExtension("EGL_NV_context_priority_realtime")) { mHasRealtimePriority = true; } } char const* GLExtensions::getEGLVersion() const { Loading
libs/renderengine/gl/GLExtensions.h +2 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ public: bool hasContextPriority() const { return mHasContextPriority; } bool hasSurfacelessContext() const { return mHasSurfacelessContext; } bool hasProtectedTexture() const { return mHasProtectedTexture; } bool hasRealtimePriority() const { return mHasRealtimePriority; } void initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version, GLubyte const* extensions); Loading @@ -67,6 +68,7 @@ private: bool mHasContextPriority = false; bool mHasSurfacelessContext = false; bool mHasProtectedTexture = false; bool mHasRealtimePriority = false; String8 mVendor; String8 mRenderer; Loading
libs/renderengine/include/renderengine/RenderEngine.h +5 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ public: LOW = 1, MEDIUM = 2, HIGH = 3, REALTIME = 4, }; enum class RenderEngineType { Loading Loading @@ -181,6 +182,10 @@ public: const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0; virtual void cleanFramebufferCache() = 0; // Returns the priority this context was actually created with. Note: this may not be // the same as specified at context creation time, due to implementation limits on the // number of contexts that can be created at a specific priority level in the system. virtual int getContextPriority() = 0; protected: friend class threaded::RenderEngineThreaded; Loading