diff --git a/.clang-format b/.clang-format index be7ad9c7be..b006c2d683 100644 --- a/.clang-format +++ b/.clang-format @@ -58,7 +58,7 @@ ForEachMacros: - BOOST_FOREACH IncludeBlocks: Regroup IncludeCategories: - - Regex: '^"(animation|backend|c|command|common|draw|drawable|drawing|effect|image|ipc_callbacks|memory|modifier|overdraw|platform|pipeline|property|render|render_context|screen_manager|text|transaction|ui|utils|visitor)/' + - Regex: '^"(animation|backend|c|command|common|draw|drawable|drawing|effect|image|ipc_callbacks|memory|modifier|overdraw|params|platform|pipeline|property|render|render_context|screen_manager|text|transaction|ui|utils|visitor)/' Priority: 3 - Regex: '<*>' Priority: 1 diff --git a/rosen/modules/render_service_base/BUILD.gn b/rosen/modules/render_service_base/BUILD.gn index 2faa6fa12b..0f03bec15a 100644 --- a/rosen/modules/render_service_base/BUILD.gn +++ b/rosen/modules/render_service_base/BUILD.gn @@ -209,9 +209,10 @@ ohos_source_set("render_service_base_src") { "src/property/rs_property_trace.cpp", #drawable + "src/drawable/rs_utilities_drawable.cpp", "src/drawable/rs_render_node_drawable_adapter.cpp", - "src/drawable/rs_property_drawable_content.cpp", - "src/drawable/rs_drawable_content.cpp", + "src/drawable/rs_property_drawable.cpp", + "src/drawable/rs_drawable.cpp", #render "src/render/rs_aibar_filter.cpp", diff --git a/rosen/modules/render_service_base/include/drawable/rs_drawable_content.h b/rosen/modules/render_service_base/include/drawable/rs_drawable.h similarity index 58% rename from rosen/modules/render_service_base/include/drawable/rs_drawable_content.h rename to rosen/modules/render_service_base/include/drawable/rs_drawable.h index c0fe8fad4b..1e1635f03a 100644 --- a/rosen/modules/render_service_base/include/drawable/rs_drawable_content.h +++ b/rosen/modules/render_service_base/include/drawable/rs_drawable.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_CONTENT_H -#define RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_CONTENT_H +#ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H +#define RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H #include #include @@ -22,17 +22,16 @@ #include #include +#include "recording/recording_canvas.h" + #include "modifier/rs_modifier_type.h" -#include "pipeline/rs_recording_canvas.h" namespace OHOS::Rosen { class RSRenderNode; class RSRenderContent; // NOTE: MUST update DrawableGeneratorLut in rs_drawable_content.cpp when new slots are added -enum class RSDrawableContentSlot : uint8_t { - INVALID = 0, - +enum class RSDrawableSlot : uint8_t { // Bounds Geometry ALPHA, MASK, @@ -81,9 +80,13 @@ enum class RSDrawableContentSlot : uint8_t { PARTICLE_EFFECT, PIXEL_STRETCH, + // Restore state RESTORE_BLEND_MODE, RESTORE_ALPHA, + // Invalid + INVALID, + // Annotations: Please remember to update this when new slots are added. // NOTE: MAX and *_END enums are using the one-past-the-end style. BG_PROPERTIES_BEGIN = BACKGROUND_COLOR, @@ -92,20 +95,27 @@ enum class RSDrawableContentSlot : uint8_t { CONTENT_PROPERTIES_END = FOREGROUND_STYLE + 1, FG_PROPERTIES_BEGIN = BINARIZATION, FG_PROPERTIES_END = FOREGROUND_COLOR + 1, - MAX = RESTORE_ALPHA + 1, + MAX = INVALID, }; // pure virtual base class -class RSDrawableContent : public std::enable_shared_from_this { +class RSDrawable : public std::enable_shared_from_this { public: - RSDrawableContent() = default; - virtual ~RSDrawableContent() = default; + RSDrawable() = default; + virtual ~RSDrawable() = default; - // type definition - using Ptr = std::shared_ptr; - using Vec = std::array(RSDrawableContentSlot::MAX)>; + // not copyable and moveable + RSDrawable(const RSDrawable&) = delete; + RSDrawable(const RSDrawable&&) = delete; + RSDrawable& operator=(const RSDrawable&) = delete; + RSDrawable& operator=(const RSDrawable&&) = delete; + + // =================type definition================== + using Ptr = std::shared_ptr; + using Vec = std::array(RSDrawableSlot::MAX)>; using Generator = std::function; + // =================virtual functions================== // Call on first create, return nullptr if no need to create // static Ptr OnGenerate(const RSRenderNode& content) { return nullptr; }; @@ -124,62 +134,15 @@ public: // !!!!!!!!!!!!!!!!!!!!!!!!!! virtual Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const = 0; - // not copyable and moveable - RSDrawableContent(const RSDrawableContent&) = delete; - RSDrawableContent(const RSDrawableContent&&) = delete; - RSDrawableContent& operator=(const RSDrawableContent&) = delete; - RSDrawableContent& operator=(const RSDrawableContent&&) = delete; - // =================Generate & Update helper methods================== // Step 1, generate DirtySlots from dirty Modifiers - static std::unordered_set CalculateDirtySlots( + static std::unordered_set CalculateDirtySlots( ModifierDirtyTypes& dirtyTypes, const Vec& drawableVec); // Step 2, for every DirtySlot, generate DrawableContent static bool UpdateDirtySlots( - const RSRenderNode& node, Vec& drawableVec, std::unordered_set& dirtySlots); + const RSRenderNode& node, Vec& drawableVec, std::unordered_set& dirtySlots); // Step 3, add necessary Clip/Save/Restore static void UpdateSaveRestore(RSRenderContent& content, Vec& drawableVec, uint8_t& drawableVecStatus); }; - -// RSChildrenDrawable, for drawing children of RSRenderNode, updates on child add/remove -class RSRenderNodeDrawableAdapter; -class RSChildrenDrawableContent : public RSDrawableContent { -public: - RSChildrenDrawableContent() = default; - ~RSChildrenDrawableContent() override = default; - - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& content) override; - void OnSync() override; - Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override; - -private: - bool needSync_ = false; - std::vector> childrenDrawables_; - std::vector> stagingChildrenDrawables_; - friend class RSChildrenDrawable; -}; - -// RSChildrenDrawable, for drawing custom modifiers -enum class RSModifierType : int16_t; -namespace Drawing { -class DrawCmdList; -} -class RSCustomModifierDrawableContent : public RSDrawableContent { -public: - RSCustomModifierDrawableContent(RSModifierType type) : type_(type) {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& content, RSModifierType type); - bool OnUpdate(const RSRenderNode& node) override; - void OnSync() override; - Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override; - -private: - RSModifierType type_; - - bool needSync_ = false; - std::vector> drawCmdList_; - std::vector> stagingDrawCmdList_; - friend class RSCustomModifierDrawable; -}; } // namespace OHOS::Rosen -#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_CONTENT_H +#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H diff --git a/rosen/modules/render_service_base/include/drawable/rs_property_drawable.h b/rosen/modules/render_service_base/include/drawable/rs_property_drawable.h new file mode 100644 index 0000000000..6662ddbf83 --- /dev/null +++ b/rosen/modules/render_service_base/include/drawable/rs_property_drawable.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_H +#define RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_H + +#include "recording/draw_cmd_list.h" + +#include "drawable/rs_drawable.h" +#include "property/rs_properties.h" + +namespace OHOS::Rosen { +class RSRenderNode; + +class RSPropertyDrawable : public RSDrawable { +public: + RSPropertyDrawable(std::shared_ptr&& drawCmdList) : drawCmdList_(std::move(drawCmdList)) {} + RSPropertyDrawable() = default; + ~RSPropertyDrawable() override = default; + + void OnSync() override; + // RSDrawable::Ptr CreateDrawable() const override; + Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override; + +protected: + bool needSync_ = false; + std::shared_ptr drawCmdList_; + std::shared_ptr stagingDrawCmdList_; + + friend class RSPropertyDrawCmdListUpdater; + friend class RSPropertyDrawableNG; +}; + +class RSBackgroundColorDrawable : public RSPropertyDrawable { +public: + RSBackgroundColorDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSBackgroundColorDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; + +class RSBackgroundShaderDrawable : public RSPropertyDrawable { +public: + RSBackgroundShaderDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSBackgroundShaderDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; + +class RSBackgroundImageDrawable : public RSPropertyDrawable { +public: + RSBackgroundImageDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSBackgroundImageDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; + +class RSBackgroundFilterDrawable : public RSPropertyDrawable { +public: + RSBackgroundFilterDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSBackgroundFilterDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; + +class RSBorderDrawable : public RSPropertyDrawable { +friend class RSOutlineDrawable; +public: + RSBorderDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSBorderDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; + +private: + static void DrawBorder(const RSProperties& properties, Drawing::Canvas& canvas, + const std::shared_ptr& border, const bool& isOutline); +}; + +class RSOutlineDrawable : public RSPropertyDrawable { +public: + RSOutlineDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSOutlineDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; + +class RSShadowDrawable : public RSPropertyDrawable { +public: + RSShadowDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSShadowDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; + +private: + static void DrawColorfulShadowInner(const RSProperties& properties, Drawing::Canvas& canvas, Drawing::Path& path); + static void DrawShadowInner(const RSProperties& properties, Drawing::Canvas& canvas, Drawing::Path& path); +}; + +class RSForegroundColorDrawable : public RSPropertyDrawable { +public: + RSForegroundColorDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSForegroundColorDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; + +class RSPixelStretchDrawable : public RSPropertyDrawable { +public: + RSPixelStretchDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSPixelStretchDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; + +class RSDynamicLightUpDrawable : public RSPropertyDrawable { +public: + RSDynamicLightUpDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSDynamicLightUpDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; + +private: + static std::shared_ptr dynamicLightUpBlenderEffect_; + + static std::shared_ptr MakeDynamicLightUpBlender(float dynamicLightUpRate, + float dynamicLightUpDeg); +}; + +class RSLightUpEffectDrawable : public RSPropertyDrawable { +public: + RSLightUpEffectDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSLightUpEffectDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; + +class RSColorFilterDrawable : public RSPropertyDrawable { +public: + RSColorFilterDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSColorFilterDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; + +class RSMaskDrawable : public RSPropertyDrawable { +public: + RSMaskDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSMaskDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; + +class RSBinarizationDrawable : public RSPropertyDrawable { +public: + RSBinarizationDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSBinarizationDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; + +private: + static std::shared_ptr binarizationShaderEffect_; + + static std::shared_ptr MakeBinarizationShader(float low, float high, + float thresholdLow, float thresholdHigh, std::shared_ptr imageShader); +}; + +class RSParticleDrawable : public RSPropertyDrawable { +public: + RSParticleDrawable(std::shared_ptr&& drawCmdList) + : RSPropertyDrawable(std::move(drawCmdList)) + {} + RSParticleDrawable() : RSPropertyDrawable() + {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& node) override; +}; +} // namespace OHOS::Rosen +#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_H diff --git a/rosen/modules/render_service_base/include/drawable/rs_property_drawable_content.h b/rosen/modules/render_service_base/include/drawable/rs_property_drawable_content.h deleted file mode 100644 index 8ebfff2da4..0000000000 --- a/rosen/modules/render_service_base/include/drawable/rs_property_drawable_content.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_CONTENT_H -#define RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_CONTENT_H - -#include "recording/draw_cmd_list.h" - -#include "drawable/rs_drawable_content.h" -#include "property/rs_properties.h" - -namespace OHOS::Rosen { -class RSRenderNode; - -class RSPropertyDrawableContent : public RSDrawableContent { -public: - RSPropertyDrawableContent(std::shared_ptr&& drawCmdList) : drawCmdList_(std::move(drawCmdList)) {} - RSPropertyDrawableContent() = default; - ~RSPropertyDrawableContent() override = default; - - void OnSync() override; - // RSDrawable::Ptr CreateDrawable() const override; - Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override; - -protected: - bool needSync_ = false; - std::shared_ptr drawCmdList_; - std::shared_ptr stagingDrawCmdList_; - - friend class RSPropertyDrawCmdListUpdater; - friend class RSPropertyDrawableNG; -}; - -class RSBackgroundColorContent : public RSPropertyDrawableContent { -public: - RSBackgroundColorContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSBackgroundColorContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; - -class RSBackgroundShaderContent : public RSPropertyDrawableContent { -public: - RSBackgroundShaderContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSBackgroundShaderContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; - -class RSBackgroundImageContent : public RSPropertyDrawableContent { -public: - RSBackgroundImageContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSBackgroundImageContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; - -class RSBackgroundFilterContent : public RSPropertyDrawableContent { -public: - RSBackgroundFilterContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSBackgroundFilterContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; - -class RSBorderContent : public RSPropertyDrawableContent { -friend class RSOutlineContent; -public: - RSBorderContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSBorderContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; - -private: - static void DrawBorder(const RSProperties& properties, Drawing::Canvas& canvas, - const std::shared_ptr& border, const bool& isOutline); -}; - -class RSOutlineContent : public RSPropertyDrawableContent { -public: - RSOutlineContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSOutlineContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; - -class RSShadowContent : public RSPropertyDrawableContent { -public: - RSShadowContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSShadowContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; - -private: - static void DrawColorfulShadowInner(const RSProperties& properties, Drawing::Canvas& canvas, Drawing::Path& path); - static void DrawShadowInner(const RSProperties& properties, Drawing::Canvas& canvas, Drawing::Path& path); -}; - -class RSForegroundColorContent : public RSPropertyDrawableContent { -public: - RSForegroundColorContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSForegroundColorContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; - -class RSPixelStretchContent : public RSPropertyDrawableContent { -public: - RSPixelStretchContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSPixelStretchContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; - -class RSDynamicLightUpContent : public RSPropertyDrawableContent { -public: - RSDynamicLightUpContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSDynamicLightUpContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; - -private: - static std::shared_ptr dynamicLightUpBlenderEffect_; - - static std::shared_ptr MakeDynamicLightUpBlender(float dynamicLightUpRate, - float dynamicLightUpDeg); -}; - -class RSLightUpEffectContent : public RSPropertyDrawableContent { -public: - RSLightUpEffectContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSLightUpEffectContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; - -class RSColorFilterContent : public RSPropertyDrawableContent { -public: - RSColorFilterContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSColorFilterContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; - -class RSMaskContent : public RSPropertyDrawableContent { -public: - RSMaskContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSMaskContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; - -class RSBinarizationShaderContent : public RSPropertyDrawableContent { -public: - RSBinarizationShaderContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSBinarizationShaderContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; - -private: - static std::shared_ptr binarizationShaderEffect_; - - static std::shared_ptr MakeBinarizationShader(float low, float high, - float thresholdLow, float thresholdHigh, std::shared_ptr imageShader); -}; - -class RSParticleContent : public RSPropertyDrawableContent { -public: - RSParticleContent(std::shared_ptr&& drawCmdList) - : RSPropertyDrawableContent(std::move(drawCmdList)) - {} - RSParticleContent() : RSPropertyDrawableContent() - {} - static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node); - bool OnUpdate(const RSRenderNode& node) override; -}; -} // namespace OHOS::Rosen -#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_CONTENT_H diff --git a/rosen/modules/render_service_base/include/drawable/rs_drawable_utils.h b/rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h similarity index 93% rename from rosen/modules/render_service_base/include/drawable/rs_drawable_utils.h rename to rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h index 25517f82e6..3a37217ebf 100644 --- a/rosen/modules/render_service_base/include/drawable/rs_drawable_utils.h +++ b/rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h @@ -13,15 +13,15 @@ * limitations under the License. */ -#ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_UTILS_H -#define RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_UTILS_H +#ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_UTILS_H +#define RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_UTILS_H #include "platform/common/rs_log.h" #include "property/rs_properties.h" namespace OHOS { namespace Rosen { -class RSDrawableUtils { +class RSPropertyDrawableUtils { public: static Drawing::RoundRect RRect2DrawingRRect(const RRect& rr) { @@ -35,19 +35,19 @@ public: radii.at(i).SetX(rr.radius_[i].x_); radii.at(i).SetY(rr.radius_[i].y_); } - return Drawing::RoundRect(rect, radii); + return {rect, radii}; } static Drawing::Rect Rect2DrawingRect(const RectF& r) { - return Drawing::Rect(r.left_, r.top_, r.left_ + r.width_, r.top_ + r.height_); + return {r.left_, r.top_, r.left_ + r.width_, r.top_ + r.height_}; } static RRect GetRRectForDrawingBorder(const RSProperties& properties, const std::shared_ptr& border, const bool& isOutline) { if (!border) { - return RRect(); + return {}; } return isOutline ? @@ -59,7 +59,7 @@ public: const bool& isOutline) { if (!border) { - return RRect(); + return {}; } return isOutline ? properties.GetRRect() : properties.GetInnerRRect(); } @@ -77,7 +77,7 @@ public: auto& colorPickerTask = properties.GetColorPickerCacheTaskShadow(); if (!colorPickerTask) { - ROSEN_LOGE("RSDrawableUtils::PickColor colorPickerTask is null"); + ROSEN_LOGE("RSPropertyDrawableUtils::PickColor colorPickerTask is null"); return false; } colorPickerTask->SetIsShadow(true); @@ -174,4 +174,4 @@ public: } // namespace Rosen } // namespace OHOS -#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_UTILS_H +#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_UTILS_H diff --git a/rosen/modules/render_service_base/include/drawable/rs_utilities_drawable.h b/rosen/modules/render_service_base/include/drawable/rs_utilities_drawable.h new file mode 100644 index 0000000000..af2c2279a5 --- /dev/null +++ b/rosen/modules/render_service_base/include/drawable/rs_utilities_drawable.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_UTILITIES_DRAWABLE_H +#define RENDER_SERVICE_BASE_DRAWABLE_RS_UTILITIES_DRAWABLE_H + +#include +#include +#include +#include +#include + +#include "drawable/rs_drawable.h" +#include "modifier/rs_modifier_type.h" + +namespace OHOS::Rosen { +// RSChildrenDrawable, for drawing children of RSRenderNode, updates on child add/remove +class RSRenderNodeDrawableAdapter; +class RSChildrenDrawableContent : public RSDrawable { +public: + RSChildrenDrawableContent() = default; + ~RSChildrenDrawableContent() override = default; + + static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); + bool OnUpdate(const RSRenderNode& content) override; + void OnSync() override; + Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override; + +private: + bool needSync_ = false; + std::vector> childrenDrawables_; + std::vector> stagingChildrenDrawables_; + friend class RSChildrenDrawable; +}; + +// RSChildrenDrawable, for drawing custom modifiers +enum class RSModifierType : int16_t; +namespace Drawing { +class DrawCmdList; +} +class RSCustomModifierDrawableContent : public RSDrawable { +public: + RSCustomModifierDrawableContent(RSModifierType type) : type_(type) {} + static RSDrawable::Ptr OnGenerate(const RSRenderNode& content, RSModifierType type); + bool OnUpdate(const RSRenderNode& node) override; + void OnSync() override; + Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override; + +private: + RSModifierType type_; + + bool needSync_ = false; + std::vector> drawCmdList_; + std::vector> stagingDrawCmdList_; + friend class RSCustomModifierDrawable; +}; + +// Save/Restore + +// Clip + +// Alpha & restore + +} // namespace OHOS::Rosen +#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_UTILITIES_DRAWABLE_H diff --git a/rosen/modules/render_service_base/include/pipeline/rs_render_node.h b/rosen/modules/render_service_base/include/pipeline/rs_render_node.h index add9e17671..2cbfde165b 100644 --- a/rosen/modules/render_service_base/include/pipeline/rs_render_node.h +++ b/rosen/modules/render_service_base/include/pipeline/rs_render_node.h @@ -26,12 +26,15 @@ #include #include #include + #include "animation/rs_animation_manager.h" #include "animation/rs_frame_rate_range.h" #include "common/rs_common_def.h" #include "common/rs_macros.h" #include "common/rs_rect.h" -#include "drawable/rs_drawable_content.h" +#include "draw/surface.h" +#include "drawable/rs_drawable.h" +#include "image/gpu_context.h" #include "memory/rs_dfx_string.h" #include "modifier/rs_render_modifier.h" #include "params/rs_render_params.h" @@ -42,9 +45,6 @@ #include "pipeline/rs_single_frame_composer.h" #include "property/rs_properties.h" -#include "draw/surface.h" -#include "image/gpu_context.h" - namespace OHOS { namespace Rosen { namespace Drawing { @@ -656,7 +656,7 @@ private: std::shared_ptr displaySync_ = nullptr; uint8_t drawableVecStatus_ = 0; - void UpdateDrawableContentVec(); + void UpdateDrawableVec(); std::map> subSurfaceNodes_; pid_t appPid_ = 0; @@ -668,7 +668,7 @@ private: bool needSync_ = false; std::shared_ptr drawCmdList_; std::shared_ptr stagingDrawCmdList_; - RSDrawableContent::Vec contentVec_; + RSDrawable::Vec drawableVec_; std::unique_ptr renderParams_; std::unique_ptr stagingRenderParams_; @@ -676,7 +676,6 @@ private: void OnSync(); friend class DrawFuncOpItem; - friend class RSAliasDrawable; friend class RSContext; friend class RSMainThread; friend class RSModifierDrawable; diff --git a/rosen/modules/render_service_base/include/property/rs_properties.h b/rosen/modules/render_service_base/include/property/rs_properties.h index fb8f57fac0..01120331d2 100755 --- a/rosen/modules/render_service_base/include/property/rs_properties.h +++ b/rosen/modules/render_service_base/include/property/rs_properties.h @@ -45,9 +45,9 @@ namespace Rosen { class RSRenderNode; class RSObjAbsGeometry; class RSB_EXPORT RSProperties final { -friend class RSBackgroundImageContent; -friend class RSBackgroundFilterContent; -friend class RSShadowContent; +friend class RSBackgroundImageDrawable; +friend class RSBackgroundFilterDrawable; +friend class RSShadowDrawable; public: RSProperties(); RSProperties(const RSProperties&) = delete; diff --git a/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp b/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp new file mode 100644 index 0000000000..255c07f8ff --- /dev/null +++ b/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "drawable/rs_drawable.h" + +#include "drawable/rs_property_drawable.h" +#include "drawable/rs_utilities_drawable.h" +#include "pipeline/rs_render_node.h" + +namespace OHOS::Rosen { +namespace { +// NOTE: This LUT should always the same size and order as RSModifierType +// key = RSModifierType, value = RSDrawableSlot +constexpr int DIRTY_LUT_SIZE = static_cast(RSModifierType::MAX_RS_MODIFIER_TYPE); +static const std::array g_propertyToDrawableLut = { + RSDrawableSlot::INVALID, // INVALID + RSDrawableSlot::INVALID, // BOUNDS + RSDrawableSlot::FRAME_OFFSET, // FRAME + RSDrawableSlot::INVALID, // POSITION_Z + RSDrawableSlot::INVALID, // PIVOT + RSDrawableSlot::INVALID, // PIVOT_Z + RSDrawableSlot::INVALID, // QUATERNION + RSDrawableSlot::INVALID, // ROTATION + RSDrawableSlot::INVALID, // ROTATION_X + RSDrawableSlot::INVALID, // ROTATION_Y + RSDrawableSlot::INVALID, // CAMERA_DISTANCE + RSDrawableSlot::INVALID, // SCALE + RSDrawableSlot::INVALID, // SKEW + RSDrawableSlot::INVALID, // TRANSLATE + RSDrawableSlot::INVALID, // TRANSLATE_Z + RSDrawableSlot::INVALID, // SUBLAYER_TRANSFORM + RSDrawableSlot::INVALID, // CORNER_RADIUS + RSDrawableSlot::ALPHA, // ALPHA + RSDrawableSlot::ALPHA, // ALPHA_OFFSCREEN + RSDrawableSlot::FOREGROUND_COLOR, // FOREGROUND_COLOR + RSDrawableSlot::BACKGROUND_COLOR, // BACKGROUND_COLOR + RSDrawableSlot::BACKGROUND_SHADER, // BACKGROUND_SHADER + RSDrawableSlot::BACKGROUND_IMAGE, // BG_IMAGE + RSDrawableSlot::BACKGROUND_IMAGE, // BG_IMAGE_WIDTH + RSDrawableSlot::BACKGROUND_IMAGE, // BG_IMAGE_HEIGHT + RSDrawableSlot::BACKGROUND_IMAGE, // BG_IMAGE_POSITION_X + RSDrawableSlot::BACKGROUND_IMAGE, // BG_IMAGE_POSITION_Y + RSDrawableSlot::INVALID, // SURFACE_BG_COLOR + RSDrawableSlot::BORDER, // BORDER_COLOR + RSDrawableSlot::BORDER, // BORDER_WIDTH + RSDrawableSlot::BORDER, // BORDER_STYLE + RSDrawableSlot::FOREGROUND_FILTER, // FILTER + RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_FILTER + RSDrawableSlot::FOREGROUND_FILTER, // LINEAR_GRADIENT_BLUR_PARA + RSDrawableSlot::DYNAMIC_LIGHT_UP, // DYNAMIC_LIGHT_UP_RATE + RSDrawableSlot::DYNAMIC_LIGHT_UP, // DYNAMIC_LIGHT_UP_DEGREE + RSDrawableSlot::FRAME_OFFSET, // FRAME_GRAVITY + RSDrawableSlot::CLIP_TO_BOUNDS, // CLIP_RRECT + RSDrawableSlot::CLIP_TO_BOUNDS, // CLIP_BOUNDS + RSDrawableSlot::CLIP_TO_BOUNDS, // CLIP_TO_BOUNDS + RSDrawableSlot::CLIP_TO_FRAME, // CLIP_TO_FRAME + RSDrawableSlot::INVALID, // VISIBLE + RSDrawableSlot::SHADOW, // SHADOW_COLOR + RSDrawableSlot::SHADOW, // SHADOW_OFFSET_X + RSDrawableSlot::SHADOW, // SHADOW_OFFSET_Y + RSDrawableSlot::SHADOW, // SHADOW_ALPHA + RSDrawableSlot::SHADOW, // SHADOW_ELEVATION + RSDrawableSlot::SHADOW, // SHADOW_RADIUS + RSDrawableSlot::SHADOW, // SHADOW_PATH + RSDrawableSlot::SHADOW, // SHADOW_MASK + RSDrawableSlot::SHADOW, // SHADOW_COLOR_STRATEGY + RSDrawableSlot::MASK, // MASK + RSDrawableSlot::INVALID, // SPHERIZE + RSDrawableSlot::LIGHT_UP_EFFECT, // LIGHT_UP_EFFECT + RSDrawableSlot::PIXEL_STRETCH, // PIXEL_STRETCH + RSDrawableSlot::PIXEL_STRETCH, // PIXEL_STRETCH_PERCENT + RSDrawableSlot::USE_EFFECT, // USE_EFFECT + RSDrawableSlot::BLEND_MODE, // COLOR_BLEND_MODE + RSDrawableSlot::BLEND_MODE, // COLOR_BLEND_APPLY_TYPE + RSDrawableSlot::INVALID, // SANDBOX + RSDrawableSlot::COLOR_FILTER, // GRAY_SCALE + RSDrawableSlot::COLOR_FILTER, // BRIGHTNESS + RSDrawableSlot::COLOR_FILTER, // CONTRAST + RSDrawableSlot::COLOR_FILTER, // SATURATE + RSDrawableSlot::COLOR_FILTER, // SEPIA + RSDrawableSlot::COLOR_FILTER, // INVERT + RSDrawableSlot::BINARIZATION, // AIINVERT + RSDrawableSlot::BACKGROUND_FILTER, // SYSTEMBAREFFECT + RSDrawableSlot::COLOR_FILTER, // HUE_ROTATE + RSDrawableSlot::COLOR_FILTER, // COLOR_BLEND + RSDrawableSlot::PARTICLE_EFFECT, // PARTICLE + RSDrawableSlot::INVALID, // SHADOW_IS_FILLED + RSDrawableSlot::OUTLINE, // OUTLINE_COLOR + RSDrawableSlot::OUTLINE, // OUTLINE_WIDTH + RSDrawableSlot::OUTLINE, // OUTLINE_STYLE + RSDrawableSlot::OUTLINE, // OUTLINE_RADIUS + RSDrawableSlot::INVALID, // USE_SHADOW_BATCHING + RSDrawableSlot::INVALID, // GREY_COEF1 + RSDrawableSlot::INVALID, // GREY_COEF2 + RSDrawableSlot::POINT_LIGHT, // LIGHT_INTENSITY + RSDrawableSlot::POINT_LIGHT, // LIGHT_POSITION + RSDrawableSlot::POINT_LIGHT, // ILLUMINATED_BORDER_WIDTH + RSDrawableSlot::POINT_LIGHT, // ILLUMINATED_TYPE + RSDrawableSlot::POINT_LIGHT, // BLOOM + RSDrawableSlot::INVALID, // CUSTOM + RSDrawableSlot::INVALID, // EXTENDED + RSDrawableSlot::TRANSITION, // TRANSITION + RSDrawableSlot::BACKGROUND_STYLE, // BACKGROUND_STYLE + RSDrawableSlot::CONTENT_STYLE, // CONTENT_STYLE + RSDrawableSlot::FOREGROUND_STYLE, // FOREGROUND_STYLE + RSDrawableSlot::OVERLAY, // OVERLAY_STYLE + RSDrawableSlot::INVALID, // NODE_MODIFIER + RSDrawableSlot::ENV_FOREGROUND_COLOR, // ENV_FOREGROUND_COLOR + RSDrawableSlot::ENV_FOREGROUND_COLOR_STRATEGY, // ENV_FOREGROUND_COLOR_STRATEGY + RSDrawableSlot::INVALID, // GEOMETRYTRANS +}; + +template +static inline RSDrawable::Ptr ModifierGenerator(const RSRenderNode& node) +{ + return RSCustomModifierDrawableContent::OnGenerate(node, type); +} + +// NOTE: This LUT should always the same size as RSDrawableSlot +// index = RSDrawableSlotType, value = DrawableGenerator +constexpr int GEN_LUT_SIZE = static_cast(RSDrawableSlot::MAX); +static const std::array g_drawableGeneratorLut = { + // Bounds Geometry + nullptr, // ALPHA, + nullptr, // MASK, + ModifierGenerator, // TRANSITION, + ModifierGenerator, // ENV_FOREGROUND_COLOR, + nullptr, // SHADOW, + nullptr, // OUTLINE, + + // BG properties in Bounds Clip + nullptr, // BG_SAVE_BOUNDS, + nullptr, // CLIP_TO_BOUNDS, + nullptr, // BLEND_MODE, + RSBackgroundColorDrawable::OnGenerate, // BACKGROUND_COLOR, + RSBackgroundShaderDrawable::OnGenerate, // BACKGROUND_SHADER, + RSBackgroundImageDrawable::OnGenerate, // BACKGROUND_IMAGE, + RSBackgroundFilterDrawable::OnGenerate, // BACKGROUND_FILTER, + nullptr, // USE_EFFECT, + ModifierGenerator, // BACKGROUND_STYLE, + RSDynamicLightUpDrawable::OnGenerate, // DYNAMIC_LIGHT_UP, + ModifierGenerator, // ENV_FOREGROUND_COLOR_STRATEGY, + nullptr, // BG_RESTORE_BOUNDS, + + // Frame Geometry + nullptr, // SAVE_FRAME, + nullptr, // FRAME_OFFSET, + nullptr, // CLIP_TO_FRAME, + ModifierGenerator, // CONTENT_STYLE, + RSChildrenDrawableContent::OnGenerate, // CHILDREN, + ModifierGenerator, // FOREGROUND_STYLE, + nullptr, // RESTORE_FRAME, + + // FG properties in Bounds clip + nullptr, // FG_SAVE_BOUNDS, + nullptr, // FG_CLIP_TO_BOUNDS, + RSBinarizationDrawable::OnGenerate, // BINARIZATION, + RSColorFilterDrawable::OnGenerate, // COLOR_FILTER, + RSLightUpEffectDrawable::OnGenerate, // LIGHT_UP_EFFECT, + nullptr, // FOREGROUND_FILTER, + RSForegroundColorDrawable::OnGenerate, // FOREGROUND_COLOR, + nullptr, // FG_RESTORE_BOUNDS, + + // No clip (unless ClipToBounds is set) + nullptr, // POINT_LIGHT, + RSBorderDrawable::OnGenerate, // BORDER, + ModifierGenerator, // OVERLAY, + RSParticleDrawable::OnGenerate, // PARTICLE_EFFECT, + RSPixelStretchDrawable::OnGenerate, // PIXEL_STRETCH, + + // Restore state + nullptr, // RESTORE_BLEND_MODE, + nullptr, // RESTORE_ALPHA, +}; + +inline std::pair GenerateSaveRestore( + RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::kCanvas) +{ + // if (type == RSPaintFilterCanvas::kNone) { + // return {}; + // } else if (type == RSPaintFilterCanvas::kCanvas) { + // auto count = std::make_shared(-1); + // return { std::make_unique(count), std::make_unique(count) }; + // } else { + // auto status = std::make_shared(); + // return { std::make_unique(status, type), + // std::make_unique(status) }; + // } + return {}; +} + +inline void SaveRestoreHelper(RSDrawable::Vec& drawableVec, RSDrawableSlot slot1, + RSDrawableSlot slot2, RSPaintFilterCanvas::SaveType saveType) +{ + std::tie(drawableVec[static_cast(slot1)], drawableVec[static_cast(slot2)]) = + GenerateSaveRestore(saveType); +} +} // namespace + +// ==================== RSDrawable ===================== +std::unordered_set RSDrawable::CalculateDirtySlots( + ModifierDirtyTypes& dirtyTypes, const Vec& drawableVec) +{ + if (dirtyTypes.none()) { + return {}; + } + + // calculate dirty slots by looking up g_propertyToDrawableLut + std::unordered_set dirtySlots; + for (size_t type = 0; type < static_cast(RSModifierType::MAX_RS_MODIFIER_TYPE); type++) { + if (!dirtyTypes.test(type)) { + continue; + } + auto dirtySlot = g_propertyToDrawableLut[type]; + if (dirtySlot != RSDrawableSlot::INVALID) { + dirtySlots.emplace(dirtySlot); + } + } + + // if bounds changed, every existing drawable needs to be updated + if (dirtyTypes.test(static_cast(RSModifierType::BOUNDS))) { + for (size_t i = 0; i < drawableVec.size(); i++) { + if (drawableVec[i]) { + dirtySlots.emplace(static_cast(i)); + } + } + } + + return dirtySlots; +} + +bool RSDrawable::UpdateDirtySlots( + const RSRenderNode& node, Vec& drawableVec, std::unordered_set& dirtySlots) +{ + // Update or generate all dirty slots + bool drawableAddedOrRemoved = false; + for (const auto& slot : dirtySlots) { + if (auto& drawable = drawableVec[static_cast(slot)]) { + // If the slot is already created, call OnUpdate + if (!drawable->OnUpdate(node)) { + // If the slot is no longer needed, destroy it + drawable.reset(); + drawableAddedOrRemoved = true; + } + } else if (auto& generator = g_drawableGeneratorLut[static_cast(slot)]) { + // If the slot is not created, call OnGenerate + if (auto drawable = generator(node)) { + drawableVec[static_cast(slot)] = std::move(drawable); + drawableAddedOrRemoved = true; + } + } + } + + return drawableAddedOrRemoved; +} + +namespace { +enum DrawableVecStatus : uint8_t { + CLIP_TO_BOUNDS = 1 << 0, + BG_BOUNDS_PROPERTY = 1 << 1, + FG_BOUNDS_PROPERTY = 1 << 2, + CLIP_TO_FRAME = 1 << 3, + FRAME_PROPERTY = 1 << 4, + HAS_CHILDREN = 1 << 5, + BOUNDS_MASK = CLIP_TO_BOUNDS | BG_BOUNDS_PROPERTY | FG_BOUNDS_PROPERTY, + FRAME_MASK = CLIP_TO_FRAME | FRAME_PROPERTY | HAS_CHILDREN, +}; + +inline bool HasPropertyDrawableInRange( + const RSDrawable::Vec& drawableVec, RSDrawableSlot begin, RSDrawableSlot end) +{ + return std::any_of(drawableVec.begin() + static_cast(begin), drawableVec.begin() + static_cast(end), + [](const auto& Ptr) { return Ptr != nullptr; }); +} + +uint8_t CalculateDrawableVecStatus(RSRenderContent& content, const RSDrawable::Vec& drawableVec) +{ + uint8_t result = 0; + auto& properties = content.GetRenderProperties(); + + // color blend mode has implicit dependency on clipToBounds + if (properties.GetClipToBounds() || properties.GetClipToRRect() || properties.GetClipBounds() != nullptr || + properties.GetColorBlendMode()) { + result |= DrawableVecStatus::CLIP_TO_BOUNDS; + } + if (properties.GetClipToFrame()) { + result |= DrawableVecStatus::CLIP_TO_FRAME; + } + + if (HasPropertyDrawableInRange( + drawableVec, RSDrawableSlot::BG_PROPERTIES_BEGIN, RSDrawableSlot::BG_PROPERTIES_END)) { + result |= DrawableVecStatus::BG_BOUNDS_PROPERTY; + } + if (HasPropertyDrawableInRange( + drawableVec, RSDrawableSlot::FG_PROPERTIES_BEGIN, RSDrawableSlot::FG_PROPERTIES_END)) { + result |= DrawableVecStatus::FG_BOUNDS_PROPERTY; + } + if (HasPropertyDrawableInRange(drawableVec, RSDrawableSlot::CONTENT_PROPERTIES_BEGIN, + RSDrawableSlot::CONTENT_PROPERTIES_END)) { + result |= DrawableVecStatus::FRAME_PROPERTY; + } + + return result; +} + +constexpr std::array boundsSlotsToErase = { + RSDrawableSlot::BG_SAVE_BOUNDS, + RSDrawableSlot::CLIP_TO_BOUNDS, + RSDrawableSlot::BG_RESTORE_BOUNDS, + RSDrawableSlot::FG_SAVE_BOUNDS, + RSDrawableSlot::FG_CLIP_TO_BOUNDS, + RSDrawableSlot::FG_RESTORE_BOUNDS, +}; + +constexpr std::array frameSlotsToErase = { + RSDrawableSlot::SAVE_FRAME, + RSDrawableSlot::RESTORE_FRAME, +}; + +void OptimizeBoundsSaveRestore(RSRenderContent& content, RSDrawable::Vec& drawableVec, uint8_t flags) +{ + // Erase existing save/clip/restore before re-generating + for (auto& slot : boundsSlotsToErase) { + drawableVec[static_cast(slot)] = nullptr; + } + + // if (flags & DrawableVecStatus::CLIP_TO_BOUNDS) { + // // case 1: ClipToBounds set. + // // add one clip, and reuse SAVE_ALL and RESTORE_ALL. + // drawableVec[static_cast(RSDrawableSlot::CLIP_TO_BOUNDS)] = + // RSClipBoundsDrawable::Generate(content); + // return; + // } + + // if ((flags & DrawableVecStatus::BG_BOUNDS_PROPERTY) && (flags & DrawableVecStatus::FG_BOUNDS_PROPERTY)) { + // // case 2: ClipToBounds not set and we have bounds properties both BG and FG. + // // add two sets of save/clip/restore before & after content. + + // // part 1: before children + // SaveRestoreHelper(drawableVec, RSDrawableSlot::BG_SAVE_BOUNDS, + // RSDrawableSlot::BG_RESTORE_BOUNDS, RSPaintFilterCanvas::kCanvas); + // drawableVec[static_cast(RSDrawableSlot::CLIP_TO_BOUNDS)] = + // RSClipBoundsDrawable::Generate(content); + + // // part 2: after children, add aliases + // drawableVec[static_cast(RSDrawableSlot::FG_SAVE_BOUNDS)] = + // GenerateAlias(RSDrawableSlot::BG_SAVE_BOUNDS); + // drawableVec[static_cast(RSDrawableSlot::FG_CLIP_TO_BOUNDS)] = + // GenerateAlias(RSDrawableSlot::CLIP_TO_BOUNDS); + // drawableVec[static_cast(RSDrawableSlot::FG_RESTORE_BOUNDS)] = + // GenerateAlias(RSDrawableSlot::BG_RESTORE_BOUNDS); + // return; + // } + + // if (flags & DrawableVecStatus::BG_BOUNDS_PROPERTY) { + // // case 3: ClipToBounds not set and we have background bounds properties. + // SaveRestoreHelper(drawableVec, RSDrawableSlot::BG_SAVE_BOUNDS, + // RSDrawableSlot::BG_RESTORE_BOUNDS, RSPaintFilterCanvas::kCanvas); + + // drawableVec[static_cast(RSDrawableSlot::CLIP_TO_BOUNDS)] = + // RSClipBoundsDrawable::Generate(content); + // return; + // } + + // if (flags & DrawableVecStatus::FG_BOUNDS_PROPERTY) { + // // case 4: ClipToBounds not set and we have foreground bounds properties. + // SaveRestoreHelper(drawableVec, RSDrawableSlot::FG_SAVE_BOUNDS, + // RSDrawableSlot::FG_RESTORE_BOUNDS, RSPaintFilterCanvas::kCanvas); + + // drawableVec[static_cast(RSDrawableSlot::FG_CLIP_TO_BOUNDS)] = + // RSClipBoundsDrawable::Generate(content); + // return; + // } + // case 5: ClipToBounds not set and no bounds properties, no need to save/clip/restore. + // nothing to do +} + +void OptimizeFrameSaveRestore(RSRenderContent& content, RSDrawable::Vec& drawableVec, uint8_t flags) +{ + // Erase existing save/clip/restore before re-generating + for (auto& slot : frameSlotsToErase) { + drawableVec[static_cast(slot)] = nullptr; + } + + // PLANNING: if both clipToFrame and clipToBounds are set, and frame == bounds, we don't need an extra clip + if (flags & DrawableVecStatus::FRAME_PROPERTY) { + // save/restore + SaveRestoreHelper(drawableVec, RSDrawableSlot::SAVE_FRAME, + RSDrawableSlot::RESTORE_FRAME, RSPaintFilterCanvas::kCanvas); + } else { + // no need to save/clip/restore + } +} +} // namespace + +void RSDrawable::UpdateSaveRestore(RSRenderContent& content, Vec& drawableVec, uint8_t& drawableVecStatus) +{ + // ==================================================================== + // Step 3: Universal save/clip/restore optimization + + // calculate new drawable map status + auto drawableVecStatusNew = CalculateDrawableVecStatus(content, drawableVec); + + // calculate changed bits + uint8_t changedBits = drawableVecStatus ^ drawableVecStatusNew; + if (changedBits & BOUNDS_MASK) { + // update bounds save/clip if need + OptimizeBoundsSaveRestore(content, drawableVec, drawableVecStatusNew); + } + if (changedBits & FRAME_MASK) { + // update frame save/clip if need + OptimizeFrameSaveRestore(content, drawableVec, drawableVecStatusNew); + } + drawableVecStatus = drawableVecStatusNew; +} +} // namespace OHOS::Rosen diff --git a/rosen/modules/render_service_base/src/drawable/rs_drawable_content.cpp b/rosen/modules/render_service_base/src/drawable/rs_drawable_content.cpp deleted file mode 100644 index 7c76a857d4..0000000000 --- a/rosen/modules/render_service_base/src/drawable/rs_drawable_content.cpp +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright (c) 2024 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "drawable/rs_drawable_content.h" - -#include "drawable/rs_property_drawable_content.h" -#include "drawable/rs_render_node_drawable_adapter.h" -#include "pipeline/rs_render_node.h" - -namespace OHOS::Rosen { -namespace { -// NOTE: This LUT should always the same size and order as RSModifierType -// key = RSModifierType, value = RSDrawableContentSlot -constexpr int DIRTY_LUT_SIZE = static_cast(RSModifierType::MAX_RS_MODIFIER_TYPE); -static const std::array g_propertyToDrawableLut = { - RSDrawableContentSlot::INVALID, // INVALID - RSDrawableContentSlot::INVALID, // BOUNDS - RSDrawableContentSlot::FRAME_OFFSET, // FRAME - RSDrawableContentSlot::INVALID, // POSITION_Z - RSDrawableContentSlot::INVALID, // PIVOT - RSDrawableContentSlot::INVALID, // PIVOT_Z - RSDrawableContentSlot::INVALID, // QUATERNION - RSDrawableContentSlot::INVALID, // ROTATION - RSDrawableContentSlot::INVALID, // ROTATION_X - RSDrawableContentSlot::INVALID, // ROTATION_Y - RSDrawableContentSlot::INVALID, // CAMERA_DISTANCE - RSDrawableContentSlot::INVALID, // SCALE - RSDrawableContentSlot::INVALID, // SKEW - RSDrawableContentSlot::INVALID, // TRANSLATE - RSDrawableContentSlot::INVALID, // TRANSLATE_Z - RSDrawableContentSlot::INVALID, // SUBLAYER_TRANSFORM - RSDrawableContentSlot::INVALID, // CORNER_RADIUS - RSDrawableContentSlot::ALPHA, // ALPHA - RSDrawableContentSlot::ALPHA, // ALPHA_OFFSCREEN - RSDrawableContentSlot::FOREGROUND_COLOR, // FOREGROUND_COLOR - RSDrawableContentSlot::BACKGROUND_COLOR, // BACKGROUND_COLOR - RSDrawableContentSlot::BACKGROUND_SHADER, // BACKGROUND_SHADER - RSDrawableContentSlot::BACKGROUND_IMAGE, // BG_IMAGE - RSDrawableContentSlot::BACKGROUND_IMAGE, // BG_IMAGE_WIDTH - RSDrawableContentSlot::BACKGROUND_IMAGE, // BG_IMAGE_HEIGHT - RSDrawableContentSlot::BACKGROUND_IMAGE, // BG_IMAGE_POSITION_X - RSDrawableContentSlot::BACKGROUND_IMAGE, // BG_IMAGE_POSITION_Y - RSDrawableContentSlot::INVALID, // SURFACE_BG_COLOR - RSDrawableContentSlot::BORDER, // BORDER_COLOR - RSDrawableContentSlot::BORDER, // BORDER_WIDTH - RSDrawableContentSlot::BORDER, // BORDER_STYLE - RSDrawableContentSlot::FOREGROUND_FILTER, // FILTER - RSDrawableContentSlot::BACKGROUND_FILTER, // BACKGROUND_FILTER - RSDrawableContentSlot::FOREGROUND_FILTER, // LINEAR_GRADIENT_BLUR_PARA - RSDrawableContentSlot::DYNAMIC_LIGHT_UP, // DYNAMIC_LIGHT_UP_RATE - RSDrawableContentSlot::DYNAMIC_LIGHT_UP, // DYNAMIC_LIGHT_UP_DEGREE - RSDrawableContentSlot::FRAME_OFFSET, // FRAME_GRAVITY - RSDrawableContentSlot::CLIP_TO_BOUNDS, // CLIP_RRECT - RSDrawableContentSlot::CLIP_TO_BOUNDS, // CLIP_BOUNDS - RSDrawableContentSlot::CLIP_TO_BOUNDS, // CLIP_TO_BOUNDS - RSDrawableContentSlot::CLIP_TO_FRAME, // CLIP_TO_FRAME - RSDrawableContentSlot::INVALID, // VISIBLE - RSDrawableContentSlot::SHADOW, // SHADOW_COLOR - RSDrawableContentSlot::SHADOW, // SHADOW_OFFSET_X - RSDrawableContentSlot::SHADOW, // SHADOW_OFFSET_Y - RSDrawableContentSlot::SHADOW, // SHADOW_ALPHA - RSDrawableContentSlot::SHADOW, // SHADOW_ELEVATION - RSDrawableContentSlot::SHADOW, // SHADOW_RADIUS - RSDrawableContentSlot::SHADOW, // SHADOW_PATH - RSDrawableContentSlot::SHADOW, // SHADOW_MASK - RSDrawableContentSlot::SHADOW, // SHADOW_COLOR_STRATEGY - RSDrawableContentSlot::MASK, // MASK - RSDrawableContentSlot::INVALID, // SPHERIZE - RSDrawableContentSlot::LIGHT_UP_EFFECT, // LIGHT_UP_EFFECT - RSDrawableContentSlot::PIXEL_STRETCH, // PIXEL_STRETCH - RSDrawableContentSlot::PIXEL_STRETCH, // PIXEL_STRETCH_PERCENT - RSDrawableContentSlot::USE_EFFECT, // USE_EFFECT - RSDrawableContentSlot::BLEND_MODE, // COLOR_BLEND_MODE - RSDrawableContentSlot::BLEND_MODE, // COLOR_BLEND_APPLY_TYPE - RSDrawableContentSlot::INVALID, // SANDBOX - RSDrawableContentSlot::COLOR_FILTER, // GRAY_SCALE - RSDrawableContentSlot::COLOR_FILTER, // BRIGHTNESS - RSDrawableContentSlot::COLOR_FILTER, // CONTRAST - RSDrawableContentSlot::COLOR_FILTER, // SATURATE - RSDrawableContentSlot::COLOR_FILTER, // SEPIA - RSDrawableContentSlot::COLOR_FILTER, // INVERT - RSDrawableContentSlot::BINARIZATION, // AIINVERT - RSDrawableContentSlot::BACKGROUND_FILTER, // SYSTEMBAREFFECT - RSDrawableContentSlot::COLOR_FILTER, // HUE_ROTATE - RSDrawableContentSlot::COLOR_FILTER, // COLOR_BLEND - RSDrawableContentSlot::PARTICLE_EFFECT, // PARTICLE - RSDrawableContentSlot::INVALID, // SHADOW_IS_FILLED - RSDrawableContentSlot::OUTLINE, // OUTLINE_COLOR - RSDrawableContentSlot::OUTLINE, // OUTLINE_WIDTH - RSDrawableContentSlot::OUTLINE, // OUTLINE_STYLE - RSDrawableContentSlot::OUTLINE, // OUTLINE_RADIUS - RSDrawableContentSlot::INVALID, // USE_SHADOW_BATCHING - RSDrawableContentSlot::INVALID, // GREY_COEF1 - RSDrawableContentSlot::INVALID, // GREY_COEF2 - RSDrawableContentSlot::POINT_LIGHT, // LIGHT_INTENSITY - RSDrawableContentSlot::POINT_LIGHT, // LIGHT_POSITION - RSDrawableContentSlot::POINT_LIGHT, // ILLUMINATED_BORDER_WIDTH - RSDrawableContentSlot::POINT_LIGHT, // ILLUMINATED_TYPE - RSDrawableContentSlot::POINT_LIGHT, // BLOOM - RSDrawableContentSlot::INVALID, // CUSTOM - RSDrawableContentSlot::INVALID, // EXTENDED - RSDrawableContentSlot::TRANSITION, // TRANSITION - RSDrawableContentSlot::BACKGROUND_STYLE, // BACKGROUND_STYLE - RSDrawableContentSlot::CONTENT_STYLE, // CONTENT_STYLE - RSDrawableContentSlot::FOREGROUND_STYLE, // FOREGROUND_STYLE - RSDrawableContentSlot::OVERLAY, // OVERLAY_STYLE - RSDrawableContentSlot::INVALID, // NODE_MODIFIER - RSDrawableContentSlot::ENV_FOREGROUND_COLOR, // ENV_FOREGROUND_COLOR - RSDrawableContentSlot::ENV_FOREGROUND_COLOR_STRATEGY, // ENV_FOREGROUND_COLOR_STRATEGY - RSDrawableContentSlot::INVALID, // GEOMETRYTRANS -}; - -template -static inline RSDrawableContent::Ptr ModifierGenerator(const RSRenderNode& node) -{ - return RSCustomModifierDrawableContent::OnGenerate(node, type); -} - -// NOTE: This LUT should always the same size as RSDrawableContentSlot -// index = RSDrawableContentSlotType, value = DrawableGenerator -constexpr int GEN_LUT_SIZE = static_cast(RSDrawableContentSlot::MAX); -static const std::array g_drawableGeneratorLut = { - nullptr, // INVALID = 0, - - // Bounds Geometry - nullptr, // BOUNDS_MATRIX, - nullptr, // ALPHA, - nullptr, // MASK, - ModifierGenerator, // TRANSITION, - ModifierGenerator, // ENV_FOREGROUND_COLOR, - nullptr, // SHADOW, - nullptr, // OUTLINE, - - // BG properties in Bounds Clip - nullptr, // BG_SAVE_BOUNDS, - nullptr, // CLIP_TO_BOUNDS, - nullptr, // BLEND_MODE, - RSBackgroundColorContent::OnGenerate, // BACKGROUND_COLOR, - RSBackgroundShaderContent::OnGenerate, // BACKGROUND_SHADER, - RSBackgroundImageContent::OnGenerate, // BACKGROUND_IMAGE, - RSBackgroundFilterContent::OnGenerate, // BACKGROUND_FILTER, - nullptr, // USE_EFFECT, - ModifierGenerator, // BACKGROUND_STYLE, - RSDynamicLightUpContent::OnGenerate, // DYNAMIC_LIGHT_UP, - ModifierGenerator, // ENV_FOREGROUND_COLOR_STRATEGY, - nullptr, // BG_RESTORE_BOUNDS, - - // Frame Geometry - nullptr, // SAVE_FRAME, - nullptr, // FRAME_OFFSET, - nullptr, // CLIP_TO_FRAME, - ModifierGenerator, // CONTENT_STYLE, - RSChildrenDrawableContent::OnGenerate, // CHILDREN, - ModifierGenerator, // FOREGROUND_STYLE, - nullptr, // RESTORE_FRAME, - - // FG properties in Bounds clip - nullptr, // FG_SAVE_BOUNDS, - nullptr, // FG_CLIP_TO_BOUNDS, - RSBinarizationShaderContent::OnGenerate, // BINARIZATION, - RSColorFilterContent::OnGenerate, // COLOR_FILTER, - RSLightUpEffectContent::OnGenerate, // LIGHT_UP_EFFECT, - nullptr, // FOREGROUND_FILTER, - RSForegroundColorContent::OnGenerate, // FOREGROUND_COLOR, - nullptr, // FG_RESTORE_BOUNDS, - - // No clip (unless ClipToBounds is set) - nullptr, // POINT_LIGHT, - RSBorderContent::OnGenerate, // BORDER, - ModifierGenerator, // OVERLAY, - RSParticleContent::OnGenerate, // PARTICLE_EFFECT, - RSPixelStretchContent::OnGenerate, // PIXEL_STRETCH, - - nullptr, // RESTORE_BLEND_MODE, -}; - -inline std::pair GenerateSaveRestore( - RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::kCanvas) -{ - // if (type == RSPaintFilterCanvas::kNone) { - // return {}; - // } else if (type == RSPaintFilterCanvas::kCanvas) { - // auto count = std::make_shared(-1); - // return { std::make_unique(count), std::make_unique(count) }; - // } else { - // auto status = std::make_shared(); - // return { std::make_unique(status, type), - // std::make_unique(status) }; - // } - return {}; -} - -inline void SaveRestoreHelper(RSDrawableContent::Vec& drawableVec, RSDrawableContentSlot slot1, - RSDrawableContentSlot slot2, RSPaintFilterCanvas::SaveType saveType) -{ - std::tie(drawableVec[static_cast(slot1)], drawableVec[static_cast(slot2)]) = - GenerateSaveRestore(saveType); -} -} // namespace - -// ==================== RSDrawableContent ===================== -std::unordered_set RSDrawableContent::CalculateDirtySlots( - ModifierDirtyTypes& dirtyTypes, const Vec& drawableVec) -{ - if (dirtyTypes.none()) { - return {}; - } - - std::unordered_set dirtySlots; - for (size_t type = 0; type < static_cast(RSModifierType::MAX_RS_MODIFIER_TYPE); type++) { - if (!dirtyTypes.test(type)) { - continue; - } - auto dirtySlot = g_propertyToDrawableLut[type]; - if (dirtySlot != RSDrawableContentSlot::INVALID) { - dirtySlots.emplace(dirtySlot); - } - } - - // if bounds changed, every existing drawable needs to be updated - if (dirtyTypes.test(static_cast(RSModifierType::BOUNDS))) { - for (size_t i = 0; i < drawableVec.size(); i++) { - if (drawableVec[i]) { - dirtySlots.emplace(static_cast(i)); - } - } - } - - return dirtySlots; -} - -bool RSDrawableContent::UpdateDirtySlots( - const RSRenderNode& node, Vec& drawableVec, std::unordered_set& dirtySlots) -{ - bool drawableAddedOrRemoved = false; - for (const auto& slot : dirtySlots) { - if (auto& drawable = drawableVec[static_cast(slot)]) { - // If the slot is already created, call OnUpdate - if (!drawable->OnUpdate(node)) { - // If the slot is no longer needed, destroy it - drawable.reset(); - drawableAddedOrRemoved = true; - } - } else if (auto& generator = g_drawableGeneratorLut[static_cast(slot)]) { - // If the slot is not created, call OnGenerate - if (auto drawable = generator(node)) { - drawableVec[static_cast(slot)] = std::move(drawable); - drawableAddedOrRemoved = true; - } - } - } - - return drawableAddedOrRemoved; -} - -namespace { -enum DrawableVecStatus : uint8_t { - CLIP_TO_BOUNDS = 1 << 0, - BG_BOUNDS_PROPERTY = 1 << 1, - FG_BOUNDS_PROPERTY = 1 << 2, - CLIP_TO_FRAME = 1 << 3, - FRAME_PROPERTY = 1 << 4, - HAS_CHILDREN = 1 << 5, - BOUNDS_MASK = CLIP_TO_BOUNDS | BG_BOUNDS_PROPERTY | FG_BOUNDS_PROPERTY, - FRAME_MASK = CLIP_TO_FRAME | FRAME_PROPERTY | HAS_CHILDREN, -}; - -inline bool HasPropertyDrawableInRange( - const RSDrawableContent::Vec& drawableVec, RSDrawableContentSlot begin, RSDrawableContentSlot end) -{ - return std::any_of(drawableVec.begin() + static_cast(begin), drawableVec.begin() + static_cast(end), - [](const auto& Ptr) { return Ptr != nullptr; }); -} - -uint8_t CalculateDrawableVecStatus(RSRenderContent& content, const RSDrawableContent::Vec& drawableVec) -{ - uint8_t result = 0; - auto& properties = content.GetRenderProperties(); - - // color blend mode has implicit dependency on clipToBounds - if (properties.GetClipToBounds() || properties.GetClipToRRect() || properties.GetClipBounds() != nullptr || - properties.GetColorBlendMode()) { - result |= DrawableVecStatus::CLIP_TO_BOUNDS; - } - if (properties.GetClipToFrame()) { - result |= DrawableVecStatus::CLIP_TO_FRAME; - } - - if (HasPropertyDrawableInRange( - drawableVec, RSDrawableContentSlot::BG_PROPERTIES_BEGIN, RSDrawableContentSlot::BG_PROPERTIES_END)) { - result |= DrawableVecStatus::BG_BOUNDS_PROPERTY; - } - if (HasPropertyDrawableInRange( - drawableVec, RSDrawableContentSlot::FG_PROPERTIES_BEGIN, RSDrawableContentSlot::FG_PROPERTIES_END)) { - result |= DrawableVecStatus::FG_BOUNDS_PROPERTY; - } - if (HasPropertyDrawableInRange(drawableVec, RSDrawableContentSlot::CONTENT_PROPERTIES_BEGIN, - RSDrawableContentSlot::CONTENT_PROPERTIES_END)) { - result |= DrawableVecStatus::FRAME_PROPERTY; - } - - return result; -} - -constexpr std::array boundsSlotsToErase = { - RSDrawableContentSlot::BG_SAVE_BOUNDS, - RSDrawableContentSlot::CLIP_TO_BOUNDS, - RSDrawableContentSlot::BG_RESTORE_BOUNDS, - RSDrawableContentSlot::FG_SAVE_BOUNDS, - RSDrawableContentSlot::FG_CLIP_TO_BOUNDS, - RSDrawableContentSlot::FG_RESTORE_BOUNDS, -}; - -constexpr std::array frameSlotsToErase = { - RSDrawableContentSlot::SAVE_FRAME, - RSDrawableContentSlot::RESTORE_FRAME, -}; - -void OptimizeBoundsSaveRestore(RSRenderContent& content, RSDrawableContent::Vec& drawableVec, uint8_t flags) -{ - // Erase existing save/clip/restore before re-generating - for (auto& slot : boundsSlotsToErase) { - drawableVec[static_cast(slot)] = nullptr; - } - - // if (flags & DrawableVecStatus::CLIP_TO_BOUNDS) { - // // case 1: ClipToBounds set. - // // add one clip, and reuse SAVE_ALL and RESTORE_ALL. - // drawableVec[static_cast(RSDrawableContentSlot::CLIP_TO_BOUNDS)] = - // RSClipBoundsDrawable::Generate(content); - // return; - // } - - // if ((flags & DrawableVecStatus::BG_BOUNDS_PROPERTY) && (flags & DrawableVecStatus::FG_BOUNDS_PROPERTY)) { - // // case 2: ClipToBounds not set and we have bounds properties both BG and FG. - // // add two sets of save/clip/restore before & after content. - - // // part 1: before children - // SaveRestoreHelper(drawableVec, RSDrawableContentSlot::BG_SAVE_BOUNDS, - // RSDrawableContentSlot::BG_RESTORE_BOUNDS, RSPaintFilterCanvas::kCanvas); - // drawableVec[static_cast(RSDrawableContentSlot::CLIP_TO_BOUNDS)] = - // RSClipBoundsDrawable::Generate(content); - - // // part 2: after children, add aliases - // drawableVec[static_cast(RSDrawableContentSlot::FG_SAVE_BOUNDS)] = - // GenerateAlias(RSDrawableContentSlot::BG_SAVE_BOUNDS); - // drawableVec[static_cast(RSDrawableContentSlot::FG_CLIP_TO_BOUNDS)] = - // GenerateAlias(RSDrawableContentSlot::CLIP_TO_BOUNDS); - // drawableVec[static_cast(RSDrawableContentSlot::FG_RESTORE_BOUNDS)] = - // GenerateAlias(RSDrawableContentSlot::BG_RESTORE_BOUNDS); - // return; - // } - - // if (flags & DrawableVecStatus::BG_BOUNDS_PROPERTY) { - // // case 3: ClipToBounds not set and we have background bounds properties. - // SaveRestoreHelper(drawableVec, RSDrawableContentSlot::BG_SAVE_BOUNDS, - // RSDrawableContentSlot::BG_RESTORE_BOUNDS, RSPaintFilterCanvas::kCanvas); - - // drawableVec[static_cast(RSDrawableContentSlot::CLIP_TO_BOUNDS)] = - // RSClipBoundsDrawable::Generate(content); - // return; - // } - - // if (flags & DrawableVecStatus::FG_BOUNDS_PROPERTY) { - // // case 4: ClipToBounds not set and we have foreground bounds properties. - // SaveRestoreHelper(drawableVec, RSDrawableContentSlot::FG_SAVE_BOUNDS, - // RSDrawableContentSlot::FG_RESTORE_BOUNDS, RSPaintFilterCanvas::kCanvas); - - // drawableVec[static_cast(RSDrawableContentSlot::FG_CLIP_TO_BOUNDS)] = - // RSClipBoundsDrawable::Generate(content); - // return; - // } - // case 5: ClipToBounds not set and no bounds properties, no need to save/clip/restore. - // nothing to do -} - -void OptimizeFrameSaveRestore(RSRenderContent& content, RSDrawableContent::Vec& drawableVec, uint8_t flags) -{ - // Erase existing save/clip/restore before re-generating - for (auto& slot : frameSlotsToErase) { - drawableVec[static_cast(slot)] = nullptr; - } - - // PLANNING: if both clipToFrame and clipToBounds are set, and frame == bounds, we don't need an extra clip - if (flags & DrawableVecStatus::FRAME_PROPERTY) { - // save/restore - SaveRestoreHelper(drawableVec, RSDrawableContentSlot::SAVE_FRAME, - RSDrawableContentSlot::RESTORE_FRAME, RSPaintFilterCanvas::kCanvas); - } else { - // no need to save/clip/restore - } -} -} // namespace - -void RSDrawableContent::UpdateSaveRestore(RSRenderContent& content, Vec& drawableVec, uint8_t& drawableVecStatus) -{ - // ==================================================================== - // Step 3: Universal save/clip/restore optimization - - // calculate new drawable map status - auto drawableVecStatusNew = CalculateDrawableVecStatus(content, drawableVec); - - // calculate changed bits - uint8_t changedBits = drawableVecStatus ^ drawableVecStatusNew; - if (changedBits & BOUNDS_MASK) { - // update bounds save/clip if need - OptimizeBoundsSaveRestore(content, drawableVec, drawableVecStatusNew); - } - if (changedBits & FRAME_MASK) { - // update frame save/clip if need - OptimizeFrameSaveRestore(content, drawableVec, drawableVecStatusNew); - } - drawableVecStatus = drawableVecStatusNew; -} - -// ==================== RSChildrenDrawableContent ===================== -RSDrawableContent::Ptr RSChildrenDrawableContent::OnGenerate(const RSRenderNode& node) -{ - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { - return ret; - } - return nullptr; -} - -bool RSChildrenDrawableContent::OnUpdate(const RSRenderNode& node) -{ - auto children = node.GetSortedChildren(); - if (children == nullptr || children->empty()) { - return false; - } - - // Regenerate children drawables - needSync_ = true; - stagingChildrenDrawables_.clear(); - for (const auto& child : *children) { - stagingChildrenDrawables_.push_back(RSRenderNodeDrawableAdapter::OnGenerate(child)); - } - return true; -} - -void RSChildrenDrawableContent::OnSync() -{ - if (!needSync_) { - return; - } - childrenDrawables_ = std::move(stagingChildrenDrawables_); - needSync_ = false; -} - -// RSDrawable::Ptr RSChildrenDrawableContent::CreateDrawable() const -Drawing::RecordingCanvas::DrawFunc RSChildrenDrawableContent::CreateDrawFunc() const -{ - auto ptr = std::static_pointer_cast(shared_from_this()); - return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { - for (const auto& drawable : ptr->childrenDrawables_) { - drawable->OnDraw(canvas); - } - }; -} - -// ==================== RSCustomModifierDrawableContent =================== -RSDrawableContent::Ptr RSCustomModifierDrawableContent::OnGenerate(const RSRenderNode& node, RSModifierType type) -{ - if (auto ret = std::make_shared(type); ret->OnUpdate(node)) { - return ret; - } - return nullptr; -} - -bool RSCustomModifierDrawableContent::OnUpdate(const RSRenderNode& node) -{ - const auto& drawCmdModifiers = node.GetDrawCmdModifiers(); - auto itr = drawCmdModifiers.find(type_); - if (itr == drawCmdModifiers.end() || itr->second.empty()) { - return false; - } - - // regenerate stagingDrawCmdList_ - needSync_ = true; - stagingDrawCmdList_.clear(); - for (const auto& modifier : itr->second) { - auto property = std::static_pointer_cast>(modifier->GetProperty()); - if (property == nullptr) { - continue; - } - if (const auto& drawCmdList = property->GetRef()) { - stagingDrawCmdList_.push_back(drawCmdList); - } - } - return true; -} - -void RSCustomModifierDrawableContent::OnSync() -{ - if (!needSync_) { - return; - } - drawCmdList_ = std::move(stagingDrawCmdList_); - needSync_ = false; -} - -Drawing::RecordingCanvas::DrawFunc RSCustomModifierDrawableContent::CreateDrawFunc() const -{ - auto ptr = std::static_pointer_cast(shared_from_this()); - return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { - for (const auto& drawCmdList : ptr->drawCmdList_) { - drawCmdList->Playback(*canvas); - } - }; -} -} // namespace OHOS::Rosen diff --git a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_content.cpp b/rosen/modules/render_service_base/src/drawable/rs_property_drawable.cpp similarity index 81% rename from rosen/modules/render_service_base/src/drawable/rs_property_drawable_content.cpp rename to rosen/modules/render_service_base/src/drawable/rs_property_drawable.cpp index 81b204911d..8112a9d788 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_content.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_property_drawable.cpp @@ -13,18 +13,15 @@ * limitations under the License. */ +#include "drawable/rs_property_drawable.h" + #include "rs_trace.h" -#include "drawable/rs_property_drawable_content.h" -#include "drawable/rs_drawable_utils.h" #include "common/rs_obj_abs_geometry.h" +#include "drawable/rs_property_drawable_utils.h" #include "effect/runtime_blender_builder.h" - -#include "pipeline/rs_canvas_render_node.h" #include "pipeline/rs_recording_canvas.h" #include "pipeline/rs_render_node.h" -#include "pipeline/rs_effect_render_node.h" -#include "platform/common/rs_log.h" #include "property/rs_properties_painter.h" namespace OHOS::Rosen { @@ -33,10 +30,10 @@ bool g_forceBgAntiAlias = true; constexpr int PARAM_TWO = 2; } // namespace -std::shared_ptr RSDynamicLightUpContent::dynamicLightUpBlenderEffect_ = nullptr; -std::shared_ptr RSBinarizationShaderContent::binarizationShaderEffect_ = nullptr; +std::shared_ptr RSDynamicLightUpDrawable::dynamicLightUpBlenderEffect_ = nullptr; +std::shared_ptr RSBinarizationDrawable::binarizationShaderEffect_ = nullptr; -void RSPropertyDrawableContent::OnSync() +void RSPropertyDrawable::OnSync() { if (!needSync_) { return; @@ -45,9 +42,9 @@ void RSPropertyDrawableContent::OnSync() needSync_ = false; } -Drawing::RecordingCanvas::DrawFunc RSPropertyDrawableContent::CreateDrawFunc() const +Drawing::RecordingCanvas::DrawFunc RSPropertyDrawable::CreateDrawFunc() const { - auto ptr = std::static_pointer_cast(shared_from_this()); + auto ptr = std::static_pointer_cast(shared_from_this()); return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { if (const auto& drawCmdList = ptr->drawCmdList_) { drawCmdList->Playback(*canvas); @@ -94,7 +91,7 @@ protected: class RSPropertyDrawCmdListUpdater : public RSPropertyDrawCmdListRecorder { public: - explicit RSPropertyDrawCmdListUpdater(int width, int height, RSPropertyDrawableContent* target) + explicit RSPropertyDrawCmdListUpdater(int width, int height, RSPropertyDrawable* target) : RSPropertyDrawCmdListRecorder(width, height), target_(target) {} ~RSPropertyDrawCmdListUpdater() override @@ -108,18 +105,18 @@ public: } private: - RSPropertyDrawableContent* target_; + RSPropertyDrawable* target_; }; -RSDrawableContent::Ptr RSBackgroundColorContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSBackgroundColorDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSBackgroundColorContent::OnUpdate(const RSRenderNode& node) +bool RSBackgroundColorDrawable::OnUpdate(const RSRenderNode& node) { const RSProperties& properties = node.GetRenderProperties(); auto bgColor = properties.GetBackgroundColor(); @@ -136,20 +133,20 @@ bool RSBackgroundColorContent::OnUpdate(const RSRenderNode& node) brush.SetAntiAlias(antiAlias); brush.SetColor(Drawing::Color(bgColor.AsArgbInt())); canvas.AttachBrush(brush); - canvas.DrawRoundRect(RSDrawableUtils::RRect2DrawingRRect(properties.GetRRect())); + canvas.DrawRoundRect(RSPropertyDrawableUtils::RRect2DrawingRRect(properties.GetRRect())); canvas.DetachBrush(); return true; } -RSDrawableContent::Ptr RSBackgroundShaderContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSBackgroundShaderDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSBackgroundShaderContent::OnUpdate(const RSRenderNode& node) +bool RSBackgroundShaderDrawable::OnUpdate(const RSRenderNode& node) { const RSProperties& properties = node.GetRenderProperties(); const auto& bgShader = properties.GetBackgroundShader(); @@ -170,15 +167,15 @@ bool RSBackgroundShaderContent::OnUpdate(const RSRenderNode& node) return true; } -RSDrawableContent::Ptr RSBackgroundImageContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSBackgroundImageDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSBackgroundImageContent::OnUpdate(const RSRenderNode& node) +bool RSBackgroundImageDrawable::OnUpdate(const RSRenderNode& node) { const RSProperties& properties = node.GetRenderProperties(); const auto& bgImage = properties.GetBgImage(); @@ -194,7 +191,7 @@ bool RSBackgroundImageContent::OnUpdate(const RSRenderNode& node) // paint backgroundColor Drawing::Brush brush; brush.SetAntiAlias(antiAlias); - auto boundsRect = RSDrawableUtils::Rect2DrawingRect(properties.GetBoundsRect()); + auto boundsRect = RSPropertyDrawableUtils::Rect2DrawingRect(properties.GetBoundsRect()); bgImage->SetDstRect(properties.GetBgImageRect()); canvas.AttachBrush(brush); bgImage->CanvasDrawImage(canvas, boundsRect, Drawing::SamplingOptions(), true); @@ -202,15 +199,15 @@ bool RSBackgroundImageContent::OnUpdate(const RSRenderNode& node) return true; } -RSDrawableContent::Ptr RSBackgroundFilterContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSBackgroundFilterDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node) +bool RSBackgroundFilterDrawable::OnUpdate(const RSRenderNode& node) { const RSProperties& properties = node.GetRenderProperties(); auto& rsFilter = properties.GetBackgroundFilter(); @@ -222,7 +219,7 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node) Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); auto surface = canvas.GetSurface(); if (surface == nullptr) { - ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate surface null"); + ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate surface null"); return false; } @@ -235,12 +232,12 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node) // cacheManager != nullptr && !canvas.GetDisableFilterCache()) { // auto node = properties.backref_.lock(); // if (node == nullptr) { - // ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate node is null"); + // ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate node is null"); // return false; // } // auto effectNode = node->ReinterpretCastTo(); // if (effectNode == nullptr) { - // ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate node reinterpret cast failed."); + // ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate node reinterpret cast failed."); // return false; // } // // node is freeze or screen rotating, force cache filterred snapshot. @@ -254,7 +251,7 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node) auto imageRect = bounds; auto imageSnapshot = surface->GetImageSnapshot(imageRect); if (imageSnapshot == nullptr) { - ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate image snapshot null"); + ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate image snapshot null"); return false; } @@ -263,7 +260,7 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node) std::shared_ptr offscreenSurface = surface->MakeSurface(imageSnapshot->GetWidth(), imageSnapshot->GetHeight()); if (offscreenSurface == nullptr) { - ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate offscreenSurface null"); + ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate offscreenSurface null"); return false; } RSPaintFilterCanvas offscreenCanvas(offscreenSurface.get()); @@ -274,7 +271,7 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node) auto imageCache = offscreenSurface->GetImageSnapshot(); if (imageCache == nullptr) { - ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate imageCache snapshot null"); + ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate imageCache snapshot null"); return false; } // TODO canvas.SetEffectData @@ -284,15 +281,15 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node) return true; } -RSDrawableContent::Ptr RSBorderContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSBorderDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSBorderContent::OnUpdate(const RSRenderNode& node) +bool RSBorderDrawable::OnUpdate(const RSRenderNode& node) { // regenerate stagingDrawCmdList_ RSPropertyDrawCmdListUpdater updater(0, 0, this); @@ -301,7 +298,7 @@ bool RSBorderContent::OnUpdate(const RSRenderNode& node) return true; } -void RSBorderContent::DrawBorder(const RSProperties& properties, Drawing::Canvas& canvas, +void RSBorderDrawable::DrawBorder(const RSProperties& properties, Drawing::Canvas& canvas, const std::shared_ptr& border, const bool& isOutline) { if (!border || !border->HasBorder()) { @@ -313,9 +310,9 @@ void RSBorderContent::DrawBorder(const RSProperties& properties, Drawing::Canvas brush.SetAntiAlias(true); pen.SetAntiAlias(true); if (border->ApplyFillStyle(brush)) { - auto roundRect = RSDrawableUtils::RRect2DrawingRRect(RSDrawableUtils::GetRRectForDrawingBorder(properties, + auto roundRect = RSPropertyDrawableUtils::RRect2DrawingRRect(RSPropertyDrawableUtils::GetRRectForDrawingBorder(properties, border, isOutline)); - auto innerRoundRect = RSDrawableUtils::RRect2DrawingRRect(RSDrawableUtils::GetInnerRRectForDrawingBorder( + auto innerRoundRect = RSPropertyDrawableUtils::RRect2DrawingRRect(RSPropertyDrawableUtils::GetInnerRRectForDrawingBorder( properties, border, isOutline)); canvas.AttachBrush(brush); canvas.DrawNestedRoundRect(roundRect, innerRoundRect); @@ -328,21 +325,21 @@ void RSBorderContent::DrawBorder(const RSProperties& properties, Drawing::Canvas border->PaintFourLine(canvas, pen, rectf); } else if (border->ApplyPathStyle(pen)) { auto borderWidth = border->GetWidth(); - RRect rrect = RSDrawableUtils::GetRRectForDrawingBorder(properties, border, isOutline); + RRect rrect = RSPropertyDrawableUtils::GetRRectForDrawingBorder(properties, border, isOutline); rrect.rect_.width_ -= borderWidth; rrect.rect_.height_ -= borderWidth; rrect.rect_.Move(borderWidth / PARAM_TWO, borderWidth / PARAM_TWO); Drawing::Path borderPath; - borderPath.AddRoundRect(RSDrawableUtils::RRect2DrawingRRect(rrect)); + borderPath.AddRoundRect(RSPropertyDrawableUtils::RRect2DrawingRRect(rrect)); canvas.AttachPen(pen); canvas.DrawPath(borderPath); canvas.DetachPen(); } else { Drawing::AutoCanvasRestore acr(canvas, true); - auto rrect = RSDrawableUtils::RRect2DrawingRRect(RSDrawableUtils::GetRRectForDrawingBorder(properties, + auto rrect = RSPropertyDrawableUtils::RRect2DrawingRRect(RSPropertyDrawableUtils::GetRRectForDrawingBorder(properties, border, isOutline)); canvas.ClipRoundRect(rrect, Drawing::ClipOp::INTERSECT, true); - auto innerRoundRect = RSDrawableUtils::RRect2DrawingRRect(RSDrawableUtils::GetInnerRRectForDrawingBorder( + auto innerRoundRect = RSPropertyDrawableUtils::RRect2DrawingRRect(RSPropertyDrawableUtils::GetInnerRRectForDrawingBorder( properties, border, isOutline)); canvas.ClipRoundRect(innerRoundRect, Drawing::ClipOp::DIFFERENCE, true); Drawing::scalar centerX = innerRoundRect.GetRect().GetLeft() + innerRoundRect.GetRect().GetWidth() / 2; @@ -359,32 +356,32 @@ void RSBorderContent::DrawBorder(const RSProperties& properties, Drawing::Canvas } } -RSDrawableContent::Ptr RSOutlineContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSOutlineDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSOutlineContent::OnUpdate(const RSRenderNode& node) +bool RSOutlineDrawable::OnUpdate(const RSRenderNode& node) { // regenerate stagingDrawCmdList_ RSPropertyDrawCmdListUpdater updater(0, 0, this); const RSProperties& properties = node.GetRenderProperties(); - RSBorderContent::DrawBorder(properties, *updater.GetRecordingCanvas(), properties.GetOutline(), true); + RSBorderDrawable::DrawBorder(properties, *updater.GetRecordingCanvas(), properties.GetOutline(), true); return true; } -RSDrawableContent::Ptr RSShadowContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSShadowDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSShadowContent::OnUpdate(const RSRenderNode& node) +bool RSShadowDrawable::OnUpdate(const RSRenderNode& node) { // regenerate stagingDrawCmdList_ RSPropertyDrawCmdListUpdater updater(0, 0, this); @@ -411,9 +408,9 @@ bool RSShadowContent::OnUpdate(const RSRenderNode& node) canvas.ClipPath(path, Drawing::ClipOp::DIFFERENCE, true); } } else { - path.AddRoundRect(RSDrawableUtils::RRect2DrawingRRect(rrect)); + path.AddRoundRect(RSPropertyDrawableUtils::RRect2DrawingRRect(rrect)); if (!properties.GetShadowIsFilled()) { - canvas.ClipRoundRect(RSDrawableUtils::RRect2DrawingRRect(rrect), Drawing::ClipOp::DIFFERENCE, true); + canvas.ClipRoundRect(RSPropertyDrawableUtils::RRect2DrawingRRect(rrect), Drawing::ClipOp::DIFFERENCE, true); } } if (properties.GetShadowMask()) { @@ -424,7 +421,7 @@ bool RSShadowContent::OnUpdate(const RSRenderNode& node) return true; } -void RSShadowContent::DrawColorfulShadowInner(const RSProperties& properties, Drawing::Canvas& canvas, +void RSShadowDrawable::DrawColorfulShadowInner(const RSProperties& properties, Drawing::Canvas& canvas, Drawing::Path& path) { // blurRadius calculation is based on the formula in Canvas::DrawShadow, 0.25f and 128.0f are constants @@ -450,7 +447,7 @@ void RSShadowContent::DrawColorfulShadowInner(const RSProperties& properties, Dr // } } -void RSShadowContent::DrawShadowInner(const RSProperties& properties, Drawing::Canvas& canvas, Drawing::Path& path) +void RSShadowDrawable::DrawShadowInner(const RSProperties& properties, Drawing::Canvas& canvas, Drawing::Path& path) { path.Offset(properties.GetShadowOffsetX(), properties.GetShadowOffsetY()); Color spotColor = properties.GetShadowColor(); @@ -470,8 +467,8 @@ void RSShadowContent::DrawShadowInner(const RSProperties& properties, Drawing::C auto& colorPickerTask = properties.GetColorPickerCacheTaskShadow(); if (colorPickerTask != nullptr && properties.GetShadowColorStrategy() != SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE) { - if (RSDrawableUtils::PickColor(properties, canvas, path, matrix, deviceClipBounds, colorPicked)) { - RSDrawableUtils::GetDarkColor(colorPicked); + if (RSPropertyDrawableUtils::PickColor(properties, canvas, path, matrix, deviceClipBounds, colorPicked)) { + RSPropertyDrawableUtils::GetDarkColor(colorPicked); } else { shadowAlpha = 0; } @@ -510,15 +507,15 @@ void RSShadowContent::DrawShadowInner(const RSProperties& properties, Drawing::C } } -RSDrawableContent::Ptr RSForegroundColorContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSForegroundColorDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSForegroundColorContent::OnUpdate(const RSRenderNode& node) +bool RSForegroundColorDrawable::OnUpdate(const RSRenderNode& node) { const RSProperties& properties = node.GetRenderProperties(); auto fgColor = properties.GetForegroundColor(); @@ -532,20 +529,20 @@ bool RSForegroundColorContent::OnUpdate(const RSRenderNode& node) brush.SetColor(Drawing::Color(fgColor.AsArgbInt())); brush.SetAntiAlias(true); canvas.AttachBrush(brush); - canvas.DrawRoundRect(RSDrawableUtils::RRect2DrawingRRect(properties.GetRRect())); + canvas.DrawRoundRect(RSPropertyDrawableUtils::RRect2DrawingRRect(properties.GetRRect())); canvas.DetachBrush(); return true; } -RSDrawableContent::Ptr RSPixelStretchContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSPixelStretchDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node) +bool RSPixelStretchDrawable::OnUpdate(const RSRenderNode& node) { const RSProperties& properties = node.GetRenderProperties(); auto& pixelStretch = properties.GetPixelStretch(); @@ -557,7 +554,7 @@ bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node) Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); auto surface = canvas.GetSurface(); if (surface == nullptr) { - ROSEN_LOGE("RSPixelStretchContent::OnUpdate surface null"); + ROSEN_LOGE("RSPixelStretchDrawable::OnUpdate surface null"); return false; } @@ -565,7 +562,7 @@ bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node) with respect to the origin of the current canvas coordinates */ Drawing::Matrix worldToLocalMat; if (!canvas.GetTotalMatrix().Invert(worldToLocalMat)) { - ROSEN_LOGE("RSPixelStretchContent::OnUpdate get invert matrix failed."); + ROSEN_LOGE("RSPixelStretchDrawable::OnUpdate get invert matrix failed."); } Drawing::Rect localClipBounds; auto tmpBounds = canvas.GetDeviceClipBounds(); @@ -574,18 +571,18 @@ bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node) Drawing::Rect fClipBounds(clipBounds.GetLeft(), clipBounds.GetTop(), clipBounds.GetRight(), clipBounds.GetBottom()); if (!worldToLocalMat.MapRect(localClipBounds, fClipBounds)) { - ROSEN_LOGE("RSPixelStretchContent::OnUpdate map rect failed."); + ROSEN_LOGE("RSPixelStretchDrawable::OnUpdate map rect failed."); } auto bounds = RSPropertiesPainter::Rect2DrawingRect(properties.GetBoundsRect()); if (!bounds.Intersect(localClipBounds)) { - ROSEN_LOGE("RSPixelStretchContent::OnUpdate intersect clipbounds failed"); + ROSEN_LOGE("RSPixelStretchDrawable::OnUpdate intersect clipbounds failed"); } auto scaledBounds = Drawing::Rect(bounds.GetLeft() - pixelStretch->x_, bounds.GetTop() - pixelStretch->y_, bounds.GetRight() + pixelStretch->z_, bounds.GetBottom() + pixelStretch->w_); if (!scaledBounds.IsValid() || !bounds.IsValid() || !clipBounds.IsValid()) { - ROSEN_LOGE("RSPixelStretchContent::OnUpdate invalid scaled bounds"); + ROSEN_LOGE("RSPixelStretchDrawable::OnUpdate invalid scaled bounds"); return false; } @@ -593,7 +590,7 @@ bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node) static_cast(fClipBounds.GetRight()), static_cast(fClipBounds.GetBottom())); auto image = surface->GetImageSnapshot(rectI); if (image == nullptr) { - ROSEN_LOGE("RSPixelStretchContent::OnUpdate image null"); + ROSEN_LOGE("RSPixelStretchDrawable::OnUpdate image null"); return false; } @@ -623,7 +620,7 @@ bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node) rotateMat.Set(Drawing::Matrix::TRANS_X, bounds.GetLeft() - transBounds.GetLeft()); rotateMat.Set(Drawing::Matrix::TRANS_Y, bounds.GetTop() - transBounds.GetTop()); if (!rotateMat.Invert(inverseMat)) { - ROSEN_LOGE("RSPixelStretchContent::OnUpdate get invert matrix failed."); + ROSEN_LOGE("RSPixelStretchDrawable::OnUpdate get invert matrix failed."); } } @@ -654,21 +651,21 @@ bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node) return true; } -RSDrawableContent::Ptr RSDynamicLightUpContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSDynamicLightUpDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSDynamicLightUpContent::OnUpdate(const RSRenderNode& node) +bool RSDynamicLightUpDrawable::OnUpdate(const RSRenderNode& node) { RSPropertyDrawCmdListUpdater updater(0, 0, this); Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); Drawing::Surface* surface = canvas.GetSurface(); if (surface == nullptr) { - ROSEN_LOGE("RSDynamicLightUpContent::OnUpdate surface is null"); + ROSEN_LOGE("RSDynamicLightUpDrawable::OnUpdate surface is null"); return false; } const RSProperties& properties = node.GetRenderProperties(); @@ -680,7 +677,7 @@ bool RSDynamicLightUpContent::OnUpdate(const RSRenderNode& node) return true; } -std::shared_ptr RSDynamicLightUpContent::MakeDynamicLightUpBlender(float dynamicLightUpRate, +std::shared_ptr RSDynamicLightUpDrawable::MakeDynamicLightUpBlender(float dynamicLightUpRate, float dynamicLightUpDeg) { static constexpr char prog[] = R"( @@ -699,7 +696,7 @@ std::shared_ptr RSDynamicLightUpContent::MakeDynamicLightUpBle if (dynamicLightUpBlenderEffect_ == nullptr) { dynamicLightUpBlenderEffect_ = Drawing::RuntimeEffect::CreateForBlender(prog); if (dynamicLightUpBlenderEffect_ == nullptr) { - ROSEN_LOGE("RSDynamicLightUpContent::MakeDynamicLightUpBlender effect error!"); + ROSEN_LOGE("RSDynamicLightUpDrawable::MakeDynamicLightUpBlender effect error!"); return nullptr; } } @@ -710,28 +707,28 @@ std::shared_ptr RSDynamicLightUpContent::MakeDynamicLightUpBle return builder->MakeBlender(); } -RSDrawableContent::Ptr RSLightUpEffectContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSLightUpEffectDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSLightUpEffectContent::OnUpdate(const RSRenderNode& node) +bool RSLightUpEffectDrawable::OnUpdate(const RSRenderNode& node) { RSPropertyDrawCmdListUpdater updater(0, 0, this); Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); Drawing::Surface* surface = canvas.GetSurface(); if (surface == nullptr) { - ROSEN_LOGE("RSLightUpEffectContent::OnUpdate surface is null"); + ROSEN_LOGE("RSLightUpEffectDrawable::OnUpdate surface is null"); return false; } auto clipBounds = canvas.GetDeviceClipBounds(); auto image = surface->GetImageSnapshot(clipBounds); if (image == nullptr) { - ROSEN_LOGE("RSLightUpEffectContent::OnUpdate image is null"); + ROSEN_LOGE("RSLightUpEffectDrawable::OnUpdate image is null"); return false; } @@ -748,15 +745,15 @@ bool RSLightUpEffectContent::OnUpdate(const RSRenderNode& node) return true; } -RSDrawableContent::Ptr RSColorFilterContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSColorFilterDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSColorFilterContent::OnUpdate(const RSRenderNode& node) +bool RSColorFilterDrawable::OnUpdate(const RSRenderNode& node) { const RSProperties& properties = node.GetRenderProperties(); // if useEffect defined, use color filter from parent EffectView. @@ -774,13 +771,13 @@ bool RSColorFilterContent::OnUpdate(const RSRenderNode& node) brush.SetFilter(filter); auto surface = canvas.GetSurface(); if (surface == nullptr) { - ROSEN_LOGE("RSColorFilterContent::OnUpdate surface is null"); + ROSEN_LOGE("RSColorFilterDrawable::OnUpdate surface is null"); return false; } auto clipBounds = canvas.GetDeviceClipBounds(); auto imageSnapshot = surface->GetImageSnapshot(clipBounds); if (imageSnapshot == nullptr) { - ROSEN_LOGE("RSColorFilterContent::OnUpdate image is null"); + ROSEN_LOGE("RSColorFilterDrawable::OnUpdate image is null"); return false; } imageSnapshot->HintCacheGpuResource(); @@ -792,30 +789,30 @@ bool RSColorFilterContent::OnUpdate(const RSRenderNode& node) return true; } -RSDrawableContent::Ptr RSMaskContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSMaskDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSMaskContent::OnUpdate(const RSRenderNode& node) +bool RSMaskDrawable::OnUpdate(const RSRenderNode& node) { const RSProperties& properties = node.GetRenderProperties(); std::shared_ptr mask = properties.GetMask(); if (mask == nullptr) { - ROSEN_LOGE("RSMaskContent::OnUpdate null mask"); + ROSEN_LOGE("RSMaskDrawable::OnUpdate null mask"); return false; } if (mask->IsSvgMask() && !mask->GetSvgDom() && !mask->GetSvgPicture()) { - ROSEN_LOGE("RSMaskContent::OnUpdate not has Svg Mask property"); + ROSEN_LOGE("RSMaskDrawable::OnUpdate not has Svg Mask property"); return false; } RSPropertyDrawCmdListUpdater updater(0, 0, this); Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); - Drawing::Rect maskBounds = RSDrawableUtils::Rect2DrawingRect(properties.GetBoundsRect()); + Drawing::Rect maskBounds = RSPropertyDrawableUtils::Rect2DrawingRect(properties.GetBoundsRect()); canvas.Save(); Drawing::SaveLayerOps slr(&maskBounds, nullptr); canvas.SaveLayer(slr); @@ -866,28 +863,28 @@ bool RSMaskContent::OnUpdate(const RSRenderNode& node) return true; } -RSDrawableContent::Ptr RSBinarizationShaderContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSBinarizationDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSBinarizationShaderContent::OnUpdate(const RSRenderNode& node) +bool RSBinarizationDrawable::OnUpdate(const RSRenderNode& node) { RSPropertyDrawCmdListUpdater updater(0, 0, this); Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); const RSProperties& properties = node.GetRenderProperties(); auto drSurface = canvas.GetSurface(); if (drSurface == nullptr) { - ROSEN_LOGE("RSBinarizationShaderContent::OnUpdate drSurface is null"); + ROSEN_LOGE("RSBinarizationDrawable::OnUpdate drSurface is null"); return false; } auto clipBounds = canvas.GetDeviceClipBounds(); auto imageSnapshot = drSurface->GetImageSnapshot(clipBounds); if (imageSnapshot == nullptr) { - ROSEN_LOGE("RSBinarizationShaderContent::OnUpdate image is null"); + ROSEN_LOGE("RSBinarizationDrawable::OnUpdate image is null"); return false; } auto& aiInvert = properties.GetAiInvert(); @@ -906,7 +903,7 @@ bool RSBinarizationShaderContent::OnUpdate(const RSRenderNode& node) return true; } -std::shared_ptr RSBinarizationShaderContent::MakeBinarizationShader(float low, float high, +std::shared_ptr RSBinarizationDrawable::MakeBinarizationShader(float low, float high, float thresholdLow, float thresholdHigh, std::shared_ptr imageShader) { static constexpr char prog[] = R"( @@ -930,7 +927,7 @@ std::shared_ptr RSBinarizationShaderContent::MakeBinariza if (binarizationShaderEffect_ == nullptr) { binarizationShaderEffect_ = Drawing::RuntimeEffect::CreateForShader(prog); if (binarizationShaderEffect_ == nullptr) { - ROSEN_LOGE("RSBinarizationShaderContent::MakeBinarizationShader effect error\n"); + ROSEN_LOGE("RSBinarizationDrawable::MakeBinarizationShader effect error\n"); return nullptr; } } @@ -945,15 +942,15 @@ std::shared_ptr RSBinarizationShaderContent::MakeBinariza return builder->MakeShader(nullptr, false); } -RSDrawableContent::Ptr RSParticleContent::OnGenerate(const RSRenderNode& node) +RSDrawable::Ptr RSParticleDrawable::OnGenerate(const RSRenderNode& node) { - if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { return ret; } return nullptr; }; -bool RSParticleContent::OnUpdate(const RSRenderNode& node) +bool RSParticleDrawable::OnUpdate(const RSRenderNode& node) { const RSProperties& properties = node.GetRenderProperties(); const auto& particleVector = properties.GetParticles(); diff --git a/rosen/modules/render_service_base/src/drawable/rs_utilities_drawable.cpp b/rosen/modules/render_service_base/src/drawable/rs_utilities_drawable.cpp new file mode 100644 index 0000000000..587d21d29e --- /dev/null +++ b/rosen/modules/render_service_base/src/drawable/rs_utilities_drawable.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "drawable/rs_utilities_drawable.h" + +#include "drawable/rs_property_drawable.h" +#include "drawable/rs_render_node_drawable_adapter.h" +#include "pipeline/rs_render_node.h" + +namespace OHOS::Rosen { + +// ==================== RSChildrenDrawableContent ===================== +RSDrawable::Ptr RSChildrenDrawableContent::OnGenerate(const RSRenderNode& node) +{ + if (auto ret = std::make_shared(); ret->OnUpdate(node)) { + return ret; + } + return nullptr; +} + +bool RSChildrenDrawableContent::OnUpdate(const RSRenderNode& node) +{ + auto children = node.GetSortedChildren(); + if (children == nullptr || children->empty()) { + return false; + } + + // Regenerate children drawables + needSync_ = true; + stagingChildrenDrawables_.clear(); + for (const auto& child : *children) { + stagingChildrenDrawables_.push_back(RSRenderNodeDrawableAdapter::OnGenerate(child)); + } + return true; +} + +void RSChildrenDrawableContent::OnSync() +{ + if (!needSync_) { + return; + } + childrenDrawables_ = std::move(stagingChildrenDrawables_); + needSync_ = false; +} + +// RSDrawable::Ptr RSChildrenDrawableContent::CreateDrawable() const +Drawing::RecordingCanvas::DrawFunc RSChildrenDrawableContent::CreateDrawFunc() const +{ + auto ptr = std::static_pointer_cast(shared_from_this()); + return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { + for (const auto& drawable : ptr->childrenDrawables_) { + drawable->OnDraw(canvas); + } + }; +} + +// ==================== RSCustomModifierDrawableContent =================== +RSDrawable::Ptr RSCustomModifierDrawableContent::OnGenerate(const RSRenderNode& node, RSModifierType type) +{ + if (auto ret = std::make_shared(type); ret->OnUpdate(node)) { + return ret; + } + return nullptr; +} + +bool RSCustomModifierDrawableContent::OnUpdate(const RSRenderNode& node) +{ + const auto& drawCmdModifiers = node.GetDrawCmdModifiers(); + auto itr = drawCmdModifiers.find(type_); + if (itr == drawCmdModifiers.end() || itr->second.empty()) { + return false; + } + + // regenerate stagingDrawCmdList_ + needSync_ = true; + stagingDrawCmdList_.clear(); + for (const auto& modifier : itr->second) { + auto property = std::static_pointer_cast>(modifier->GetProperty()); + if (property == nullptr) { + continue; + } + if (const auto& drawCmdList = property->GetRef()) { + stagingDrawCmdList_.push_back(drawCmdList); + } + } + return true; +} + +void RSCustomModifierDrawableContent::OnSync() +{ + if (!needSync_) { + return; + } + drawCmdList_ = std::move(stagingDrawCmdList_); + needSync_ = false; +} + +Drawing::RecordingCanvas::DrawFunc RSCustomModifierDrawableContent::CreateDrawFunc() const +{ + auto ptr = std::static_pointer_cast(shared_from_this()); + return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { + for (const auto& drawCmdList : ptr->drawCmdList_) { + drawCmdList->Playback(*canvas); + } + }; +} +} // namespace OHOS::Rosen diff --git a/rosen/modules/render_service_base/src/pipeline/rs_render_node.cpp b/rosen/modules/render_service_base/src/pipeline/rs_render_node.cpp index e624c2ce92..381440bca2 100644 --- a/rosen/modules/render_service_base/src/pipeline/rs_render_node.cpp +++ b/rosen/modules/render_service_base/src/pipeline/rs_render_node.cpp @@ -22,25 +22,27 @@ #include #include +#include "benchmarks/file_utils.h" #include "rs_trace.h" + #include "animation/rs_render_animation.h" #include "common/rs_obj_abs_geometry.h" -#include "benchmarks/file_utils.h" #include "common/rs_optional_trace.h" #include "modifier/rs_modifier_type.h" #include "pipeline/rs_context.h" #include "pipeline/rs_display_render_node.h" #include "pipeline/rs_effect_render_node.h" #include "pipeline/rs_paint_filter_canvas.h" +#include "pipeline/rs_recording_canvas.h" #include "pipeline/rs_root_render_node.h" #include "pipeline/rs_surface_render_node.h" #include "platform/common/rs_log.h" #include "platform/common/rs_system_properties.h" #include "property/rs_properties_painter.h" -// #include "property/rs_property_drawable.h" #include "property/rs_property_trace.h" #include "transaction/rs_transaction_proxy.h" #include "visitor/rs_node_visitor.h" + #ifdef DDGR_ENABLE_FEATURE_OPINC #include "rs_auto_cache.h" #endif @@ -1423,7 +1425,7 @@ void RSRenderNode::ApplyModifiers() // UpdateDrawableVec(); // } - UpdateDrawableContentVec(); + UpdateDrawableVec(); #endif @@ -1445,27 +1447,27 @@ void RSRenderNode::MarkParentNeedRegenerateChildren() const parent->isChildrenSorted_ = false; } -void RSRenderNode::UpdateDrawableContentVec() +void RSRenderNode::UpdateDrawableVec() { #ifndef ROSEN_ARKUI_X // Step 1: Collect dirty slots - auto dirtySlots = RSDrawableContent::CalculateDirtySlots(dirtyTypes_, contentVec_); + auto dirtySlots = RSDrawable::CalculateDirtySlots(dirtyTypes_, drawableVec_); if (dirtySlots.empty()) { return; } // Step 2: Update or regenerate drawable if needed - bool drawableChanged = RSDrawableContent::UpdateDirtySlots(*this, contentVec_, dirtySlots); + bool drawableChanged = RSDrawable::UpdateDirtySlots(*this, drawableVec_, dirtySlots); if (drawableChanged || drawableVecStatus_ == 0) { // Step 3: if any drawables changed, update save/clip/restore - RSDrawableContent::UpdateSaveRestore(*renderContent_, contentVec_, drawableVecStatus_); + RSDrawable::UpdateSaveRestore(*renderContent_, drawableVec_, drawableVecStatus_); // Step 4: Generate drawCmdList from drawables // TODO: use correct W/H instead of 0 auto recordingCanvas_ = std::make_unique(0, 0, true); - for (const auto& drawable : contentVec_) { + for (const auto& drawable : drawableVec_) { if (drawable) { recordingCanvas_->DrawDrawFunc(drawable->CreateDrawFunc()); } @@ -2757,7 +2759,7 @@ void RSRenderNode::OnSync() // Sync drawCmdList drawCmdList_ = std::move(stagingDrawCmdList_); // Sync each drawable. PLANNING: use dirty mask to only sync changed properties - std::for_each(contentVec_.begin(), contentVec_.end(), [](auto& drawableContent) { + std::for_each(drawableVec_.begin(), drawableVec_.end(), [](auto& drawableContent) { if (drawableContent) { drawableContent->OnSync(); }