Loading libs/renderengine/RenderEngine.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -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 libs/renderengine/gl/GLESRenderEngine.cpp +27 −19 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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()); Loading Loading @@ -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 { Loading @@ -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; } } Loading Loading @@ -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) { Loading @@ -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); Loading @@ -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; } } Loading Loading @@ -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) { Loading libs/renderengine/gl/GLESRenderEngine.h +5 −5 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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; Loading libs/renderengine/include/renderengine/RenderEngine.h +20 −11 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ class Image; class Mesh; class Texture; struct RenderEngineCreationArgs; struct RenderEngineResult; namespace threaded { class RenderEngineThreaded; Loading Loading @@ -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 Loading Loading @@ -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 { Loading Loading @@ -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 Loading libs/renderengine/include/renderengine/mock/RenderEngine.h +9 −4 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/renderengine/RenderEngine.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -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
libs/renderengine/gl/GLESRenderEngine.cpp +27 −19 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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()); Loading Loading @@ -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 { Loading @@ -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; } } Loading Loading @@ -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) { Loading @@ -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); Loading @@ -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; } } Loading Loading @@ -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) { Loading
libs/renderengine/gl/GLESRenderEngine.h +5 −5 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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; Loading
libs/renderengine/include/renderengine/RenderEngine.h +20 −11 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ class Image; class Mesh; class Texture; struct RenderEngineCreationArgs; struct RenderEngineResult; namespace threaded { class RenderEngineThreaded; Loading Loading @@ -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 Loading Loading @@ -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 { Loading Loading @@ -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 Loading
libs/renderengine/include/renderengine/mock/RenderEngine.h +9 −4 Original line number Diff line number Diff line Loading @@ -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