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

Commit 23c31af2 authored by Marin Shalamanov's avatar Marin Shalamanov
Browse files

SF: Clean framebuffer cache on hotplug

This CL cleans the framebuffer cache when a hotplug event
for already connected display is processed. This way when we
destruct the DisplayDevice the framebuffers will be completely
deallocated, so they can later be reallocated.

Test: 1. unplug HDMI
      2. adb shell dumpsys SurfaceFlinger | grep FramebufferSurface
         verify only 3 framebuffers are allocated
      3. plug HDMI
      5. adb shell dumpsys SurfaceFlinger | grep FramebufferSurface
         verify only 3 framebuffers are allocated
Test: Using dev SurfaceFlinger backdoor (1036) which injects hotplug:
      adb shell service call SurfaceFlinger 1036 && \
        adb shell dumpsys SurfaceFlinger | grep FramebufferSurface
Bug: 160112047
Bug: 167670568
Change-Id: I96282bec439ebf413dcd5d57f6b884eccef19c5f
parent 8436cbdf
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -451,15 +451,10 @@ GLESRenderEngine::GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisp
GLESRenderEngine::~GLESRenderEngine() {
    // Destroy the image manager first.
    mImageManager = nullptr;
    cleanFramebufferCache();
    std::lock_guard<std::mutex> lock(mRenderingMutex);
    unbindFrameBuffer(mDrawingBuffer.get());
    mDrawingBuffer = nullptr;
    while (!mFramebufferImageCache.empty()) {
        EGLImageKHR expired = mFramebufferImageCache.front().second;
        mFramebufferImageCache.pop_front();
        eglDestroyImageKHR(mEGLDisplay, expired);
        DEBUG_EGL_IMAGE_TRACKER_DESTROY();
    }
    eglDestroyImageKHR(mEGLDisplay, mPlaceholderImage);
    mImageCache.clear();
    eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
@@ -965,6 +960,7 @@ bool GLESRenderEngine::cleanupPostRender(CleanupMode mode) {
    // Bind the texture to placeholder so that backing image data can be freed.
    GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(getFramebufferForDrawing());
    glFramebuffer->allocateBuffers(1, 1, mPlaceholderDrawBuffer);

    // Release the cached fence here, so that we don't churn reallocations when
    // we could no-op repeated calls of this method instead.
    mLastDrawFence = nullptr;
@@ -972,6 +968,20 @@ bool GLESRenderEngine::cleanupPostRender(CleanupMode mode) {
    return true;
}

void GLESRenderEngine::cleanFramebufferCache() {
    std::lock_guard<std::mutex> lock(mFramebufferImageCacheMutex);
    // Bind the texture to placeholder so that backing image data can be freed.
    GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(getFramebufferForDrawing());
    glFramebuffer->allocateBuffers(1, 1, mPlaceholderDrawBuffer);

    while (!mFramebufferImageCache.empty()) {
        EGLImageKHR expired = mFramebufferImageCache.front().second;
        mFramebufferImageCache.pop_front();
        eglDestroyImageKHR(mEGLDisplay, expired);
        DEBUG_EGL_IMAGE_TRACKER_DESTROY();
    }
}

void GLESRenderEngine::checkErrors() const {
    checkErrors(nullptr);
}
+1 −0
Original line number Diff line number Diff line
@@ -135,6 +135,7 @@ private:
    status_t bindFrameBuffer(Framebuffer* framebuffer);
    void unbindFrameBuffer(Framebuffer* framebuffer);
    void bindExternalTextureImage(uint32_t texName, const Image& image);
    void cleanFramebufferCache() EXCLUDES(mFramebufferImageCacheMutex) override;

    // A data space is considered HDR data space if it has BT2020 color space
    // with PQ or HLG transfer function.
+1 −0
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ public:
                                const std::vector<const LayerSettings*>& layers,
                                const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
                                base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0;
    virtual void cleanFramebufferCache() = 0;

protected:
    friend class threaded::RenderEngineThreaded;
+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ public:
                 status_t(const DisplaySettings&, const std::vector<const LayerSettings*>&,
                          const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
                          base::unique_fd*));
    MOCK_METHOD0(cleanFramebufferCache, void());
};

} // namespace mock
+15 −0
Original line number Diff line number Diff line
@@ -322,6 +322,21 @@ status_t RenderEngineThreaded::drawLayers(const DisplaySettings& display,
    return resultFuture.get();
}

void RenderEngineThreaded::cleanFramebufferCache() {
    std::promise<void> resultPromise;
    std::future<void> resultFuture = resultPromise.get_future();
    {
        std::lock_guard lock(mThreadMutex);
        mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
            ATRACE_NAME("REThreaded::cleanFramebufferCache");
            instance.cleanFramebufferCache();
            resultPromise.set_value();
        });
    }
    mCondition.notify_one();
    resultFuture.wait();
}

} // namespace threaded
} // namespace renderengine
} // namespace android
Loading