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

Commit c3da3fa8 authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Automerger Merge Worker
Browse files

Merge "Defer deleting ExternalTextures that go out of scope during DrawLayers"...

Merge "Defer deleting ExternalTextures that go out of scope during DrawLayers" into sc-dev am: d966a695

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/14948686

Change-Id: I5e717ab005238051cf0da0249f2d023f45582855
parents 5210e8e5 d966a695
Loading
Loading
Loading
Loading
+8 −29
Original line number Diff line number Diff line
@@ -970,37 +970,17 @@ void GLESRenderEngine::unbindFrameBuffer(Framebuffer* /*framebuffer*/) {
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

bool GLESRenderEngine::cleanupPostRender(CleanupMode mode) {
bool GLESRenderEngine::canSkipPostRenderCleanup() const {
    return mPriorResourcesCleaned ||
            (mLastDrawFence != nullptr && mLastDrawFence->getStatus() != Fence::Status::Signaled);
}

void GLESRenderEngine::cleanupPostRender() {
    ATRACE_CALL();

    if (mPriorResourcesCleaned ||
        (mLastDrawFence != nullptr && mLastDrawFence->getStatus() != Fence::Status::Signaled)) {
    if (canSkipPostRenderCleanup()) {
        // If we don't have a prior frame needing cleanup, then don't do anything.
        return false;
    }

    // This is a bit of a band-aid fix for FrameCaptureProcessor, as we should
    // not need to keep memory around if we don't need to do so.
    if (mode == CleanupMode::CLEAN_ALL) {
        // TODO: SurfaceFlinger memory utilization may benefit from resetting
        // texture bindings as well. Assess if it does and there's no performance regression
        // when rebinding the same image data to the same texture, and if so then its mode
        // behavior can be tweaked.
        if (mPlaceholderImage != EGL_NO_IMAGE_KHR) {
            for (auto [textureName, bufferId] : mTextureView) {
                if (bufferId && mPlaceholderImage != EGL_NO_IMAGE_KHR) {
                    glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureName);
                    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
                                                 static_cast<GLeglImageOES>(mPlaceholderImage));
                    mTextureView[textureName] = std::nullopt;
                    checkErrors();
                }
            }
        }
        {
            std::lock_guard<std::mutex> lock(mRenderingMutex);
            mImageCache.clear();
        }
        return;
    }

    // Bind the texture to placeholder so that backing image data can be freed.
@@ -1011,7 +991,6 @@ bool GLESRenderEngine::cleanupPostRender(CleanupMode mode) {
    // we could no-op repeated calls of this method instead.
    mLastDrawFence = nullptr;
    mPriorResourcesCleaned = true;
    return true;
}

void GLESRenderEngine::cleanFramebufferCache() {
+2 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ public:
                        const std::shared_ptr<ExternalTexture>& buffer,
                        const bool useFramebufferCache, base::unique_fd&& bufferFence,
                        base::unique_fd* drawFence) override;
    bool cleanupPostRender(CleanupMode mode) override;
    void cleanupPostRender() override;
    int getContextPriority() override;
    bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
    void onPrimaryDisplaySizeChanged(ui::Size size) override {}
@@ -106,6 +106,7 @@ protected:
    void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable)
            EXCLUDES(mRenderingMutex);
    void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
    bool canSkipPostRenderCleanup() const override;

private:
    friend class BindNativeBufferAsFramebuffer;
+14 −19
Original line number Diff line number Diff line
@@ -114,25 +114,6 @@ public:
    virtual void genTextures(size_t count, uint32_t* names) = 0;
    virtual void deleteTextures(size_t count, uint32_t const* names) = 0;

    enum class CleanupMode {
        CLEAN_OUTPUT_RESOURCES,
        CLEAN_ALL,
    };
    // Clean-up method that should be called on the main thread after the
    // drawFence returned by drawLayers fires. This method will free up
    // resources used by the most recently drawn frame. If the frame is still
    // being drawn, then this call is silently ignored.
    //
    // If mode is CLEAN_OUTPUT_RESOURCES, then only resources related to the
    // output framebuffer are cleaned up, including the sibling texture.
    //
    // If mode is CLEAN_ALL, then we also cleanup resources related to any input
    // buffers.
    //
    // Returns true if resources were cleaned up, and false if we didn't need to
    // do any work.
    virtual bool cleanupPostRender(CleanupMode mode = CleanupMode::CLEAN_OUTPUT_RESOURCES) = 0;

    // queries that are required to be thread safe
    virtual size_t getMaxTextureSize() const = 0;
    virtual size_t getMaxViewportDims() const = 0;
@@ -186,6 +167,13 @@ public:
                                const std::shared_ptr<ExternalTexture>& buffer,
                                const bool useFramebufferCache, base::unique_fd&& bufferFence,
                                base::unique_fd* drawFence) = 0;

    // Clean-up method that should be called on the main thread after the
    // drawFence returned by drawLayers fires. This method will free up
    // resources used by the most recently drawn frame. If the frame is still
    // being drawn, then the implementation is free to silently ignore this call.
    virtual void cleanupPostRender() = 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
