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

Commit 4cabdd0d authored by Sally Qi's avatar Sally Qi
Browse files

First patch for async renderengine.

1. return a std::future object from DrawLayers() instead to make it
asynchronously
2. retire drawFence value from drawLayers() parameter list.

Bug: 180657548
Test: android.hardware.graphics.composer@2.2-vts, libcompositionengine_test, libsurfaceflinger_unittest and
librenderengine_test pass

Change-Id: If63c11762d1cce7b053cc72aaeaed6dd7904877f
parent 8d795707
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -95,5 +95,16 @@ void RenderEngine::validateOutputBufferUsage(const sp<GraphicBuffer>& buffer) {
                        "output buffer not gpu writeable");
}

std::future<RenderEngineResult> RenderEngine::drawLayers(
        const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
        const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
        base::unique_fd&& bufferFence) {
    const auto resultPromise = std::make_shared<std::promise<RenderEngineResult>>();
    std::future<RenderEngineResult> resultFuture = resultPromise->get_future();
    drawLayersInternal(std::move(resultPromise), display, layers, buffer, useFramebufferCache,
                       std::move(bufferFence));
    return resultFuture;
}

} // namespace renderengine
} // namespace android
+27 −19
Original line number Diff line number Diff line
@@ -1078,15 +1078,16 @@ EGLImageKHR GLESRenderEngine::createFramebufferImageIfNeeded(ANativeWindowBuffer
    return image;
}

status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
                                      const std::vector<const LayerSettings*>& layers,
                                      const std::shared_ptr<ExternalTexture>& buffer,
                                      const bool useFramebufferCache, base::unique_fd&& bufferFence,
                                      base::unique_fd* drawFence) {
void GLESRenderEngine::drawLayersInternal(
        const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
        const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
        const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
        base::unique_fd&& bufferFence) {
    ATRACE_CALL();
    if (layers.empty()) {
        ALOGV("Drawing empty layer stack");
        return NO_ERROR;
        resultPromise->set_value({NO_ERROR, base::unique_fd()});
        return;
    }

    if (bufferFence.get() >= 0) {
@@ -1100,7 +1101,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,

    if (buffer == nullptr) {
        ALOGE("No output buffer provided. Aborting GPU composition.");
        return BAD_VALUE;
        resultPromise->set_value({BAD_VALUE, base::unique_fd()});
        return;
    }

    validateOutputBufferUsage(buffer->getBuffer());
@@ -1128,7 +1130,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
            ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
                  buffer->getBuffer()->handle);
            checkErrors();
            return fbo->getStatus();
            resultPromise->set_value({fbo->getStatus(), base::unique_fd()});
            return;
        }
        setViewportAndProjection(display.physicalDisplay, display.clip);
    } else {
@@ -1139,7 +1142,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
            ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).",
                  buffer->getBuffer()->handle);
            checkErrors();
            return status;
            resultPromise->set_value({status, base::unique_fd()});
            return;
        }
    }

@@ -1172,7 +1176,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
                ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
                      buffer->getBuffer()->handle);
                checkErrors("Can't render first blur pass");
                return status;
                resultPromise->set_value({status, base::unique_fd()});
                return;
            }

            if (blurLayers.size() == 0) {
@@ -1194,7 +1199,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
                ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
                      buffer->getBuffer()->handle);
                checkErrors("Can't bind native framebuffer");
                return status;
                resultPromise->set_value({status, base::unique_fd()});
                return;
            }

            status = mBlurFilter->render(blurLayersSize > 1);
@@ -1202,7 +1208,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
                ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
                      buffer->getBuffer()->handle);
                checkErrors("Can't render blur filter");
                return status;
                resultPromise->set_value({status, base::unique_fd()});
                return;
            }
        }

@@ -1289,30 +1296,31 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
        }
    }

    if (drawFence != nullptr) {
        *drawFence = flush();
    }
    base::unique_fd drawFence = flush();

    // If flush failed or we don't support native fences, we need to force the
    // gl command stream to be executed.
    if (drawFence == nullptr || drawFence->get() < 0) {
    if (drawFence.get() < 0) {
        bool success = finish();
        if (!success) {
            ALOGE("Failed to flush RenderEngine commands");
            checkErrors();
            // Chances are, something illegal happened (either the caller passed
            // us bad parameters, or we messed up our shader generation).
            return INVALID_OPERATION;
            resultPromise->set_value({INVALID_OPERATION, std::move(drawFence)});
            return;
        }
        mLastDrawFence = nullptr;
    } else {
        // The caller takes ownership of drawFence, so we need to duplicate the
        // fd here.
        mLastDrawFence = new Fence(dup(drawFence->get()));
        mLastDrawFence = new Fence(dup(drawFence.get()));
    }
    mPriorResourcesCleaned = false;

    checkErrors();
    return NO_ERROR;
    resultPromise->set_value({NO_ERROR, std::move(drawFence)});
    return;
}

