From 5d73828feb15356710bfa4bcb1f25c0f9b3017af Mon Sep 17 00:00:00 2001 From: Zhang Peng Date: Wed, 17 Apr 2024 17:50:21 +0800 Subject: [PATCH 1/5] re-implement blend mode fallback mode fix boot-animation Signed-off-by: Zhang Peng Change-Id: I677fe03abd8e55d48111cabcfaa8f4df4a55130b --- .../core/pipeline/rs_uni_render_visitor.cpp | 6 ++-- .../include/drawable/rs_misc_drawable.h | 9 ++++-- .../drawable/rs_property_drawable_utils.h | 2 +- .../include/pipeline/rs_paint_filter_canvas.h | 12 ++++---- .../ohos/overdraw/rs_listened_canvas.h | 4 +-- .../src/drawable/rs_misc_drawable.cpp | 19 +++++++++++-- .../rs_property_drawable_background.cpp | 1 + .../drawable/rs_property_drawable_utils.cpp | 26 +++++++++-------- .../src/pipeline/rs_paint_filter_canvas.cpp | 28 +++++++++++++------ .../ohos/overdraw/rs_listened_canvas.cpp | 10 ++----- .../rs_property_drawable_bounds_geometry.cpp | 25 +++++------------ 11 files changed, 78 insertions(+), 64 deletions(-) diff --git a/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.cpp b/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.cpp index 114c7285b3..1c6bb31e98 100644 --- a/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.cpp +++ b/rosen/modules/render_service/core/pipeline/rs_uni_render_visitor.cpp @@ -5215,10 +5215,10 @@ void RSUniRenderVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node) bool backgroundTransparent = !node.GetAncoForceDoDirect() && (static_cast(node.GetRenderProperties().GetBackgroundColor().GetAlpha()) < UINT8_MAX); node.SetHardwareForcedDisabledState( - (node.IsHardwareForcedDisabledByFilter() || canvas_->GetAlpha() < 1.f || - backgroundTransparent || IsRosenWebHardwareDisabled(node, rotation) || + (node.IsHardwareForcedDisabledByFilter() || canvas_->GetAlpha() < 1.f || backgroundTransparent || + IsRosenWebHardwareDisabled(node, rotation) || RSUniRenderUtil::GetRotationDegreeFromMatrix(node.GetTotalMatrix()) % ROTATION_90 != 0 || - canvas_->GetBlendOffscreenLayerCnt() > 0) && + canvas_->HasOffscreenLayer()) && (!node.IsHardwareEnabledTopSurface() || node.HasSubNodeShouldPaint())); node.SetHardwareDisabledByCache(isUpdateCachedSurface_); node.ResetHardwareForcedDisabledBySrcRect(); diff --git a/rosen/modules/render_service_base/include/drawable/rs_misc_drawable.h b/rosen/modules/render_service_base/include/drawable/rs_misc_drawable.h index 8f8fb1bfbd..2d54532c86 100644 --- a/rosen/modules/render_service_base/include/drawable/rs_misc_drawable.h +++ b/rosen/modules/render_service_base/include/drawable/rs_misc_drawable.h @@ -204,13 +204,18 @@ private: class RSEndBlendModeDrawable : public RSDrawable { public: - RSEndBlendModeDrawable() = default; + RSEndBlendModeDrawable(int blendApplyType) : blendApplyType_(blendApplyType) {} ~RSEndBlendModeDrawable() override = default; static RSDrawable::Ptr OnGenerate(const RSRenderNode& node); bool OnUpdate(const RSRenderNode& node) override; - void OnSync() override {}; + void OnSync() override; Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override; + +private: + bool needSync_ = false; + int blendApplyType_; + int stagingBlendApplyType_; }; } // namespace DrawableV2 } // namespace OHOS::Rosen diff --git a/rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h b/rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h index 629f85056e..f0dfa1e320 100644 --- a/rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h +++ b/rosen/modules/render_service_base/include/drawable/rs_property_drawable_utils.h @@ -56,7 +56,7 @@ public: static void DrawUseEffect(RSPaintFilterCanvas* canvas); static void BeginBlendMode(RSPaintFilterCanvas& canvas, int blendMode, int blendModeApplyType); - static void EndBlendMode(RSPaintFilterCanvas& canvas); + static void EndBlendMode(RSPaintFilterCanvas& canvas, int blendModeApplyType); static Color CalculateInvertColor(const Color& backgroundColor); static Color GetInvertBackgroundColor(RSPaintFilterCanvas& canvas, bool needClipToBounds, diff --git a/rosen/modules/render_service_base/include/pipeline/rs_paint_filter_canvas.h b/rosen/modules/render_service_base/include/pipeline/rs_paint_filter_canvas.h index b79ca0f6de..f4acd21cd0 100644 --- a/rosen/modules/render_service_base/include/pipeline/rs_paint_filter_canvas.h +++ b/rosen/modules/render_service_base/include/pipeline/rs_paint_filter_canvas.h @@ -137,7 +137,7 @@ class RSB_EXPORT RSPaintFilterCanvas : public RSPaintFilterCanvasBase { public: RSPaintFilterCanvas(Drawing::Canvas* canvas, float alpha = 1.0f); RSPaintFilterCanvas(Drawing::Surface* surface, float alpha = 1.0f); - ~RSPaintFilterCanvas() override {}; + ~RSPaintFilterCanvas() override = default;; void CopyConfiguration(const RSPaintFilterCanvas& other); void PushDirtyRegion(Drawing::Region& resultRegion); @@ -162,11 +162,10 @@ public: int GetEnvSaveCount() const; void RestoreEnvToCount(int count); + // blendmode related + void SaveLayer(const Drawing::SaveLayerOps& saveLayerOps) override; void SetBlendMode(std::optional blendMode); - int GetBlendOffscreenLayerCnt() const - { - return 0; - }; + bool HasOffscreenLayer() const; // save/restore utils struct SaveStatus { @@ -271,9 +270,8 @@ protected: Color envForegroundColor_; std::shared_ptr effectData_; std::optional blendMode_; + bool hasOffscreenLayer_; }; - const std::stack& GetAlphaStack(); - const std::stack& GetEnvStack(); bool OnFilter() const override; inline bool OnFilterWithBrush(Drawing::Brush& brush) const override diff --git a/rosen/modules/render_service_base/include/platform/ohos/overdraw/rs_listened_canvas.h b/rosen/modules/render_service_base/include/platform/ohos/overdraw/rs_listened_canvas.h index 4157044547..7353622ae8 100644 --- a/rosen/modules/render_service_base/include/platform/ohos/overdraw/rs_listened_canvas.h +++ b/rosen/modules/render_service_base/include/platform/ohos/overdraw/rs_listened_canvas.h @@ -24,8 +24,8 @@ class RSCanvasListener; class RSB_EXPORT RSListenedCanvas : public RSPaintFilterCanvas { public: - RSListenedCanvas(Drawing::Canvas& canvas, float alpha = 1.0f); - RSListenedCanvas(Drawing::Surface& surface, float alpha = 1.0f); + RSListenedCanvas(Drawing::Canvas& canvas); + RSListenedCanvas(Drawing::Surface& surface); void SetListener(const std::shared_ptr& listener); // shapes diff --git a/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp b/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp index a26a80eb47..3fd34d649f 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp @@ -306,7 +306,7 @@ RSDrawable::Ptr RSEndBlendModeDrawable::OnGenerate(const RSRenderNode& node) return nullptr; } - return std::make_shared(); + return std::make_shared(properties.GetColorBlendApplyType()); }; bool RSEndBlendModeDrawable::OnUpdate(const RSRenderNode& node) @@ -318,14 +318,27 @@ bool RSEndBlendModeDrawable::OnUpdate(const RSRenderNode& node) return false; } + stagingBlendApplyType_ = properties.GetColorBlendApplyType(); + needSync_ = true; + return true; } +void RSEndBlendModeDrawable::OnSync() +{ + if (needSync_ == false) { + return; + } + blendApplyType_ = stagingBlendApplyType_; + needSync_ = false; +} + Drawing::RecordingCanvas::DrawFunc RSEndBlendModeDrawable::CreateDrawFunc() const { - return [](Drawing::Canvas* canvas, const Drawing::Rect* rect) { + auto ptr = std::static_pointer_cast(shared_from_this()); + return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { auto paintFilterCanvas = static_cast(canvas); - RSPropertyDrawableUtils::EndBlendMode(*paintFilterCanvas); + RSPropertyDrawableUtils::EndBlendMode(*paintFilterCanvas, ptr->blendApplyType_); }; } diff --git a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_background.cpp b/rosen/modules/render_service_base/src/drawable/rs_property_drawable_background.cpp index 5ce3a6979c..8dd3a50d85 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_background.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_property_drawable_background.cpp @@ -153,6 +153,7 @@ Drawing::RecordingCanvas::DrawFunc RSMaskShadowDrawable::CreateDrawFunc() const { auto ptr = std::static_pointer_cast(shared_from_this()); return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { + Drawing::AutoCanvasRestore rst(*canvas, true); RSPropertyDrawableUtils::CeilMatrixTrans(canvas); ptr->drawCmdList_->Playback(*canvas); }; diff --git a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_utils.cpp b/rosen/modules/render_service_base/src/drawable/rs_property_drawable_utils.cpp index 2b9b062c81..8d2d1cafd9 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_property_drawable_utils.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_property_drawable_utils.cpp @@ -17,8 +17,8 @@ #include "common/rs_optional_trace.h" #include "platform/common/rs_log.h" -#include "render/rs_material_filter.h" #include "property/rs_properties_painter.h" +#include "render/rs_material_filter.h" namespace OHOS { namespace Rosen { @@ -182,7 +182,6 @@ void RSPropertyDrawableUtils::CeilMatrixTrans(Drawing::Canvas* canvas) { // The translation of the matrix is rounded to improve the hit ratio of skia blurfilter cache, // the function in for more details. - Drawing::AutoCanvasRestore rst(*canvas, true); auto matrix = canvas->GetTotalMatrix(); matrix.Set(Drawing::Matrix::TRANS_X, std::ceil(matrix.Get(Drawing::Matrix::TRANS_X))); matrix.Set(Drawing::Matrix::TRANS_Y, std::ceil(matrix.Get(Drawing::Matrix::TRANS_Y))); @@ -703,8 +702,8 @@ Drawing::Path RSPropertyDrawableUtils::CreateShadowPath(const std::shared_ptrClipPath(path, Drawing::ClipOp::DIFFERENCE, true); } @@ -754,6 +753,12 @@ void RSPropertyDrawableUtils::DrawUseEffect(RSPaintFilterCanvas* canvas) void RSPropertyDrawableUtils::BeginBlendMode(RSPaintFilterCanvas& canvas, int blendMode, int blendModeApplyType) { + if (!canvas.HasOffscreenLayer() && RSPropertiesPainter::IsDangerousBlendMode(blendMode - 1, blendModeApplyType)) { + Drawing::SaveLayerOps maskLayerRec(nullptr, nullptr, 0); + canvas.SaveLayer(maskLayerRec); + ROSEN_LOGD("Dangerous offscreen blendmode may produce transparent pixels, add extra offscreen here."); + } + // fast blend mode if (blendModeApplyType == static_cast(RSColorBlendApplyType::FAST)) { canvas.SetBlendMode({ blendMode - 1 }); // map blendMode to SkBlendMode @@ -761,10 +766,8 @@ void RSPropertyDrawableUtils::BeginBlendMode(RSPaintFilterCanvas& canvas, int bl } // save layer mode - auto matrix = canvas.GetTotalMatrix(); - matrix.Set(Drawing::Matrix::TRANS_X, std::ceil(matrix.Get(Drawing::Matrix::TRANS_X))); - matrix.Set(Drawing::Matrix::TRANS_Y, std::ceil(matrix.Get(Drawing::Matrix::TRANS_Y))); - canvas.SetMatrix(matrix); + CeilMatrixTrans(&canvas); + Drawing::Brush blendBrush_; blendBrush_.SetAlphaF(canvas.GetAlpha()); blendBrush_.SetBlendMode(static_cast(blendMode - 1)); // map blendMode to Drawing::BlendMode @@ -775,11 +778,12 @@ void RSPropertyDrawableUtils::BeginBlendMode(RSPaintFilterCanvas& canvas, int bl canvas.SetAlpha(1.0f); } -void RSPropertyDrawableUtils::EndBlendMode(RSPaintFilterCanvas& canvas) +void RSPropertyDrawableUtils::EndBlendMode(RSPaintFilterCanvas& canvas, int blendModeApplyType) { - canvas.RestoreEnv(); - canvas.RestoreAlpha(); - canvas.Restore(); + // RSRenderNodeDrawable will do other necessary work (restore canvas & env), we only need to restore alpha + if (blendModeApplyType != static_cast(RSColorBlendApplyType::FAST)) { + canvas.RestoreAlpha(); + } } Color RSPropertyDrawableUtils::CalculateInvertColor(const Color& backgroundColor) diff --git a/rosen/modules/render_service_base/src/pipeline/rs_paint_filter_canvas.cpp b/rosen/modules/render_service_base/src/pipeline/rs_paint_filter_canvas.cpp index 31e59f74b9..fe54c0cfbe 100644 --- a/rosen/modules/render_service_base/src/pipeline/rs_paint_filter_canvas.cpp +++ b/rosen/modules/render_service_base/src/pipeline/rs_paint_filter_canvas.cpp @@ -902,17 +902,18 @@ CoreCanvas& RSPaintFilterCanvasBase::DetachPaint() } RSPaintFilterCanvas::RSPaintFilterCanvas(Drawing::Canvas* canvas, float alpha) - : RSPaintFilterCanvasBase(canvas), alphaStack_({ std::clamp(alpha, 0.f, 1.f) }), // construct stack with given alpha - // Temporary fix, this default color should be 0x000000FF, fix this after foreground color refactor - envStack_({ Env({ RSColor(0xFF000000) }) }) // construct stack with default foreground color -{} + : RSPaintFilterCanvasBase(canvas), alphaStack_({ 1.0f }), + envStack_({ Env { .envForegroundColor_ = RSColor(0xFF000000), .hasOffscreenLayer_ = false } }) +{ + (void)alpha; // alpha is no longer used, but we keep it for backward compatibility +} RSPaintFilterCanvas::RSPaintFilterCanvas(Drawing::Surface* surface, float alpha) - : RSPaintFilterCanvasBase(surface ? surface->GetCanvas().get() : nullptr), surface_(surface), - alphaStack_({ std::clamp(alpha, 0.f, 1.f) }), // construct stack with given alpha - // Temporary fix, this default color should be 0x000000FF, fix this after foreground color refactor - envStack_({ Env({ RSColor(0xFF000000) }) }) // construct stack with default foreground color -{} + : RSPaintFilterCanvasBase(surface ? surface->GetCanvas().get() : nullptr), surface_(surface), alphaStack_({ 1.0f }), + envStack_({ Env { .envForegroundColor_ = RSColor(0xFF000000), .hasOffscreenLayer_ = false } }) +{ + (void)alpha; // alpha is no longer used, but we keep it for backward compatibility +} Drawing::Surface* RSPaintFilterCanvas::GetSurface() const { @@ -1365,5 +1366,14 @@ bool RSPaintFilterCanvas::GetRecordDrawable() const { return recordDrawable_; } +bool RSPaintFilterCanvas::HasOffscreenLayer() const +{ + return envStack_.top().hasOffscreenLayer_; +} +void RSPaintFilterCanvas::SaveLayer(const Drawing::SaveLayerOps& saveLayerOps) +{ + envStack_.top().hasOffscreenLayer_ = true; + RSPaintFilterCanvasBase::SaveLayer(saveLayerOps); +} } // namespace Rosen } // namespace OHOS diff --git a/rosen/modules/render_service_base/src/platform/ohos/overdraw/rs_listened_canvas.cpp b/rosen/modules/render_service_base/src/platform/ohos/overdraw/rs_listened_canvas.cpp index b10462f5b4..cc8584a563 100644 --- a/rosen/modules/render_service_base/src/platform/ohos/overdraw/rs_listened_canvas.cpp +++ b/rosen/modules/render_service_base/src/platform/ohos/overdraw/rs_listened_canvas.cpp @@ -20,15 +20,9 @@ namespace OHOS { namespace Rosen { -RSListenedCanvas::RSListenedCanvas(Drawing::Canvas& canvas, float alpha) - : RSPaintFilterCanvas(&canvas, alpha) -{ -} +RSListenedCanvas::RSListenedCanvas(Drawing::Canvas& canvas) : RSPaintFilterCanvas(&canvas) {} -RSListenedCanvas::RSListenedCanvas(Drawing::Surface& surface, float alpha) - : RSPaintFilterCanvas(&surface, alpha) -{ -} +RSListenedCanvas::RSListenedCanvas(Drawing::Surface& surface) : RSPaintFilterCanvas(&surface) {} void RSListenedCanvas::SetListener(const std::shared_ptr &listener) { diff --git a/rosen/modules/render_service_base/src/property/rs_property_drawable_bounds_geometry.cpp b/rosen/modules/render_service_base/src/property/rs_property_drawable_bounds_geometry.cpp index f864891fa3..1be2984830 100644 --- a/rosen/modules/render_service_base/src/property/rs_property_drawable_bounds_geometry.cpp +++ b/rosen/modules/render_service_base/src/property/rs_property_drawable_bounds_geometry.cpp @@ -17,25 +17,16 @@ #include -#include "include/core/SkMaskFilter.h" -#include "include/core/SkPaint.h" -#include "include/core/SkPoint3.h" -#include "include/effects/SkImageFilters.h" -#include "include/effects/SkLumaColorFilter.h" -#include "include/utils/SkShadowUtils.h" -#include "src/image/SkImage_Base.h" - #include "common/rs_obj_abs_geometry.h" #include "common/rs_optional_trace.h" #include "pipeline/rs_canvas_render_node.h" #include "pipeline/rs_effect_render_node.h" #include "pipeline/rs_paint_filter_canvas.h" #include "platform/common/rs_log.h" +#include "platform/common/rs_system_properties.h" #include "property/rs_properties.h" #include "property/rs_properties_def.h" #include "property/rs_properties_painter.h" -#include "render/rs_skia_filter.h" -#include "platform/common/rs_system_properties.h" namespace { constexpr int PARAM_DOUBLE = 2; @@ -1096,9 +1087,9 @@ RSBlendSaveLayerDrawable::RSBlendSaveLayerDrawable(int blendMode) void RSBlendSaveLayerDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const { - if (canvas.GetBlendOffscreenLayerCnt() == 0 && - RSPropertiesPainter::IsDangerousBlendMode(static_cast(blendBrush_.GetBlendMode()), - static_cast(RSColorBlendApplyType::SAVE_LAYER))) { + if (!canvas.HasOffscreenLayer() && + RSPropertiesPainter::IsDangerousBlendMode( + static_cast(blendBrush_.GetBlendMode()), static_cast(RSColorBlendApplyType::SAVE_LAYER))) { Drawing::SaveLayerOps maskLayerRec(nullptr, nullptr, 0); canvas.SaveLayer(maskLayerRec); ROSEN_LOGD("Dangerous offscreen blendmode may produce transparent pixels, add extra offscreen here."); @@ -1118,7 +1109,7 @@ void RSBlendSaveLayerDrawable::Draw(const RSRenderContent& content, RSPaintFilte void RSBlendFastDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const { - if (canvas.GetBlendOffscreenLayerCnt() == 0 && + if (!canvas.HasOffscreenLayer() && RSPropertiesPainter::IsDangerousBlendMode(blendMode_ - 1, static_cast(RSColorBlendApplyType::FAST))) { Drawing::SaveLayerOps maskLayerRec(nullptr, nullptr, 0); canvas.SaveLayer(maskLayerRec); @@ -1127,16 +1118,14 @@ void RSBlendFastDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanv canvas.SetBlendMode({ blendMode_ - 1 }); // map blendMode to SkBlendMode } - void RSBlendSaveLayerRestoreDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const { - canvas.RestoreAlpha(); - canvas.Restore(); + // SAVE_ALL slot will do all necessary restore } void RSBlendFastRestoreDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const { - canvas.Restore(); + // SAVE_ALL slot will do all necessary restore } } // namespace OHOS::Rosen From 45c8e98015fed72f7d69063397d7f191a05884e3 Mon Sep 17 00:00:00 2001 From: Zhang Peng Date: Wed, 17 Apr 2024 16:47:28 +0800 Subject: [PATCH 2/5] misc refactor UpdateDisplayList Signed-off-by: Zhang Peng Change-Id: Icbee61d3737f17d85dd0c7918887ebdaa18d636c --- .../src/pipeline/rs_render_node.cpp | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) 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 2678ad1024..4534930318 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 @@ -2107,61 +2107,62 @@ void RSRenderNode::UpdateDisplayList() return; } + int8_t index = 0; // Note: the loop range is [begin, end], both end is included. - auto AppendDrawFunc = [&](RSDrawableSlot begin, RSDrawableSlot end) -> int8_t { - auto beginIndex = static_cast(begin); + auto AppendDrawFunc = [&](RSDrawableSlot end) -> int8_t { auto endIndex = static_cast(end); - for (int8_t i = beginIndex; i <= endIndex; ++i) { - if (const auto& drawable = drawableVec_[i]) { + for (; index <= endIndex; ++index) { + if (const auto& drawable = drawableVec_[index]) { stagingDrawCmdList_.emplace_back(drawable->CreateDrawFunc()); } } - // If the last drawable exist, return its index, otherwise return -1 + // If the end drawable exist, return its index, otherwise return -1 return drawableVec_[endIndex] != nullptr ? stagingDrawCmdList_.size() - 1 : -1; }; // Update index of SHADOW - stagingDrawCmdIndex_.shadowIndex_ = AppendDrawFunc(RSDrawableSlot::SAVE_ALL, RSDrawableSlot::SHADOW); + stagingDrawCmdIndex_.shadowIndex_ = AppendDrawFunc(RSDrawableSlot::SHADOW); - AppendDrawFunc(RSDrawableSlot::FOREGROUND_FILTER, RSDrawableSlot::OUTLINE); + AppendDrawFunc(RSDrawableSlot::OUTLINE); stagingDrawCmdIndex_.renderGroupBeginIndex_ = stagingDrawCmdList_.size(); // Update index of BACKGROUND_COLOR stagingDrawCmdIndex_.backgroundColorIndex_ = - AppendDrawFunc(RSDrawableSlot::BG_SAVE_BOUNDS, RSDrawableSlot::BACKGROUND_COLOR); + AppendDrawFunc(RSDrawableSlot::BACKGROUND_COLOR); // Update index of BACKGROUND_FILTER stagingDrawCmdIndex_.backgroundFilterIndex_ = - AppendDrawFunc(RSDrawableSlot::BACKGROUND_SHADER, RSDrawableSlot::BACKGROUND_FILTER); + AppendDrawFunc(RSDrawableSlot::BACKGROUND_FILTER); // Update index of USE_EFFECT - stagingDrawCmdIndex_.useEffectIndex_ = AppendDrawFunc(RSDrawableSlot::USE_EFFECT, RSDrawableSlot::USE_EFFECT); + stagingDrawCmdIndex_.useEffectIndex_ = AppendDrawFunc(RSDrawableSlot::USE_EFFECT); - AppendDrawFunc(RSDrawableSlot::BACKGROUND_STYLE, RSDrawableSlot::BG_RESTORE_BOUNDS); + AppendDrawFunc(RSDrawableSlot::BG_RESTORE_BOUNDS); if (drawableVecStatus_ & FRAME_PROPERTY) { // Update index of CONTENT_STYLE - stagingDrawCmdIndex_.contentIndex_ = AppendDrawFunc(RSDrawableSlot::SAVE_FRAME, RSDrawableSlot::CONTENT_STYLE); + stagingDrawCmdIndex_.contentIndex_ = AppendDrawFunc(RSDrawableSlot::CONTENT_STYLE); // Update index of BACKGROUND_END stagingDrawCmdIndex_.backgroundEndIndex_ = stagingDrawCmdIndex_.contentIndex_ == -1 ? stagingDrawCmdList_.size() : stagingDrawCmdIndex_.contentIndex_; // Update index of CHILDREN - stagingDrawCmdIndex_.childrenIndex_ = AppendDrawFunc(RSDrawableSlot::CHILDREN, RSDrawableSlot::CHILDREN); + stagingDrawCmdIndex_.childrenIndex_ = AppendDrawFunc(RSDrawableSlot::CHILDREN); stagingDrawCmdIndex_.foregroundBeginIndex_ = stagingDrawCmdList_.size(); - AppendDrawFunc(RSDrawableSlot::FOREGROUND_STYLE, RSDrawableSlot::RESTORE_FRAME); + AppendDrawFunc(RSDrawableSlot::RESTORE_FRAME); } else { // Nothing inside frame, skip useless slots and update indexes stagingDrawCmdIndex_.contentIndex_ = -1; stagingDrawCmdIndex_.childrenIndex_ = -1; stagingDrawCmdIndex_.backgroundEndIndex_ = stagingDrawCmdList_.size(); stagingDrawCmdIndex_.foregroundBeginIndex_ = stagingDrawCmdList_.size(); + index = static_cast(RSDrawableSlot::FG_SAVE_BOUNDS); } stagingDrawCmdIndex_.renderGroupEndIndex_ = stagingDrawCmdList_.size(); - AppendDrawFunc(RSDrawableSlot::FG_SAVE_BOUNDS, RSDrawableSlot::RESTORE_ALL); + AppendDrawFunc(RSDrawableSlot::RESTORE_ALL); stagingDrawCmdIndex_.endIndex_ = stagingDrawCmdList_.size(); stagingRenderParams_->SetContentEmpty(false); #endif From 521a2a56c2c6a822cd67eb1f78c94adc1a88b564 Mon Sep 17 00:00:00 2001 From: Zhang Peng Date: Tue, 16 Apr 2024 14:47:02 +0800 Subject: [PATCH 3/5] minor refactor on RSDrawable::CalculateDirtySlots, fix corner radius issues Signed-off-by: Zhang Peng Change-Id: I4f59fc2d49c6a3c20d2d2c0b697f13854db8f655 --- .../src/drawable/rs_drawable.cpp | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp b/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp index a2d56d3a87..c83591df20 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp @@ -16,11 +16,13 @@ #include "drawable/rs_drawable.h" #include + #include "drawable/rs_misc_drawable.h" #include "drawable/rs_property_drawable.h" #include "drawable/rs_property_drawable_background.h" #include "drawable/rs_property_drawable_foreground.h" #include "pipeline/rs_render_node.h" +#include "pipeline/rs_surface_render_node.h" namespace OHOS::Rosen { namespace { @@ -243,9 +245,11 @@ static uint8_t CalculateDrawableVecStatus(RSRenderNode& node, const RSDrawable:: uint8_t result = 0; auto& properties = node.GetRenderProperties(); - // color blend mode has implicit dependency on clipToBounds - if (properties.GetClipToBounds() || properties.GetClipToRRect() || properties.GetClipBounds() != nullptr || - properties.GetColorBlendMode() != static_cast(RSColorBlendMode::NONE)) { + // ClipToBounds if either 1. is surface node, 2. has explicit clip properties, 3. has blend mode + bool shouldClipToBounds = node.IsInstanceOf() || properties.GetClipToBounds() || + properties.GetClipToRRect() || properties.GetClipBounds() != nullptr || + properties.GetColorBlendMode() != static_cast(RSColorBlendMode::NONE); + if (shouldClipToBounds) { result |= DrawableVecStatus::CLIP_TO_BOUNDS; } @@ -303,6 +307,7 @@ inline static void SaveRestoreHelper(RSDrawable::Vec& drawableVec, RSDrawableSlo static void OptimizeBoundsSaveRestore(RSRenderNode& node, RSDrawable::Vec& drawableVec, uint8_t flags) { + // Erase existing save/clip/restore before re-generating constexpr static std::array boundsSlotsToErase = { RSDrawableSlot::BG_SAVE_BOUNDS, RSDrawableSlot::CLIP_TO_BOUNDS, @@ -311,8 +316,6 @@ static void OptimizeBoundsSaveRestore(RSRenderNode& node, RSDrawable::Vec& drawa RSDrawableSlot::FG_CLIP_TO_BOUNDS, RSDrawableSlot::FG_RESTORE_BOUNDS, }; - - // Erase existing save/clip/restore before re-generating for (auto& slot : boundsSlotsToErase) { drawableVec[static_cast(slot)] = nullptr; } @@ -424,31 +427,38 @@ std::unordered_set RSDrawable::CalculateDirtySlots( } // Step 1.2: expand dirty slots by rules - // planning: border etc. should be updated when border radius changed - if (dirtySlots.count(RSDrawableSlot::FRAME_OFFSET)) { - if (drawableVec[static_cast(RSDrawableSlot::CLIP_TO_FRAME)]) { - dirtySlots.emplace(RSDrawableSlot::CLIP_TO_FRAME); - } - } - - // Step 1.3: 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)); + // if bounds or cornerRadius changed, mark affected drawables as dirty + static constexpr std::array boundsDirtyTypes = { + RSDrawableSlot::MASK, + RSDrawableSlot::SHADOW, + RSDrawableSlot::OUTLINE, + RSDrawableSlot::CLIP_TO_BOUNDS, + RSDrawableSlot::BACKGROUND_COLOR, + RSDrawableSlot::BACKGROUND_SHADER, + RSDrawableSlot::BACKGROUND_IMAGE, + RSDrawableSlot::ENV_FOREGROUND_COLOR_STRATEGY, + RSDrawableSlot::FG_CLIP_TO_BOUNDS, + RSDrawableSlot::FOREGROUND_COLOR, + RSDrawableSlot::POINT_LIGHT, + RSDrawableSlot::BORDER, + RSDrawableSlot::PIXEL_STRETCH, + }; + if (dirtyTypes.test(static_cast(RSModifierType::BOUNDS)) || + dirtyTypes.test(static_cast(RSModifierType::CORNER_RADIUS))) { + for (auto slot : boundsDirtyTypes) { + if (drawableVec[static_cast(slot)]) { + dirtySlots.emplace(slot); } } } - // Step 1.4: if corner radius changed, update border and outline - if (dirtyTypes.test(static_cast(RSModifierType::CORNER_RADIUS))) { - // border may should be updated with corner radius - if (drawableVec[static_cast(RSDrawableSlot::BORDER)]) { - dirtySlots.emplace(RSDrawableSlot::BORDER); + // if frame changed, mark affected drawables as dirty + if (dirtySlots.count(RSDrawableSlot::FRAME_OFFSET)) { + if (drawableVec[static_cast(RSDrawableSlot::CLIP_TO_FRAME)]) { + dirtySlots.emplace(RSDrawableSlot::CLIP_TO_FRAME); } - - if (drawableVec[static_cast(RSDrawableSlot::OUTLINE)]) { - dirtySlots.emplace(RSDrawableSlot::OUTLINE); + if (drawableVec[static_cast(RSDrawableSlot::FOREGROUND_FILTER)]) { + dirtySlots.emplace(RSDrawableSlot::FOREGROUND_FILTER); } } From 8672ec2a9e0461ef96f0eba35bf1e020646564b8 Mon Sep 17 00:00:00 2001 From: Zhang Peng Date: Wed, 17 Apr 2024 14:26:55 +0800 Subject: [PATCH 4/5] fix background color for surface node Signed-off-by: Zhang Peng Change-Id: I3878c29e90eb2b0ab376a887658ffbf7a7c98d4c --- .../rs_render_node_shadow_drawable.cpp | 2 +- .../rs_surface_render_node_drawable.cpp | 3 +++ .../rs_render_node_drawable_adapter.h | 13 ++++++---- .../src/drawable/rs_misc_drawable.cpp | 6 ++--- .../rs_render_node_drawable_adapter.cpp | 24 +++++++++++++++---- 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/rosen/modules/render_service/core/drawable/rs_render_node_shadow_drawable.cpp b/rosen/modules/render_service/core/drawable/rs_render_node_shadow_drawable.cpp index b34d2c8dce..961fa4d412 100644 --- a/rosen/modules/render_service/core/drawable/rs_render_node_shadow_drawable.cpp +++ b/rosen/modules/render_service/core/drawable/rs_render_node_shadow_drawable.cpp @@ -53,7 +53,7 @@ void RSRenderNodeShadowDrawable::Draw(Drawing::Canvas& canvas) return; } - SetSkipShadow(false); + SetSkip(SkipType::NONE); DrawRangeImpl(canvas, rect, 0, shadowIndex + 1); } diff --git a/rosen/modules/render_service/core/drawable/rs_surface_render_node_drawable.cpp b/rosen/modules/render_service/core/drawable/rs_surface_render_node_drawable.cpp index a45be47816..2b674798d2 100644 --- a/rosen/modules/render_service/core/drawable/rs_surface_render_node_drawable.cpp +++ b/rosen/modules/render_service/core/drawable/rs_surface_render_node_drawable.cpp @@ -173,6 +173,7 @@ void RSSurfaceRenderNodeDrawable::OnDraw(Drawing::Canvas& canvas) bool isSelfDrawingSurface = surfaceParams->GetSurfaceNodeType() == RSSurfaceNodeType::SELF_DRAWING_NODE; if (isSelfDrawingSurface && !surfaceParams->IsSpherizeValid()) { + SetSkip(surfaceParams->GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE); rscanvas->Save(); } @@ -299,6 +300,7 @@ void RSSurfaceRenderNodeDrawable::CaptureSingleSurfaceNode(RSSurfaceRenderNode& auto nodeType = surfaceParams.GetSurfaceNodeType(); bool isSelfDrawingSurface = (nodeType == RSSurfaceNodeType::SELF_DRAWING_NODE); if (isSelfDrawingSurface && !surfaceParams.IsSpherizeValid()) { + SetSkip(surfaceParams.GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE); canvas.Save(); } @@ -389,6 +391,7 @@ void RSSurfaceRenderNodeDrawable::CaptureSurfaceInDisplay(RSSurfaceRenderNode& s auto nodeType = surfaceParams.GetSurfaceNodeType(); bool isSelfDrawingSurface = (nodeType == RSSurfaceNodeType::SELF_DRAWING_NODE); if (isSelfDrawingSurface) { + SetSkip(surfaceParams.GetBuffer() != nullptr ? SkipType::SKIP_BACKGROUND_COLOR : SkipType::NONE); canvas.Save(); } diff --git a/rosen/modules/render_service_base/include/drawable/rs_render_node_drawable_adapter.h b/rosen/modules/render_service_base/include/drawable/rs_render_node_drawable_adapter.h index 4970b6849a..7949f4d3b1 100644 --- a/rosen/modules/render_service_base/include/drawable/rs_render_node_drawable_adapter.h +++ b/rosen/modules/render_service_base/include/drawable/rs_render_node_drawable_adapter.h @@ -33,6 +33,12 @@ class Canvas; } namespace DrawableV2 { +enum class SkipType : uint8_t { + NONE = 0, + SKIP_SHADOW = 1, + SKIP_BACKGROUND_COLOR = 2 +}; + class RSB_EXPORT RSRenderNodeDrawableAdapter { public: explicit RSRenderNodeDrawableAdapter(std::shared_ptr&& node); @@ -55,10 +61,7 @@ public: static SharedPtr GetDrawableById(NodeId id); static SharedPtr OnGenerateShadowDrawable(const std::shared_ptr& node); - void SetSkipShadow(bool skip) - { - skipShadow_ = skip; - } + void SetSkip(SkipType type); protected: // Util functions @@ -109,7 +112,7 @@ private: static Generator shadowGenerator_; static std::map RenderNodeDrawableCache; static inline std::mutex cacheMapMutex_; - bool skipShadow_ = false; + int8_t skipIndex_ = -1; }; } // namespace DrawableV2 diff --git a/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp b/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp index 3fd34d649f..09a2ad04d2 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_misc_drawable.cpp @@ -45,7 +45,7 @@ bool RSChildrenDrawable::OnUpdate(const RSRenderNode& node) continue; } if (auto childDrawable = RSRenderNodeDrawableAdapter::OnGenerate(child)) { - childDrawable->SetSkipShadow(false); + childDrawable->SetSkip(SkipType::NONE); stagingChildrenDrawableVec_.push_back(std::move(childDrawable)); } } @@ -63,7 +63,7 @@ bool RSChildrenDrawable::OnUpdate(const RSRenderNode& node) stagingChildrenDrawableVec_.push_back(std::move(shadowDrawable)); } if (auto childDrawable = RSRenderNodeDrawableAdapter::OnGenerate(child)) { - childDrawable->SetSkipShadow(true); + childDrawable->SetSkip(SkipType::SKIP_SHADOW); pendingChildren.push_back(std::move(childDrawable)); } } @@ -107,7 +107,7 @@ bool RSChildrenDrawable::OnSharedTransition(const RSRenderNode::SharedPtr& node) // for higher hierarchy node, we add paired node (lower in hierarchy) first, then add it if (auto childDrawable = RSRenderNodeDrawableAdapter::OnGenerate(pairedNode)) { // NOTE: skip shared-transition shadow for now - childDrawable->SetSkipShadow(true); + childDrawable->SetSkip(SkipType::SKIP_SHADOW); stagingChildrenDrawableVec_.push_back(std::move(childDrawable)); } } diff --git a/rosen/modules/render_service_base/src/drawable/rs_render_node_drawable_adapter.cpp b/rosen/modules/render_service_base/src/drawable/rs_render_node_drawable_adapter.cpp index 95f8dd81ed..245e6afe90 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_render_node_drawable_adapter.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_render_node_drawable_adapter.cpp @@ -129,13 +129,12 @@ void RSRenderNodeDrawableAdapter::DrawRangeImpl( const auto& drawCmdList_ = renderNode_->drawCmdList_; - if (UNLIKELY(skipShadow_)) { - auto shadowIndex = renderNode_->drawCmdIndex_.shadowIndex_; - if (shadowIndex != -1 || start <= shadowIndex || end > shadowIndex) { - for (auto i = start; i < shadowIndex; i++) { + if (UNLIKELY(skipIndex_ != -1)) { + if (start <= skipIndex_ || end > skipIndex_) { + for (auto i = start; i < skipIndex_; i++) { drawCmdList_[i](&canvas, &rect); } - for (auto i = shadowIndex + 1; i < end; i++) { + for (auto i = skipIndex_ + 1; i < end; i++) { drawCmdList_[i](&canvas, &rect); } } @@ -326,4 +325,19 @@ bool RSRenderNodeDrawableAdapter::HasFilterOrEffect() const return renderNode_->drawCmdIndex_.shadowIndex_ != -1 || renderNode_->drawCmdIndex_.backgroundFilterIndex_ != -1 || renderNode_->drawCmdIndex_.useEffectIndex_ != -1; } +void RSRenderNodeDrawableAdapter::SetSkip(SkipType type) +{ + switch (type) { + case SkipType::SKIP_BACKGROUND_COLOR: + skipIndex_ = renderNode_->drawCmdIndex_.backgroundColorIndex_; + break; + case SkipType::SKIP_SHADOW: + skipIndex_ = renderNode_->drawCmdIndex_.shadowIndex_; + break; + case SkipType::NONE: + default: + skipIndex_ = -1; + break; + } +} } // namespace OHOS::Rosen::DrawableV2 From e392476235d5693274657d34deeb52de292f55f8 Mon Sep 17 00:00:00 2001 From: Zhang Peng Date: Wed, 17 Apr 2024 18:12:12 +0800 Subject: [PATCH 5/5] add static_assert to check LUT size Signed-off-by: Zhang Peng Change-Id: I6e825857f359fc0b54febaeec60bb8f8d2289fc0 --- .../include/modifier/rs_modifier_type.h | 232 +++++++++--------- .../src/drawable/rs_drawable.cpp | 32 ++- .../src/property/rs_properties.cpp | 6 +- 3 files changed, 145 insertions(+), 125 deletions(-) diff --git a/rosen/modules/render_service_base/include/modifier/rs_modifier_type.h b/rosen/modules/render_service_base/include/modifier/rs_modifier_type.h index fdc190db08..54e7192f0d 100644 --- a/rosen/modules/render_service_base/include/modifier/rs_modifier_type.h +++ b/rosen/modules/render_service_base/include/modifier/rs_modifier_type.h @@ -27,122 +27,122 @@ namespace Rosen { // b. g_propertyToDrawableLut in rs_drawable_content.cpp // 2. Property modifier(i.e. to be applied to RSProperties) MUST be added before CUSTOM enum, else wise it will not work enum class RSModifierType : int16_t { - INVALID = 0, // 0 - BOUNDS, // 1 - FRAME, // 2 - POSITION_Z, // 3 - PIVOT, // 4 - PIVOT_Z, // 5 - QUATERNION, // 6 - ROTATION, // 7 - ROTATION_X, // 8 - ROTATION_Y, // 9 - CAMERA_DISTANCE, // 10 - SCALE, // 11 - SKEW, // 12 - PERSP, // 13 - TRANSLATE, // 14 - TRANSLATE_Z, // 15 - SUBLAYER_TRANSFORM, // 16 - CORNER_RADIUS, // 17 - ALPHA, // 18 - ALPHA_OFFSCREEN, // 19 - FOREGROUND_COLOR, // 20 - BACKGROUND_COLOR, // 21 - BACKGROUND_SHADER, // 22 - BG_IMAGE, // 23 - BG_IMAGE_INNER_RECT, // 24 - BG_IMAGE_WIDTH, // 25 - BG_IMAGE_HEIGHT, // 26 - BG_IMAGE_POSITION_X, // 27 - BG_IMAGE_POSITION_Y, // 28 - SURFACE_BG_COLOR, // 29 - BORDER_COLOR, // 30 - BORDER_WIDTH, // 31 - BORDER_STYLE, // 32 - FILTER, // 33 - BACKGROUND_FILTER, // 34 - LINEAR_GRADIENT_BLUR_PARA, // 35 - DYNAMIC_LIGHT_UP_RATE, // 36 - DYNAMIC_LIGHT_UP_DEGREE, // 37 - FRAME_GRAVITY, // 38 - CLIP_RRECT, // 39 - CLIP_BOUNDS, // 40 - CLIP_TO_BOUNDS, // 41 - CLIP_TO_FRAME, // 42 - VISIBLE, // 43 - SHADOW_COLOR, // 44 - SHADOW_OFFSET_X, // 45 - SHADOW_OFFSET_Y, // 46 - SHADOW_ALPHA, // 47 - SHADOW_ELEVATION, // 48 - SHADOW_RADIUS, // 49 - SHADOW_PATH, // 50 - SHADOW_MASK, // 51 - SHADOW_COLOR_STRATEGY, // 52 - MASK, // 53 - SPHERIZE, // 54 - LIGHT_UP_EFFECT, // 55 - PIXEL_STRETCH, // 56 - PIXEL_STRETCH_PERCENT, // 57 - USE_EFFECT, // 58 - COLOR_BLEND_MODE, // 59 - COLOR_BLEND_APPLY_TYPE, // 60 - SANDBOX, // 61 - GRAY_SCALE, // 62 - BRIGHTNESS, // 63 - CONTRAST, // 64 - SATURATE, // 65 - SEPIA, // 66 - INVERT, // 67 - AIINVERT, // 68 - SYSTEMBAREFFECT, // 69 - HUE_ROTATE, // 70 - COLOR_BLEND, // 71 - PARTICLE, // 72 - SHADOW_IS_FILLED, // 73 - OUTLINE_COLOR, // 74 - OUTLINE_WIDTH, // 75 - OUTLINE_STYLE, // 76 - OUTLINE_RADIUS, // 77 - USE_SHADOW_BATCHING, // 78 - GREY_COEF, // 79 - LIGHT_INTENSITY, // 80 - LIGHT_COLOR, // 81 - LIGHT_POSITION, // 82 - ILLUMINATED_BORDER_WIDTH, // 83 - ILLUMINATED_TYPE, // 84 - BLOOM, // 85 - PARTICLE_EMITTER_UPDATER, // 86 - FOREGROUND_EFFECT_RADIUS, // 87 - MOTION_BLUR_PARA, // 88 - DYNAMIC_DIM_DEGREE, // 89 - BACKGROUND_BLUR_RADIUS, // 90 - BACKGROUND_BLUR_SATURATION, // 91 - BACKGROUND_BLUR_BRIGHTNESS, // 92 - BACKGROUND_BLUR_MASK_COLOR, // 93 - BACKGROUND_BLUR_COLOR_MODE, // 94 - BACKGROUND_BLUR_RADIUS_X, // 95 - BACKGROUND_BLUR_RADIUS_Y, // 96 - FOREGROUND_BLUR_RADIUS, // 97 - FOREGROUND_BLUR_SATURATION, // 98 - FOREGROUND_BLUR_BRIGHTNESS, // 99 - FOREGROUND_BLUR_MASK_COLOR, // 100 - FOREGROUND_BLUR_COLOR_MODE, // 101 - FOREGROUND_BLUR_RADIUS_X, // 102 - FOREGROUND_BLUR_RADIUS_Y, // 103 - CUSTOM, // 104 - EXTENDED, // 105 - TRANSITION, // 106 - BACKGROUND_STYLE, // 107 - CONTENT_STYLE, // 108 - FOREGROUND_STYLE, // 109 - OVERLAY_STYLE, // 110 - NODE_MODIFIER, // 111 - ENV_FOREGROUND_COLOR, // 112 - ENV_FOREGROUND_COLOR_STRATEGY, // 113 - GEOMETRYTRANS, // 114 - CHILDREN, // 115, PLACEHOLDER, no such modifier, but we need a dirty flag + INVALID = 0, + BOUNDS, + FRAME, + POSITION_Z, + PIVOT, + PIVOT_Z, + QUATERNION, + ROTATION, + ROTATION_X, + ROTATION_Y, + CAMERA_DISTANCE, + SCALE, + SKEW, + PERSP, + TRANSLATE, + TRANSLATE_Z, + SUBLAYER_TRANSFORM, + CORNER_RADIUS, + ALPHA, + ALPHA_OFFSCREEN, + FOREGROUND_COLOR, + BACKGROUND_COLOR, + BACKGROUND_SHADER, + BG_IMAGE, + BG_IMAGE_INNER_RECT, + BG_IMAGE_WIDTH, + BG_IMAGE_HEIGHT, + BG_IMAGE_POSITION_X, + BG_IMAGE_POSITION_Y, + SURFACE_BG_COLOR, + BORDER_COLOR, + BORDER_WIDTH, + BORDER_STYLE, + FILTER, + BACKGROUND_FILTER, + LINEAR_GRADIENT_BLUR_PARA, + DYNAMIC_LIGHT_UP_RATE, + DYNAMIC_LIGHT_UP_DEGREE, + FRAME_GRAVITY, + CLIP_RRECT, + CLIP_BOUNDS, + CLIP_TO_BOUNDS, + CLIP_TO_FRAME, + VISIBLE, + SHADOW_COLOR, + SHADOW_OFFSET_X, + SHADOW_OFFSET_Y, + SHADOW_ALPHA, + SHADOW_ELEVATION, + SHADOW_RADIUS, + SHADOW_PATH, + SHADOW_MASK, + SHADOW_COLOR_STRATEGY, + MASK, + SPHERIZE, + LIGHT_UP_EFFECT, + PIXEL_STRETCH, + PIXEL_STRETCH_PERCENT, + USE_EFFECT, + COLOR_BLEND_MODE, + COLOR_BLEND_APPLY_TYPE, + SANDBOX, + GRAY_SCALE, + BRIGHTNESS, + CONTRAST, + SATURATE, + SEPIA, + INVERT, + AIINVERT, + SYSTEMBAREFFECT, + HUE_ROTATE, + COLOR_BLEND, + PARTICLE, + SHADOW_IS_FILLED, + OUTLINE_COLOR, + OUTLINE_WIDTH, + OUTLINE_STYLE, + OUTLINE_RADIUS, + USE_SHADOW_BATCHING, + GREY_COEF, + LIGHT_INTENSITY, + LIGHT_COLOR, + LIGHT_POSITION, + ILLUMINATED_BORDER_WIDTH, + ILLUMINATED_TYPE, + BLOOM, + PARTICLE_EMITTER_UPDATER, + FOREGROUND_EFFECT_RADIUS, + MOTION_BLUR_PARA, + DYNAMIC_DIM_DEGREE, + BACKGROUND_BLUR_RADIUS, + BACKGROUND_BLUR_SATURATION, + BACKGROUND_BLUR_BRIGHTNESS, + BACKGROUND_BLUR_MASK_COLOR, + BACKGROUND_BLUR_COLOR_MODE, + BACKGROUND_BLUR_RADIUS_X, + BACKGROUND_BLUR_RADIUS_Y, + FOREGROUND_BLUR_RADIUS, + FOREGROUND_BLUR_SATURATION, + FOREGROUND_BLUR_BRIGHTNESS, + FOREGROUND_BLUR_MASK_COLOR, + FOREGROUND_BLUR_COLOR_MODE, + FOREGROUND_BLUR_RADIUS_X, + FOREGROUND_BLUR_RADIUS_Y, + CUSTOM, + EXTENDED, + TRANSITION, + BACKGROUND_STYLE, + CONTENT_STYLE, + FOREGROUND_STYLE, + OVERLAY_STYLE, + NODE_MODIFIER, + ENV_FOREGROUND_COLOR, + ENV_FOREGROUND_COLOR_STRATEGY, + GEOMETRYTRANS, + CHILDREN, // PLACEHOLDER, no such modifier, but we need a dirty flag MAX_RS_MODIFIER_TYPE, }; using ModifierDirtyTypes = std::bitset(RSModifierType::MAX_RS_MODIFIER_TYPE)>; diff --git a/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp b/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp index c83591df20..cf42cc9cc8 100644 --- a/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp +++ b/rosen/modules/render_service_base/src/drawable/rs_drawable.cpp @@ -31,7 +31,7 @@ using namespace DrawableV2; // 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 = { +static constexpr std::array g_propertyToDrawableLut = { RSDrawableSlot::INVALID, // INVALID RSDrawableSlot::CLIP_TO_BOUNDS, // BOUNDS RSDrawableSlot::FRAME_OFFSET, // FRAME @@ -120,6 +120,7 @@ static const std::array g_propertyToDrawableLut RSDrawableSlot::POINT_LIGHT, // BLOOM RSDrawableSlot::PARTICLE_EFFECT, // PARTICLE_EMITTER_UPDATER RSDrawableSlot::FOREGROUND_FILTER, // FOREGROUND_EFFECT_RADIUS + RSDrawableSlot::INVALID, // MOTION_BLUR_PARA RSDrawableSlot::DYNAMIC_DIM, // DYNAMIC_DIM RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_BLUR_RADIUS RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_BLUR_SATURATION @@ -128,13 +129,13 @@ static const std::array g_propertyToDrawableLut RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_BLUR_COLOR_MODE RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_BLUR_RADIUS_X RSDrawableSlot::BACKGROUND_FILTER, // BACKGROUND_BLUR_RADIUS_Y - RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_RADIUS - RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_SATURATION - RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_BRIGHTNESS - RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_MASK_COLOR - RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_COLOR_MODE - RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_RADIUS_X - RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_RADIUS_Y + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_RADIUS + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_SATURATION + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_BRIGHTNESS + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_MASK_COLOR + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_COLOR_MODE + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_RADIUS_X + RSDrawableSlot::COMPOSITING_FILTER, // FOREGROUND_BLUR_RADIUS_Y RSDrawableSlot::INVALID, // CUSTOM RSDrawableSlot::INVALID, // EXTENDED RSDrawableSlot::TRANSITION, // TRANSITION @@ -149,6 +150,21 @@ static const std::array g_propertyToDrawableLut RSDrawableSlot::CHILDREN, // CHILDREN }; +// Check if g_propertyToDrawableLut size match and is fully initialized (the last element should not be default value) +static_assert(g_propertyToDrawableLut.size() == static_cast(RSModifierType::MAX_RS_MODIFIER_TYPE)); +static_assert(g_propertyToDrawableLut.back() != RSDrawableSlot {}); + +// Randomly check some LUT index and value +static_assert(g_propertyToDrawableLut[static_cast(RSModifierType::USE_EFFECT)] == RSDrawableSlot::USE_EFFECT); +static_assert( + g_propertyToDrawableLut[static_cast(RSModifierType::FOREGROUND_COLOR)] == RSDrawableSlot::FOREGROUND_COLOR); +static_assert( + g_propertyToDrawableLut[static_cast(RSModifierType::CLIP_TO_FRAME)] == RSDrawableSlot::CLIP_TO_FRAME); +static_assert( + g_propertyToDrawableLut[static_cast(RSModifierType::USE_SHADOW_BATCHING)] == RSDrawableSlot::CHILDREN); +static_assert(g_propertyToDrawableLut[static_cast(RSModifierType::TRANSITION)] == RSDrawableSlot::TRANSITION); +static_assert(g_propertyToDrawableLut[static_cast(RSModifierType::CHILDREN)] == RSDrawableSlot::CHILDREN); + template static inline RSDrawable::Ptr ModifierGenerator(const RSRenderNode& node) { diff --git a/rosen/modules/render_service_base/src/property/rs_properties.cpp b/rosen/modules/render_service_base/src/property/rs_properties.cpp index 83d7f3726d..a5ca42eff1 100644 --- a/rosen/modules/render_service_base/src/property/rs_properties.cpp +++ b/rosen/modules/render_service_base/src/property/rs_properties.cpp @@ -53,7 +53,7 @@ constexpr uint8_t BORDER_TYPE_NONE = (uint32_t)BorderStyle::NONE; using ResetPropertyFunc = void (*)(RSProperties* prop); // Every modifier before RSModifierType::CUSTOM is property modifier, and it should have a ResetPropertyFunc // NOTE: alway add new resetter when adding new property modifier -const std::array(RSModifierType::CUSTOM)> g_propertyResetterLUT = { +constexpr static std::array(RSModifierType::CUSTOM)> g_propertyResetterLUT = { nullptr, // INVALID nullptr, // BOUNDS nullptr, // FRAME @@ -159,6 +159,10 @@ const std::array(RSModifierType::CUSTOM)> g_ [](RSProperties* prop) { prop->SetForegroundBlurRadiusX(0.f); }, // FOREGROUND_BLUR_RADIUS_X [](RSProperties* prop) { prop->SetForegroundBlurRadiusY(0.f); }, // FOREGROUND_BLUR_RADIUS_Y }; + +// Check if g_propertyResetterLUT size match and is fully initialized (the last element should never be nullptr) +static_assert(g_propertyResetterLUT.size() == static_cast(RSModifierType::CUSTOM)); +static_assert(g_propertyResetterLUT.back() != nullptr); } // namespace // Only enable filter cache when uni-render is enabled and filter cache is enabled