@@ -234,8 +222,15 @@ protected:
    // that's conflict serializable, i.e. unmap a buffer should never occur before binding the
    // buffer if the caller called mapExternalTextureBuffer before calling unmap.
    virtual void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) = 0;

    // A thread safe query to determine if any post rendering cleanup is necessary.  Returning true
    // is a signal that calling the postRenderCleanup method would be a no-op and that callers can
    // avoid any thread synchronization that may be required by directly calling postRenderCleanup.
    virtual bool canSkipPostRenderCleanup() const = 0;

    friend class ExternalTexture;
    friend class threaded::RenderEngineThreaded;
    friend class RenderEngineTest_cleanupPostRender_cleansUpOnce_Test;
    const RenderEngineType mRenderEngineType;
};

+2 −1
Original line number Diff line number Diff line
@@ -45,7 +45,8 @@ public:
    MOCK_CONST_METHOD0(isProtected, bool());
    MOCK_CONST_METHOD0(supportsProtectedContent, bool());
    MOCK_METHOD1(useProtectedContext, bool(bool));
    MOCK_METHOD1(cleanupPostRender, bool(CleanupMode mode));
    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&&,
+10 −7
Original line number Diff line number Diff line
@@ -29,8 +29,8 @@ namespace renderengine {
namespace skia {

AutoBackendTexture::AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer,
                                       bool isOutputBuffer)
      : mIsOutputBuffer(isOutputBuffer) {
                                       bool isOutputBuffer, CleanupManager& cleanupMgr)
      : mCleanupMgr(cleanupMgr), mIsOutputBuffer(isOutputBuffer) {
    ATRACE_CALL();
    AHardwareBuffer_Desc desc;
    AHardwareBuffer_describe(buffer, &desc);
@@ -49,6 +49,13 @@ AutoBackendTexture::AutoBackendTexture(GrDirectContext* context, AHardwareBuffer
             this, desc.width, desc.height, createProtectedImage, isOutputBuffer, desc.format);
}

AutoBackendTexture::~AutoBackendTexture() {
    if (mBackendTexture.isValid()) {
        mDeleteProc(mImageCtx);
        mBackendTexture = {};
    }
}

void AutoBackendTexture::unref(bool releaseLocalResources) {
    if (releaseLocalResources) {
        mSurface = nullptr;
@@ -57,11 +64,7 @@ void AutoBackendTexture::unref(bool releaseLocalResources) {

    mUsageCount--;
    if (mUsageCount <= 0) {
        if (mBackendTexture.isValid()) {
            mDeleteProc(mImageCtx);
            mBackendTexture = {};
        }
        delete this;
        mCleanupMgr.add(this);
    }
}

Loading