From eb09113ec7b9c8f6dbf56488471fcf91de90406f Mon Sep 17 00:00:00 2001 From: Hparty <420024556@qq.com> Date: Wed, 30 Oct 2024 21:16:00 +0800 Subject: [PATCH] add surface id --- include/tgfx/core/Surface.h | 1 + include/tgfx/layers/DisplayList.h | 2 ++ include/tgfx/layers/LayerProperty.h | 7 +++++-- include/tgfx/layers/PathProvider.h | 4 ++++ include/tgfx/layers/filters/LayerFilter.h | 4 ++++ src/gpu/Surface.cpp | 2 +- src/layers/DisplayList.cpp | 10 ++++++++-- src/layers/LayerProperty.cpp | 6 +++++- src/layers/PathProvider.cpp | 5 +++++ src/layers/filters/LayerFilter.cpp | 4 ++++ 10 files changed, 39 insertions(+), 6 deletions(-) diff --git a/include/tgfx/core/Surface.h b/include/tgfx/core/Surface.h index 7c07000..3c9469e 100644 --- a/include/tgfx/core/Surface.h +++ b/include/tgfx/core/Surface.h @@ -175,6 +175,7 @@ class Surface { */ uint32_t contentVersion() const; + uint32_t _uniqueID = 0; std::shared_ptr renderTargetProxy = nullptr; uint32_t _renderFlags = 0; RenderContext* renderContext = nullptr; diff --git a/include/tgfx/layers/DisplayList.h b/include/tgfx/layers/DisplayList.h index da191dc..a1a9df1 100644 --- a/include/tgfx/layers/DisplayList.h +++ b/include/tgfx/layers/DisplayList.h @@ -48,7 +48,9 @@ class DisplayList { void render(Surface* surface, bool replaceAll = true); private: + bool needRender(const Surface* surface) const; std::shared_ptr _root = nullptr; uint32_t surfaceContentVersion = 0u; + uint32_t surfaceID = 0u; }; } // namespace tgfx diff --git a/include/tgfx/layers/LayerProperty.h b/include/tgfx/layers/LayerProperty.h index 9c27809..bc6573b 100644 --- a/include/tgfx/layers/LayerProperty.h +++ b/include/tgfx/layers/LayerProperty.h @@ -32,11 +32,14 @@ class LayerProperty { protected: /** - * Mark the property as dirty and notify the layer that the content needs to be updated. + * Invalidate this property and notify the layer that the content needs to be updated. */ void invalidate(); - bool dirty = true; + /** + * Called when the property is invalidated. + */ + virtual void onInvalidate(); private: void attachToLayer(const Layer* layer); diff --git a/include/tgfx/layers/PathProvider.h b/include/tgfx/layers/PathProvider.h index 063d109..5c04295 100644 --- a/include/tgfx/layers/PathProvider.h +++ b/include/tgfx/layers/PathProvider.h @@ -49,7 +49,11 @@ class PathProvider : public LayerProperty { virtual Path onGeneratePath(); + void onInvalidate() override; + private: Path path = {}; + + bool dirty = true; }; } // namespace tgfx diff --git a/include/tgfx/layers/filters/LayerFilter.h b/include/tgfx/layers/filters/LayerFilter.h index 47e0067..c31e38e 100644 --- a/include/tgfx/layers/filters/LayerFilter.h +++ b/include/tgfx/layers/filters/LayerFilter.h @@ -45,7 +45,11 @@ class LayerFilter : public LayerProperty { */ virtual std::shared_ptr onCreateImageFilter(float scale) = 0; + void onInvalidate() override; + private: + bool dirty = true; + float lastScale = 1.0f; std::unique_ptr _clipBounds = nullptr; diff --git a/src/gpu/Surface.cpp b/src/gpu/Surface.cpp index 6946751..90d7851 100644 --- a/src/gpu/Surface.cpp +++ b/src/gpu/Surface.cpp @@ -67,7 +67,7 @@ std::shared_ptr Surface::MakeFrom(std::shared_ptr re } Surface::Surface(std::shared_ptr proxy, uint32_t renderFlags) - : renderTargetProxy(std::move(proxy)), _renderFlags(renderFlags) { + : _uniqueID(UniqueID::Next()), renderTargetProxy(std::move(proxy)), _renderFlags(renderFlags) { DEBUG_ASSERT(this->renderTargetProxy != nullptr); } diff --git a/src/layers/DisplayList.cpp b/src/layers/DisplayList.cpp index 4086e87..62ab87e 100644 --- a/src/layers/DisplayList.cpp +++ b/src/layers/DisplayList.cpp @@ -30,8 +30,7 @@ Layer* DisplayList::root() const { } void DisplayList::render(Surface* surface, bool replaceAll) { - if (!surface || (surface->contentVersion() == surfaceContentVersion && !_root->bitFields.dirty && - replaceAll)) { + if (!surface || !needRender(surface)) { return; } auto canvas = surface->getCanvas(); @@ -41,5 +40,12 @@ void DisplayList::render(Surface* surface, bool replaceAll) { DrawArgs args(surface->getContext(), surface->renderFlags(), true); _root->drawLayer(args, canvas, 1.0f, BlendMode::SrcOver); surfaceContentVersion = surface->contentVersion(); + surfaceID = surface->_uniqueID; } + +bool DisplayList::needRender(const Surface* surface) const { + return surface->_uniqueID != surfaceID || surface->contentVersion() != surfaceContentVersion || + _root->bitFields.dirty; +} + } // namespace tgfx \ No newline at end of file diff --git a/src/layers/LayerProperty.cpp b/src/layers/LayerProperty.cpp index 767bd4e..2868a02 100644 --- a/src/layers/LayerProperty.cpp +++ b/src/layers/LayerProperty.cpp @@ -22,13 +22,17 @@ namespace tgfx { void LayerProperty::invalidate() { - dirty = true; + onInvalidate(); for (auto& owner : owners) { if (auto layer = owner.lock()) { layer->invalidateContent(); } } } + +void LayerProperty::onInvalidate() { +} + void LayerProperty::attachToLayer(const Layer* layer) { owners.push_back(layer->weakThis); } diff --git a/src/layers/PathProvider.cpp b/src/layers/PathProvider.cpp index 2232335..7937e0f 100644 --- a/src/layers/PathProvider.cpp +++ b/src/layers/PathProvider.cpp @@ -41,4 +41,9 @@ Path PathProvider::getPath() { Path PathProvider::onGeneratePath() { return path; } + +void PathProvider::onInvalidate() { + dirty = true; +} + } // namespace tgfx diff --git a/src/layers/filters/LayerFilter.cpp b/src/layers/filters/LayerFilter.cpp index 924efda..c480751 100644 --- a/src/layers/filters/LayerFilter.cpp +++ b/src/layers/filters/LayerFilter.cpp @@ -29,4 +29,8 @@ std::shared_ptr LayerFilter::getImageFilter(float filterScale) { return lastFilter; } +void LayerFilter::onInvalidate() { + dirty = true; +} + } // namespace tgfx \ No newline at end of file