diff options
| -rw-r--r-- | libs/renderengine/gl/GLESRenderEngine.cpp | 31 | ||||
| -rw-r--r-- | libs/renderengine/gl/GLESRenderEngine.h | 8 | ||||
| -rw-r--r-- | libs/renderengine/gl/GLFramebuffer.cpp | 10 | ||||
| -rw-r--r-- | libs/renderengine/gl/GLFramebuffer.h | 4 | ||||
| -rw-r--r-- | libs/renderengine/include/renderengine/Framebuffer.h | 3 | ||||
| -rw-r--r-- | libs/renderengine/include/renderengine/RenderEngine.h | 15 | ||||
| -rw-r--r-- | libs/renderengine/include/renderengine/mock/Framebuffer.h | 2 | ||||
| -rw-r--r-- | libs/renderengine/include/renderengine/mock/RenderEngine.h | 4 | ||||
| -rw-r--r-- | libs/renderengine/tests/RenderEngineTest.cpp | 26 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/CompositionTest.cpp | 15 |
11 files changed, 82 insertions, 41 deletions
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp index 1980f50bac..5847402a23 100644 --- a/libs/renderengine/gl/GLESRenderEngine.cpp +++ b/libs/renderengine/gl/GLESRenderEngine.cpp @@ -808,12 +808,14 @@ bool GLESRenderEngine::useProtectedContext(bool useProtectedContext) { return success; } EGLImageKHR GLESRenderEngine::createFramebufferImageIfNeeded(ANativeWindowBuffer* nativeBuffer, - bool isProtected) { + bool isProtected, + bool useFramebufferCache) { sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(nativeBuffer); - uint64_t bufferId = graphicBuffer->getId(); - for (const auto& image : mFramebufferImageCache) { - if (image.first == bufferId) { - return image.second; + if (useFramebufferCache) { + for (const auto& image : mFramebufferImageCache) { + if (image.first == graphicBuffer->getId()) { + return image.second; + } } } EGLint attributes[] = { @@ -823,13 +825,15 @@ EGLImageKHR GLESRenderEngine::createFramebufferImageIfNeeded(ANativeWindowBuffer }; EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, nativeBuffer, attributes); - if (image != EGL_NO_IMAGE_KHR) { - if (mFramebufferImageCache.size() >= mFramebufferImageCacheSize) { - EGLImageKHR expired = mFramebufferImageCache.front().second; - mFramebufferImageCache.pop_front(); - eglDestroyImageKHR(mEGLDisplay, expired); + if (useFramebufferCache) { + if (image != EGL_NO_IMAGE_KHR) { + if (mFramebufferImageCache.size() >= mFramebufferImageCacheSize) { + EGLImageKHR expired = mFramebufferImageCache.front().second; + mFramebufferImageCache.pop_front(); + eglDestroyImageKHR(mEGLDisplay, expired); + } + mFramebufferImageCache.push_back({graphicBuffer->getId(), image}); } - mFramebufferImageCache.push_back({bufferId, image}); } return image; } @@ -837,7 +841,8 @@ EGLImageKHR GLESRenderEngine::createFramebufferImageIfNeeded(ANativeWindowBuffer status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, const std::vector<LayerSettings>& layers, ANativeWindowBuffer* const buffer, - base::unique_fd&& bufferFence, base::unique_fd* drawFence) { + const bool useFramebufferCache, base::unique_fd&& bufferFence, + base::unique_fd* drawFence) { ATRACE_CALL(); if (layers.empty()) { ALOGV("Drawing empty layer stack"); @@ -857,7 +862,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, { std::lock_guard<std::mutex> lock(mRenderingMutex); - BindNativeBufferAsFramebuffer fbo(*this, buffer); + BindNativeBufferAsFramebuffer fbo(*this, buffer, useFramebufferCache); if (fbo.getStatus() != NO_ERROR) { ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).", diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h index 8c8f308d3b..cbde5f4b67 100644 --- a/libs/renderengine/gl/GLESRenderEngine.h +++ b/libs/renderengine/gl/GLESRenderEngine.h @@ -83,14 +83,16 @@ public: bool supportsProtectedContent() const override; bool useProtectedContext(bool useProtectedContext) override; status_t drawLayers(const DisplaySettings& display, const std::vector<LayerSettings>& layers, - ANativeWindowBuffer* buffer, base::unique_fd&& bufferFence, - base::unique_fd* drawFence) EXCLUDES(mRenderingMutex) override; + ANativeWindowBuffer* buffer, const bool useFramebufferCache, + base::unique_fd&& bufferFence, base::unique_fd* drawFence) + EXCLUDES(mRenderingMutex) override; // internal to RenderEngine EGLDisplay getEGLDisplay() const { return mEGLDisplay; } EGLConfig getEGLConfig() const { return mEGLConfig; } // Creates an output image for rendering to - EGLImageKHR createFramebufferImageIfNeeded(ANativeWindowBuffer* nativeBuffer, bool isProtected); + EGLImageKHR createFramebufferImageIfNeeded(ANativeWindowBuffer* nativeBuffer, bool isProtected, + bool useFramebufferCache); // Test-only methods // Returns true iff mImageCache contains an image keyed by bufferId diff --git a/libs/renderengine/gl/GLFramebuffer.cpp b/libs/renderengine/gl/GLFramebuffer.cpp index c45598cc16..dacf8d3d82 100644 --- a/libs/renderengine/gl/GLFramebuffer.cpp +++ b/libs/renderengine/gl/GLFramebuffer.cpp @@ -41,19 +41,25 @@ GLFramebuffer::~GLFramebuffer() { glDeleteTextures(1, &mTextureName); } -bool GLFramebuffer::setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected) { +bool GLFramebuffer::setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected, + const bool useFramebufferCache) { ATRACE_CALL(); if (mEGLImage != EGL_NO_IMAGE_KHR) { + if (!usingFramebufferCache) { + eglDestroyImageKHR(mEGLDisplay, mEGLImage); + } mEGLImage = EGL_NO_IMAGE_KHR; mBufferWidth = 0; mBufferHeight = 0; } if (nativeBuffer) { - mEGLImage = mEngine.createFramebufferImageIfNeeded(nativeBuffer, isProtected); + mEGLImage = mEngine.createFramebufferImageIfNeeded(nativeBuffer, isProtected, + useFramebufferCache); if (mEGLImage == EGL_NO_IMAGE_KHR) { return false; } + usingFramebufferCache = useFramebufferCache; mBufferWidth = nativeBuffer->width; mBufferHeight = nativeBuffer->height; } diff --git a/libs/renderengine/gl/GLFramebuffer.h b/libs/renderengine/gl/GLFramebuffer.h index 1289fbff19..b7650bbfd9 100644 --- a/libs/renderengine/gl/GLFramebuffer.h +++ b/libs/renderengine/gl/GLFramebuffer.h @@ -35,7 +35,8 @@ public: explicit GLFramebuffer(GLESRenderEngine& engine); ~GLFramebuffer() override; - bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected) override; + bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected, + const bool useFramebufferCache) override; EGLImageKHR getEGLImage() const { return mEGLImage; } uint32_t getTextureName() const { return mTextureName; } uint32_t getFramebufferName() const { return mFramebufferName; } @@ -46,6 +47,7 @@ private: GLESRenderEngine& mEngine; EGLDisplay mEGLDisplay; EGLImageKHR mEGLImage; + bool usingFramebufferCache = false; uint32_t mTextureName, mFramebufferName; int32_t mBufferHeight = 0; diff --git a/libs/renderengine/include/renderengine/Framebuffer.h b/libs/renderengine/include/renderengine/Framebuffer.h index 66eb9ef206..65111278e0 100644 --- a/libs/renderengine/include/renderengine/Framebuffer.h +++ b/libs/renderengine/include/renderengine/Framebuffer.h @@ -27,7 +27,8 @@ class Framebuffer { public: virtual ~Framebuffer() = default; - virtual bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected) = 0; + virtual bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected, + const bool useFramebufferCache) = 0; }; } // namespace renderengine diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h index b211551348..fa57215997 100644 --- a/libs/renderengine/include/renderengine/RenderEngine.h +++ b/libs/renderengine/include/renderengine/RenderEngine.h @@ -170,6 +170,9 @@ public: // @param layers The layers to draw onto the display, in Z-order. // @param buffer The buffer which will be drawn to. This buffer will be // ready once drawFence fires. + // @param useFramebufferCache True if the framebuffer cache should be used. + // If an implementation does not cache output framebuffers, then this + // 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 @@ -180,8 +183,8 @@ public: // now, this always returns NO_ERROR. virtual status_t drawLayers(const DisplaySettings& display, const std::vector<LayerSettings>& layers, - ANativeWindowBuffer* buffer, base::unique_fd&& bufferFence, - base::unique_fd* drawFence) = 0; + ANativeWindowBuffer* buffer, const bool useFramebufferCache, + base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0; protected: // Gets a framebuffer to render to. This framebuffer may or may not be @@ -195,14 +198,16 @@ protected: class BindNativeBufferAsFramebuffer { public: - BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer) + BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer, + const bool useFramebufferCache) : mEngine(engine), mFramebuffer(mEngine.getFramebufferForDrawing()), mStatus(NO_ERROR) { - mStatus = mFramebuffer->setNativeWindowBuffer(buffer, mEngine.isProtected()) + mStatus = mFramebuffer->setNativeWindowBuffer(buffer, mEngine.isProtected(), + useFramebufferCache) ? mEngine.bindFrameBuffer(mFramebuffer) : NO_MEMORY; } ~BindNativeBufferAsFramebuffer() { - mFramebuffer->setNativeWindowBuffer(nullptr, false); + mFramebuffer->setNativeWindowBuffer(nullptr, false, /*arbitrary*/ true); mEngine.unbindFrameBuffer(mFramebuffer); } status_t getStatus() const { return mStatus; } diff --git a/libs/renderengine/include/renderengine/mock/Framebuffer.h b/libs/renderengine/include/renderengine/mock/Framebuffer.h index 7695885616..dfb6a4e41e 100644 --- a/libs/renderengine/include/renderengine/mock/Framebuffer.h +++ b/libs/renderengine/include/renderengine/mock/Framebuffer.h @@ -28,7 +28,7 @@ public: Framebuffer(); ~Framebuffer() override; - MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer*, bool)); + MOCK_METHOD3(setNativeWindowBuffer, bool(ANativeWindowBuffer*, bool, const bool)); }; } // namespace mock diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h index 479c7ac035..7393f7a754 100644 --- a/libs/renderengine/include/renderengine/mock/RenderEngine.h +++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h @@ -77,9 +77,9 @@ public: MOCK_CONST_METHOD0(isProtected, bool()); MOCK_CONST_METHOD0(supportsProtectedContent, bool()); MOCK_METHOD1(useProtectedContext, bool(bool)); - MOCK_METHOD5(drawLayers, + MOCK_METHOD6(drawLayers, status_t(const DisplaySettings&, const std::vector<LayerSettings>&, - ANativeWindowBuffer*, base::unique_fd&&, base::unique_fd*)); + ANativeWindowBuffer*, const bool, base::unique_fd&&, base::unique_fd*)); }; } // namespace mock diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp index 8c93cf432c..351ca6b1f5 100644 --- a/libs/renderengine/tests/RenderEngineTest.cpp +++ b/libs/renderengine/tests/RenderEngineTest.cpp @@ -118,7 +118,7 @@ struct RenderEngineTest : public ::testing::Test { void invokeDraw(renderengine::DisplaySettings settings, std::vector<renderengine::LayerSettings> layers, sp<GraphicBuffer> buffer) { base::unique_fd fence; - status_t status = sRE->drawLayers(settings, layers, buffer->getNativeBuffer(), + status_t status = sRE->drawLayers(settings, layers, buffer->getNativeBuffer(), true, base::unique_fd(), &fence); sCurrentBuffer = buffer; @@ -770,7 +770,7 @@ TEST_F(RenderEngineTest, drawLayers_nullOutputBuffer) { BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this); layers.push_back(layer); base::unique_fd fence; - status_t status = sRE->drawLayers(settings, layers, nullptr, base::unique_fd(), &fence); + status_t status = sRE->drawLayers(settings, layers, nullptr, true, base::unique_fd(), &fence); ASSERT_EQ(BAD_VALUE, status); } @@ -787,13 +787,33 @@ TEST_F(RenderEngineTest, drawLayers_nullOutputFence) { layer.alpha = 1.0; layers.push_back(layer); - status_t status = sRE->drawLayers(settings, layers, mBuffer->getNativeBuffer(), + status_t status = sRE->drawLayers(settings, layers, mBuffer->getNativeBuffer(), true, base::unique_fd(), nullptr); sCurrentBuffer = mBuffer; ASSERT_EQ(NO_ERROR, status); expectBufferColor(fullscreenRect(), 255, 0, 0, 255); } +TEST_F(RenderEngineTest, drawLayers_doesNotCacheFramebuffer) { + renderengine::DisplaySettings settings; + settings.physicalDisplay = fullscreenRect(); + settings.clip = fullscreenRect(); + + std::vector<renderengine::LayerSettings> layers; + renderengine::LayerSettings layer; + layer.geometry.boundaries = fullscreenRect().toFloatRect(); + BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this); + layer.alpha = 1.0; + layers.push_back(layer); + + status_t status = sRE->drawLayers(settings, layers, mBuffer->getNativeBuffer(), false, + base::unique_fd(), nullptr); + sCurrentBuffer = mBuffer; + ASSERT_EQ(NO_ERROR, status); + ASSERT_FALSE(sRE->isFramebufferImageCachedForTesting(mBuffer->getId())); + expectBufferColor(fullscreenRect(), 255, 0, 0, 255); +} + TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) { fillRedBuffer<ColorSourceVariant>(); } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1a68cc6039..c0d7f2d726 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3437,7 +3437,8 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& displayDevice, } } renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayers, - buf->getNativeBuffer(), std::move(fd), readyFence); + buf->getNativeBuffer(), /*useFramebufferCache=*/true, std::move(fd), + readyFence); if (expensiveRenderingExpected && displayId) { mPowerAdvisor.setExpensiveRenderingExpected(*displayId, false); } @@ -5754,7 +5755,7 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, base::unique_fd drawFence; getRenderEngine().useProtectedContext(false); getRenderEngine().drawLayers(clientCompositionDisplay, clientCompositionLayers, buffer, - std::move(bufferFence), &drawFence); + /*useFramebufferCache=*/false, std::move(bufferFence), &drawFence); *outSyncFd = drawFence.release(); } diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index ea2818d532..ef3dfef38f 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -175,7 +175,6 @@ public: renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); mock::MessageQueue* mMessageQueue = new mock::MessageQueue(); mock::DispSync* mPrimaryDispSync = new mock::DispSync(); - renderengine::mock::Framebuffer* mReFrameBuffer = new renderengine::mock::Framebuffer(); sp<Fence> mClientTargetAcquireFence = Fence::NO_FENCE; @@ -312,8 +311,8 @@ struct BaseDisplayVariant { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillRepeatedly( [](const renderengine::DisplaySettings& displaySettings, - const std::vector<renderengine::LayerSettings>& /*layerSettings*/, - ANativeWindowBuffer*, base::unique_fd&&, base::unique_fd*) -> status_t { + const std::vector<renderengine::LayerSettings>&, ANativeWindowBuffer*, + const bool, base::unique_fd&&, base::unique_fd*) -> status_t { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), displaySettings.physicalDisplay); @@ -351,8 +350,8 @@ struct BaseDisplayVariant { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillRepeatedly( [](const renderengine::DisplaySettings& displaySettings, - const std::vector<renderengine::LayerSettings>& /*layerSettings*/, - ANativeWindowBuffer*, base::unique_fd&&, base::unique_fd*) -> status_t { + const std::vector<renderengine::LayerSettings>&, ANativeWindowBuffer*, + const bool, base::unique_fd&&, base::unique_fd*) -> status_t { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), displaySettings.physicalDisplay); @@ -581,7 +580,7 @@ struct BaseLayerProperties { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillOnce([](const renderengine::DisplaySettings& displaySettings, const std::vector<renderengine::LayerSettings>& layerSettings, - ANativeWindowBuffer*, base::unique_fd&&, + ANativeWindowBuffer*, const bool, base::unique_fd&&, base::unique_fd*) -> status_t { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), @@ -624,7 +623,7 @@ struct BaseLayerProperties { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillOnce([](const renderengine::DisplaySettings& displaySettings, const std::vector<renderengine::LayerSettings>& layerSettings, - ANativeWindowBuffer*, base::unique_fd&&, + ANativeWindowBuffer*, const bool, base::unique_fd&&, base::unique_fd*) -> status_t { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), @@ -694,7 +693,7 @@ struct SecureLayerProperties : public BaseLayerProperties<SecureLayerProperties> EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillOnce([](const renderengine::DisplaySettings& displaySettings, const std::vector<renderengine::LayerSettings>& layerSettings, - ANativeWindowBuffer*, base::unique_fd&&, + ANativeWindowBuffer*, const bool, base::unique_fd&&, base::unique_fd*) -> status_t { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), |