void GLESRenderEngine::setViewportAndProjection(Rect viewport, Rect clip) {
+5 −5
Original line number Diff line number Diff line
@@ -63,11 +63,6 @@ public:
    bool isProtected() const override { return mInProtectedContext; }
    bool supportsProtectedContent() const override;
    void useProtectedContext(bool useProtectedContext) override;
    status_t drawLayers(const DisplaySettings& display,
                        const std::vector<const LayerSettings*>& layers,
                        const std::shared_ptr<ExternalTexture>& buffer,
                        const bool useFramebufferCache, base::unique_fd&& bufferFence,
                        base::unique_fd* drawFence) override;
    void cleanupPostRender() override;
    int getContextPriority() override;
    bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
@@ -107,6 +102,11 @@ protected:
            EXCLUDES(mRenderingMutex);
    void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
    bool canSkipPostRenderCleanup() const override;
    void drawLayersInternal(const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
                            const DisplaySettings& display,
                            const std::vector<const LayerSettings*>& layers,
                            const std::shared_ptr<ExternalTexture>& buffer,
                            const bool useFramebufferCache, base::unique_fd&& bufferFence) override;

private:
    friend class BindNativeBufferAsFramebuffer;
+20 −11
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ class Image;
class Mesh;
class Texture;
struct RenderEngineCreationArgs;
struct RenderEngineResult;

namespace threaded {
class RenderEngineThreaded;
@@ -156,17 +157,12 @@ public:
    // parameter does nothing.
    // @param bufferFence Fence signalling that the buffer is ready to be drawn
    // to.
    // @param drawFence A pointer to a fence, which will fire when the buffer
    // has been drawn to and is ready to be examined. The fence will be
    // initialized by this method. The caller will be responsible for owning the
    // fence.
    // @return An error code indicating whether drawing was successful. For
    // now, this always returns NO_ERROR.
    virtual status_t drawLayers(const DisplaySettings& display,
                                const std::vector<const LayerSettings*>& layers,
                                const std::shared_ptr<ExternalTexture>& buffer,
                                const bool useFramebufferCache, base::unique_fd&& bufferFence,
                                base::unique_fd* drawFence) = 0;
    // @return A future object of RenderEngineResult struct indicating whether
    // drawing was successful in async mode.
    virtual std::future<RenderEngineResult> drawLayers(
            const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
            const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
            base::unique_fd&& bufferFence);

    // Clean-up method that should be called on the main thread after the
    // drawFence returned by drawLayers fires. This method will free up
@@ -232,6 +228,12 @@ protected:
    friend class threaded::RenderEngineThreaded;
    friend class RenderEngineTest_cleanupPostRender_cleansUpOnce_Test;
    const RenderEngineType mRenderEngineType;

    virtual void drawLayersInternal(
            const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
            const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
            const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
            base::unique_fd&& bufferFence) = 0;
};

struct RenderEngineCreationArgs {
@@ -318,6 +320,13 @@ private:
            RenderEngine::RenderEngineType::SKIA_GL_THREADED;
};

struct RenderEngineResult {
    // status indicates if drawing is successful
    status_t status;
    // drawFence will fire when the buffer has been drawn to and is ready to be examined.
    base::unique_fd drawFence;
};

} // namespace renderengine
} // namespace android

+9 −4
Original line number Diff line number Diff line
@@ -47,10 +47,15 @@ public:
    MOCK_METHOD1(useProtectedContext, void(bool));
    MOCK_METHOD0(cleanupPostRender, void());
    MOCK_CONST_METHOD0(canSkipPostRenderCleanup, bool());
    MOCK_METHOD6(drawLayers,
                 status_t(const DisplaySettings&, const std::vector<const LayerSettings*>&,
                          const std::shared_ptr<ExternalTexture>&, const bool, base::unique_fd&&,
                          base::unique_fd*));
    MOCK_METHOD5(drawLayers,
                 std::future<RenderEngineResult>(const DisplaySettings&,
                                                 const std::vector<const LayerSettings*>&,
                                                 const std::shared_ptr<ExternalTexture>&,
                                                 const bool, base::unique_fd&&));
    MOCK_METHOD6(drawLayersInternal,
                 void(const std::shared_ptr<std::promise<RenderEngineResult>>&&,
                      const DisplaySettings&, const std::vector<const LayerSettings*>&,
                      const std::shared_ptr<ExternalTexture>&, const bool, base::unique_fd&&));
    MOCK_METHOD0(cleanFramebufferCache, void());
    MOCK_METHOD0(getContextPriority, int());
    MOCK_METHOD0(supportsBackgroundBlur, bool());
Loading