Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6f09469 authored by Alec Mouri's avatar Alec Mouri Committed by Ana Krulec
Browse files

Plumbing through GPU context priority from SF to RE

Test: Run the code. Check logcat.
      atest librenderengine_test
Bug: 168740533
Change-Id: I6e34c4064dfd75ac96b86e0af587a208fc93d975
parent c7cb19c5
Loading
Loading
Loading
Loading
+53 −10
Original line number Diff line number Diff line
@@ -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);
@@ -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__);
@@ -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");
@@ -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;
}

@@ -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.
@@ -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) {
@@ -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);
+5 −1
Original line number Diff line number Diff line
@@ -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
@@ -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();
+4 −0
Original line number Diff line number Diff line
@@ -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 {
+2 −0
Original line number Diff line number Diff line
@@ -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);
@@ -67,6 +68,7 @@ private:
    bool mHasContextPriority = false;
    bool mHasSurfacelessContext = false;
    bool mHasProtectedTexture = false;
    bool mHasRealtimePriority = false;

    String8 mVendor;
    String8 mRenderer;
+5 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ public:
        LOW = 1,
        MEDIUM = 2,
        HIGH = 3,
        REALTIME = 4,
    };

    enum class RenderEngineType {
@@ -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