rename and refactor

Signed-off-by: Zhang Peng <zhangpeng280@huawei.com>
This commit is contained in:
Zhang Peng 2024-03-04 15:16:21 +08:00
parent 5ca4892d9b
commit 2458ff41a2
No known key found for this signature in database
GPG Key ID: 735EEEEEEEEEEEEE
14 changed files with 1014 additions and 951 deletions

View File

@ -58,7 +58,7 @@ ForEachMacros:
- BOOST_FOREACH - BOOST_FOREACH
IncludeBlocks: Regroup IncludeBlocks: Regroup
IncludeCategories: 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 Priority: 3
- Regex: '<*>' - Regex: '<*>'
Priority: 1 Priority: 1

View File

@ -209,9 +209,10 @@ ohos_source_set("render_service_base_src") {
"src/property/rs_property_trace.cpp", "src/property/rs_property_trace.cpp",
#drawable #drawable
"src/drawable/rs_utilities_drawable.cpp",
"src/drawable/rs_render_node_drawable_adapter.cpp", "src/drawable/rs_render_node_drawable_adapter.cpp",
"src/drawable/rs_property_drawable_content.cpp", "src/drawable/rs_property_drawable.cpp",
"src/drawable/rs_drawable_content.cpp", "src/drawable/rs_drawable.cpp",
#render #render
"src/render/rs_aibar_filter.cpp", "src/render/rs_aibar_filter.cpp",

View File

@ -13,8 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_CONTENT_H #ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H
#define RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_CONTENT_H #define RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H
#include <bitset> #include <bitset>
#include <cstdint> #include <cstdint>
@ -22,17 +22,16 @@
#include <memory> #include <memory>
#include <unordered_set> #include <unordered_set>
#include "recording/recording_canvas.h"
#include "modifier/rs_modifier_type.h" #include "modifier/rs_modifier_type.h"
#include "pipeline/rs_recording_canvas.h"
namespace OHOS::Rosen { namespace OHOS::Rosen {
class RSRenderNode; class RSRenderNode;
class RSRenderContent; class RSRenderContent;
// NOTE: MUST update DrawableGeneratorLut in rs_drawable_content.cpp when new slots are added // NOTE: MUST update DrawableGeneratorLut in rs_drawable_content.cpp when new slots are added
enum class RSDrawableContentSlot : uint8_t { enum class RSDrawableSlot : uint8_t {
INVALID = 0,
// Bounds Geometry // Bounds Geometry
ALPHA, ALPHA,
MASK, MASK,
@ -81,9 +80,13 @@ enum class RSDrawableContentSlot : uint8_t {
PARTICLE_EFFECT, PARTICLE_EFFECT,
PIXEL_STRETCH, PIXEL_STRETCH,
// Restore state
RESTORE_BLEND_MODE, RESTORE_BLEND_MODE,
RESTORE_ALPHA, RESTORE_ALPHA,
// Invalid
INVALID,
// Annotations: Please remember to update this when new slots are added. // Annotations: Please remember to update this when new slots are added.
// NOTE: MAX and *_END enums are using the one-past-the-end style. // NOTE: MAX and *_END enums are using the one-past-the-end style.
BG_PROPERTIES_BEGIN = BACKGROUND_COLOR, BG_PROPERTIES_BEGIN = BACKGROUND_COLOR,
@ -92,20 +95,27 @@ enum class RSDrawableContentSlot : uint8_t {
CONTENT_PROPERTIES_END = FOREGROUND_STYLE + 1, CONTENT_PROPERTIES_END = FOREGROUND_STYLE + 1,
FG_PROPERTIES_BEGIN = BINARIZATION, FG_PROPERTIES_BEGIN = BINARIZATION,
FG_PROPERTIES_END = FOREGROUND_COLOR + 1, FG_PROPERTIES_END = FOREGROUND_COLOR + 1,
MAX = RESTORE_ALPHA + 1, MAX = INVALID,
}; };
// pure virtual base class // pure virtual base class
class RSDrawableContent : public std::enable_shared_from_this<RSDrawableContent> { class RSDrawable : public std::enable_shared_from_this<RSDrawable> {
public: public:
RSDrawableContent() = default; RSDrawable() = default;
virtual ~RSDrawableContent() = default; virtual ~RSDrawable() = default;
// type definition // not copyable and moveable
using Ptr = std::shared_ptr<RSDrawableContent>; RSDrawable(const RSDrawable&) = delete;
using Vec = std::array<Ptr, static_cast<size_t>(RSDrawableContentSlot::MAX)>; RSDrawable(const RSDrawable&&) = delete;
RSDrawable& operator=(const RSDrawable&) = delete;
RSDrawable& operator=(const RSDrawable&&) = delete;
// =================type definition==================
using Ptr = std::shared_ptr<RSDrawable>;
using Vec = std::array<Ptr, static_cast<size_t>(RSDrawableSlot::MAX)>;
using Generator = std::function<Ptr(const RSRenderNode&)>; using Generator = std::function<Ptr(const RSRenderNode&)>;
// =================virtual functions==================
// Call on first create, return nullptr if no need to create // Call on first create, return nullptr if no need to create
// static Ptr OnGenerate(const RSRenderNode& content) { return nullptr; }; // static Ptr OnGenerate(const RSRenderNode& content) { return nullptr; };
@ -124,62 +134,15 @@ public:
// !!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!
virtual Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const = 0; 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================== // =================Generate & Update helper methods==================
// Step 1, generate DirtySlots from dirty Modifiers // Step 1, generate DirtySlots from dirty Modifiers
static std::unordered_set<RSDrawableContentSlot> CalculateDirtySlots( static std::unordered_set<RSDrawableSlot> CalculateDirtySlots(
ModifierDirtyTypes& dirtyTypes, const Vec& drawableVec); ModifierDirtyTypes& dirtyTypes, const Vec& drawableVec);
// Step 2, for every DirtySlot, generate DrawableContent // Step 2, for every DirtySlot, generate DrawableContent
static bool UpdateDirtySlots( static bool UpdateDirtySlots(
const RSRenderNode& node, Vec& drawableVec, std::unordered_set<RSDrawableContentSlot>& dirtySlots); const RSRenderNode& node, Vec& drawableVec, std::unordered_set<RSDrawableSlot>& dirtySlots);
// Step 3, add necessary Clip/Save/Restore // Step 3, add necessary Clip/Save/Restore
static void UpdateSaveRestore(RSRenderContent& content, Vec& drawableVec, uint8_t& drawableVecStatus); 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<std::unique_ptr<RSRenderNodeDrawableAdapter>> childrenDrawables_;
std::vector<std::unique_ptr<RSRenderNodeDrawableAdapter>> 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<const std::shared_ptr<Drawing::DrawCmdList>> drawCmdList_;
std::vector<const std::shared_ptr<Drawing::DrawCmdList>> stagingDrawCmdList_;
friend class RSCustomModifierDrawable;
};
} // namespace OHOS::Rosen } // namespace OHOS::Rosen
#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_CONTENT_H #endif // RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H

View File

@ -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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList> drawCmdList_;
std::shared_ptr<Drawing::DrawCmdList> stagingDrawCmdList_;
friend class RSPropertyDrawCmdListUpdater;
friend class RSPropertyDrawableNG;
};
class RSBackgroundColorDrawable : public RSPropertyDrawable {
public:
RSBackgroundColorDrawable(std::shared_ptr<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<RSBorder>& border, const bool& isOutline);
};
class RSOutlineDrawable : public RSPropertyDrawable {
public:
RSOutlineDrawable(std::shared_ptr<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::RuntimeEffect> dynamicLightUpBlenderEffect_;
static std::shared_ptr<Drawing::Blender> MakeDynamicLightUpBlender(float dynamicLightUpRate,
float dynamicLightUpDeg);
};
class RSLightUpEffectDrawable : public RSPropertyDrawable {
public:
RSLightUpEffectDrawable(std::shared_ptr<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::RuntimeEffect> binarizationShaderEffect_;
static std::shared_ptr<Drawing::ShaderEffect> MakeBinarizationShader(float low, float high,
float thresholdLow, float thresholdHigh, std::shared_ptr<Drawing::ShaderEffect> imageShader);
};
class RSParticleDrawable : public RSPropertyDrawable {
public:
RSParticleDrawable(std::shared_ptr<Drawing::DrawCmdList>&& 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

View File

@ -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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList> drawCmdList_;
std::shared_ptr<Drawing::DrawCmdList> stagingDrawCmdList_;
friend class RSPropertyDrawCmdListUpdater;
friend class RSPropertyDrawableNG;
};
class RSBackgroundColorContent : public RSPropertyDrawableContent {
public:
RSBackgroundColorContent(std::shared_ptr<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<RSBorder>& border, const bool& isOutline);
};
class RSOutlineContent : public RSPropertyDrawableContent {
public:
RSOutlineContent(std::shared_ptr<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::RuntimeEffect> dynamicLightUpBlenderEffect_;
static std::shared_ptr<Drawing::Blender> MakeDynamicLightUpBlender(float dynamicLightUpRate,
float dynamicLightUpDeg);
};
class RSLightUpEffectContent : public RSPropertyDrawableContent {
public:
RSLightUpEffectContent(std::shared_ptr<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::DrawCmdList>&& 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<Drawing::RuntimeEffect> binarizationShaderEffect_;
static std::shared_ptr<Drawing::ShaderEffect> MakeBinarizationShader(float low, float high,
float thresholdLow, float thresholdHigh, std::shared_ptr<Drawing::ShaderEffect> imageShader);
};
class RSParticleContent : public RSPropertyDrawableContent {
public:
RSParticleContent(std::shared_ptr<Drawing::DrawCmdList>&& 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

View File

@ -13,15 +13,15 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_UTILS_H #ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_UTILS_H
#define RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_UTILS_H #define RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_UTILS_H
#include "platform/common/rs_log.h" #include "platform/common/rs_log.h"
#include "property/rs_properties.h" #include "property/rs_properties.h"
namespace OHOS { namespace OHOS {
namespace Rosen { namespace Rosen {
class RSDrawableUtils { class RSPropertyDrawableUtils {
public: public:
static Drawing::RoundRect RRect2DrawingRRect(const RRect& rr) static Drawing::RoundRect RRect2DrawingRRect(const RRect& rr)
{ {
@ -35,19 +35,19 @@ public:
radii.at(i).SetX(rr.radius_[i].x_); radii.at(i).SetX(rr.radius_[i].x_);
radii.at(i).SetY(rr.radius_[i].y_); radii.at(i).SetY(rr.radius_[i].y_);
} }
return Drawing::RoundRect(rect, radii); return {rect, radii};
} }
static Drawing::Rect Rect2DrawingRect(const RectF& r) 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<RSBorder>& border, static RRect GetRRectForDrawingBorder(const RSProperties& properties, const std::shared_ptr<RSBorder>& border,
const bool& isOutline) const bool& isOutline)
{ {
if (!border) { if (!border) {
return RRect(); return {};
} }
return isOutline ? return isOutline ?
@ -59,7 +59,7 @@ public:
const bool& isOutline) const bool& isOutline)
{ {
if (!border) { if (!border) {
return RRect(); return {};
} }
return isOutline ? properties.GetRRect() : properties.GetInnerRRect(); return isOutline ? properties.GetRRect() : properties.GetInnerRRect();
} }
@ -77,7 +77,7 @@ public:
auto& colorPickerTask = properties.GetColorPickerCacheTaskShadow(); auto& colorPickerTask = properties.GetColorPickerCacheTaskShadow();
if (!colorPickerTask) { if (!colorPickerTask) {
ROSEN_LOGE("RSDrawableUtils::PickColor colorPickerTask is null"); ROSEN_LOGE("RSPropertyDrawableUtils::PickColor colorPickerTask is null");
return false; return false;
} }
colorPickerTask->SetIsShadow(true); colorPickerTask->SetIsShadow(true);
@ -174,4 +174,4 @@ public:
} // namespace Rosen } // namespace Rosen
} // namespace OHOS } // namespace OHOS
#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_UTILS_H #endif // RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_UTILS_H

View File

@ -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 <bitset>
#include <cstdint>
#include <functional>
#include <memory>
#include <unordered_set>
#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<std::unique_ptr<RSRenderNodeDrawableAdapter>> childrenDrawables_;
std::vector<std::unique_ptr<RSRenderNodeDrawableAdapter>> 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<const std::shared_ptr<Drawing::DrawCmdList>> drawCmdList_;
std::vector<const std::shared_ptr<Drawing::DrawCmdList>> stagingDrawCmdList_;
friend class RSCustomModifierDrawable;
};
// Save/Restore
// Clip
// Alpha & restore
} // namespace OHOS::Rosen
#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_UTILITIES_DRAWABLE_H

View File

@ -26,12 +26,15 @@
#include <unordered_set> #include <unordered_set>
#include <variant> #include <variant>
#include <vector> #include <vector>
#include "animation/rs_animation_manager.h" #include "animation/rs_animation_manager.h"
#include "animation/rs_frame_rate_range.h" #include "animation/rs_frame_rate_range.h"
#include "common/rs_common_def.h" #include "common/rs_common_def.h"
#include "common/rs_macros.h" #include "common/rs_macros.h"
#include "common/rs_rect.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 "memory/rs_dfx_string.h"
#include "modifier/rs_render_modifier.h" #include "modifier/rs_render_modifier.h"
#include "params/rs_render_params.h" #include "params/rs_render_params.h"
@ -42,9 +45,6 @@
#include "pipeline/rs_single_frame_composer.h" #include "pipeline/rs_single_frame_composer.h"
#include "property/rs_properties.h" #include "property/rs_properties.h"
#include "draw/surface.h"
#include "image/gpu_context.h"
namespace OHOS { namespace OHOS {
namespace Rosen { namespace Rosen {
namespace Drawing { namespace Drawing {
@ -656,7 +656,7 @@ private:
std::shared_ptr<RSRenderDisplaySync> displaySync_ = nullptr; std::shared_ptr<RSRenderDisplaySync> displaySync_ = nullptr;
uint8_t drawableVecStatus_ = 0; uint8_t drawableVecStatus_ = 0;
void UpdateDrawableContentVec(); void UpdateDrawableVec();
std::map<NodeId, std::vector<WeakPtr>> subSurfaceNodes_; std::map<NodeId, std::vector<WeakPtr>> subSurfaceNodes_;
pid_t appPid_ = 0; pid_t appPid_ = 0;
@ -668,7 +668,7 @@ private:
bool needSync_ = false; bool needSync_ = false;
std::shared_ptr<Drawing::DrawCmdList> drawCmdList_; std::shared_ptr<Drawing::DrawCmdList> drawCmdList_;
std::shared_ptr<Drawing::DrawCmdList> stagingDrawCmdList_; std::shared_ptr<Drawing::DrawCmdList> stagingDrawCmdList_;
RSDrawableContent::Vec contentVec_; RSDrawable::Vec drawableVec_;
std::unique_ptr<RSRenderParams> renderParams_; std::unique_ptr<RSRenderParams> renderParams_;
std::unique_ptr<RSRenderParams> stagingRenderParams_; std::unique_ptr<RSRenderParams> stagingRenderParams_;
@ -676,7 +676,6 @@ private:
void OnSync(); void OnSync();
friend class DrawFuncOpItem; friend class DrawFuncOpItem;
friend class RSAliasDrawable;
friend class RSContext; friend class RSContext;
friend class RSMainThread; friend class RSMainThread;
friend class RSModifierDrawable; friend class RSModifierDrawable;

View File

@ -45,9 +45,9 @@ namespace Rosen {
class RSRenderNode; class RSRenderNode;
class RSObjAbsGeometry; class RSObjAbsGeometry;
class RSB_EXPORT RSProperties final { class RSB_EXPORT RSProperties final {
friend class RSBackgroundImageContent; friend class RSBackgroundImageDrawable;
friend class RSBackgroundFilterContent; friend class RSBackgroundFilterDrawable;
friend class RSShadowContent; friend class RSShadowDrawable;
public: public:
RSProperties(); RSProperties();
RSProperties(const RSProperties&) = delete; RSProperties(const RSProperties&) = delete;

View File

@ -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<int>(RSModifierType::MAX_RS_MODIFIER_TYPE);
static const std::array<RSDrawableSlot, DIRTY_LUT_SIZE> 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<RSModifierType type>
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<int>(RSDrawableSlot::MAX);
static const std::array<RSDrawable::Generator, GEN_LUT_SIZE> g_drawableGeneratorLut = {
// Bounds Geometry
nullptr, // ALPHA,
nullptr, // MASK,
ModifierGenerator<RSModifierType::TRANSITION>, // TRANSITION,
ModifierGenerator<RSModifierType::ENV_FOREGROUND_COLOR>, // 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<RSModifierType::BACKGROUND_STYLE>, // BACKGROUND_STYLE,
RSDynamicLightUpDrawable::OnGenerate, // DYNAMIC_LIGHT_UP,
ModifierGenerator<RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY>, // ENV_FOREGROUND_COLOR_STRATEGY,
nullptr, // BG_RESTORE_BOUNDS,
// Frame Geometry
nullptr, // SAVE_FRAME,
nullptr, // FRAME_OFFSET,
nullptr, // CLIP_TO_FRAME,
ModifierGenerator<RSModifierType::CONTENT_STYLE>, // CONTENT_STYLE,
RSChildrenDrawableContent::OnGenerate, // CHILDREN,
ModifierGenerator<RSModifierType::FOREGROUND_STYLE>, // 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<RSModifierType::OVERLAY_STYLE>, // OVERLAY,
RSParticleDrawable::OnGenerate, // PARTICLE_EFFECT,
RSPixelStretchDrawable::OnGenerate, // PIXEL_STRETCH,
// Restore state
nullptr, // RESTORE_BLEND_MODE,
nullptr, // RESTORE_ALPHA,
};
inline std::pair<RSDrawable::Ptr, RSDrawable::Ptr> GenerateSaveRestore(
RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::kCanvas)
{
// if (type == RSPaintFilterCanvas::kNone) {
// return {};
// } else if (type == RSPaintFilterCanvas::kCanvas) {
// auto count = std::make_shared<int>(-1);
// return { std::make_unique<RSSaveDrawable>(count), std::make_unique<RSRestoreDrawable>(count) };
// } else {
// auto status = std::make_shared<RSPaintFilterCanvas::SaveStatus>();
// return { std::make_unique<RSCustomSaveDrawable>(status, type),
// std::make_unique<RSCustomRestoreDrawable>(status) };
// }
return {};
}
inline void SaveRestoreHelper(RSDrawable::Vec& drawableVec, RSDrawableSlot slot1,
RSDrawableSlot slot2, RSPaintFilterCanvas::SaveType saveType)
{
std::tie(drawableVec[static_cast<size_t>(slot1)], drawableVec[static_cast<size_t>(slot2)]) =
GenerateSaveRestore(saveType);
}
} // namespace
// ==================== RSDrawable =====================
std::unordered_set<RSDrawableSlot> RSDrawable::CalculateDirtySlots(
ModifierDirtyTypes& dirtyTypes, const Vec& drawableVec)
{
if (dirtyTypes.none()) {
return {};
}
// calculate dirty slots by looking up g_propertyToDrawableLut
std::unordered_set<RSDrawableSlot> dirtySlots;
for (size_t type = 0; type < static_cast<size_t>(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<size_t>(RSModifierType::BOUNDS))) {
for (size_t i = 0; i < drawableVec.size(); i++) {
if (drawableVec[i]) {
dirtySlots.emplace(static_cast<RSDrawableSlot>(i));
}
}
}
return dirtySlots;
}
bool RSDrawable::UpdateDirtySlots(
const RSRenderNode& node, Vec& drawableVec, std::unordered_set<RSDrawableSlot>& dirtySlots)
{
// Update or generate all dirty slots
bool drawableAddedOrRemoved = false;
for (const auto& slot : dirtySlots) {
if (auto& drawable = drawableVec[static_cast<size_t>(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<int>(slot)]) {
// If the slot is not created, call OnGenerate
if (auto drawable = generator(node)) {
drawableVec[static_cast<size_t>(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<size_t>(begin), drawableVec.begin() + static_cast<size_t>(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<size_t>(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<size_t>(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<size_t>(RSDrawableSlot::CLIP_TO_BOUNDS)] =
// RSClipBoundsDrawable::Generate(content);
// // part 2: after children, add aliases
// drawableVec[static_cast<size_t>(RSDrawableSlot::FG_SAVE_BOUNDS)] =
// GenerateAlias(RSDrawableSlot::BG_SAVE_BOUNDS);
// drawableVec[static_cast<size_t>(RSDrawableSlot::FG_CLIP_TO_BOUNDS)] =
// GenerateAlias(RSDrawableSlot::CLIP_TO_BOUNDS);
// drawableVec[static_cast<size_t>(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<size_t>(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<size_t>(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<size_t>(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

View File

@ -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<int>(RSModifierType::MAX_RS_MODIFIER_TYPE);
static const std::array<RSDrawableContentSlot, DIRTY_LUT_SIZE> 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<RSModifierType type>
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<int>(RSDrawableContentSlot::MAX);
static const std::array<RSDrawableContent::Generator, GEN_LUT_SIZE> g_drawableGeneratorLut = {
nullptr, // INVALID = 0,
// Bounds Geometry
nullptr, // BOUNDS_MATRIX,
nullptr, // ALPHA,
nullptr, // MASK,
ModifierGenerator<RSModifierType::TRANSITION>, // TRANSITION,
ModifierGenerator<RSModifierType::ENV_FOREGROUND_COLOR>, // 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<RSModifierType::BACKGROUND_STYLE>, // BACKGROUND_STYLE,
RSDynamicLightUpContent::OnGenerate, // DYNAMIC_LIGHT_UP,
ModifierGenerator<RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY>, // ENV_FOREGROUND_COLOR_STRATEGY,
nullptr, // BG_RESTORE_BOUNDS,
// Frame Geometry
nullptr, // SAVE_FRAME,
nullptr, // FRAME_OFFSET,
nullptr, // CLIP_TO_FRAME,
ModifierGenerator<RSModifierType::CONTENT_STYLE>, // CONTENT_STYLE,
RSChildrenDrawableContent::OnGenerate, // CHILDREN,
ModifierGenerator<RSModifierType::FOREGROUND_STYLE>, // 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<RSModifierType::OVERLAY_STYLE>, // OVERLAY,
RSParticleContent::OnGenerate, // PARTICLE_EFFECT,
RSPixelStretchContent::OnGenerate, // PIXEL_STRETCH,
nullptr, // RESTORE_BLEND_MODE,
};
inline std::pair<RSDrawableContent::Ptr, RSDrawableContent::Ptr> GenerateSaveRestore(
RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::kCanvas)
{
// if (type == RSPaintFilterCanvas::kNone) {
// return {};
// } else if (type == RSPaintFilterCanvas::kCanvas) {
// auto count = std::make_shared<int>(-1);
// return { std::make_unique<RSSaveDrawable>(count), std::make_unique<RSRestoreDrawable>(count) };
// } else {
// auto status = std::make_shared<RSPaintFilterCanvas::SaveStatus>();
// return { std::make_unique<RSCustomSaveDrawable>(status, type),
// std::make_unique<RSCustomRestoreDrawable>(status) };
// }
return {};
}
inline void SaveRestoreHelper(RSDrawableContent::Vec& drawableVec, RSDrawableContentSlot slot1,
RSDrawableContentSlot slot2, RSPaintFilterCanvas::SaveType saveType)
{
std::tie(drawableVec[static_cast<size_t>(slot1)], drawableVec[static_cast<size_t>(slot2)]) =
GenerateSaveRestore(saveType);
}
} // namespace
// ==================== RSDrawableContent =====================
std::unordered_set<RSDrawableContentSlot> RSDrawableContent::CalculateDirtySlots(
ModifierDirtyTypes& dirtyTypes, const Vec& drawableVec)
{
if (dirtyTypes.none()) {
return {};
}
std::unordered_set<RSDrawableContentSlot> dirtySlots;
for (size_t type = 0; type < static_cast<size_t>(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<size_t>(RSModifierType::BOUNDS))) {
for (size_t i = 0; i < drawableVec.size(); i++) {
if (drawableVec[i]) {
dirtySlots.emplace(static_cast<RSDrawableContentSlot>(i));
}
}
}
return dirtySlots;
}
bool RSDrawableContent::UpdateDirtySlots(
const RSRenderNode& node, Vec& drawableVec, std::unordered_set<RSDrawableContentSlot>& dirtySlots)
{
bool drawableAddedOrRemoved = false;
for (const auto& slot : dirtySlots) {
if (auto& drawable = drawableVec[static_cast<size_t>(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<int>(slot)]) {
// If the slot is not created, call OnGenerate
if (auto drawable = generator(node)) {
drawableVec[static_cast<size_t>(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<size_t>(begin), drawableVec.begin() + static_cast<size_t>(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<size_t>(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<size_t>(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<size_t>(RSDrawableContentSlot::CLIP_TO_BOUNDS)] =
// RSClipBoundsDrawable::Generate(content);
// // part 2: after children, add aliases
// drawableVec[static_cast<size_t>(RSDrawableContentSlot::FG_SAVE_BOUNDS)] =
// GenerateAlias(RSDrawableContentSlot::BG_SAVE_BOUNDS);
// drawableVec[static_cast<size_t>(RSDrawableContentSlot::FG_CLIP_TO_BOUNDS)] =
// GenerateAlias(RSDrawableContentSlot::CLIP_TO_BOUNDS);
// drawableVec[static_cast<size_t>(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<size_t>(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<size_t>(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<size_t>(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<RSChildrenDrawableContent>(); 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<const RSChildrenDrawableContent>(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<RSCustomModifierDrawableContent>(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<RSRenderProperty<Drawing::DrawCmdListPtr>>(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<const RSCustomModifierDrawableContent>(shared_from_this());
return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) {
for (const auto& drawCmdList : ptr->drawCmdList_) {
drawCmdList->Playback(*canvas);
}
};
}
} // namespace OHOS::Rosen

View File

@ -13,18 +13,15 @@
* limitations under the License. * limitations under the License.
*/ */
#include "drawable/rs_property_drawable.h"
#include "rs_trace.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 "common/rs_obj_abs_geometry.h"
#include "drawable/rs_property_drawable_utils.h"
#include "effect/runtime_blender_builder.h" #include "effect/runtime_blender_builder.h"
#include "pipeline/rs_canvas_render_node.h"
#include "pipeline/rs_recording_canvas.h" #include "pipeline/rs_recording_canvas.h"
#include "pipeline/rs_render_node.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" #include "property/rs_properties_painter.h"
namespace OHOS::Rosen { namespace OHOS::Rosen {
@ -33,10 +30,10 @@ bool g_forceBgAntiAlias = true;
constexpr int PARAM_TWO = 2; constexpr int PARAM_TWO = 2;
} // namespace } // namespace
std::shared_ptr<Drawing::RuntimeEffect> RSDynamicLightUpContent::dynamicLightUpBlenderEffect_ = nullptr; std::shared_ptr<Drawing::RuntimeEffect> RSDynamicLightUpDrawable::dynamicLightUpBlenderEffect_ = nullptr;
std::shared_ptr<Drawing::RuntimeEffect> RSBinarizationShaderContent::binarizationShaderEffect_ = nullptr; std::shared_ptr<Drawing::RuntimeEffect> RSBinarizationDrawable::binarizationShaderEffect_ = nullptr;
void RSPropertyDrawableContent::OnSync() void RSPropertyDrawable::OnSync()
{ {
if (!needSync_) { if (!needSync_) {
return; return;
@ -45,9 +42,9 @@ void RSPropertyDrawableContent::OnSync()
needSync_ = false; needSync_ = false;
} }
Drawing::RecordingCanvas::DrawFunc RSPropertyDrawableContent::CreateDrawFunc() const Drawing::RecordingCanvas::DrawFunc RSPropertyDrawable::CreateDrawFunc() const
{ {
auto ptr = std::static_pointer_cast<const RSPropertyDrawableContent>(shared_from_this()); auto ptr = std::static_pointer_cast<const RSPropertyDrawable>(shared_from_this());
return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) { return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) {
if (const auto& drawCmdList = ptr->drawCmdList_) { if (const auto& drawCmdList = ptr->drawCmdList_) {
drawCmdList->Playback(*canvas); drawCmdList->Playback(*canvas);
@ -94,7 +91,7 @@ protected:
class RSPropertyDrawCmdListUpdater : public RSPropertyDrawCmdListRecorder { class RSPropertyDrawCmdListUpdater : public RSPropertyDrawCmdListRecorder {
public: public:
explicit RSPropertyDrawCmdListUpdater(int width, int height, RSPropertyDrawableContent* target) explicit RSPropertyDrawCmdListUpdater(int width, int height, RSPropertyDrawable* target)
: RSPropertyDrawCmdListRecorder(width, height), target_(target) : RSPropertyDrawCmdListRecorder(width, height), target_(target)
{} {}
~RSPropertyDrawCmdListUpdater() override ~RSPropertyDrawCmdListUpdater() override
@ -108,18 +105,18 @@ public:
} }
private: 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<RSBackgroundColorContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSBackgroundColorDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSBackgroundColorContent::OnUpdate(const RSRenderNode& node) bool RSBackgroundColorDrawable::OnUpdate(const RSRenderNode& node)
{ {
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
auto bgColor = properties.GetBackgroundColor(); auto bgColor = properties.GetBackgroundColor();
@ -136,20 +133,20 @@ bool RSBackgroundColorContent::OnUpdate(const RSRenderNode& node)
brush.SetAntiAlias(antiAlias); brush.SetAntiAlias(antiAlias);
brush.SetColor(Drawing::Color(bgColor.AsArgbInt())); brush.SetColor(Drawing::Color(bgColor.AsArgbInt()));
canvas.AttachBrush(brush); canvas.AttachBrush(brush);
canvas.DrawRoundRect(RSDrawableUtils::RRect2DrawingRRect(properties.GetRRect())); canvas.DrawRoundRect(RSPropertyDrawableUtils::RRect2DrawingRRect(properties.GetRRect()));
canvas.DetachBrush(); canvas.DetachBrush();
return true; return true;
} }
RSDrawableContent::Ptr RSBackgroundShaderContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSBackgroundShaderDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSBackgroundShaderContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSBackgroundShaderDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSBackgroundShaderContent::OnUpdate(const RSRenderNode& node) bool RSBackgroundShaderDrawable::OnUpdate(const RSRenderNode& node)
{ {
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
const auto& bgShader = properties.GetBackgroundShader(); const auto& bgShader = properties.GetBackgroundShader();
@ -170,15 +167,15 @@ bool RSBackgroundShaderContent::OnUpdate(const RSRenderNode& node)
return true; return true;
} }
RSDrawableContent::Ptr RSBackgroundImageContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSBackgroundImageDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSBackgroundImageContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSBackgroundImageDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSBackgroundImageContent::OnUpdate(const RSRenderNode& node) bool RSBackgroundImageDrawable::OnUpdate(const RSRenderNode& node)
{ {
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
const auto& bgImage = properties.GetBgImage(); const auto& bgImage = properties.GetBgImage();
@ -194,7 +191,7 @@ bool RSBackgroundImageContent::OnUpdate(const RSRenderNode& node)
// paint backgroundColor // paint backgroundColor
Drawing::Brush brush; Drawing::Brush brush;
brush.SetAntiAlias(antiAlias); brush.SetAntiAlias(antiAlias);
auto boundsRect = RSDrawableUtils::Rect2DrawingRect(properties.GetBoundsRect()); auto boundsRect = RSPropertyDrawableUtils::Rect2DrawingRect(properties.GetBoundsRect());
bgImage->SetDstRect(properties.GetBgImageRect()); bgImage->SetDstRect(properties.GetBgImageRect());
canvas.AttachBrush(brush); canvas.AttachBrush(brush);
bgImage->CanvasDrawImage(canvas, boundsRect, Drawing::SamplingOptions(), true); bgImage->CanvasDrawImage(canvas, boundsRect, Drawing::SamplingOptions(), true);
@ -202,15 +199,15 @@ bool RSBackgroundImageContent::OnUpdate(const RSRenderNode& node)
return true; return true;
} }
RSDrawableContent::Ptr RSBackgroundFilterContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSBackgroundFilterDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSBackgroundFilterContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSBackgroundFilterDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node) bool RSBackgroundFilterDrawable::OnUpdate(const RSRenderNode& node)
{ {
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
auto& rsFilter = properties.GetBackgroundFilter(); auto& rsFilter = properties.GetBackgroundFilter();
@ -222,7 +219,7 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node)
Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); Drawing::Canvas& canvas = *updater.GetRecordingCanvas();
auto surface = canvas.GetSurface(); auto surface = canvas.GetSurface();
if (surface == nullptr) { if (surface == nullptr) {
ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate surface null"); ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate surface null");
return false; return false;
} }
@ -235,12 +232,12 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node)
// cacheManager != nullptr && !canvas.GetDisableFilterCache()) { // cacheManager != nullptr && !canvas.GetDisableFilterCache()) {
// auto node = properties.backref_.lock(); // auto node = properties.backref_.lock();
// if (node == nullptr) { // if (node == nullptr) {
// ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate node is null"); // ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate node is null");
// return false; // return false;
// } // }
// auto effectNode = node->ReinterpretCastTo<RSEffectRenderNode>(); // auto effectNode = node->ReinterpretCastTo<RSEffectRenderNode>();
// if (effectNode == nullptr) { // if (effectNode == nullptr) {
// ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate node reinterpret cast failed."); // ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate node reinterpret cast failed.");
// return false; // return false;
// } // }
// // node is freeze or screen rotating, force cache filterred snapshot. // // node is freeze or screen rotating, force cache filterred snapshot.
@ -254,7 +251,7 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node)
auto imageRect = bounds; auto imageRect = bounds;
auto imageSnapshot = surface->GetImageSnapshot(imageRect); auto imageSnapshot = surface->GetImageSnapshot(imageRect);
if (imageSnapshot == nullptr) { if (imageSnapshot == nullptr) {
ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate image snapshot null"); ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate image snapshot null");
return false; return false;
} }
@ -263,7 +260,7 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node)
std::shared_ptr<Drawing::Surface> offscreenSurface = std::shared_ptr<Drawing::Surface> offscreenSurface =
surface->MakeSurface(imageSnapshot->GetWidth(), imageSnapshot->GetHeight()); surface->MakeSurface(imageSnapshot->GetWidth(), imageSnapshot->GetHeight());
if (offscreenSurface == nullptr) { if (offscreenSurface == nullptr) {
ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate offscreenSurface null"); ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate offscreenSurface null");
return false; return false;
} }
RSPaintFilterCanvas offscreenCanvas(offscreenSurface.get()); RSPaintFilterCanvas offscreenCanvas(offscreenSurface.get());
@ -274,7 +271,7 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node)
auto imageCache = offscreenSurface->GetImageSnapshot(); auto imageCache = offscreenSurface->GetImageSnapshot();
if (imageCache == nullptr) { if (imageCache == nullptr) {
ROSEN_LOGE("RSBackgroundFilterContent::OnUpdate imageCache snapshot null"); ROSEN_LOGE("RSBackgroundFilterDrawable::OnUpdate imageCache snapshot null");
return false; return false;
} }
// TODO canvas.SetEffectData // TODO canvas.SetEffectData
@ -284,15 +281,15 @@ bool RSBackgroundFilterContent::OnUpdate(const RSRenderNode& node)
return true; return true;
} }
RSDrawableContent::Ptr RSBorderContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSBorderDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSBorderContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSBorderDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSBorderContent::OnUpdate(const RSRenderNode& node) bool RSBorderDrawable::OnUpdate(const RSRenderNode& node)
{ {
// regenerate stagingDrawCmdList_ // regenerate stagingDrawCmdList_
RSPropertyDrawCmdListUpdater updater(0, 0, this); RSPropertyDrawCmdListUpdater updater(0, 0, this);
@ -301,7 +298,7 @@ bool RSBorderContent::OnUpdate(const RSRenderNode& node)
return true; return true;
} }
void RSBorderContent::DrawBorder(const RSProperties& properties, Drawing::Canvas& canvas, void RSBorderDrawable::DrawBorder(const RSProperties& properties, Drawing::Canvas& canvas,
const std::shared_ptr<RSBorder>& border, const bool& isOutline) const std::shared_ptr<RSBorder>& border, const bool& isOutline)
{ {
if (!border || !border->HasBorder()) { if (!border || !border->HasBorder()) {
@ -313,9 +310,9 @@ void RSBorderContent::DrawBorder(const RSProperties& properties, Drawing::Canvas
brush.SetAntiAlias(true); brush.SetAntiAlias(true);
pen.SetAntiAlias(true); pen.SetAntiAlias(true);
if (border->ApplyFillStyle(brush)) { if (border->ApplyFillStyle(brush)) {
auto roundRect = RSDrawableUtils::RRect2DrawingRRect(RSDrawableUtils::GetRRectForDrawingBorder(properties, auto roundRect = RSPropertyDrawableUtils::RRect2DrawingRRect(RSPropertyDrawableUtils::GetRRectForDrawingBorder(properties,
border, isOutline)); border, isOutline));
auto innerRoundRect = RSDrawableUtils::RRect2DrawingRRect(RSDrawableUtils::GetInnerRRectForDrawingBorder( auto innerRoundRect = RSPropertyDrawableUtils::RRect2DrawingRRect(RSPropertyDrawableUtils::GetInnerRRectForDrawingBorder(
properties, border, isOutline)); properties, border, isOutline));
canvas.AttachBrush(brush); canvas.AttachBrush(brush);
canvas.DrawNestedRoundRect(roundRect, innerRoundRect); canvas.DrawNestedRoundRect(roundRect, innerRoundRect);
@ -328,21 +325,21 @@ void RSBorderContent::DrawBorder(const RSProperties& properties, Drawing::Canvas
border->PaintFourLine(canvas, pen, rectf); border->PaintFourLine(canvas, pen, rectf);
} else if (border->ApplyPathStyle(pen)) { } else if (border->ApplyPathStyle(pen)) {
auto borderWidth = border->GetWidth(); auto borderWidth = border->GetWidth();
RRect rrect = RSDrawableUtils::GetRRectForDrawingBorder(properties, border, isOutline); RRect rrect = RSPropertyDrawableUtils::GetRRectForDrawingBorder(properties, border, isOutline);
rrect.rect_.width_ -= borderWidth; rrect.rect_.width_ -= borderWidth;
rrect.rect_.height_ -= borderWidth; rrect.rect_.height_ -= borderWidth;
rrect.rect_.Move(borderWidth / PARAM_TWO, borderWidth / PARAM_TWO); rrect.rect_.Move(borderWidth / PARAM_TWO, borderWidth / PARAM_TWO);
Drawing::Path borderPath; Drawing::Path borderPath;
borderPath.AddRoundRect(RSDrawableUtils::RRect2DrawingRRect(rrect)); borderPath.AddRoundRect(RSPropertyDrawableUtils::RRect2DrawingRRect(rrect));
canvas.AttachPen(pen); canvas.AttachPen(pen);
canvas.DrawPath(borderPath); canvas.DrawPath(borderPath);
canvas.DetachPen(); canvas.DetachPen();
} else { } else {
Drawing::AutoCanvasRestore acr(canvas, true); Drawing::AutoCanvasRestore acr(canvas, true);
auto rrect = RSDrawableUtils::RRect2DrawingRRect(RSDrawableUtils::GetRRectForDrawingBorder(properties, auto rrect = RSPropertyDrawableUtils::RRect2DrawingRRect(RSPropertyDrawableUtils::GetRRectForDrawingBorder(properties,
border, isOutline)); border, isOutline));
canvas.ClipRoundRect(rrect, Drawing::ClipOp::INTERSECT, true); canvas.ClipRoundRect(rrect, Drawing::ClipOp::INTERSECT, true);
auto innerRoundRect = RSDrawableUtils::RRect2DrawingRRect(RSDrawableUtils::GetInnerRRectForDrawingBorder( auto innerRoundRect = RSPropertyDrawableUtils::RRect2DrawingRRect(RSPropertyDrawableUtils::GetInnerRRectForDrawingBorder(
properties, border, isOutline)); properties, border, isOutline));
canvas.ClipRoundRect(innerRoundRect, Drawing::ClipOp::DIFFERENCE, true); canvas.ClipRoundRect(innerRoundRect, Drawing::ClipOp::DIFFERENCE, true);
Drawing::scalar centerX = innerRoundRect.GetRect().GetLeft() + innerRoundRect.GetRect().GetWidth() / 2; 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<RSOutlineContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSOutlineDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSOutlineContent::OnUpdate(const RSRenderNode& node) bool RSOutlineDrawable::OnUpdate(const RSRenderNode& node)
{ {
// regenerate stagingDrawCmdList_ // regenerate stagingDrawCmdList_
RSPropertyDrawCmdListUpdater updater(0, 0, this); RSPropertyDrawCmdListUpdater updater(0, 0, this);
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
RSBorderContent::DrawBorder(properties, *updater.GetRecordingCanvas(), properties.GetOutline(), true); RSBorderDrawable::DrawBorder(properties, *updater.GetRecordingCanvas(), properties.GetOutline(), true);
return true; return true;
} }
RSDrawableContent::Ptr RSShadowContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSShadowDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSShadowContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSShadowDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSShadowContent::OnUpdate(const RSRenderNode& node) bool RSShadowDrawable::OnUpdate(const RSRenderNode& node)
{ {
// regenerate stagingDrawCmdList_ // regenerate stagingDrawCmdList_
RSPropertyDrawCmdListUpdater updater(0, 0, this); RSPropertyDrawCmdListUpdater updater(0, 0, this);
@ -411,9 +408,9 @@ bool RSShadowContent::OnUpdate(const RSRenderNode& node)
canvas.ClipPath(path, Drawing::ClipOp::DIFFERENCE, true); canvas.ClipPath(path, Drawing::ClipOp::DIFFERENCE, true);
} }
} else { } else {
path.AddRoundRect(RSDrawableUtils::RRect2DrawingRRect(rrect)); path.AddRoundRect(RSPropertyDrawableUtils::RRect2DrawingRRect(rrect));
if (!properties.GetShadowIsFilled()) { if (!properties.GetShadowIsFilled()) {
canvas.ClipRoundRect(RSDrawableUtils::RRect2DrawingRRect(rrect), Drawing::ClipOp::DIFFERENCE, true); canvas.ClipRoundRect(RSPropertyDrawableUtils::RRect2DrawingRRect(rrect), Drawing::ClipOp::DIFFERENCE, true);
} }
} }
if (properties.GetShadowMask()) { if (properties.GetShadowMask()) {
@ -424,7 +421,7 @@ bool RSShadowContent::OnUpdate(const RSRenderNode& node)
return true; return true;
} }
void RSShadowContent::DrawColorfulShadowInner(const RSProperties& properties, Drawing::Canvas& canvas, void RSShadowDrawable::DrawColorfulShadowInner(const RSProperties& properties, Drawing::Canvas& canvas,
Drawing::Path& path) Drawing::Path& path)
{ {
// blurRadius calculation is based on the formula in Canvas::DrawShadow, 0.25f and 128.0f are constants // 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()); path.Offset(properties.GetShadowOffsetX(), properties.GetShadowOffsetY());
Color spotColor = properties.GetShadowColor(); Color spotColor = properties.GetShadowColor();
@ -470,8 +467,8 @@ void RSShadowContent::DrawShadowInner(const RSProperties& properties, Drawing::C
auto& colorPickerTask = properties.GetColorPickerCacheTaskShadow(); auto& colorPickerTask = properties.GetColorPickerCacheTaskShadow();
if (colorPickerTask != nullptr && if (colorPickerTask != nullptr &&
properties.GetShadowColorStrategy() != SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE) { properties.GetShadowColorStrategy() != SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE) {
if (RSDrawableUtils::PickColor(properties, canvas, path, matrix, deviceClipBounds, colorPicked)) { if (RSPropertyDrawableUtils::PickColor(properties, canvas, path, matrix, deviceClipBounds, colorPicked)) {
RSDrawableUtils::GetDarkColor(colorPicked); RSPropertyDrawableUtils::GetDarkColor(colorPicked);
} else { } else {
shadowAlpha = 0; 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<RSForegroundColorContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSForegroundColorDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSForegroundColorContent::OnUpdate(const RSRenderNode& node) bool RSForegroundColorDrawable::OnUpdate(const RSRenderNode& node)
{ {
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
auto fgColor = properties.GetForegroundColor(); auto fgColor = properties.GetForegroundColor();
@ -532,20 +529,20 @@ bool RSForegroundColorContent::OnUpdate(const RSRenderNode& node)
brush.SetColor(Drawing::Color(fgColor.AsArgbInt())); brush.SetColor(Drawing::Color(fgColor.AsArgbInt()));
brush.SetAntiAlias(true); brush.SetAntiAlias(true);
canvas.AttachBrush(brush); canvas.AttachBrush(brush);
canvas.DrawRoundRect(RSDrawableUtils::RRect2DrawingRRect(properties.GetRRect())); canvas.DrawRoundRect(RSPropertyDrawableUtils::RRect2DrawingRRect(properties.GetRRect()));
canvas.DetachBrush(); canvas.DetachBrush();
return true; return true;
} }
RSDrawableContent::Ptr RSPixelStretchContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSPixelStretchDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSPixelStretchContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSPixelStretchDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node) bool RSPixelStretchDrawable::OnUpdate(const RSRenderNode& node)
{ {
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
auto& pixelStretch = properties.GetPixelStretch(); auto& pixelStretch = properties.GetPixelStretch();
@ -557,7 +554,7 @@ bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node)
Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); Drawing::Canvas& canvas = *updater.GetRecordingCanvas();
auto surface = canvas.GetSurface(); auto surface = canvas.GetSurface();
if (surface == nullptr) { if (surface == nullptr) {
ROSEN_LOGE("RSPixelStretchContent::OnUpdate surface null"); ROSEN_LOGE("RSPixelStretchDrawable::OnUpdate surface null");
return false; return false;
} }
@ -565,7 +562,7 @@ bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node)
with respect to the origin of the current canvas coordinates */ with respect to the origin of the current canvas coordinates */
Drawing::Matrix worldToLocalMat; Drawing::Matrix worldToLocalMat;
if (!canvas.GetTotalMatrix().Invert(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; Drawing::Rect localClipBounds;
auto tmpBounds = canvas.GetDeviceClipBounds(); auto tmpBounds = canvas.GetDeviceClipBounds();
@ -574,18 +571,18 @@ bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node)
Drawing::Rect fClipBounds(clipBounds.GetLeft(), clipBounds.GetTop(), clipBounds.GetRight(), Drawing::Rect fClipBounds(clipBounds.GetLeft(), clipBounds.GetTop(), clipBounds.GetRight(),
clipBounds.GetBottom()); clipBounds.GetBottom());
if (!worldToLocalMat.MapRect(localClipBounds, fClipBounds)) { 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()); auto bounds = RSPropertiesPainter::Rect2DrawingRect(properties.GetBoundsRect());
if (!bounds.Intersect(localClipBounds)) { 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_, auto scaledBounds = Drawing::Rect(bounds.GetLeft() - pixelStretch->x_, bounds.GetTop() - pixelStretch->y_,
bounds.GetRight() + pixelStretch->z_, bounds.GetBottom() + pixelStretch->w_); bounds.GetRight() + pixelStretch->z_, bounds.GetBottom() + pixelStretch->w_);
if (!scaledBounds.IsValid() || !bounds.IsValid() || !clipBounds.IsValid()) { if (!scaledBounds.IsValid() || !bounds.IsValid() || !clipBounds.IsValid()) {
ROSEN_LOGE("RSPixelStretchContent::OnUpdate invalid scaled bounds"); ROSEN_LOGE("RSPixelStretchDrawable::OnUpdate invalid scaled bounds");
return false; return false;
} }
@ -593,7 +590,7 @@ bool RSPixelStretchContent::OnUpdate(const RSRenderNode& node)
static_cast<int>(fClipBounds.GetRight()), static_cast<int>(fClipBounds.GetBottom())); static_cast<int>(fClipBounds.GetRight()), static_cast<int>(fClipBounds.GetBottom()));
auto image = surface->GetImageSnapshot(rectI); auto image = surface->GetImageSnapshot(rectI);
if (image == nullptr) { if (image == nullptr) {
ROSEN_LOGE("RSPixelStretchContent::OnUpdate image null"); ROSEN_LOGE("RSPixelStretchDrawable::OnUpdate image null");
return false; 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_X, bounds.GetLeft() - transBounds.GetLeft());
rotateMat.Set(Drawing::Matrix::TRANS_Y, bounds.GetTop() - transBounds.GetTop()); rotateMat.Set(Drawing::Matrix::TRANS_Y, bounds.GetTop() - transBounds.GetTop());
if (!rotateMat.Invert(inverseMat)) { 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; return true;
} }
RSDrawableContent::Ptr RSDynamicLightUpContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSDynamicLightUpDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSDynamicLightUpContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSDynamicLightUpDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSDynamicLightUpContent::OnUpdate(const RSRenderNode& node) bool RSDynamicLightUpDrawable::OnUpdate(const RSRenderNode& node)
{ {
RSPropertyDrawCmdListUpdater updater(0, 0, this); RSPropertyDrawCmdListUpdater updater(0, 0, this);
Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); Drawing::Canvas& canvas = *updater.GetRecordingCanvas();
Drawing::Surface* surface = canvas.GetSurface(); Drawing::Surface* surface = canvas.GetSurface();
if (surface == nullptr) { if (surface == nullptr) {
ROSEN_LOGE("RSDynamicLightUpContent::OnUpdate surface is null"); ROSEN_LOGE("RSDynamicLightUpDrawable::OnUpdate surface is null");
return false; return false;
} }
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
@ -680,7 +677,7 @@ bool RSDynamicLightUpContent::OnUpdate(const RSRenderNode& node)
return true; return true;
} }
std::shared_ptr<Drawing::Blender> RSDynamicLightUpContent::MakeDynamicLightUpBlender(float dynamicLightUpRate, std::shared_ptr<Drawing::Blender> RSDynamicLightUpDrawable::MakeDynamicLightUpBlender(float dynamicLightUpRate,
float dynamicLightUpDeg) float dynamicLightUpDeg)
{ {
static constexpr char prog[] = R"( static constexpr char prog[] = R"(
@ -699,7 +696,7 @@ std::shared_ptr<Drawing::Blender> RSDynamicLightUpContent::MakeDynamicLightUpBle
if (dynamicLightUpBlenderEffect_ == nullptr) { if (dynamicLightUpBlenderEffect_ == nullptr) {
dynamicLightUpBlenderEffect_ = Drawing::RuntimeEffect::CreateForBlender(prog); dynamicLightUpBlenderEffect_ = Drawing::RuntimeEffect::CreateForBlender(prog);
if (dynamicLightUpBlenderEffect_ == nullptr) { if (dynamicLightUpBlenderEffect_ == nullptr) {
ROSEN_LOGE("RSDynamicLightUpContent::MakeDynamicLightUpBlender effect error!"); ROSEN_LOGE("RSDynamicLightUpDrawable::MakeDynamicLightUpBlender effect error!");
return nullptr; return nullptr;
} }
} }
@ -710,28 +707,28 @@ std::shared_ptr<Drawing::Blender> RSDynamicLightUpContent::MakeDynamicLightUpBle
return builder->MakeBlender(); return builder->MakeBlender();
} }
RSDrawableContent::Ptr RSLightUpEffectContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSLightUpEffectDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSLightUpEffectContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSLightUpEffectDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSLightUpEffectContent::OnUpdate(const RSRenderNode& node) bool RSLightUpEffectDrawable::OnUpdate(const RSRenderNode& node)
{ {
RSPropertyDrawCmdListUpdater updater(0, 0, this); RSPropertyDrawCmdListUpdater updater(0, 0, this);
Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); Drawing::Canvas& canvas = *updater.GetRecordingCanvas();
Drawing::Surface* surface = canvas.GetSurface(); Drawing::Surface* surface = canvas.GetSurface();
if (surface == nullptr) { if (surface == nullptr) {
ROSEN_LOGE("RSLightUpEffectContent::OnUpdate surface is null"); ROSEN_LOGE("RSLightUpEffectDrawable::OnUpdate surface is null");
return false; return false;
} }
auto clipBounds = canvas.GetDeviceClipBounds(); auto clipBounds = canvas.GetDeviceClipBounds();
auto image = surface->GetImageSnapshot(clipBounds); auto image = surface->GetImageSnapshot(clipBounds);
if (image == nullptr) { if (image == nullptr) {
ROSEN_LOGE("RSLightUpEffectContent::OnUpdate image is null"); ROSEN_LOGE("RSLightUpEffectDrawable::OnUpdate image is null");
return false; return false;
} }
@ -748,15 +745,15 @@ bool RSLightUpEffectContent::OnUpdate(const RSRenderNode& node)
return true; return true;
} }
RSDrawableContent::Ptr RSColorFilterContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSColorFilterDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSColorFilterContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSColorFilterDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSColorFilterContent::OnUpdate(const RSRenderNode& node) bool RSColorFilterDrawable::OnUpdate(const RSRenderNode& node)
{ {
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
// if useEffect defined, use color filter from parent EffectView. // if useEffect defined, use color filter from parent EffectView.
@ -774,13 +771,13 @@ bool RSColorFilterContent::OnUpdate(const RSRenderNode& node)
brush.SetFilter(filter); brush.SetFilter(filter);
auto surface = canvas.GetSurface(); auto surface = canvas.GetSurface();
if (surface == nullptr) { if (surface == nullptr) {
ROSEN_LOGE("RSColorFilterContent::OnUpdate surface is null"); ROSEN_LOGE("RSColorFilterDrawable::OnUpdate surface is null");
return false; return false;
} }
auto clipBounds = canvas.GetDeviceClipBounds(); auto clipBounds = canvas.GetDeviceClipBounds();
auto imageSnapshot = surface->GetImageSnapshot(clipBounds); auto imageSnapshot = surface->GetImageSnapshot(clipBounds);
if (imageSnapshot == nullptr) { if (imageSnapshot == nullptr) {
ROSEN_LOGE("RSColorFilterContent::OnUpdate image is null"); ROSEN_LOGE("RSColorFilterDrawable::OnUpdate image is null");
return false; return false;
} }
imageSnapshot->HintCacheGpuResource(); imageSnapshot->HintCacheGpuResource();
@ -792,30 +789,30 @@ bool RSColorFilterContent::OnUpdate(const RSRenderNode& node)
return true; return true;
} }
RSDrawableContent::Ptr RSMaskContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSMaskDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSMaskContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSMaskDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSMaskContent::OnUpdate(const RSRenderNode& node) bool RSMaskDrawable::OnUpdate(const RSRenderNode& node)
{ {
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
std::shared_ptr<RSMask> mask = properties.GetMask(); std::shared_ptr<RSMask> mask = properties.GetMask();
if (mask == nullptr) { if (mask == nullptr) {
ROSEN_LOGE("RSMaskContent::OnUpdate null mask"); ROSEN_LOGE("RSMaskDrawable::OnUpdate null mask");
return false; return false;
} }
if (mask->IsSvgMask() && !mask->GetSvgDom() && !mask->GetSvgPicture()) { 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; return false;
} }
RSPropertyDrawCmdListUpdater updater(0, 0, this); RSPropertyDrawCmdListUpdater updater(0, 0, this);
Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); Drawing::Canvas& canvas = *updater.GetRecordingCanvas();
Drawing::Rect maskBounds = RSDrawableUtils::Rect2DrawingRect(properties.GetBoundsRect()); Drawing::Rect maskBounds = RSPropertyDrawableUtils::Rect2DrawingRect(properties.GetBoundsRect());
canvas.Save(); canvas.Save();
Drawing::SaveLayerOps slr(&maskBounds, nullptr); Drawing::SaveLayerOps slr(&maskBounds, nullptr);
canvas.SaveLayer(slr); canvas.SaveLayer(slr);
@ -866,28 +863,28 @@ bool RSMaskContent::OnUpdate(const RSRenderNode& node)
return true; return true;
} }
RSDrawableContent::Ptr RSBinarizationShaderContent::OnGenerate(const RSRenderNode& node) RSDrawable::Ptr RSBinarizationDrawable::OnGenerate(const RSRenderNode& node)
{ {
if (auto ret = std::make_shared<RSBinarizationShaderContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSBinarizationDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSBinarizationShaderContent::OnUpdate(const RSRenderNode& node) bool RSBinarizationDrawable::OnUpdate(const RSRenderNode& node)
{ {
RSPropertyDrawCmdListUpdater updater(0, 0, this); RSPropertyDrawCmdListUpdater updater(0, 0, this);
Drawing::Canvas& canvas = *updater.GetRecordingCanvas(); Drawing::Canvas& canvas = *updater.GetRecordingCanvas();
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
auto drSurface = canvas.GetSurface(); auto drSurface = canvas.GetSurface();
if (drSurface == nullptr) { if (drSurface == nullptr) {
ROSEN_LOGE("RSBinarizationShaderContent::OnUpdate drSurface is null"); ROSEN_LOGE("RSBinarizationDrawable::OnUpdate drSurface is null");
return false; return false;
} }
auto clipBounds = canvas.GetDeviceClipBounds(); auto clipBounds = canvas.GetDeviceClipBounds();
auto imageSnapshot = drSurface->GetImageSnapshot(clipBounds); auto imageSnapshot = drSurface->GetImageSnapshot(clipBounds);
if (imageSnapshot == nullptr) { if (imageSnapshot == nullptr) {
ROSEN_LOGE("RSBinarizationShaderContent::OnUpdate image is null"); ROSEN_LOGE("RSBinarizationDrawable::OnUpdate image is null");
return false; return false;
} }
auto& aiInvert = properties.GetAiInvert(); auto& aiInvert = properties.GetAiInvert();
@ -906,7 +903,7 @@ bool RSBinarizationShaderContent::OnUpdate(const RSRenderNode& node)
return true; return true;
} }
std::shared_ptr<Drawing::ShaderEffect> RSBinarizationShaderContent::MakeBinarizationShader(float low, float high, std::shared_ptr<Drawing::ShaderEffect> RSBinarizationDrawable::MakeBinarizationShader(float low, float high,
float thresholdLow, float thresholdHigh, std::shared_ptr<Drawing::ShaderEffect> imageShader) float thresholdLow, float thresholdHigh, std::shared_ptr<Drawing::ShaderEffect> imageShader)
{ {
static constexpr char prog[] = R"( static constexpr char prog[] = R"(
@ -930,7 +927,7 @@ std::shared_ptr<Drawing::ShaderEffect> RSBinarizationShaderContent::MakeBinariza
if (binarizationShaderEffect_ == nullptr) { if (binarizationShaderEffect_ == nullptr) {
binarizationShaderEffect_ = Drawing::RuntimeEffect::CreateForShader(prog); binarizationShaderEffect_ = Drawing::RuntimeEffect::CreateForShader(prog);
if (binarizationShaderEffect_ == nullptr) { if (binarizationShaderEffect_ == nullptr) {
ROSEN_LOGE("RSBinarizationShaderContent::MakeBinarizationShader effect error\n"); ROSEN_LOGE("RSBinarizationDrawable::MakeBinarizationShader effect error\n");
return nullptr; return nullptr;
} }
} }
@ -945,15 +942,15 @@ std::shared_ptr<Drawing::ShaderEffect> RSBinarizationShaderContent::MakeBinariza
return builder->MakeShader(nullptr, false); 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<RSParticleContent>(); ret->OnUpdate(node)) { if (auto ret = std::make_shared<RSParticleDrawable>(); ret->OnUpdate(node)) {
return ret; return ret;
} }
return nullptr; return nullptr;
}; };
bool RSParticleContent::OnUpdate(const RSRenderNode& node) bool RSParticleDrawable::OnUpdate(const RSRenderNode& node)
{ {
const RSProperties& properties = node.GetRenderProperties(); const RSProperties& properties = node.GetRenderProperties();
const auto& particleVector = properties.GetParticles(); const auto& particleVector = properties.GetParticles();

View File

@ -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<RSChildrenDrawableContent>(); 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<const RSChildrenDrawableContent>(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<RSCustomModifierDrawableContent>(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<RSRenderProperty<Drawing::DrawCmdListPtr>>(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<const RSCustomModifierDrawableContent>(shared_from_this());
return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) {
for (const auto& drawCmdList : ptr->drawCmdList_) {
drawCmdList->Playback(*canvas);
}
};
}
} // namespace OHOS::Rosen

View File

@ -22,25 +22,27 @@
#include <set> #include <set>
#include <utility> #include <utility>
#include "benchmarks/file_utils.h"
#include "rs_trace.h" #include "rs_trace.h"
#include "animation/rs_render_animation.h" #include "animation/rs_render_animation.h"
#include "common/rs_obj_abs_geometry.h" #include "common/rs_obj_abs_geometry.h"
#include "benchmarks/file_utils.h"
#include "common/rs_optional_trace.h" #include "common/rs_optional_trace.h"
#include "modifier/rs_modifier_type.h" #include "modifier/rs_modifier_type.h"
#include "pipeline/rs_context.h" #include "pipeline/rs_context.h"
#include "pipeline/rs_display_render_node.h" #include "pipeline/rs_display_render_node.h"
#include "pipeline/rs_effect_render_node.h" #include "pipeline/rs_effect_render_node.h"
#include "pipeline/rs_paint_filter_canvas.h" #include "pipeline/rs_paint_filter_canvas.h"
#include "pipeline/rs_recording_canvas.h"
#include "pipeline/rs_root_render_node.h" #include "pipeline/rs_root_render_node.h"
#include "pipeline/rs_surface_render_node.h" #include "pipeline/rs_surface_render_node.h"
#include "platform/common/rs_log.h" #include "platform/common/rs_log.h"
#include "platform/common/rs_system_properties.h" #include "platform/common/rs_system_properties.h"
#include "property/rs_properties_painter.h" #include "property/rs_properties_painter.h"
// #include "property/rs_property_drawable.h"
#include "property/rs_property_trace.h" #include "property/rs_property_trace.h"
#include "transaction/rs_transaction_proxy.h" #include "transaction/rs_transaction_proxy.h"
#include "visitor/rs_node_visitor.h" #include "visitor/rs_node_visitor.h"
#ifdef DDGR_ENABLE_FEATURE_OPINC #ifdef DDGR_ENABLE_FEATURE_OPINC
#include "rs_auto_cache.h" #include "rs_auto_cache.h"
#endif #endif
@ -1423,7 +1425,7 @@ void RSRenderNode::ApplyModifiers()
// UpdateDrawableVec(); // UpdateDrawableVec();
// } // }
UpdateDrawableContentVec(); UpdateDrawableVec();
#endif #endif
@ -1445,27 +1447,27 @@ void RSRenderNode::MarkParentNeedRegenerateChildren() const
parent->isChildrenSorted_ = false; parent->isChildrenSorted_ = false;
} }
void RSRenderNode::UpdateDrawableContentVec() void RSRenderNode::UpdateDrawableVec()
{ {
#ifndef ROSEN_ARKUI_X #ifndef ROSEN_ARKUI_X
// Step 1: Collect dirty slots // Step 1: Collect dirty slots
auto dirtySlots = RSDrawableContent::CalculateDirtySlots(dirtyTypes_, contentVec_); auto dirtySlots = RSDrawable::CalculateDirtySlots(dirtyTypes_, drawableVec_);
if (dirtySlots.empty()) { if (dirtySlots.empty()) {
return; return;
} }
// Step 2: Update or regenerate drawable if needed // 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) { if (drawableChanged || drawableVecStatus_ == 0) {
// Step 3: if any drawables changed, update save/clip/restore // 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 // Step 4: Generate drawCmdList from drawables
// TODO: use correct W/H instead of 0 // TODO: use correct W/H instead of 0
auto recordingCanvas_ = std::make_unique<ExtendRecordingCanvas>(0, 0, true); auto recordingCanvas_ = std::make_unique<ExtendRecordingCanvas>(0, 0, true);
for (const auto& drawable : contentVec_) { for (const auto& drawable : drawableVec_) {
if (drawable) { if (drawable) {
recordingCanvas_->DrawDrawFunc(drawable->CreateDrawFunc()); recordingCanvas_->DrawDrawFunc(drawable->CreateDrawFunc());
} }
@ -2757,7 +2759,7 @@ void RSRenderNode::OnSync()
// Sync drawCmdList // Sync drawCmdList
drawCmdList_ = std::move(stagingDrawCmdList_); drawCmdList_ = std::move(stagingDrawCmdList_);
// Sync each drawable. PLANNING: use dirty mask to only sync changed properties // 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) { if (drawableContent) {
drawableContent->OnSync(); drawableContent->OnSync();
} }