From cdf18df05a08eb52d41272ac9e2e9e2e8e26e237 Mon Sep 17 00:00:00 2001 From: domrjchen Date: Tue, 29 Oct 2024 10:39:05 +0800 Subject: [PATCH] Handle the clearAll flag in RenderTargetCreateTask instead of creating a ClearOp. --- src/core/ImageFilter.cpp | 4 ++-- src/core/filters/BlurImageFilter.cpp | 4 ++-- src/core/images/Image.cpp | 4 ++-- src/gpu/OpContext.cpp | 22 ++++++++-------------- src/gpu/OpContext.h | 15 +++++---------- src/gpu/ProxyProvider.cpp | 8 +------- src/gpu/RenderTarget.h | 3 ++- src/gpu/opengl/GLRenderTarget.cpp | 9 ++++++++- src/gpu/tasks/RenderTargetCreateTask.cpp | 12 +++++++----- src/gpu/tasks/RenderTargetCreateTask.h | 6 ++++-- test/src/CanvasTest.cpp | 6 ------ 11 files changed, 41 insertions(+), 52 deletions(-) diff --git a/src/core/ImageFilter.cpp b/src/core/ImageFilter.cpp index da24d54f..9490b174 100644 --- a/src/core/ImageFilter.cpp +++ b/src/core/ImageFilter.cpp @@ -53,8 +53,8 @@ std::shared_ptr ImageFilter::lockTextureProxy(std::shared_ptrgetTextureProxy(); } diff --git a/src/core/filters/BlurImageFilter.cpp b/src/core/filters/BlurImageFilter.cpp index a664788f..647dae9e 100644 --- a/src/core/filters/BlurImageFilter.cpp +++ b/src/core/filters/BlurImageFilter.cpp @@ -96,8 +96,8 @@ void BlurImageFilter::draw(std::shared_ptr renderTarget, auto blurProcessor = DualBlurFragmentProcessor::Make(isDown ? DualBlurPassMode::Down : DualBlurPassMode::Up, std::move(imageProcessor), blurOffset, texelSize); - OpContext opContext(std::move(renderTarget), true); - opContext.fillWithFP(std::move(blurProcessor), uvMatrix); + OpContext opContext(std::move(renderTarget)); + opContext.fillWithFP(std::move(blurProcessor), uvMatrix, true); } Rect BlurImageFilter::onFilterBounds(const Rect& srcRect) const { diff --git a/src/core/images/Image.cpp b/src/core/images/Image.cpp index de08e550..5ba6662c 100644 --- a/src/core/images/Image.cpp +++ b/src/core/images/Image.cpp @@ -257,8 +257,8 @@ std::shared_ptr Image::lockTextureProxy(const TPArgs& args, if (processor == nullptr) { return nullptr; } - OpContext opContext(renderTarget, true); - opContext.fillWithFP(std::move(processor), Matrix::I()); + OpContext opContext(renderTarget); + opContext.fillWithFP(std::move(processor), Matrix::I(), true); return textureProxy; } } // namespace tgfx diff --git a/src/gpu/OpContext.cpp b/src/gpu/OpContext.cpp index e07c06cd..d3afe770 100644 --- a/src/gpu/OpContext.cpp +++ b/src/gpu/OpContext.cpp @@ -21,24 +21,14 @@ #include "gpu/ops/FillRectOp.h" namespace tgfx { -OpContext::~OpContext() { - if (autoResolve) { - auto drawingManager = renderTargetProxy->getContext()->drawingManager(); - drawingManager->addTextureResolveTask(renderTargetProxy); - } -} - -void OpContext::fillWithFP(std::unique_ptr fp, const Matrix& uvMatrix) { +void OpContext::fillWithFP(std::unique_ptr fp, const Matrix& uvMatrix, + bool autoResolve) { fillRectWithFP(Rect::MakeWH(renderTargetProxy->width(), renderTargetProxy->height()), - std::move(fp), uvMatrix); - if (autoResolve) { - auto drawingManager = renderTargetProxy->getContext()->drawingManager(); - drawingManager->addTextureResolveTask(renderTargetProxy); - } + std::move(fp), uvMatrix, autoResolve); } void OpContext::fillRectWithFP(const Rect& dstRect, std::unique_ptr fp, - const Matrix& uvMatrix) { + const Matrix& uvMatrix, bool autoResolve) { if (fp == nullptr) { return; } @@ -46,6 +36,10 @@ void OpContext::fillRectWithFP(const Rect& dstRect, std::unique_ptraddColorFP(std::move(fp)); op->setBlendMode(BlendMode::Src); addOp(std::move(op)); + if (autoResolve) { + auto drawingManager = renderTargetProxy->getContext()->drawingManager(); + drawingManager->addTextureResolveTask(renderTargetProxy); + } } void OpContext::addOp(std::unique_ptr op) { diff --git a/src/gpu/OpContext.h b/src/gpu/OpContext.h index a1361b1e..da948b1f 100644 --- a/src/gpu/OpContext.h +++ b/src/gpu/OpContext.h @@ -28,29 +28,24 @@ namespace tgfx { */ class OpContext { public: - /** - * If autoResolve is true, the RenderTarget will be resolved after OpContext is destroyed. - */ - explicit OpContext(std::shared_ptr renderTargetProxy, bool autoResolve = false) - : renderTargetProxy(std::move(renderTargetProxy)), autoResolve(autoResolve) { + explicit OpContext(std::shared_ptr renderTargetProxy) + : renderTargetProxy(std::move(renderTargetProxy)) { } - ~OpContext(); - RenderTargetProxy* renderTarget() const { return renderTargetProxy.get(); } - void fillWithFP(std::unique_ptr fp, const Matrix& uvMatrix); + void fillWithFP(std::unique_ptr fp, const Matrix& uvMatrix, + bool autoResolve = false); void fillRectWithFP(const Rect& dstRect, std::unique_ptr fp, - const Matrix& uvMatrix); + const Matrix& uvMatrix, bool autoResolve = false); void addOp(std::unique_ptr op); private: std::shared_ptr renderTargetProxy = nullptr; std::shared_ptr opsTask = nullptr; - bool autoResolve = false; }; } // namespace tgfx diff --git a/src/gpu/ProxyProvider.cpp b/src/gpu/ProxyProvider.cpp index 9348ac56..79333855 100644 --- a/src/gpu/ProxyProvider.cpp +++ b/src/gpu/ProxyProvider.cpp @@ -19,7 +19,6 @@ #include "ProxyProvider.h" #include "gpu/DrawingManager.h" #include "gpu/PlainTexture.h" -#include "gpu/ops/ClearOp.h" #include "gpu/proxies/TextureRenderTargetProxy.h" #include "gpu/tasks/GpuBufferCreateTask.h" #include "gpu/tasks/RenderTargetCreateTask.h" @@ -175,7 +174,7 @@ std::shared_ptr ProxyProvider::createRenderTargetProxy( sampleCount = caps->getSampleCount(sampleCount, format); auto uniqueKey = UniqueKey::Make(); auto task = RenderTargetCreateTask::MakeFrom(uniqueKey, textureProxy->getUniqueKey(), format, - sampleCount); + sampleCount, clearAll); if (task == nullptr) { return nullptr; } @@ -183,11 +182,6 @@ std::shared_ptr ProxyProvider::createRenderTargetProxy( drawingManager->addResourceTask(std::move(task)); auto proxy = std::shared_ptr( new TextureRenderTargetProxy(uniqueKey, std::move(textureProxy), format, sampleCount)); - if (clearAll) { - auto opsTask = drawingManager->addOpsTask(proxy); - auto rect = Rect::MakeWH(proxy->width(), proxy->height()); - opsTask->addOp(ClearOp::Make(Color::Transparent(), rect)); - } addResourceProxy(proxy, uniqueKey); return proxy; } diff --git a/src/gpu/RenderTarget.h b/src/gpu/RenderTarget.h index 38523eac..be6e2399 100644 --- a/src/gpu/RenderTarget.h +++ b/src/gpu/RenderTarget.h @@ -40,7 +40,8 @@ class RenderTarget : public Resource { * Creates a new RenderTarget which uses specified Texture as pixel storage. The caller must * ensure the texture is valid for the lifetime of the returned RenderTarget. */ - static std::shared_ptr MakeFrom(const Texture* texture, int sampleCount = 1); + static std::shared_ptr MakeFrom(const Texture* texture, int sampleCount = 1, + bool clearAll = false); /** * Returns the display width of the render target. diff --git a/src/gpu/opengl/GLRenderTarget.cpp b/src/gpu/opengl/GLRenderTarget.cpp index 31edc593..4decf58b 100644 --- a/src/gpu/opengl/GLRenderTarget.cpp +++ b/src/gpu/opengl/GLRenderTarget.cpp @@ -137,7 +137,8 @@ static bool CreateRenderBuffer(const Texture* texture, GLFrameBuffer* renderTarg #endif } -std::shared_ptr RenderTarget::MakeFrom(const Texture* texture, int sampleCount) { +std::shared_ptr RenderTarget::MakeFrom(const Texture* texture, int sampleCount, + bool clearAll) { if (texture == nullptr || texture->isYUV()) { return nullptr; } @@ -173,6 +174,12 @@ std::shared_ptr RenderTarget::MakeFrom(const Texture* texture, int return nullptr; } #endif + if (clearAll) { + gl->viewport(0, 0, texture->width(), texture->height()); + gl->disable(GL_SCISSOR_TEST); + gl->clearColor(0, 0, 0, 0); + gl->clear(GL_COLOR_BUFFER_BIT); + } auto rt = new GLRenderTarget(texture->width(), texture->height(), texture->origin(), sampleCount, textureFBInfo, glSampler->target); rt->frameBufferForDraw = renderTargetFBInfo; diff --git a/src/gpu/tasks/RenderTargetCreateTask.cpp b/src/gpu/tasks/RenderTargetCreateTask.cpp index 8864b998..d8cc669d 100644 --- a/src/gpu/tasks/RenderTargetCreateTask.cpp +++ b/src/gpu/tasks/RenderTargetCreateTask.cpp @@ -25,15 +25,17 @@ namespace tgfx { std::shared_ptr RenderTargetCreateTask::MakeFrom(UniqueKey uniqueKey, UniqueKey textureKey, PixelFormat pixelFormat, - int sampleCount) { + int sampleCount, + bool clearAll) { return std::shared_ptr(new RenderTargetCreateTask( - std::move(uniqueKey), std::move(textureKey), pixelFormat, sampleCount)); + std::move(uniqueKey), std::move(textureKey), pixelFormat, sampleCount, clearAll)); } RenderTargetCreateTask::RenderTargetCreateTask(UniqueKey uniqueKey, UniqueKey textureKey, - PixelFormat pixelFormat, int sampleCount) + PixelFormat pixelFormat, int sampleCount, + bool clearAll) : ResourceTask(std::move(uniqueKey)), textureKey(std::move(textureKey)), - pixelFormat(pixelFormat), sampleCount(sampleCount) { + pixelFormat(pixelFormat), sampleCount(sampleCount), clearAll(clearAll) { } std::shared_ptr RenderTargetCreateTask::onMakeResource(Context* context) { @@ -46,7 +48,7 @@ std::shared_ptr RenderTargetCreateTask::onMakeResource(Context* contex LOGE("RenderTargetCreateTask::onMakeResource() the texture format mismatch!"); return nullptr; } - auto renderTarget = RenderTarget::MakeFrom(texture.get(), sampleCount); + auto renderTarget = RenderTarget::MakeFrom(texture.get(), sampleCount, clearAll); if (renderTarget == nullptr) { LOGE("RenderTargetCreateTask::onMakeResource() Failed to create the render target!"); } diff --git a/src/gpu/tasks/RenderTargetCreateTask.h b/src/gpu/tasks/RenderTargetCreateTask.h index 20f79ed2..28ecd681 100644 --- a/src/gpu/tasks/RenderTargetCreateTask.h +++ b/src/gpu/tasks/RenderTargetCreateTask.h @@ -28,7 +28,8 @@ class RenderTargetCreateTask : public ResourceTask { */ static std::shared_ptr MakeFrom(UniqueKey uniqueKey, UniqueKey textureKey, PixelFormat pixelFormat, - int sampleCount = 1); + int sampleCount = 1, + bool clearAll = false); protected: std::shared_ptr onMakeResource(Context* context) override; @@ -37,8 +38,9 @@ class RenderTargetCreateTask : public ResourceTask { UniqueKey textureKey = {}; PixelFormat pixelFormat = PixelFormat::RGBA_8888; int sampleCount = 1; + bool clearAll = false; RenderTargetCreateTask(UniqueKey uniqueKey, UniqueKey textureKey, PixelFormat pixelFormat, - int sampleCount); + int sampleCount, bool clearAll); }; } // namespace tgfx diff --git a/test/src/CanvasTest.cpp b/test/src/CanvasTest.cpp index e724d8d4..1e7d2f01 100644 --- a/test/src/CanvasTest.cpp +++ b/test/src/CanvasTest.cpp @@ -114,8 +114,6 @@ TGFX_TEST(CanvasTest, merge_draw_call_rect) { int width = 72; int height = 72; auto surface = Surface::Make(context, width, height); - // clear the pending ClearOp. - context->flush(); auto canvas = surface->getCanvas(); canvas->clearRect(Rect::MakeWH(surface->width(), surface->height()), Color::White()); Paint paint; @@ -173,8 +171,6 @@ TGFX_TEST(CanvasTest, merge_draw_call_rrect) { int width = 72; int height = 72; auto surface = Surface::Make(context, width, height); - // clear the pending ClearOp. - context->flush(); auto canvas = surface->getCanvas(); canvas->clearRect(Rect::MakeWH(width, height), Color::White()); Paint paint; @@ -216,8 +212,6 @@ TGFX_TEST(CanvasTest, merge_draw_clear_op) { int width = 72; int height = 72; auto surface = Surface::Make(context, width, height); - // clear the pending ClearOp. - context->flush(); auto canvas = surface->getCanvas(); canvas->clearRect(Rect::MakeWH(width, height), Color::White()); canvas->save();