!40 UpdateDrawableContentVec 接入ApplyModifiers,实现ApplyModifiers中计算matrix并传入RenderParam

Merge pull request !40 from ZhangPeng/DEV-new-drawable-6-v2
This commit is contained in:
刘超 2024-03-04 06:30:27 +00:00 committed by Gitee
commit 5ca4892d9b
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
39 changed files with 570 additions and 2968 deletions

View File

@ -30,7 +30,7 @@ RSRenderNodeDrawable::Ptr RSCanvasRenderNodeDrawable::OnGenerate(std::shared_ptr
return std::make_unique<RSCanvasRenderNodeDrawable>(std::move(node));
}
void RSCanvasRenderNodeDrawable::OnDraw(RSPaintFilterCanvas* canvas) const
void RSCanvasRenderNodeDrawable::OnDraw(Drawing::Canvas* canvas) const
{
if (!renderNode_) {
RS_LOGE("There is no CanvasNode in drawable");

View File

@ -25,7 +25,7 @@ public:
~RSCanvasRenderNodeDrawable() override = default;
static RSRenderNodeDrawable::Ptr OnGenerate(std::shared_ptr<const RSRenderNode> node);
void OnDraw(RSPaintFilterCanvas* canvas) const override;
void OnDraw(Drawing::Canvas* canvas) const override;
private:
using Registrar = RenderNodeDrawableRegistrar<RSRenderNodeType::CANVAS_DRAWING_NODE, OnGenerate>;

View File

@ -15,13 +15,14 @@
#include "drawable/rs_display_render_node_drawable.h"
#include "rs_trace.h"
#include "pipeline/rs_base_render_engine.h"
#include "pipeline/rs_display_render_node.h"
#include "pipeline/rs_paint_filter_canvas.h"
#include "pipeline/rs_processor_factory.h"
#include "pipeline/rs_uni_render_listener.h"
#include "pipeline/rs_uni_render_thread.h"
#include "rs_trace.h"
#include "screen_manager/rs_screen_manager.h"
namespace OHOS::Rosen {
@ -36,7 +37,7 @@ RSRenderNodeDrawable::Ptr RSDisplayRenderNodeDrawable::OnGenerate(std::shared_pt
return std::make_unique<RSDisplayRenderNodeDrawable>(std::move(node));
}
void RSDisplayRenderNodeDrawable::OnDraw(RSPaintFilterCanvas* canvas) const
void RSDisplayRenderNodeDrawable::OnDraw(Drawing::Canvas* canvas) const
{
(void)canvas;

View File

@ -25,7 +25,7 @@ public:
~RSDisplayRenderNodeDrawable() override = default;
static RSRenderNodeDrawable::Ptr OnGenerate(std::shared_ptr<const RSRenderNode> node);
void OnDraw(RSPaintFilterCanvas* canvas) const override;
void OnDraw(Drawing::Canvas* canvas) const override;
private:
using Registrar = RenderNodeDrawableRegistrar<RSRenderNodeType::DISPLAY_NODE, OnGenerate>;

View File

@ -30,7 +30,7 @@ RSRenderNodeDrawable::Ptr RSEffectRenderNodeDrawable::OnGenerate(std::shared_ptr
return std::make_unique<RSEffectRenderNodeDrawable>(std::move(node));
}
void RSEffectRenderNodeDrawable::OnDraw(RSPaintFilterCanvas* canvas) const
void RSEffectRenderNodeDrawable::OnDraw(Drawing::Canvas* canvas) const
{
if (!renderNode_) {
RS_LOGE("There is no CanvasNode in RSEffectRenderNodeDrawable");

View File

@ -29,7 +29,7 @@ public:
~RSEffectRenderNodeDrawable() override = default;
static RSRenderNodeDrawable::Ptr OnGenerate(std::shared_ptr<const RSRenderNode> node);
void OnDraw(RSPaintFilterCanvas* canvas) const override;
void OnDraw(Drawing::Canvas* canvas) const override;
private:
using Registrar = RenderNodeDrawableRegistrar<RSRenderNodeType::EFFECT_NODE, OnGenerate>;

View File

@ -43,7 +43,7 @@ RSRenderNodeDrawable::Ptr RSRenderNodeDrawable::OnGenerate(std::shared_ptr<const
return nullptr;
}
void RSRenderNodeDrawable::OnDraw(RSPaintFilterCanvas* canvas) const
void RSRenderNodeDrawable::OnDraw(Drawing::Canvas* canvas) const
{
if (renderNode_ == nullptr) {
return;

View File

@ -22,7 +22,6 @@
namespace OHOS::Rosen {
class RSRenderNode;
class RSPaintFilterCanvas;
// Used by RSUniRenderThread and RSChildrenDrawable
class RSRenderNodeDrawable : public RSRenderNodeDrawableAdapter {
@ -31,7 +30,7 @@ public:
~RSRenderNodeDrawable() override = default;
static RSRenderNodeDrawable::Ptr OnGenerate(std::shared_ptr<const RSRenderNode> node);
void OnDraw(RSPaintFilterCanvas* canvas) const override;
void OnDraw(Drawing::Canvas* canvas) const override;
protected:
using Registrar = RenderNodeDrawableRegistrar<RSRenderNodeType::RS_NODE, OnGenerate>;

View File

@ -30,7 +30,7 @@ RSRenderNodeDrawable::Ptr RSRootRenderNodeDrawable::OnGenerate(std::shared_ptr<c
return std::make_unique<RSRootRenderNodeDrawable>(std::move(node));
}
void RSRootRenderNodeDrawable::OnDraw(RSPaintFilterCanvas* canvas) const
void RSRootRenderNodeDrawable::OnDraw(Drawing::Canvas* canvas) const
{
if (!renderNode_) {
RS_LOGE("There is no CanvasNode in RSRootRenderNodeDrawable");

View File

@ -29,7 +29,7 @@ public:
~RSRootRenderNodeDrawable() override = default;
static RSRenderNodeDrawable::Ptr OnGenerate(std::shared_ptr<const RSRenderNode> node);
void OnDraw(RSPaintFilterCanvas* canvas) const override;
void OnDraw(Drawing::Canvas* canvas) const override;
private:
using Registrar = RenderNodeDrawableRegistrar<RSRenderNodeType::ROOT_NODE, OnGenerate>;

View File

@ -30,7 +30,7 @@ RSRenderNodeDrawable::Ptr RSSurfaceRenderNodeDrawable::OnGenerate(std::shared_pt
return std::make_unique<RSSurfaceRenderNodeDrawable>(std::move(node));
}
void RSSurfaceRenderNodeDrawable::OnDraw(RSPaintFilterCanvas* canvas) const
void RSSurfaceRenderNodeDrawable::OnDraw(Drawing::Canvas* canvas) const
{
if (!renderNode_) {
RS_LOGE("There is no CanvasNode in RSSurfaceRenderNodeDrawable");

View File

@ -29,7 +29,7 @@ public:
~RSSurfaceRenderNodeDrawable() override = default;
static RSRenderNodeDrawable::Ptr OnGenerate(std::shared_ptr<const RSRenderNode> node);
void OnDraw(RSPaintFilterCanvas* canvas) const override;
void OnDraw(Drawing::Canvas* canvas) const override;
private:
using Registrar = RenderNodeDrawableRegistrar<RSRenderNodeType::SURFACE_NODE, OnGenerate>;

View File

@ -206,17 +206,11 @@ ohos_source_set("render_service_base_src") {
"src/property/rs_point_light_manager.cpp",
"src/property/rs_properties.cpp",
"src/property/rs_properties_painter.cpp",
"src/property/rs_property_drawable.cpp",
"src/property/rs_property_drawable_bounds_geometry.cpp",
"src/property/rs_property_drawable_frame_geometry.cpp",
"src/property/rs_property_drawable_utilities.cpp",
"src/property/rs_property_trace.cpp",
#drawable
"src/drawable/rs_render_node_drawable_adapter.cpp",
"src/drawable/rs_property_drawable_ng.cpp",
"src/drawable/rs_property_drawable_content.cpp",
"src/drawable/rs_drawable.cpp",
"src/drawable/rs_drawable_content.cpp",
#render
@ -305,12 +299,6 @@ ohos_source_set("render_service_base_src") {
"src/pipeline/rs_uni_render_judgement.cpp",
"src/pipeline/sk_resource_manager.cpp",
#property
"src/property/rs_property_drawable.cpp",
"src/property/rs_property_drawable_bounds_geometry.cpp",
"src/property/rs_property_drawable_frame_geometry.cpp",
"src/property/rs_property_drawable_utilities.cpp",
#transaction
"src/transaction/rs_hgm_config_data.cpp",
"src/transaction/rs_occlusion_data.cpp",

View File

@ -1,70 +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_DRAWABLE_H
#define RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H
#include <memory>
namespace OHOS::Rosen {
class RSRenderNode;
class RSPaintFilterCanvas;
// Pure virtual base class
class RSDrawable {
public:
RSDrawable() = default;
virtual ~RSDrawable() = default;
// 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&)>;
// Call in RenderThread during drawing
virtual void OnDraw(RSPaintFilterCanvas* canvas) const = 0;
// not copyable and moveable
RSDrawable(const RSDrawable&) = delete;
RSDrawable(const RSDrawable&&) = delete;
RSDrawable& operator=(const RSDrawable&) = delete;
RSDrawable& operator=(const RSDrawable&&) = delete;
};
class RSChildrenDrawableContent;
class RSChildrenDrawable : public RSDrawable {
public:
RSChildrenDrawable(std::shared_ptr<const RSChildrenDrawableContent> content);
~RSChildrenDrawable() override = default;
void OnDraw(RSPaintFilterCanvas* canvas) const override;
private:
std::shared_ptr<const RSChildrenDrawableContent> content_;
};
class RSCustomModifierDrawableContent;
class RSCustomModifierDrawable : public RSDrawable {
public:
RSCustomModifierDrawable(std::shared_ptr<const RSCustomModifierDrawableContent> content);
~RSCustomModifierDrawable() override = default;
void OnDraw(RSPaintFilterCanvas* canvas) const override;
private:
std::shared_ptr<const RSCustomModifierDrawableContent> content_;
};
} // namespace OHOS::Rosen
#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H

View File

@ -22,20 +22,18 @@
#include <memory>
#include <unordered_set>
#include "drawable/rs_drawable.h"
#include "modifier/rs_modifier_type.h"
#include "pipeline/rs_recording_canvas.h"
namespace OHOS::Rosen {
class RSRenderNode;
class RSRenderContent;
// NOTE: MUST update DrawableGeneratorLut in rs_property_drawable.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 {
INVALID = 0,
SAVE_ALL,
// Bounds Geometry
BOUNDS_MATRIX,
ALPHA,
MASK,
TRANSITION,
@ -84,7 +82,7 @@ enum class RSDrawableContentSlot : uint8_t {
PIXEL_STRETCH,
RESTORE_BLEND_MODE,
RESTORE_ALL,
RESTORE_ALPHA,
// Annotations: Please remember to update this when new slots are added.
// NOTE: MAX and *_END enums are using the one-past-the-end style.
@ -94,7 +92,7 @@ enum class RSDrawableContentSlot : uint8_t {
CONTENT_PROPERTIES_END = FOREGROUND_STYLE + 1,
FG_PROPERTIES_BEGIN = BINARIZATION,
FG_PROPERTIES_END = FOREGROUND_COLOR + 1,
MAX = RESTORE_ALL + 1,
MAX = RESTORE_ALPHA + 1,
};
// pure virtual base class
@ -120,7 +118,11 @@ public:
// Call on thread sync
virtual void OnSync() = 0;
virtual RSDrawable::Ptr CreateDrawable() const = 0;
// !!!!!!!!!!!!!!!!!!!!!!!!!!
// Important Note:
// DrawFunc can only access the RT members variables, accessing staging members will cause a crash
// !!!!!!!!!!!!!!!!!!!!!!!!!!
virtual Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const = 0;
// not copyable and moveable
RSDrawableContent(const RSDrawableContent&) = delete;
@ -128,15 +130,12 @@ public:
RSDrawableContent& operator=(const RSDrawableContent&) = delete;
RSDrawableContent& operator=(const RSDrawableContent&&) = delete;
#ifdef USE_ROSEN_DRAWING
// =================Generate & Update helper methods==================
// Step 1, generate DirtySlots from dirty Modifiers
using ModifierDirtyTypes = std::bitset<static_cast<int>(RSModifierType::MAX_RS_MODIFIER_TYPE)>;
static std::unordered_set<RSDrawableContentSlot> GenerateDirtySlots(
static std::unordered_set<RSDrawableContentSlot> CalculateDirtySlots(
ModifierDirtyTypes& dirtyTypes, const Vec& drawableVec);
#endif
// Step 2, for every DirtySlot, generate DrawableContent
static bool UpdateDrawableVec(
static bool UpdateDirtySlots(
const RSRenderNode& node, Vec& drawableVec, std::unordered_set<RSDrawableContentSlot>& dirtySlots);
// Step 3, add necessary Clip/Save/Restore
static void UpdateSaveRestore(RSRenderContent& content, Vec& drawableVec, uint8_t& drawableVecStatus);
@ -152,7 +151,7 @@ public:
static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& node);
bool OnUpdate(const RSRenderNode& content) override;
void OnSync() override;
RSDrawable::Ptr CreateDrawable() const override;
Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override;
private:
bool needSync_ = false;
@ -172,7 +171,7 @@ public:
static RSDrawableContent::Ptr OnGenerate(const RSRenderNode& content, RSModifierType type);
bool OnUpdate(const RSRenderNode& node) override;
void OnSync() override;
RSDrawable::Ptr CreateDrawable() const override;
Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override;
private:
RSModifierType type_;

View File

@ -19,7 +19,6 @@
#include "recording/draw_cmd_list.h"
#include "drawable/rs_drawable_content.h"
#include "drawable/rs_property_drawable_ng.h"
#include "property/rs_properties.h"
namespace OHOS::Rosen {
@ -32,7 +31,8 @@ public:
~RSPropertyDrawableContent() override = default;
void OnSync() override;
RSDrawable::Ptr CreateDrawable() const override;
// RSDrawable::Ptr CreateDrawable() const override;
Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const override;
protected:
bool needSync_ = false;

View File

@ -1,35 +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_H
#define RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_H
#include "drawable/rs_drawable.h"
namespace OHOS::Rosen {
class RSPropertyDrawableContent;
class RSPropertyDrawableNG : public RSDrawable {
public:
RSPropertyDrawableNG(std::shared_ptr<const RSPropertyDrawableContent> cmdList);
~RSPropertyDrawableNG() override = default;
void OnDraw(RSPaintFilterCanvas* canvas) const override;
protected:
std::shared_ptr<const RSPropertyDrawableContent> cmdList_;
};
} // namespace OHOS::Rosen
#endif // RENDER_SERVICE_BASE_DRAWABLE_RS_PROPERTY_DRAWABLE_H

View File

@ -24,7 +24,9 @@
namespace OHOS::Rosen {
class RSRenderNode;
class RSPaintFilterCanvas;
namespace Drawing {
class Canvas;
}
class RSB_EXPORT RSRenderNodeDrawableAdapter {
public:
@ -38,7 +40,7 @@ public:
RSRenderNodeDrawableAdapter& operator=(const RSRenderNodeDrawableAdapter&&) = delete;
// This method can only be called in RenderThread
virtual void OnDraw(RSPaintFilterCanvas* canvas) const = 0;
virtual void OnDraw(Drawing::Canvas* canvas) const = 0;
using Ptr = std::unique_ptr<RSRenderNodeDrawableAdapter>;
static Ptr OnGenerate(const std::shared_ptr<const RSRenderNode>& node);

View File

@ -16,13 +16,16 @@
#ifndef RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_MODIFIER_TYPE_H
#define RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_MODIFIER_TYPE_H
#include <bitset>
#include <cstdint>
namespace OHOS {
namespace Rosen {
// NOTE:
// 1. MUST update g_propertyResetterLUT in rs_properties.cpp when new properties are added
// 2. property modifier MUST be added before CUSTOM, else wise it will be treated as draw modifier
// 1. Following LUTs must be updated according when this enum is updated :
// a. g_propertyResetterLUT in rs_properties.cpp
// b. g_propertyToDrawableLut in rs_drawable_content.cpp
// 2. Property modifier(i.e. to be applied to RSProperties) MUST be added before CUSTOM enum, else wise it will not work
enum class RSModifierType : int16_t {
INVALID = 0, // 0
BOUNDS, // 1
@ -121,6 +124,7 @@ enum class RSModifierType : int16_t {
GEOMETRYTRANS, // 94
MAX_RS_MODIFIER_TYPE,
};
using ModifierDirtyTypes = std::bitset<static_cast<int>(RSModifierType::MAX_RS_MODIFIER_TYPE)>;
enum class RSRenderPropertyType : int16_t {
INVALID = 0,

View File

@ -19,7 +19,6 @@
#include "memory/rs_dfx_string.h"
#include "modifier/rs_render_modifier.h"
#include "property/rs_properties.h"
#include "property/rs_property_drawable.h"
namespace OHOS {
namespace Rosen {
@ -39,18 +38,12 @@ public:
using DrawCmdContainer = std::map<RSModifierType, std::list<std::shared_ptr<RSRenderModifier>>>;
RSRenderNodeType GetType() const;
void DrawPropertyDrawable(RSPropertyDrawableSlot slot, RSPaintFilterCanvas& canvas) const;
void DrawPropertyDrawableRange(
RSPropertyDrawableSlot begin, RSPropertyDrawableSlot end, RSPaintFilterCanvas& canvas) const;
private:
RSProperties renderProperties_;
RSPropertyDrawable::DrawableVec propertyDrawablesVec_;
DrawCmdContainer drawCmdModifiers_;
RSRenderNodeType type_ = RSRenderNodeType::UNKNOW;
friend class RSRenderNode;
friend class RSModifierDrawable;
friend class RSCustomModifierDrawCmdList;
};
} // namespace Rosen

View File

@ -41,7 +41,6 @@
#include "pipeline/rs_render_display_sync.h"
#include "pipeline/rs_single_frame_composer.h"
#include "property/rs_properties.h"
#include "property/rs_property_drawable.h"
#include "draw/surface.h"
#include "image/gpu_context.h"
@ -54,7 +53,6 @@ class DrawCmdList;
class RSContext;
class RSNodeVisitor;
class RSCommand;
class RSPropertyDrawable;
namespace NativeBufferUtils {
class VulkanCleanupHelper;
}
@ -518,17 +516,8 @@ protected:
NodeId drawingCacheRootId_ = INVALID_NODEID;
bool mustRenewedInfo_ = false;
std::bitset<static_cast<int>(RSModifierType::MAX_RS_MODIFIER_TYPE)> dirtyTypes_;
ModifierDirtyTypes dirtyTypes_;
bool isBootAnimation_ = false;
inline void DrawPropertyDrawable(RSPropertyDrawableSlot slot, RSPaintFilterCanvas& canvas)
{
renderContent_->DrawPropertyDrawable(slot, canvas);
}
inline void DrawPropertyDrawableRange(
RSPropertyDrawableSlot begin, RSPropertyDrawableSlot end, RSPaintFilterCanvas& canvas)
{
renderContent_->DrawPropertyDrawableRange(begin, end, canvas);
}
private:
NodeId id_;
@ -667,8 +656,7 @@ private:
std::shared_ptr<RSRenderDisplaySync> displaySync_ = nullptr;
uint8_t drawableVecStatus_ = 0;
void UpdateDrawableVec();
void UpdateDrawableVecInternal(std::unordered_set<RSPropertyDrawableSlot> dirtySlots);
void UpdateDrawableContentVec();
std::map<NodeId, std::vector<WeakPtr>> subSurfaceNodes_;
pid_t appPid_ = 0;

View File

@ -356,7 +356,7 @@ public:
void OnApplyModifiers();
private:
void ResetProperty(const std::bitset<static_cast<int>(RSModifierType::MAX_RS_MODIFIER_TYPE)>& dirtyTypes);
void ResetProperty(const ModifierDirtyTypes& dirtyTypes);
void SetDirty();
void ResetDirty();
bool IsDirty() const;

View File

@ -1,132 +0,0 @@
/*
* Copyright (c) 2023 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_PROPERTY_RS_PROPERTY_DRAWABLE_H
#define RENDER_SERVICE_BASE_PROPERTY_RS_PROPERTY_DRAWABLE_H
#include <bitset>
#include <memory>
#include <set>
#include <vector>
#include "modifier/rs_render_modifier.h"
namespace OHOS::Rosen {
class RSPaintFilterCanvas;
class RSProperties;
class RSRenderContent;
class RSRenderNode;
// NOTE: MUST update DrawableGeneratorLut in rs_property_drawable.cpp when new slots are added
enum class RSPropertyDrawableSlot : uint8_t {
INVALID = 0,
SAVE_ALL,
// Bounds Geometry
BOUNDS_MATRIX,
ALPHA,
MASK,
TRANSITION,
ENV_FOREGROUND_COLOR,
SHADOW,
OUTLINE,
// BG properties in Bounds Clip
BG_SAVE_BOUNDS,
CLIP_TO_BOUNDS,
BLEND_MODE,
BACKGROUND_COLOR,
BACKGROUND_SHADER,
BACKGROUND_IMAGE,
BACKGROUND_FILTER,
USE_EFFECT,
BACKGROUND_STYLE,
DYNAMIC_LIGHT_UP,
ENV_FOREGROUND_COLOR_STRATEGY,
BG_RESTORE_BOUNDS,
// Frame Geometry
SAVE_FRAME,
FRAME_OFFSET,
CLIP_TO_FRAME,
CONTENT_STYLE,
CHILDREN,
FOREGROUND_STYLE,
RESTORE_FRAME,
// FG properties in Bounds clip
FG_SAVE_BOUNDS,
FG_CLIP_TO_BOUNDS,
BINARIZATION,
COLOR_FILTER,
LIGHT_UP_EFFECT,
FOREGROUND_FILTER,
FOREGROUND_COLOR,
FG_RESTORE_BOUNDS,
// No clip (unless ClipToBounds is set)
POINT_LIGHT,
BORDER,
OVERLAY,
PARTICLE_EFFECT,
PIXEL_STRETCH,
RESTORE_BLEND_MODE,
RESTORE_ALL,
// Annotations: Please remember to update this when new slots are added.
// NOTE: MAX and *_END enums are using the one-past-the-end style.
BG_PROPERTIES_BEGIN = BACKGROUND_COLOR,
BG_PROPERTIES_END = ENV_FOREGROUND_COLOR_STRATEGY + 1,
CONTENT_PROPERTIES_BEGIN = FRAME_OFFSET,
CONTENT_PROPERTIES_END = FOREGROUND_STYLE + 1,
FG_PROPERTIES_BEGIN = BINARIZATION,
FG_PROPERTIES_END = FOREGROUND_COLOR + 1,
MAX = RESTORE_ALL + 1,
};
// Pure virtual base class
class RSPropertyDrawable {
public:
RSPropertyDrawable() = default;
virtual ~RSPropertyDrawable() = default;
// not copyable and moveable
RSPropertyDrawable(const RSPropertyDrawable&) = delete;
RSPropertyDrawable(const RSPropertyDrawable&&) = delete;
RSPropertyDrawable& operator=(const RSPropertyDrawable&) = delete;
RSPropertyDrawable& operator=(const RSPropertyDrawable&&) = delete;
virtual void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const = 0;
// return true if this drawable can be updated, default is false
virtual bool Update(const RSRenderContent& content) { return false; };
// Aliases
using DrawablePtr = std::unique_ptr<RSPropertyDrawable>;
using DrawableVec = std::array<DrawablePtr, static_cast<size_t>(RSPropertyDrawableSlot::MAX)>;
using DrawableGenerator = std::function<DrawablePtr(const RSRenderContent&)>;
// Generator Utilities
static void InitializeSaveRestore(const RSRenderContent& content, DrawableVec& drawableVec);
static std::unordered_set<RSPropertyDrawableSlot> GenerateDirtySlots(
const RSProperties& properties,
std::bitset<static_cast<int>(RSModifierType::MAX_RS_MODIFIER_TYPE)>& dirtyTypes);
static bool UpdateDrawableVec(const RSRenderContent& content, DrawableVec& drawableVec,
std::unordered_set<RSPropertyDrawableSlot>& dirtySlots);
static void UpdateSaveRestore(
RSRenderContent& content, DrawableVec& drawableVec, uint8_t& drawableVecStatus);
};
} // namespace OHOS::Rosen
#endif // RENDER_SERVICE_BASE_PROPERTY_RS_PROPERTY_DRAWABLE_H

View File

@ -1,419 +0,0 @@
/*
* Copyright (c) 2023 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_PROPERTY_RS_PROPERTY_DRAWABLE_BOUNDS_GEOMETRY_H
#define RENDER_SERVICE_BASE_PROPERTY_RS_PROPERTY_DRAWABLE_BOUNDS_GEOMETRY_H
#include <utility>
#include "include/core/SkPaint.h"
#include "property/rs_property_drawable.h"
namespace OHOS::Rosen {
class RSSkiaFilter;
enum class FilterType;
class RSBoundsGeometryDrawable : public RSPropertyDrawable {
public:
explicit RSBoundsGeometryDrawable() = default;
~RSBoundsGeometryDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
};
class RSClipBoundsDrawable : public RSPropertyDrawable {
public:
explicit RSClipBoundsDrawable() = default;
~RSClipBoundsDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
};
// ============================================================================
// PointLight
class RSPointLightDrawable : public RSPropertyDrawable {
public:
explicit RSPointLightDrawable() = default;
~RSPointLightDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
};
// ============================================================================
// Border
class RSBorderDrawable : public RSPropertyDrawable {
public:
explicit RSBorderDrawable(Drawing::Brush&& brush, Drawing::Pen&& pen)
: RSPropertyDrawable(), brush_(std::move(brush)), pen_(std::move(pen))
{}
~RSBorderDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
protected:
Drawing::Brush brush_;
Drawing::Pen pen_;
};
class RSBorderDRRectDrawable : public RSBorderDrawable {
public:
explicit RSBorderDRRectDrawable(Drawing::Brush&& brush, Drawing::Pen&& pen,
const RSProperties& properties, const bool& drawBorder);
~RSBorderDRRectDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
void OnBoundsChange(const RSProperties& properties);
private:
bool drawBorder_;
Drawing::RoundRect inner_;
Drawing::RoundRect outer_;
};
class RSBorderFourLineDrawable : public RSBorderDrawable {
public:
explicit RSBorderFourLineDrawable(Drawing::Brush&& brush, Drawing::Pen&& pen,
const RSProperties& properties, const bool& drawBorder);
~RSBorderFourLineDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
void OnBoundsChange(const RSProperties& properties);
private:
bool drawBorder_;
RectF rect_;
};
class RSBorderPathDrawable : public RSBorderDrawable {
public:
explicit RSBorderPathDrawable(Drawing::Brush&& brush, Drawing::Pen&& pen,
const RSProperties& properties, const bool& drawBorder);
~RSBorderPathDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
void OnBoundsChange(const RSProperties& properties);
private:
bool drawBorder_;
Drawing::Path borderPath_;
};
class RSBorderFourLineRoundCornerDrawable : public RSBorderDrawable {
public:
explicit RSBorderFourLineRoundCornerDrawable(Drawing::Brush&& brush, Drawing::Pen&& pen,
const RSProperties& properties, const bool& drawBorder);
~RSBorderFourLineRoundCornerDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
void OnBoundsChange(const RSProperties& properties);
private:
bool drawBorder_;
Drawing::RoundRect innerRrect_;
Drawing::RoundRect rrect_;
};
// ============================================================================
// Outline
class RSOutlineDrawable : public RSBorderDrawable {
public:
explicit RSOutlineDrawable(Drawing::Brush&& brush, Drawing::Pen&& pen)
: RSBorderDrawable(std::move(brush), std::move(pen))
{}
~RSOutlineDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
};
// ============================================================================
// Mask
class RSMaskDrawable : public RSPropertyDrawable {
public:
explicit RSMaskDrawable(std::shared_ptr<RSMask> mask);
~RSMaskDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
protected:
std::shared_ptr<RSMask> mask_;
Drawing::Brush maskFilterBrush_;
Drawing::Brush maskBrush_;
};
class RSSvgDomMaskDrawable : public RSMaskDrawable {
public:
explicit RSSvgDomMaskDrawable(std::shared_ptr<RSMask> mask);
~RSSvgDomMaskDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
};
class RSSvgPictureMaskDrawable : public RSMaskDrawable {
public:
explicit RSSvgPictureMaskDrawable(std::shared_ptr<RSMask> mask);
~RSSvgPictureMaskDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
};
class RSGradientMaskDrawable : public RSMaskDrawable {
public:
explicit RSGradientMaskDrawable(std::shared_ptr<RSMask> mask);
~RSGradientMaskDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
};
class RSPathMaskDrawable : public RSMaskDrawable {
public:
explicit RSPathMaskDrawable(std::shared_ptr<RSMask> mask);
~RSPathMaskDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
};
// ============================================================================
// Shadow
class RSShadowBaseDrawable : public RSPropertyDrawable {
public:
explicit RSShadowBaseDrawable(const RSProperties& properties);
~RSShadowBaseDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
protected:
void ClipShadowPath(const RSRenderContent& content, RSPaintFilterCanvas& canvas, Drawing::Path& path) const;
float offsetX_;
float offsetY_;
const Color color_;
};
class RSShadowDrawable : public RSShadowBaseDrawable {
public:
explicit RSShadowDrawable(const RSProperties& properties);
~RSShadowDrawable() override = default;
RSColor GetColorForShadow(const RSRenderContent& content, RSPaintFilterCanvas& canvas,
Drawing::Path& skPath, Drawing::Matrix& matrix, Drawing::RectI& deviceClipBounds) const;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
protected:
const float radius_;
};
class RSColorfulShadowDrawable : public RSShadowBaseDrawable {
public:
explicit RSColorfulShadowDrawable(const RSProperties& properties);
~RSColorfulShadowDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
protected:
Drawing::Brush blurBrush_;
std::weak_ptr<RSRenderNode> node_;
};
class RSHardwareAccelerationShadowDrawable : public RSShadowBaseDrawable {
public:
explicit RSHardwareAccelerationShadowDrawable(const RSProperties& properties);
~RSHardwareAccelerationShadowDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
protected:
const float shadowElevation_;
};
// ============================================================================
// DynamicLightUp
class RSDynamicLightUpDrawable : public RSPropertyDrawable {
public:
explicit RSDynamicLightUpDrawable() = default;
~RSDynamicLightUpDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
bool Update(const RSRenderContent& content) override;
};
// ============================================================================
// Binarization
class RSBinarizationDrawable : public RSPropertyDrawable {
public:
explicit RSBinarizationDrawable() = default;
~RSBinarizationDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
};
// ============================================================================
// LightUpEffect
class RSLightUpEffectDrawable : public RSPropertyDrawable {
public:
explicit RSLightUpEffectDrawable() = default;
~RSLightUpEffectDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
bool Update(const RSRenderContent& content) override;
};
// ============================================================================
// BackgroundFilter
class RSBackgroundFilterDrawable : public RSPropertyDrawable {
public:
explicit RSBackgroundFilterDrawable() = default;
~RSBackgroundFilterDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
bool Update(const RSRenderContent& content) override;
};
// ForegroundFilter
class RSForegroundFilterDrawable : public RSPropertyDrawable {
public:
explicit RSForegroundFilterDrawable() = default;
~RSForegroundFilterDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
bool Update(const RSRenderContent& content) override;
};
// EffectDataGenerate
class RSEffectDataGenerateDrawable : public RSPropertyDrawable {
public:
explicit RSEffectDataGenerateDrawable() = default;
~RSEffectDataGenerateDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
bool Update(const RSRenderContent& content) override;
};
// RSEffectDataApply
class RSEffectDataApplyDrawable : public RSPropertyDrawable {
public:
explicit RSEffectDataApplyDrawable() = default;
~RSEffectDataApplyDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
bool Update(const RSRenderContent& content) override;
};
// ============================================================================
// ForegroundColor
class RSForegroundColorDrawable : public RSPropertyDrawable {
public:
explicit RSForegroundColorDrawable(Drawing::Brush&& brush) : brush_(std::move(brush)) {}
~RSForegroundColorDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
bool Update(const RSRenderContent& content) override;
private:
Drawing::Brush brush_;
};
// ============================================================================
// Particle
class RSParticleDrawable : public RSPropertyDrawable {
public:
explicit RSParticleDrawable() = default;
~RSParticleDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
bool Update(const RSRenderContent& content) override;
};
// ============================================================================
// PixelStretch
class RSPixelStretchDrawable : public RSPropertyDrawable {
public:
explicit RSPixelStretchDrawable() = default;
~RSPixelStretchDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
bool Update(const RSRenderContent& content) override;
};
// ============================================================================
// Background
class RSBackgroundDrawable : public RSPropertyDrawable {
public:
explicit RSBackgroundDrawable() = default;
~RSBackgroundDrawable() override = default;
static void setForceBgAntiAlias(bool antiAlias);
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
protected:
Drawing::Brush brush_;
};
class RSBackgroundColorDrawable : public RSBackgroundDrawable {
public:
explicit RSBackgroundColorDrawable(Drawing::Color color) : RSBackgroundDrawable()
{
brush_.SetColor(color);
}
~RSBackgroundColorDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
bool Update(const RSRenderContent& content) override;
};
class RSBackgroundShaderDrawable : public RSBackgroundDrawable {
public:
explicit RSBackgroundShaderDrawable(std::shared_ptr<Drawing::ShaderEffect> filter) : RSBackgroundDrawable()
{
brush_.SetShaderEffect(std::move(filter));
}
~RSBackgroundShaderDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
bool Update(const RSRenderContent& content) override;
};
class RSBackgroundImageDrawable : public RSBackgroundDrawable {
public:
explicit RSBackgroundImageDrawable() = default;
~RSBackgroundImageDrawable() override = default;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
bool Update(const RSRenderContent& content) override;
};
// blend mode save and restore
std::unique_ptr<RSPropertyDrawable> BlendSaveDrawableGenerate(const RSRenderContent& context);
std::unique_ptr<RSPropertyDrawable> BlendRestoreDrawableGenerate(const RSRenderContent& context);
class RSBlendSaveLayerDrawable : public RSPropertyDrawable {
public:
explicit RSBlendSaveLayerDrawable(int blendMode);
~RSBlendSaveLayerDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
private:
Drawing::Brush blendBrush_;
};
class RSBlendFastDrawable : public RSPropertyDrawable {
public:
explicit RSBlendFastDrawable(int blendMode) : blendMode_(blendMode) {}
~RSBlendFastDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
private:
int blendMode_;
};
class RSBlendSaveLayerRestoreDrawable : public RSPropertyDrawable {
public:
explicit RSBlendSaveLayerRestoreDrawable() = default;
~RSBlendSaveLayerRestoreDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
};
class RSBlendFastRestoreDrawable : public RSPropertyDrawable {
public:
explicit RSBlendFastRestoreDrawable() = default;
~RSBlendFastRestoreDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
};
} // namespace OHOS::Rosen
#endif // RENDER_SERVICE_BASE_PROPERTY_RS_PROPERTY_DRAWABLE_BOUNDS_GEOMETRY_H

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) 2023 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_PROPERTY_RS_PROPERTY_DRAWABLE_FRAME_GEOMETRY_H
#define RENDER_SERVICE_BASE_PROPERTY_RS_PROPERTY_DRAWABLE_FRAME_GEOMETRY_H
#include "include/core/SkPaint.h"
#include "property/rs_property_drawable.h"
namespace OHOS::Rosen {
class RSFrameGeometryDrawable : public RSPropertyDrawable {
public:
explicit RSFrameGeometryDrawable() = default;
~RSFrameGeometryDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
};
// ============================================================================
// ClipFrame
class RSClipFrameDrawable : public RSPropertyDrawable {
public:
explicit RSClipFrameDrawable() = default;
~RSClipFrameDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
};
// ============================================================================
//
class RSColorFilterDrawable : public RSPropertyDrawable {
public:
explicit RSColorFilterDrawable(Drawing::Brush&& brush) : brush_(std::move(brush)) {}
~RSColorFilterDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
bool Update(const RSRenderContent& content) override;
private:
Drawing::Brush brush_;
};
} // namespace OHOS::Rosen
#endif // RENDER_SERVICE_BASE_PROPERTY_RS_PROPERTY_DRAWABLE_FRAME_GEOMETRY_H

View File

@ -1,113 +0,0 @@
/*
* Copyright (c) 2023 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_PROPERTY_RS_PROPERTY_DRAWABLE_UTILITIES_H
#define RENDER_SERVICE_BASE_PROPERTY_RS_PROPERTY_DRAWABLE_UTILITIES_H
#include "pipeline/rs_paint_filter_canvas.h"
#include "property/rs_property_drawable.h"
namespace OHOS::Rosen {
// ============================================================================
// alias (reference or soft link) of another drawable
class RSAliasDrawable : public RSPropertyDrawable {
public:
explicit RSAliasDrawable(RSPropertyDrawableSlot slot);
~RSAliasDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
private:
RSPropertyDrawableSlot slot_;
};
// ============================================================================
// Save and Restore
class RSSaveDrawable : public RSPropertyDrawable {
public:
explicit RSSaveDrawable(std::shared_ptr<int> content);
~RSSaveDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
private:
std::shared_ptr<int> content_;
};
class RSRestoreDrawable : public RSPropertyDrawable {
public:
explicit RSRestoreDrawable(std::shared_ptr<int> content);
~RSRestoreDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
private:
std::shared_ptr<int> content_;
};
class RSCustomSaveDrawable : public RSPropertyDrawable {
public:
explicit RSCustomSaveDrawable(
std::shared_ptr<RSPaintFilterCanvas::SaveStatus> content, RSPaintFilterCanvas::SaveType type);
~RSCustomSaveDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
private:
std::shared_ptr<RSPaintFilterCanvas::SaveStatus> content_;
RSPaintFilterCanvas::SaveType type_;
};
class RSCustomRestoreDrawable : public RSPropertyDrawable {
public:
explicit RSCustomRestoreDrawable(std::shared_ptr<RSPaintFilterCanvas::SaveStatus> content);
~RSCustomRestoreDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
private:
std::shared_ptr<RSPaintFilterCanvas::SaveStatus> content_;
};
// ============================================================================
// Alpha
class RSAlphaDrawable : public RSPropertyDrawable {
public:
explicit RSAlphaDrawable(float alpha);
~RSAlphaDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
static RSPropertyDrawable::DrawablePtr Generate(const RSRenderContent& content);
protected:
float alpha_;
};
class RSAlphaOffscreenDrawable : public RSAlphaDrawable {
public:
explicit RSAlphaOffscreenDrawable(float alpha);
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
};
// ============================================================================
// Adapter for RSRenderModifier
class RSModifierDrawable : public RSPropertyDrawable {
public:
explicit RSModifierDrawable(RSModifierType type);
~RSModifierDrawable() override = default;
void Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const override;
private:
RSModifierType type_;
};
}; // namespace OHOS::Rosen
#endif // RENDER_SERVICE_BASE_PROPERTY_RS_PROPERTY_DRAWABLE_UTILITIES_H

View File

@ -1,50 +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.h"
#include "recording/draw_cmd_list.h"
#include "drawable/rs_drawable_content.h"
#include "drawable/rs_render_node_drawable_adapter.h"
#include "pipeline/rs_paint_filter_canvas.h"
namespace OHOS::Rosen {
// =================== RSChildrenDrawable =====================
RSChildrenDrawable::RSChildrenDrawable(std::shared_ptr<const RSChildrenDrawableContent> content)
: content_(std::move(content))
{}
void RSChildrenDrawable::OnDraw(RSPaintFilterCanvas* canvas) const
{
for (auto& drawable : content_->childrenDrawables_) {
drawable->OnDraw(canvas);
}
}
// =================== RSCustomModifierDrawable =====================
RSCustomModifierDrawable::RSCustomModifierDrawable(std::shared_ptr<const RSCustomModifierDrawableContent> content)
: content_(std::move(content))
{}
void RSCustomModifierDrawable::OnDraw(RSPaintFilterCanvas* canvas) const
{
for (auto& drawCmdList : content_->drawCmdList_) {
drawCmdList->Playback(*canvas);
}
}
} // namespace OHOS::Rosen

View File

@ -21,99 +21,105 @@
namespace OHOS::Rosen {
namespace {
// NOTE: This LUT should always the same size and order as RSModifierType
// key = RSModifierType, value = RSDrawableContentSlot
static const std::unordered_map<RSModifierType, RSDrawableContentSlot> g_propertyToDrawableLut = {
{ RSModifierType::INVALID, RSDrawableContentSlot::INVALID },
{ RSModifierType::BOUNDS, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::FRAME, RSDrawableContentSlot::FRAME_OFFSET },
{ RSModifierType::POSITION_Z, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::PIVOT, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::PIVOT_Z, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::QUATERNION, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::ROTATION, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::ROTATION_X, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::ROTATION_Y, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::CAMERA_DISTANCE, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::SCALE, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::SKEW, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::TRANSLATE, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::TRANSLATE_Z, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::SUBLAYER_TRANSFORM, RSDrawableContentSlot::INVALID },
{ RSModifierType::CORNER_RADIUS, RSDrawableContentSlot::INVALID },
{ RSModifierType::ALPHA, RSDrawableContentSlot::ALPHA },
{ RSModifierType::ALPHA_OFFSCREEN, RSDrawableContentSlot::ALPHA },
{ RSModifierType::FOREGROUND_COLOR, RSDrawableContentSlot::FOREGROUND_COLOR },
{ RSModifierType::BACKGROUND_COLOR, RSDrawableContentSlot::BACKGROUND_COLOR },
{ RSModifierType::BACKGROUND_SHADER, RSDrawableContentSlot::BACKGROUND_SHADER },
{ RSModifierType::BG_IMAGE, RSDrawableContentSlot::BACKGROUND_IMAGE },
{ RSModifierType::BG_IMAGE_WIDTH, RSDrawableContentSlot::BACKGROUND_IMAGE },
{ RSModifierType::BG_IMAGE_HEIGHT, RSDrawableContentSlot::BACKGROUND_IMAGE },
{ RSModifierType::BG_IMAGE_POSITION_X, RSDrawableContentSlot::BACKGROUND_IMAGE },
{ RSModifierType::BG_IMAGE_POSITION_Y, RSDrawableContentSlot::BACKGROUND_IMAGE },
{ RSModifierType::SURFACE_BG_COLOR, RSDrawableContentSlot::INVALID },
{ RSModifierType::BORDER_COLOR, RSDrawableContentSlot::BORDER },
{ RSModifierType::BORDER_WIDTH, RSDrawableContentSlot::BORDER },
{ RSModifierType::BORDER_STYLE, RSDrawableContentSlot::BORDER },
{ RSModifierType::FILTER, RSDrawableContentSlot::FOREGROUND_FILTER },
{ RSModifierType::BACKGROUND_FILTER, RSDrawableContentSlot::BACKGROUND_FILTER },
{ RSModifierType::LINEAR_GRADIENT_BLUR_PARA, RSDrawableContentSlot::FOREGROUND_FILTER },
{ RSModifierType::DYNAMIC_LIGHT_UP_RATE, RSDrawableContentSlot::DYNAMIC_LIGHT_UP },
{ RSModifierType::DYNAMIC_LIGHT_UP_DEGREE, RSDrawableContentSlot::DYNAMIC_LIGHT_UP },
{ RSModifierType::FRAME_GRAVITY, RSDrawableContentSlot::FRAME_OFFSET },
{ RSModifierType::CLIP_RRECT, RSDrawableContentSlot::CLIP_TO_BOUNDS },
{ RSModifierType::CLIP_BOUNDS, RSDrawableContentSlot::CLIP_TO_BOUNDS },
{ RSModifierType::CLIP_TO_BOUNDS, RSDrawableContentSlot::CLIP_TO_BOUNDS },
{ RSModifierType::CLIP_TO_FRAME, RSDrawableContentSlot::CLIP_TO_FRAME },
{ RSModifierType::VISIBLE, RSDrawableContentSlot::INVALID },
{ RSModifierType::SHADOW_COLOR, RSDrawableContentSlot::SHADOW },
{ RSModifierType::SHADOW_OFFSET_X, RSDrawableContentSlot::SHADOW },
{ RSModifierType::SHADOW_OFFSET_Y, RSDrawableContentSlot::SHADOW },
{ RSModifierType::SHADOW_ALPHA, RSDrawableContentSlot::SHADOW },
{ RSModifierType::SHADOW_ELEVATION, RSDrawableContentSlot::SHADOW },
{ RSModifierType::SHADOW_RADIUS, RSDrawableContentSlot::SHADOW },
{ RSModifierType::SHADOW_PATH, RSDrawableContentSlot::SHADOW },
{ RSModifierType::SHADOW_MASK, RSDrawableContentSlot::SHADOW },
{ RSModifierType::MASK, RSDrawableContentSlot::MASK },
{ RSModifierType::SPHERIZE, RSDrawableContentSlot::INVALID },
{ RSModifierType::LIGHT_UP_EFFECT, RSDrawableContentSlot::LIGHT_UP_EFFECT },
{ RSModifierType::AIINVERT, RSDrawableContentSlot::BINARIZATION },
{ RSModifierType::SYSTEMBAREFFECT, RSDrawableContentSlot::BACKGROUND_FILTER },
{ RSModifierType::PIXEL_STRETCH, RSDrawableContentSlot::PIXEL_STRETCH },
{ RSModifierType::PIXEL_STRETCH_PERCENT, RSDrawableContentSlot::PIXEL_STRETCH },
{ RSModifierType::USE_EFFECT, RSDrawableContentSlot::USE_EFFECT },
{ RSModifierType::SANDBOX, RSDrawableContentSlot::BOUNDS_MATRIX },
{ RSModifierType::GRAY_SCALE, RSDrawableContentSlot::COLOR_FILTER },
{ RSModifierType::BRIGHTNESS, RSDrawableContentSlot::COLOR_FILTER },
{ RSModifierType::CONTRAST, RSDrawableContentSlot::COLOR_FILTER },
{ RSModifierType::SATURATE, RSDrawableContentSlot::COLOR_FILTER },
{ RSModifierType::SEPIA, RSDrawableContentSlot::COLOR_FILTER },
{ RSModifierType::INVERT, RSDrawableContentSlot::COLOR_FILTER },
{ RSModifierType::HUE_ROTATE, RSDrawableContentSlot::COLOR_FILTER },
{ RSModifierType::COLOR_BLEND, RSDrawableContentSlot::COLOR_FILTER },
{ RSModifierType::PARTICLE, RSDrawableContentSlot::PARTICLE_EFFECT },
{ RSModifierType::SHADOW_IS_FILLED, RSDrawableContentSlot::INVALID },
{ RSModifierType::COLOR_BLEND_MODE, RSDrawableContentSlot::BLEND_MODE },
{ RSModifierType::COLOR_BLEND_APPLY_TYPE, RSDrawableContentSlot::BLEND_MODE },
{ RSModifierType::OUTLINE_COLOR, RSDrawableContentSlot::OUTLINE },
{ RSModifierType::OUTLINE_WIDTH, RSDrawableContentSlot::OUTLINE },
{ RSModifierType::OUTLINE_STYLE, RSDrawableContentSlot::OUTLINE },
{ RSModifierType::OUTLINE_RADIUS, RSDrawableContentSlot::OUTLINE },
{ RSModifierType::USE_SHADOW_BATCHING, RSDrawableContentSlot::INVALID },
{ RSModifierType::LIGHT_INTENSITY, RSDrawableContentSlot::POINT_LIGHT },
{ RSModifierType::LIGHT_POSITION, RSDrawableContentSlot::POINT_LIGHT },
{ RSModifierType::ILLUMINATED_TYPE, RSDrawableContentSlot::POINT_LIGHT },
{ RSModifierType::BLOOM, RSDrawableContentSlot::POINT_LIGHT },
{ RSModifierType::CUSTOM, RSDrawableContentSlot::INVALID },
{ RSModifierType::EXTENDED, RSDrawableContentSlot::INVALID },
{ RSModifierType::TRANSITION, RSDrawableContentSlot::TRANSITION },
{ RSModifierType::BACKGROUND_STYLE, RSDrawableContentSlot::BACKGROUND_STYLE },
{ RSModifierType::CONTENT_STYLE, RSDrawableContentSlot::CONTENT_STYLE },
{ RSModifierType::FOREGROUND_STYLE, RSDrawableContentSlot::FOREGROUND_STYLE },
{ RSModifierType::OVERLAY_STYLE, RSDrawableContentSlot::OVERLAY },
{ RSModifierType::NODE_MODIFIER, RSDrawableContentSlot::INVALID },
{ RSModifierType::ENV_FOREGROUND_COLOR, RSDrawableContentSlot::ENV_FOREGROUND_COLOR },
{ RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY, RSDrawableContentSlot::ENV_FOREGROUND_COLOR_STRATEGY },
{ RSModifierType::GEOMETRYTRANS, RSDrawableContentSlot::INVALID },
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>
@ -123,11 +129,10 @@ static inline RSDrawableContent::Ptr ModifierGenerator(const RSRenderNode& node)
}
// NOTE: This LUT should always the same size as RSDrawableContentSlot
// index = RSPropertyDrawableType, value = DrawableGenerator
constexpr int LUT_SIZE = static_cast<int>(RSDrawableContentSlot::MAX);
static const std::array<RSDrawableContent::Generator, LUT_SIZE> g_drawableGeneratorLut = {
// 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,
nullptr, // SAVE_ALL,
// Bounds Geometry
nullptr, // BOUNDS_MATRIX,
@ -145,10 +150,10 @@ static const std::array<RSDrawableContent::Generator, LUT_SIZE> g_drawableGenera
RSBackgroundColorContent::OnGenerate, // BACKGROUND_COLOR,
RSBackgroundShaderContent::OnGenerate, // BACKGROUND_SHADER,
RSBackgroundImageContent::OnGenerate, // BACKGROUND_IMAGE,
nullptr, // BACKGROUND_FILTER,
RSBackgroundFilterContent::OnGenerate, // BACKGROUND_FILTER,
nullptr, // USE_EFFECT,
ModifierGenerator<RSModifierType::BACKGROUND_STYLE>, // BACKGROUND_STYLE,
nullptr, // DYNAMIC_LIGHT_UP,
RSDynamicLightUpContent::OnGenerate, // DYNAMIC_LIGHT_UP,
ModifierGenerator<RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY>, // ENV_FOREGROUND_COLOR_STRATEGY,
nullptr, // BG_RESTORE_BOUNDS,
@ -162,29 +167,51 @@ static const std::array<RSDrawableContent::Generator, LUT_SIZE> g_drawableGenera
nullptr, // RESTORE_FRAME,
// FG properties in Bounds clip
nullptr, // FG_SAVE_BOUNDS,
nullptr, // FG_CLIP_TO_BOUNDS,
nullptr, // BINARIZATION,
nullptr, // COLOR_FILTER,
nullptr, // LIGHT_UP_EFFECT,
nullptr, // FOREGROUND_FILTER,
nullptr, // FOREGROUND_COLOR,
nullptr, // FG_RESTORE_BOUNDS,
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,
nullptr, // PARTICLE_EFFECT,
nullptr, // PIXEL_STRETCH,
RSParticleContent::OnGenerate, // PARTICLE_EFFECT,
RSPixelStretchContent::OnGenerate, // PIXEL_STRETCH,
nullptr, // RESTORE_BLEND_MODE,
nullptr, // RESTORE_ALL,
};
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::GenerateDirtySlots(
std::unordered_set<RSDrawableContentSlot> RSDrawableContent::CalculateDirtySlots(
ModifierDirtyTypes& dirtyTypes, const Vec& drawableVec)
{
if (dirtyTypes.none()) {
@ -193,12 +220,12 @@ std::unordered_set<RSDrawableContentSlot> RSDrawableContent::GenerateDirtySlots(
std::unordered_set<RSDrawableContentSlot> dirtySlots;
for (size_t type = 0; type < static_cast<size_t>(RSModifierType::MAX_RS_MODIFIER_TYPE); type++) {
if (dirtyTypes[type]) {
auto it = g_propertyToDrawableLut.find(static_cast<RSModifierType>(type));
if (it == g_propertyToDrawableLut.end() || it->second == RSDrawableContentSlot::INVALID) {
continue;
}
dirtySlots.emplace(it->second);
if (!dirtyTypes.test(type)) {
continue;
}
auto dirtySlot = g_propertyToDrawableLut[type];
if (dirtySlot != RSDrawableContentSlot::INVALID) {
dirtySlots.emplace(dirtySlot);
}
}
@ -214,7 +241,7 @@ std::unordered_set<RSDrawableContentSlot> RSDrawableContent::GenerateDirtySlots(
return dirtySlots;
}
bool RSDrawableContent::UpdateDrawableVec(
bool RSDrawableContent::UpdateDirtySlots(
const RSRenderNode& node, Vec& drawableVec, std::unordered_set<RSDrawableContentSlot>& dirtySlots)
{
bool drawableAddedOrRemoved = false;
@ -238,12 +265,164 @@ bool RSDrawableContent::UpdateDrawableVec(
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)
{
// TODO: fill necessary save/restore into slots
(void)content;
(void)drawableVec;
(void)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 =====================
@ -257,13 +436,13 @@ RSDrawableContent::Ptr RSChildrenDrawableContent::OnGenerate(const RSRenderNode&
bool RSChildrenDrawableContent::OnUpdate(const RSRenderNode& node)
{
needSync_ = true;
stagingChildrenDrawables_.clear();
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));
@ -280,10 +459,15 @@ void RSChildrenDrawableContent::OnSync()
needSync_ = false;
}
RSDrawable::Ptr RSChildrenDrawableContent::CreateDrawable() const
// RSDrawable::Ptr RSChildrenDrawableContent::CreateDrawable() const
Drawing::RecordingCanvas::DrawFunc RSChildrenDrawableContent::CreateDrawFunc() const
{
auto ptr = std::static_pointer_cast<const RSChildrenDrawableContent>(shared_from_this());
return std::make_shared<RSChildrenDrawable>(ptr);
return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) {
for (const auto& drawable : ptr->childrenDrawables_) {
drawable->OnDraw(canvas);
}
};
}
// ==================== RSCustomModifierDrawableContent ===================
@ -297,15 +481,15 @@ RSDrawableContent::Ptr RSCustomModifierDrawableContent::OnGenerate(const RSRende
bool RSCustomModifierDrawableContent::OnUpdate(const RSRenderNode& node)
{
stagingDrawCmdList_.clear();
needSync_ = true;
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) {
@ -327,9 +511,13 @@ void RSCustomModifierDrawableContent::OnSync()
needSync_ = false;
}
RSDrawable::Ptr RSCustomModifierDrawableContent::CreateDrawable() const
Drawing::RecordingCanvas::DrawFunc RSCustomModifierDrawableContent::CreateDrawFunc() const
{
auto ptr = std::static_pointer_cast<const RSCustomModifierDrawableContent>(shared_from_this());
return std::make_shared<RSCustomModifierDrawable>(ptr);
return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) {
for (const auto& drawCmdList : ptr->drawCmdList_) {
drawCmdList->Playback(*canvas);
}
};
}
} // namespace OHOS::Rosen

View File

@ -45,10 +45,14 @@ void RSPropertyDrawableContent::OnSync()
needSync_ = false;
}
RSDrawable::Ptr RSPropertyDrawableContent::CreateDrawable() const
Drawing::RecordingCanvas::DrawFunc RSPropertyDrawableContent::CreateDrawFunc() const
{
auto ptr = std::static_pointer_cast<const RSPropertyDrawableContent>(shared_from_this());
return std::make_shared<RSPropertyDrawableNG>(ptr);
return [ptr](Drawing::Canvas* canvas, const Drawing::Rect* rect) {
if (const auto& drawCmdList = ptr->drawCmdList_) {
drawCmdList->Playback(*canvas);
}
};
}
class RSPropertyDrawCmdListRecorder {

View File

@ -1,48 +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_property_drawable_ng.h"
#include "drawable/rs_property_drawable_content.h"
#include "pipeline/rs_paint_filter_canvas.h"
#include "platform/common/rs_log.h"
namespace OHOS::Rosen {
RSPropertyDrawableNG::RSPropertyDrawableNG(std::shared_ptr<const RSPropertyDrawableContent> cmdList)
: cmdList_(std::move(cmdList))
{}
void RSPropertyDrawableNG::OnDraw(RSPaintFilterCanvas* canvas) const
{
if (cmdList_ == nullptr) {
// empty draw cmd should be filter out during OnGenerate and OnUpdate, we should not reach here
ROSEN_LOGE("RSPropertyDrawableNG::OnDraw, cmdList_ is null");
return;
}
if (canvas == nullptr) {
ROSEN_LOGE("RSPropertyDrawableNG::OnDraw, canvas is null");
return;
}
const auto& drawCmdList = cmdList_->drawCmdList_;
if (drawCmdList == nullptr) {
return;
}
drawCmdList->Playback(*canvas);
}
} // namespace OHOS::Rosen

View File

@ -29,7 +29,6 @@
#include "render/rs_light_up_effect_filter.h"
#include "platform/common/rs_log.h"
#include "visitor/rs_node_visitor.h"
#include "property/rs_property_drawable.h"
namespace OHOS {
namespace Rosen {
@ -113,23 +112,23 @@ void RSCanvasRenderNode::Process(const std::shared_ptr<RSNodeVisitor>& visitor)
void RSCanvasRenderNode::ProcessTransitionBeforeChildren(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::MASK, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::MASK, canvas);
// return;
// }
RSRenderNode::ProcessTransitionBeforeChildren(canvas);
}
void RSCanvasRenderNode::ProcessShadowBatching(RSPaintFilterCanvas& canvas)
{
RSAutoCanvasRestore acr(&canvas);
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawableRange(
RSPropertyDrawableSlot::BOUNDS_MATRIX, RSPropertyDrawableSlot::TRANSITION, canvas);
DrawPropertyDrawable(
RSPropertyDrawableSlot::SHADOW, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawableRange(
// RSPropertyDrawableSlot::BOUNDS_MATRIX, RSPropertyDrawableSlot::TRANSITION, canvas);
// DrawPropertyDrawable(
// RSPropertyDrawableSlot::SHADOW, canvas);
// return;
// }
RSModifierContext context = { GetMutableRenderProperties(), &canvas };
ApplyBoundsGeometry(canvas);
ApplyAlpha(canvas);
@ -157,36 +156,36 @@ void RSCanvasRenderNode::DrawShadow(RSModifierContext& context, RSPaintFilterCan
void RSCanvasRenderNode::PropertyDrawableRender(RSPaintFilterCanvas& canvas, bool includeProperty)
{
auto parent = GetParent().lock();
if (RSSystemProperties::GetUseShadowBatchingEnabled() && parent &&
parent->GetRenderProperties().GetUseShadowBatching()) {
DrawPropertyDrawableRange(
RSPropertyDrawableSlot::TRANSITION, RSPropertyDrawableSlot::ENV_FOREGROUND_COLOR, canvas);
if (includeProperty) {
DrawPropertyDrawableRange(
RSPropertyDrawableSlot::BG_SAVE_BOUNDS, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
} else {
DrawPropertyDrawableRange(
RSPropertyDrawableSlot::SAVE_FRAME, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
}
} else {
if (includeProperty) {
DrawPropertyDrawableRange(RSPropertyDrawableSlot::TRANSITION, RSPropertyDrawableSlot::CLIP_TO_FRAME,
canvas);
} else {
DrawPropertyDrawableRange(RSPropertyDrawableSlot::TRANSITION, RSPropertyDrawableSlot::OUTLINE, canvas);
DrawPropertyDrawableRange(
RSPropertyDrawableSlot::SAVE_FRAME, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
}
}
// auto parent = GetParent().lock();
// if (RSSystemProperties::GetUseShadowBatchingEnabled() && parent &&
// parent->GetRenderProperties().GetUseShadowBatching()) {
// DrawPropertyDrawableRange(
// RSPropertyDrawableSlot::TRANSITION, RSPropertyDrawableSlot::ENV_FOREGROUND_COLOR, canvas);
// if (includeProperty) {
// DrawPropertyDrawableRange(
// RSPropertyDrawableSlot::BG_SAVE_BOUNDS, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
// } else {
// DrawPropertyDrawableRange(
// RSPropertyDrawableSlot::SAVE_FRAME, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
// }
// } else {
// if (includeProperty) {
// DrawPropertyDrawableRange(RSPropertyDrawableSlot::TRANSITION, RSPropertyDrawableSlot::CLIP_TO_FRAME,
// canvas);
// } else {
// DrawPropertyDrawableRange(RSPropertyDrawableSlot::TRANSITION, RSPropertyDrawableSlot::OUTLINE, canvas);
// DrawPropertyDrawableRange(
// RSPropertyDrawableSlot::SAVE_FRAME, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
// }
// }
}
void RSCanvasRenderNode::ProcessAnimatePropertyBeforeChildren(RSPaintFilterCanvas& canvas, bool includeProperty)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
PropertyDrawableRender(canvas, includeProperty);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// PropertyDrawableRender(canvas, includeProperty);
// return;
// }
RSModifierContext context = { GetMutableRenderProperties(), &canvas };
DrawShadow(context, canvas);
@ -229,31 +228,31 @@ void RSCanvasRenderNode::ProcessAnimatePropertyBeforeChildren(RSPaintFilterCanva
void RSCanvasRenderNode::ProcessRenderContents(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawable(RSPropertyDrawableSlot::CONTENT_STYLE, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawable(RSPropertyDrawableSlot::CONTENT_STYLE, canvas);
// return;
// }
RSModifierContext context = { GetMutableRenderProperties(), &canvas };
ApplyDrawCmdModifier(context, RSModifierType::CONTENT_STYLE);
}
void RSCanvasRenderNode::ProcessRenderBeforeChildren(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::CLIP_TO_FRAME, canvas);
// return;
// }
ProcessTransitionBeforeChildren(canvas);
ProcessAnimatePropertyBeforeChildren(canvas, true);
}
void RSCanvasRenderNode::ProcessAnimatePropertyAfterChildren(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawableRange(
RSPropertyDrawableSlot::FOREGROUND_STYLE, RSPropertyDrawableSlot::PARTICLE_EFFECT, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawableRange(
// RSPropertyDrawableSlot::FOREGROUND_STYLE, RSPropertyDrawableSlot::PARTICLE_EFFECT, canvas);
// return;
// }
RSModifierContext context = { GetMutableRenderProperties(), &canvas };
ApplyDrawCmdModifier(context, RSModifierType::FOREGROUND_STYLE);
@ -286,21 +285,21 @@ void RSCanvasRenderNode::ProcessAnimatePropertyAfterChildren(RSPaintFilterCanvas
void RSCanvasRenderNode::ProcessTransitionAfterChildren(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawableRange(RSPropertyDrawableSlot::PIXEL_STRETCH, RSPropertyDrawableSlot::RESTORE_ALL, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawableRange(RSPropertyDrawableSlot::PIXEL_STRETCH, RSPropertyDrawableSlot::RESTORE_ALL, canvas);
// return;
// }
RSPropertiesPainter::DrawPixelStretch(GetRenderProperties(), canvas);
RSRenderNode::ProcessRenderAfterChildren(canvas);
}
void RSCanvasRenderNode::ProcessRenderAfterChildren(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawableRange(
RSPropertyDrawableSlot::FOREGROUND_STYLE, RSPropertyDrawableSlot::RESTORE_ALL, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawableRange(
// RSPropertyDrawableSlot::FOREGROUND_STYLE, RSPropertyDrawableSlot::RESTORE_ALL, canvas);
// return;
// }
ProcessAnimatePropertyAfterChildren(canvas);
ProcessTransitionAfterChildren(canvas);
canvas.RestoreEnv();

View File

@ -31,56 +31,56 @@ const RSProperties& RSRenderContent::GetRenderProperties() const
return renderProperties_;
}
void RSRenderContent::DrawPropertyDrawable(RSPropertyDrawableSlot slot, RSPaintFilterCanvas& canvas) const
{
auto& drawablePtr = propertyDrawablesVec_[static_cast<size_t>(slot)];
if (!drawablePtr) {
return;
}
// void RSRenderContent::DrawPropertyDrawable(RSPropertyDrawableSlot slot, RSPaintFilterCanvas& canvas) const
// {
// auto& drawablePtr = propertyDrawablesVec_[static_cast<size_t>(slot)];
// if (!drawablePtr) {
// return;
// }
auto recordingCanvas = canvas.GetRecordingCanvas();
if (recordingCanvas == nullptr || !canvas.GetRecordDrawable()) {
// non-recording canvas, draw directly
drawablePtr->Draw(*this, canvas);
return;
}
// auto recordingCanvas = canvas.GetRecordingCanvas();
// if (recordingCanvas == nullptr || !canvas.GetRecordDrawable()) {
// // non-recording canvas, draw directly
// drawablePtr->Draw(*this, canvas);
// return;
// }
auto castRecordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas.GetRecordingCanvas());
auto drawFunc = [sharedPtr = shared_from_this(), slot](Drawing::Canvas* canvas, const Drawing::Rect* rect) -> void {
if (auto canvasPtr = static_cast<RSPaintFilterCanvas*>(canvas)) {
sharedPtr->DrawPropertyDrawable(slot, *canvasPtr);
}
};
// recording canvas, record lambda that draws the drawable
castRecordingCanvas->DrawDrawFunc(std::move(drawFunc));
}
// auto castRecordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas.GetRecordingCanvas());
// auto drawFunc = [sharedPtr = shared_from_this(), slot](Drawing::Canvas* canvas, const Drawing::Rect* rect) -> void {
// if (auto canvasPtr = static_cast<RSPaintFilterCanvas*>(canvas)) {
// sharedPtr->DrawPropertyDrawable(slot, *canvasPtr);
// }
// };
// // recording canvas, record lambda that draws the drawable
// castRecordingCanvas->DrawDrawFunc(std::move(drawFunc));
// }
void RSRenderContent::DrawPropertyDrawableRange(
RSPropertyDrawableSlot begin, RSPropertyDrawableSlot end, RSPaintFilterCanvas& canvas) const
{
auto recordingCanvas = canvas.GetRecordingCanvas();
if (recordingCanvas == nullptr || !canvas.GetRecordDrawable()) {
// non-recording canvas, draw directly
std::for_each(propertyDrawablesVec_.begin() + static_cast<size_t>(begin),
propertyDrawablesVec_.begin() + static_cast<size_t>(end) + 1, // +1 since we need to include end
[&](auto& drawablePtr) {
if (drawablePtr) {
drawablePtr->Draw(*this, canvas);
}
});
return;
}
// void RSRenderContent::DrawPropertyDrawableRange(
// RSPropertyDrawableSlot begin, RSPropertyDrawableSlot end, RSPaintFilterCanvas& canvas) const
// {
// auto recordingCanvas = canvas.GetRecordingCanvas();
// if (recordingCanvas == nullptr || !canvas.GetRecordDrawable()) {
// // non-recording canvas, draw directly
// std::for_each(propertyDrawablesVec_.begin() + static_cast<size_t>(begin),
// propertyDrawablesVec_.begin() + static_cast<size_t>(end) + 1, // +1 since we need to include end
// [&](auto& drawablePtr) {
// if (drawablePtr) {
// drawablePtr->Draw(*this, canvas);
// }
// });
// return;
// }
auto castRecordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas.GetRecordingCanvas());
auto drawFunc =
[sharedPtr = shared_from_this(), begin, end](Drawing::Canvas* canvas, const Drawing::Rect* rect) -> void {
if (auto canvasPtr = static_cast<RSPaintFilterCanvas*>(canvas)) {
sharedPtr->DrawPropertyDrawableRange(begin, end, *canvasPtr);
}
};
// recording canvas, record lambda that draws the drawable
castRecordingCanvas->DrawDrawFunc(std::move(drawFunc));
}
// auto castRecordingCanvas = static_cast<ExtendRecordingCanvas*>(canvas.GetRecordingCanvas());
// auto drawFunc =
// [sharedPtr = shared_from_this(), begin, end](Drawing::Canvas* canvas, const Drawing::Rect* rect) -> void {
// if (auto canvasPtr = static_cast<RSPaintFilterCanvas*>(canvas)) {
// sharedPtr->DrawPropertyDrawableRange(begin, end, *canvasPtr);
// }
// };
// // recording canvas, record lambda that draws the drawable
// castRecordingCanvas->DrawDrawFunc(std::move(drawFunc));
// }
RSRenderNodeType RSRenderContent::GetType() const
{

View File

@ -37,7 +37,7 @@
#include "platform/common/rs_log.h"
#include "platform/common/rs_system_properties.h"
#include "property/rs_properties_painter.h"
#include "property/rs_property_drawable.h"
// #include "property/rs_property_drawable.h"
#include "property/rs_property_trace.h"
#include "transaction/rs_transaction_proxy.h"
#include "visitor/rs_node_visitor.h"
@ -1229,10 +1229,10 @@ void RSRenderNode::RenderTraceDebug() const
void RSRenderNode::ApplyBoundsGeometry(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::BOUNDS_MATRIX, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::BOUNDS_MATRIX, canvas);
// return;
// }
renderNodeSaveCount_ = canvas.SaveAllStatus();
auto boundsGeo = (GetRenderProperties().GetBoundsGeometry());
if (boundsGeo && (!boundsGeo->IsEmpty() || boundsGeo->IsValidOffset())) {
@ -1242,10 +1242,10 @@ void RSRenderNode::ApplyBoundsGeometry(RSPaintFilterCanvas& canvas)
void RSRenderNode::ApplyAlpha(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawable(RSPropertyDrawableSlot::ALPHA, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawable(RSPropertyDrawableSlot::ALPHA, canvas);
// return;
// }
auto alpha = GetRenderProperties().GetAlpha();
if (alpha < 1.f) {
if (!(GetRenderProperties().GetAlphaOffscreen() || IsForcedDrawInGroup())) {
@ -1262,10 +1262,10 @@ void RSRenderNode::ApplyAlpha(RSPaintFilterCanvas& canvas)
void RSRenderNode::ProcessTransitionBeforeChildren(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::MASK, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawableRange(RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::MASK, canvas);
// return;
// }
ApplyBoundsGeometry(canvas);
ApplyAlpha(canvas);
RSPropertiesPainter::DrawMask(GetRenderProperties(), canvas);
@ -1278,19 +1278,19 @@ void RSRenderNode::ProcessRenderBeforeChildren(RSPaintFilterCanvas& canvas)
void RSRenderNode::ProcessTransitionAfterChildren(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawable(RSPropertyDrawableSlot::RESTORE_ALL, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawable(RSPropertyDrawableSlot::RESTORE_ALL, canvas);
// return;
// }
canvas.RestoreStatus(renderNodeSaveCount_);
}
void RSRenderNode::ProcessRenderAfterChildren(RSPaintFilterCanvas& canvas)
{
if (RSSystemProperties::GetPropertyDrawableEnable()) {
DrawPropertyDrawable(RSPropertyDrawableSlot::RESTORE_ALL, canvas);
return;
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// DrawPropertyDrawable(RSPropertyDrawableSlot::RESTORE_ALL, canvas);
// return;
// }
canvas.RestoreStatus(renderNodeSaveCount_);
}
@ -1404,6 +1404,9 @@ void RSRenderNode::ApplyModifiers()
GetMutableRenderProperties().OnApplyModifiers();
OnApplyModifiers();
// Temporary code, copy matrix into render params
UpdateRenderParams();
#if defined(NEW_SKIA) && (defined(RS_ENABLE_GL) || defined(RS_ENABLE_VK))
if (auto& manager = GetRenderProperties().GetFilterCacheManager(false);
manager != nullptr &&
@ -1415,10 +1418,13 @@ void RSRenderNode::ApplyModifiers()
manager->InvalidateCache();
}
if (RSSystemProperties::GetPropertyDrawableEnable()) {
// Generate drawable
UpdateDrawableVec();
}
// if (RSSystemProperties::GetPropertyDrawableEnable()) {
// // Generate drawable
// UpdateDrawableVec();
// }
UpdateDrawableContentVec();
#endif
// update state
@ -1439,43 +1445,74 @@ void RSRenderNode::MarkParentNeedRegenerateChildren() const
parent->isChildrenSorted_ = false;
}
void RSRenderNode::UpdateDrawableVec()
void RSRenderNode::UpdateDrawableContentVec()
{
#ifndef ROSEN_ARKUI_X
// Collect dirty slots
auto dirtySlots = RSPropertyDrawable::GenerateDirtySlots(GetRenderProperties(), dirtyTypes_);
if (!GetIsUsedBySubThread()) {
UpdateDrawableVecInternal(dirtySlots);
} else if (auto context = context_.lock()) {
context->PostTask([weakPtr = weak_from_this(), dirtySlots]() {
if (auto node = weakPtr.lock()) {
node->UpdateDrawableVecInternal(dirtySlots);
// Step 1: Collect dirty slots
auto dirtySlots = RSDrawableContent::CalculateDirtySlots(dirtyTypes_, contentVec_);
if (dirtySlots.empty()) {
return;
}
// Step 2: Update or regenerate drawable if needed
bool drawableChanged = RSDrawableContent::UpdateDirtySlots(*this, contentVec_, dirtySlots);
if (drawableChanged || drawableVecStatus_ == 0) {
// Step 3: if any drawables changed, update save/clip/restore
RSDrawableContent::UpdateSaveRestore(*renderContent_, contentVec_, drawableVecStatus_);
// Step 4: Generate drawCmdList from drawables
// TODO: use correct W/H instead of 0
auto recordingCanvas_ = std::make_unique<ExtendRecordingCanvas>(0, 0, true);
for (const auto& drawable : contentVec_) {
if (drawable) {
recordingCanvas_->DrawDrawFunc(drawable->CreateDrawFunc());
}
});
} else {
ROSEN_LOGI("%{public}s GetIsUsedBySubThread[%{public}d].", __func__, GetIsUsedBySubThread());
UpdateDrawableVecInternal(dirtySlots);
}
stagingDrawCmdList_ = recordingCanvas_->GetDrawCmdList();
needSync_ = true;
}
#endif
}
void RSRenderNode::UpdateDrawableVecInternal(std::unordered_set<RSPropertyDrawableSlot> dirtySlots)
{
#ifndef ROSEN_ARKUI_X
// initialize necessary save/clip/restore
if (drawableVecStatus_ == 0) {
RSPropertyDrawable::InitializeSaveRestore(*renderContent_, renderContent_->propertyDrawablesVec_);
}
// Update or regenerate drawable
bool drawableChanged =
RSPropertyDrawable::UpdateDrawableVec(*renderContent_, renderContent_->propertyDrawablesVec_, dirtySlots);
// if 1. first initialized or 2. any drawables changed, update save/clip/restore
if (drawableChanged || drawableVecStatus_ == 0) {
RSPropertyDrawable::UpdateSaveRestore(
*renderContent_, renderContent_->propertyDrawablesVec_, drawableVecStatus_);
}
#endif
}
// void RSRenderNode::UpdateDrawableVec()
// {
// #ifndef ROSEN_ARKUI_X
// // Collect dirty slots
// auto dirtySlots = RSPropertyDrawable::GenerateDirtySlots(GetRenderProperties(), dirtyTypes_);
// if (!GetIsUsedBySubThread()) {
// UpdateDrawableVecInternal(dirtySlots);
// } else if (auto context = context_.lock()) {
// context->PostTask([weakPtr = weak_from_this(), dirtySlots]() {
// if (auto node = weakPtr.lock()) {
// node->UpdateDrawableVecInternal(dirtySlots);
// }
// });
// } else {
// ROSEN_LOGI("%{public}s GetIsUsedBySubThread[%{public}d].", __func__, GetIsUsedBySubThread());
// UpdateDrawableVecInternal(dirtySlots);
// }
// #endif
// }
// void RSRenderNode::UpdateDrawableVecInternal(std::unordered_set<RSPropertyDrawableSlot> dirtySlots)
// {
// #ifndef ROSEN_ARKUI_X
// // initialize necessary save/clip/restore
// if (drawableVecStatus_ == 0) {
// RSPropertyDrawable::InitializeSaveRestore(*renderContent_, renderContent_->propertyDrawablesVec_);
// }
// // Update or regenerate drawable
// bool drawableChanged =
// RSPropertyDrawable::UpdateDrawableVec(*renderContent_, renderContent_->propertyDrawablesVec_, dirtySlots);
// // if 1. first initialized or 2. any drawables changed, update save/clip/restore
// if (drawableChanged || drawableVecStatus_ == 0) {
// RSPropertyDrawable::UpdateSaveRestore(
// *renderContent_, renderContent_->propertyDrawablesVec_, drawableVecStatus_);
// }
// #endif
// }
void RSRenderNode::UpdateEffectRegion(std::optional<Drawing::RectI>& region, bool isForced)
{

View File

@ -34,7 +34,6 @@
#include "render/rs_skia_filter.h"
#include "transaction/rs_render_service_client.h"
#include "visitor/rs_node_visitor.h"
#include "property/rs_property_drawable.h"
namespace OHOS {
namespace Rosen {

View File

@ -159,13 +159,13 @@ RSProperties::RSProperties()
RSProperties::~RSProperties() = default;
void RSProperties::ResetProperty(const std::bitset<static_cast<int>(RSModifierType::MAX_RS_MODIFIER_TYPE)>& dirtyTypes)
void RSProperties::ResetProperty(const ModifierDirtyTypes& dirtyTypes)
{
if (dirtyTypes.none()) {
return;
}
for (uint8_t type = 0; type < static_cast<size_t>(RSModifierType::CUSTOM); type++) {
if (dirtyTypes[type]) {
if (dirtyTypes.test(type)) {
if (auto& resetFunc = g_propertyResetterLUT[type]) {
resetFunc(this);
}
@ -2783,6 +2783,9 @@ void RSProperties::OnApplyModifiers()
if (clipToFrame_ && clipToBounds_ && frameOffsetX_ == 0 && frameOffsetY_ == 0) {
clipToFrame_ = false;
}
// TODO: temporary fix to calculate relative matrix in OnApplyModifiers, later RSRenderNode::Update will
// overwrite it.
boundsGeo_->UpdateByMatrixFromSelf();
if (RSSystemProperties::IsPcType()) {
frameGeo_->Round();
boundsGeo_->Round();

View File

@ -1,468 +0,0 @@
/*
* Copyright (c) 2023 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 "property/rs_property_drawable.h"
#include "pipeline/rs_render_node.h"
#include "platform/common/rs_log.h"
#include "property/rs_properties.h"
#include "property/rs_property_drawable_bounds_geometry.h"
#include "property/rs_property_drawable_frame_geometry.h"
#include "property/rs_property_drawable_utilities.h"
namespace OHOS::Rosen {
namespace {
template<RSModifierType T>
inline RSModifierDrawable::DrawablePtr CustomModifierAdapter(const RSRenderContent&)
{
return std::make_unique<RSModifierDrawable>(T);
}
inline RSPropertyDrawable::DrawablePtr GenerateAlias(RSPropertyDrawableSlot slot)
{
return std::make_unique<RSAliasDrawable>(slot);
}
inline std::pair<RSPropertyDrawable::DrawablePtr, RSPropertyDrawable::DrawablePtr> 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) };
}
}
inline void SaveRestoreHelper(RSPropertyDrawable::DrawableVec& drawableVec, RSPropertyDrawableSlot slot1,
RSPropertyDrawableSlot slot2, RSPaintFilterCanvas::SaveType saveType)
{
std::tie(drawableVec[static_cast<size_t>(slot1)], drawableVec[static_cast<size_t>(slot2)]) =
GenerateSaveRestore(saveType);
}
// key = RSModifierType, value = RSPropertyDrawableType
static const std::unordered_map<RSModifierType, RSPropertyDrawableSlot> g_propertyToDrawableLut = {
{ RSModifierType::INVALID, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::BOUNDS, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::FRAME, RSPropertyDrawableSlot::FRAME_OFFSET },
{ RSModifierType::POSITION_Z, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::PIVOT, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::PIVOT_Z, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::QUATERNION, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::ROTATION, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::ROTATION_X, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::ROTATION_Y, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::CAMERA_DISTANCE, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::SCALE, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::SKEW, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::TRANSLATE, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::TRANSLATE_Z, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::SUBLAYER_TRANSFORM, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::CORNER_RADIUS, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::ALPHA, RSPropertyDrawableSlot::ALPHA },
{ RSModifierType::ALPHA_OFFSCREEN, RSPropertyDrawableSlot::ALPHA },
{ RSModifierType::FOREGROUND_COLOR, RSPropertyDrawableSlot::FOREGROUND_COLOR },
{ RSModifierType::BACKGROUND_COLOR, RSPropertyDrawableSlot::BACKGROUND_COLOR },
{ RSModifierType::BACKGROUND_SHADER, RSPropertyDrawableSlot::BACKGROUND_SHADER },
{ RSModifierType::BG_IMAGE, RSPropertyDrawableSlot::BACKGROUND_IMAGE },
{ RSModifierType::BG_IMAGE_WIDTH, RSPropertyDrawableSlot::BACKGROUND_IMAGE },
{ RSModifierType::BG_IMAGE_HEIGHT, RSPropertyDrawableSlot::BACKGROUND_IMAGE },
{ RSModifierType::BG_IMAGE_POSITION_X, RSPropertyDrawableSlot::BACKGROUND_IMAGE },
{ RSModifierType::BG_IMAGE_POSITION_Y, RSPropertyDrawableSlot::BACKGROUND_IMAGE },
{ RSModifierType::SURFACE_BG_COLOR, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::BORDER_COLOR, RSPropertyDrawableSlot::BORDER },
{ RSModifierType::BORDER_WIDTH, RSPropertyDrawableSlot::BORDER },
{ RSModifierType::BORDER_STYLE, RSPropertyDrawableSlot::BORDER },
{ RSModifierType::FILTER, RSPropertyDrawableSlot::FOREGROUND_FILTER },
{ RSModifierType::BACKGROUND_FILTER, RSPropertyDrawableSlot::BACKGROUND_FILTER },
{ RSModifierType::LINEAR_GRADIENT_BLUR_PARA, RSPropertyDrawableSlot::FOREGROUND_FILTER },
{ RSModifierType::DYNAMIC_LIGHT_UP_RATE, RSPropertyDrawableSlot::DYNAMIC_LIGHT_UP },
{ RSModifierType::DYNAMIC_LIGHT_UP_DEGREE, RSPropertyDrawableSlot::DYNAMIC_LIGHT_UP },
{ RSModifierType::FRAME_GRAVITY, RSPropertyDrawableSlot::FRAME_OFFSET },
{ RSModifierType::CLIP_RRECT, RSPropertyDrawableSlot::CLIP_TO_BOUNDS },
{ RSModifierType::CLIP_BOUNDS, RSPropertyDrawableSlot::CLIP_TO_BOUNDS },
{ RSModifierType::CLIP_TO_BOUNDS, RSPropertyDrawableSlot::CLIP_TO_BOUNDS },
{ RSModifierType::CLIP_TO_FRAME, RSPropertyDrawableSlot::CLIP_TO_FRAME },
{ RSModifierType::VISIBLE, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::SHADOW_COLOR, RSPropertyDrawableSlot::SHADOW },
{ RSModifierType::SHADOW_OFFSET_X, RSPropertyDrawableSlot::SHADOW },
{ RSModifierType::SHADOW_OFFSET_Y, RSPropertyDrawableSlot::SHADOW },
{ RSModifierType::SHADOW_ALPHA, RSPropertyDrawableSlot::SHADOW },
{ RSModifierType::SHADOW_ELEVATION, RSPropertyDrawableSlot::SHADOW },
{ RSModifierType::SHADOW_RADIUS, RSPropertyDrawableSlot::SHADOW },
{ RSModifierType::SHADOW_PATH, RSPropertyDrawableSlot::SHADOW },
{ RSModifierType::SHADOW_MASK, RSPropertyDrawableSlot::SHADOW },
{ RSModifierType::MASK, RSPropertyDrawableSlot::MASK },
{ RSModifierType::SPHERIZE, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::LIGHT_UP_EFFECT, RSPropertyDrawableSlot::LIGHT_UP_EFFECT },
{ RSModifierType::AIINVERT, RSPropertyDrawableSlot::BINARIZATION },
{ RSModifierType::SYSTEMBAREFFECT, RSPropertyDrawableSlot::BACKGROUND_FILTER },
{ RSModifierType::PIXEL_STRETCH, RSPropertyDrawableSlot::PIXEL_STRETCH },
{ RSModifierType::PIXEL_STRETCH_PERCENT, RSPropertyDrawableSlot::PIXEL_STRETCH },
{ RSModifierType::USE_EFFECT, RSPropertyDrawableSlot::USE_EFFECT },
{ RSModifierType::SANDBOX, RSPropertyDrawableSlot::BOUNDS_MATRIX },
{ RSModifierType::GRAY_SCALE, RSPropertyDrawableSlot::COLOR_FILTER },
{ RSModifierType::BRIGHTNESS, RSPropertyDrawableSlot::COLOR_FILTER },
{ RSModifierType::CONTRAST, RSPropertyDrawableSlot::COLOR_FILTER },
{ RSModifierType::SATURATE, RSPropertyDrawableSlot::COLOR_FILTER },
{ RSModifierType::SEPIA, RSPropertyDrawableSlot::COLOR_FILTER },
{ RSModifierType::INVERT, RSPropertyDrawableSlot::COLOR_FILTER },
{ RSModifierType::HUE_ROTATE, RSPropertyDrawableSlot::COLOR_FILTER },
{ RSModifierType::COLOR_BLEND, RSPropertyDrawableSlot::COLOR_FILTER },
{ RSModifierType::PARTICLE, RSPropertyDrawableSlot::PARTICLE_EFFECT },
{ RSModifierType::SHADOW_IS_FILLED, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::COLOR_BLEND_MODE, RSPropertyDrawableSlot::BLEND_MODE },
{ RSModifierType::COLOR_BLEND_APPLY_TYPE, RSPropertyDrawableSlot::BLEND_MODE },
{ RSModifierType::OUTLINE_COLOR, RSPropertyDrawableSlot::OUTLINE },
{ RSModifierType::OUTLINE_WIDTH, RSPropertyDrawableSlot::OUTLINE },
{ RSModifierType::OUTLINE_STYLE, RSPropertyDrawableSlot::OUTLINE },
{ RSModifierType::OUTLINE_RADIUS, RSPropertyDrawableSlot::OUTLINE },
{ RSModifierType::USE_SHADOW_BATCHING, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::LIGHT_INTENSITY, RSPropertyDrawableSlot::POINT_LIGHT },
{ RSModifierType::LIGHT_POSITION, RSPropertyDrawableSlot::POINT_LIGHT },
{ RSModifierType::ILLUMINATED_TYPE, RSPropertyDrawableSlot::POINT_LIGHT },
{ RSModifierType::BLOOM, RSPropertyDrawableSlot::POINT_LIGHT },
{ RSModifierType::CUSTOM, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::EXTENDED, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::TRANSITION, RSPropertyDrawableSlot::TRANSITION },
{ RSModifierType::BACKGROUND_STYLE, RSPropertyDrawableSlot::BACKGROUND_STYLE },
{ RSModifierType::CONTENT_STYLE, RSPropertyDrawableSlot::CONTENT_STYLE },
{ RSModifierType::FOREGROUND_STYLE, RSPropertyDrawableSlot::FOREGROUND_STYLE },
{ RSModifierType::OVERLAY_STYLE, RSPropertyDrawableSlot::OVERLAY },
{ RSModifierType::NODE_MODIFIER, RSPropertyDrawableSlot::INVALID },
{ RSModifierType::ENV_FOREGROUND_COLOR, RSPropertyDrawableSlot::ENV_FOREGROUND_COLOR },
{ RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY, RSPropertyDrawableSlot::ENV_FOREGROUND_COLOR_STRATEGY },
{ RSModifierType::GEOMETRYTRANS, RSPropertyDrawableSlot::INVALID },
};
// NOTE: This LUT should always the same size as RSPropertyDrawableSlot
// index = RSPropertyDrawableType, value = DrawableGenerator
constexpr int LUT_SIZE = static_cast<int>(RSPropertyDrawableSlot::MAX);
static const std::array<RSPropertyDrawable::DrawableGenerator, LUT_SIZE> g_drawableGeneratorLut = {
nullptr, // INVALID = 0
nullptr, // SAVE_ALL
// Bounds Geometry
nullptr, // BOUNDS_MATRIX
RSAlphaDrawable::Generate, // ALPHA
RSMaskDrawable::Generate, // MASK
CustomModifierAdapter<RSModifierType::TRANSITION>, // TRANSITION
CustomModifierAdapter<RSModifierType::ENV_FOREGROUND_COLOR>, // ENV_FOREGROUND_COLOR
RSShadowDrawable::Generate, // SHADOW
RSOutlineDrawable::Generate, // OUTLINE
// BG properties in Bounds Clip
nullptr, // BG_SAVE_BOUNDS
nullptr, // CLIP_TO_BOUNDS
BlendSaveDrawableGenerate, // BLEND_MODE
RSBackgroundColorDrawable::Generate, // BACKGROUND_COLOR
RSBackgroundShaderDrawable::Generate, // BACKGROUND_SHADER
RSBackgroundImageDrawable::Generate, // BACKGROUND_IMAGE
RSBackgroundFilterDrawable::Generate, // BACKGROUND_FILTER
RSEffectDataApplyDrawable::Generate, // USE_EFFECT
CustomModifierAdapter<RSModifierType::BACKGROUND_STYLE>, // BACKGROUND_STYLE
RSDynamicLightUpDrawable::Generate, // DYNAMIC_LIGHT_UP
CustomModifierAdapter<RSModifierType::ENV_FOREGROUND_COLOR_STRATEGY>, // ENV_FOREGROUND_COLOR_STRATEGY
nullptr, // BG_RESTORE_BOUNDS
// Frame Geometry
nullptr, // SAVE_FRAME
nullptr, // FRAME_OFFSET
RSClipFrameDrawable::Generate, // CLIP_TO_FRAME
CustomModifierAdapter<RSModifierType::CONTENT_STYLE>, // CONTENT_STYLE
nullptr, // CHILDREN
CustomModifierAdapter<RSModifierType::FOREGROUND_STYLE>, // FOREGROUND_STYLE
nullptr, // RESTORE_FRAME
// FG properties in Bounds clip
nullptr, // FG_SAVE_BOUNDS
nullptr, // EXTRA_CLIP_TO_BOUNDS
RSBinarizationDrawable::Generate, // BINARIZATION,
RSColorFilterDrawable::Generate, // COLOR_FILTER
RSLightUpEffectDrawable::Generate, // LIGHT_UP_EFFECT
RSForegroundFilterDrawable::Generate, // FOREGROUND_FILTER
RSForegroundColorDrawable::Generate, // FOREGROUND_COLOR
nullptr, // FG_RESTORE_BOUNDS
// No clip (unless ClipToBounds is set)
RSPointLightDrawable::Generate, // POINT_LIGHT
RSBorderDrawable::Generate, // BORDER
CustomModifierAdapter<RSModifierType::OVERLAY_STYLE>, // OVERLAY
RSParticleDrawable::Generate, // PARTICLE_EFFECT
RSPixelStretchDrawable::Generate, // PIXEL_STRETCH
BlendRestoreDrawableGenerate, // RESTORE_BLEND
nullptr, // RESTORE_ALL
};
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,
};
} // namespace
std::unordered_set<RSPropertyDrawableSlot> RSPropertyDrawable::GenerateDirtySlots(
const RSProperties& properties, std::bitset<static_cast<int>(RSModifierType::MAX_RS_MODIFIER_TYPE)>& dirtyTypes)
{
// Step 1.1: collect dirty slots
std::unordered_set<RSPropertyDrawableSlot> dirtySlots;
for (uint8_t type = 0; type < static_cast<size_t>(RSModifierType::MAX_RS_MODIFIER_TYPE); type++) {
if (dirtyTypes[type]) {
auto it = g_propertyToDrawableLut.find(static_cast<RSModifierType>(type));
if (it == g_propertyToDrawableLut.end() || it->second == RSPropertyDrawableSlot::INVALID) {
continue;
}
dirtySlots.emplace(it->second);
}
}
// Step 1.2: expand dirty slots if needed
if (dirtyTypes.test(static_cast<size_t>(RSModifierType::BOUNDS))) {
if (properties.GetPixelStretch().has_value()) {
dirtySlots.emplace(RSPropertyDrawableSlot::PIXEL_STRETCH);
}
if (properties.GetBorder() != nullptr) {
dirtySlots.emplace(RSPropertyDrawableSlot::BORDER);
}
if (properties.GetOutline() != nullptr) {
dirtySlots.emplace(RSPropertyDrawableSlot::OUTLINE);
}
// PLANNING: add other slots: ClipToFrame, ColorFilter
}
if (dirtyTypes.test(static_cast<size_t>(RSModifierType::CORNER_RADIUS))) {
// border may should be updated with corner radius
if (properties.GetBorder() != nullptr) {
dirtySlots.emplace(RSPropertyDrawableSlot::BORDER);
}
if (properties.GetOutline() != nullptr) {
dirtySlots.emplace(RSPropertyDrawableSlot::OUTLINE);
}
}
if (dirtySlots.count(RSPropertyDrawableSlot::BLEND_MODE)) {
// BlendMode Restore should be regenerated with BlendMode
dirtySlots.emplace(RSPropertyDrawableSlot::RESTORE_BLEND_MODE);
}
return dirtySlots;
}
bool RSPropertyDrawable::UpdateDrawableVec(
const RSRenderContent& content, DrawableVec& drawableVec, std::unordered_set<RSPropertyDrawableSlot>& dirtySlots)
{
if (dirtySlots.empty()) {
return false;
}
// ====================================================================
// Step 2.1: re-generate drawables for all dirty slots
auto drawableSlotChanged = false;
for (const auto& slot : dirtySlots) {
auto& origDrawable = drawableVec[static_cast<size_t>(slot)];
if (origDrawable != nullptr && origDrawable->Update(content)) {
continue;
}
auto& generator = g_drawableGeneratorLut[static_cast<int>(slot)];
if (!generator) {
continue;
}
auto drawable = generator(content);
if (bool(origDrawable) != bool(drawable)) {
// drawable slot changed (nullptr to non-nullptr or vice versa)
drawableSlotChanged = true;
}
origDrawable = std::move(drawable);
}
// Step 2.2: post-generate hooks (PLANNING: refactor this into a separate function)
// Temporary fix, change of clipToBounds should trigger UpdateSaveRestore
if (!drawableSlotChanged && dirtySlots.count(RSPropertyDrawableSlot::CLIP_TO_BOUNDS)) {
drawableSlotChanged = true;
}
return drawableSlotChanged;
}
namespace {
inline bool HasPropertyDrawableInRange(
const RSPropertyDrawable::DrawableVec& drawableVec, RSPropertyDrawableSlot begin, RSPropertyDrawableSlot end)
{
return std::any_of(drawableVec.begin() + static_cast<size_t>(begin), drawableVec.begin() + static_cast<size_t>(end),
[](const auto& drawablePtr) { return drawablePtr != nullptr; });
}
uint8_t CalculateDrawableVecStatus(RSRenderContent& content, const RSPropertyDrawable::DrawableVec& 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, RSPropertyDrawableSlot::BG_PROPERTIES_BEGIN, RSPropertyDrawableSlot::BG_PROPERTIES_END)) {
result |= DrawableVecStatus::BG_BOUNDS_PROPERTY;
}
if (HasPropertyDrawableInRange(
drawableVec, RSPropertyDrawableSlot::FG_PROPERTIES_BEGIN, RSPropertyDrawableSlot::FG_PROPERTIES_END)) {
result |= DrawableVecStatus::FG_BOUNDS_PROPERTY;
}
if (HasPropertyDrawableInRange(drawableVec, RSPropertyDrawableSlot::CONTENT_PROPERTIES_BEGIN,
RSPropertyDrawableSlot::CONTENT_PROPERTIES_END)) {
result |= DrawableVecStatus::FRAME_PROPERTY;
}
return result;
}
constexpr std::array boundsSlotsToErase = {
RSPropertyDrawableSlot::BG_SAVE_BOUNDS,
RSPropertyDrawableSlot::CLIP_TO_BOUNDS,
RSPropertyDrawableSlot::BG_RESTORE_BOUNDS,
RSPropertyDrawableSlot::FG_SAVE_BOUNDS,
RSPropertyDrawableSlot::FG_CLIP_TO_BOUNDS,
RSPropertyDrawableSlot::FG_RESTORE_BOUNDS,
};
constexpr std::array frameSlotsToErase = {
RSPropertyDrawableSlot::SAVE_FRAME,
RSPropertyDrawableSlot::RESTORE_FRAME,
};
void OptimizeBoundsSaveRestore(RSRenderContent& content, RSPropertyDrawable::DrawableVec& 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>(RSPropertyDrawableSlot::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, RSPropertyDrawableSlot::BG_SAVE_BOUNDS,
RSPropertyDrawableSlot::BG_RESTORE_BOUNDS, RSPaintFilterCanvas::kCanvas);
drawableVec[static_cast<size_t>(RSPropertyDrawableSlot::CLIP_TO_BOUNDS)] =
RSClipBoundsDrawable::Generate(content);
// part 2: after children, add aliases
drawableVec[static_cast<size_t>(RSPropertyDrawableSlot::FG_SAVE_BOUNDS)] =
GenerateAlias(RSPropertyDrawableSlot::BG_SAVE_BOUNDS);
drawableVec[static_cast<size_t>(RSPropertyDrawableSlot::FG_CLIP_TO_BOUNDS)] =
GenerateAlias(RSPropertyDrawableSlot::CLIP_TO_BOUNDS);
drawableVec[static_cast<size_t>(RSPropertyDrawableSlot::FG_RESTORE_BOUNDS)] =
GenerateAlias(RSPropertyDrawableSlot::BG_RESTORE_BOUNDS);
return;
}
if (flags & DrawableVecStatus::BG_BOUNDS_PROPERTY) {
// case 3: ClipToBounds not set and we have background bounds properties.
SaveRestoreHelper(drawableVec, RSPropertyDrawableSlot::BG_SAVE_BOUNDS,
RSPropertyDrawableSlot::BG_RESTORE_BOUNDS, RSPaintFilterCanvas::kCanvas);
drawableVec[static_cast<size_t>(RSPropertyDrawableSlot::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, RSPropertyDrawableSlot::FG_SAVE_BOUNDS,
RSPropertyDrawableSlot::FG_RESTORE_BOUNDS, RSPaintFilterCanvas::kCanvas);
drawableVec[static_cast<size_t>(RSPropertyDrawableSlot::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, RSPropertyDrawable::DrawableVec& 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, RSPropertyDrawableSlot::SAVE_FRAME,
RSPropertyDrawableSlot::RESTORE_FRAME, RSPaintFilterCanvas::kCanvas);
} else {
// no need to save/clip/restore
}
}
} // namespace
void RSPropertyDrawable::InitializeSaveRestore(const RSRenderContent& content, DrawableVec& drawableVec)
{
SaveRestoreHelper(
drawableVec, RSPropertyDrawableSlot::SAVE_ALL, RSPropertyDrawableSlot::RESTORE_ALL, RSPaintFilterCanvas::kAll);
drawableVec[static_cast<size_t>(RSPropertyDrawableSlot::BOUNDS_MATRIX)] =
RSBoundsGeometryDrawable::Generate(content);
drawableVec[static_cast<size_t>(RSPropertyDrawableSlot::FRAME_OFFSET)] = RSFrameGeometryDrawable::Generate(content);
}
void RSPropertyDrawable::UpdateSaveRestore(
RSRenderContent& content, DrawableVec& 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,987 +0,0 @@
/*
* Copyright (c) 2023 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 "property/rs_property_drawable_bounds_geometry.h"
#include <utility>
#include "include/core/SkMaskFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint3.h"
#include "include/effects/SkImageFilters.h"
#include "include/effects/SkLumaColorFilter.h"
#include "include/utils/SkShadowUtils.h"
#include "src/image/SkImage_Base.h"
#include "common/rs_obj_abs_geometry.h"
#include "common/rs_optional_trace.h"
#include "pipeline/rs_canvas_render_node.h"
#include "pipeline/rs_effect_render_node.h"
#include "pipeline/rs_paint_filter_canvas.h"
#include "platform/common/rs_log.h"
#include "property/rs_properties.h"
#include "property/rs_properties_def.h"
#include "property/rs_properties_painter.h"
#include "render/rs_skia_filter.h"
#include "platform/common/rs_system_properties.h"
namespace {
constexpr int PARAM_DOUBLE = 2;
constexpr int16_t BORDER_TRANSPARENT = 255;
} // namespace
namespace OHOS::Rosen {
// ============================================================================
// Bounds geometry
void RSBoundsGeometryDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.ConcatMatrix(content.GetRenderProperties().GetBoundsGeometry()->GetMatrix());
}
RSPropertyDrawable::DrawablePtr RSBoundsGeometryDrawable::Generate(const RSRenderContent& content)
{
return std::make_unique<RSBoundsGeometryDrawable>();
}
void RSClipBoundsDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
// Planning: Generate() should calculate the draw op and cache it
auto& properties = content.GetRenderProperties();
if (properties.GetClipBounds() != nullptr) {
canvas.ClipPath(properties.GetClipBounds()->GetDrawingPath(), Drawing::ClipOp::INTERSECT, true);
} else if (properties.GetClipToRRect()) {
canvas.ClipRoundRect(
RSPropertiesPainter::RRect2DrawingRRect(properties.GetClipRRect()), Drawing::ClipOp::INTERSECT, false);
} else if (!properties.GetCornerRadius().IsZero()) {
canvas.ClipRoundRect(
RSPropertiesPainter::RRect2DrawingRRect(properties.GetRRect()), Drawing::ClipOp::INTERSECT, true);
} else {
canvas.ClipRect(
RSPropertiesPainter::Rect2DrawingRect(properties.GetBoundsRect()), Drawing::ClipOp::INTERSECT, true);
}
}
RSPropertyDrawable::DrawablePtr RSClipBoundsDrawable::Generate(const RSRenderContent& content)
{
return std::make_unique<RSClipBoundsDrawable>();
}
// ============================================================================
// PointLight
RSPropertyDrawable::DrawablePtr RSPointLightDrawable::Generate(const RSRenderContent& content)
{
const auto& properties = content.GetRenderProperties();
const auto& illuminatedPtr = properties.GetIlluminated();
if (illuminatedPtr && illuminatedPtr->IsIlluminatedValid()) {
return std::make_unique<RSPointLightDrawable>();
}
return nullptr;
}
void RSPointLightDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto& properties = content.GetRenderProperties();
const auto& illuminatedPtr = properties.GetIlluminated();
if (illuminatedPtr && illuminatedPtr->IsIlluminated()) {
RSPropertiesPainter::DrawLight(properties, canvas);
}
}
// ============================================================================
// Border
RSPropertyDrawable::DrawablePtr RSBorderDrawable::Generate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
auto border = properties.GetBorder();
if (!border || !border->HasBorder()) {
return nullptr;
}
Drawing::Pen pen;
Drawing::Brush brush;
pen.SetAntiAlias(true);
brush.SetAntiAlias(true);
if (border->ApplyFillStyle(brush)) {
return std::make_unique<RSBorderDRRectDrawable>(
std::move(brush), std::move(pen), properties, true);
} else if (properties.GetCornerRadius().IsZero() && border->ApplyFourLine(pen)) {
return std::make_unique<RSBorderFourLineDrawable>(
std::move(brush), std::move(pen), properties, true);
} else if (border->ApplyPathStyle(pen)) {
return std::make_unique<RSBorderPathDrawable>(
std::move(brush), std::move(pen), properties, true);
} else {
return std::make_unique<RSBorderFourLineRoundCornerDrawable>(
std::move(brush), std::move(pen), properties, true);
}
}
RSBorderDRRectDrawable::RSBorderDRRectDrawable(Drawing::Brush&& brush, Drawing::Pen&& pen,
const RSProperties& properties, const bool& drawBorder)
: RSBorderDrawable(std::move(brush), std::move(pen))
{
drawBorder_ = drawBorder;
OnBoundsChange(properties);
}
void RSBorderDRRectDrawable::OnBoundsChange(const RSProperties& properties)
{
if (drawBorder_) {
inner_ = RSPropertiesPainter::RRect2DrawingRRect(properties.GetInnerRRect());
outer_ = RSPropertiesPainter::RRect2DrawingRRect(properties.GetRRect());
} else {
inner_ = RSPropertiesPainter::RRect2DrawingRRect(properties.GetRRect());
RectF rect = properties.GetBoundsRect().MakeOutset(properties.GetOutline()->GetWidthFour());
outer_ = RSPropertiesPainter::RRect2DrawingRRect(RRect(rect, properties.GetOutline()->GetRadiusFour()));
}
}
void RSBorderDRRectDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.AttachBrush(brush_);
canvas.DrawNestedRoundRect(outer_, inner_);
canvas.DetachBrush();
}
RSBorderFourLineDrawable::RSBorderFourLineDrawable(Drawing::Brush&& brush, Drawing::Pen&& pen,
const RSProperties& properties, const bool& drawBorder)
: RSBorderDrawable(std::move(brush), std::move(pen))
{
drawBorder_ = drawBorder;
OnBoundsChange(properties);
}
void RSBorderFourLineDrawable::OnBoundsChange(const RSProperties& properties)
{
if (drawBorder_) {
rect_ = properties.GetBoundsRect();
} else {
rect_ = properties.GetBoundsRect().MakeOutset(properties.GetOutline()->GetWidthFour());
}
}
void RSBorderFourLineDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto pen = pen_;
if (drawBorder_) {
content.GetRenderProperties().GetBorder()->PaintFourLine(canvas, pen, rect_);
} else {
content.GetRenderProperties().GetOutline()->PaintFourLine(canvas, pen, rect_);
}
}
RSBorderPathDrawable::RSBorderPathDrawable(Drawing::Brush&& brush, Drawing::Pen&& pen,
const RSProperties& properties, const bool& drawBorder)
: RSBorderDrawable(std::move(brush), std::move(pen))
{
drawBorder_ = drawBorder;
OnBoundsChange(properties);
}
void RSBorderPathDrawable::OnBoundsChange(const RSProperties& properties)
{
float borderWidth;
RRect rrect;
if (drawBorder_) {
borderWidth = properties.GetBorder()->GetWidth();
rrect = properties.GetRRect();
} else {
borderWidth = properties.GetOutline()->GetWidth();
RectF rect = properties.GetBoundsRect().MakeOutset(properties.GetOutline()->GetWidthFour());
rrect = RRect(rect, properties.GetOutline()->GetRadiusFour());
}
rrect.rect_.width_ -= borderWidth;
rrect.rect_.height_ -= borderWidth;
rrect.rect_.Move(borderWidth / PARAM_DOUBLE, borderWidth / PARAM_DOUBLE);
borderPath_.Reset();
borderPath_.AddRoundRect(RSPropertiesPainter::RRect2DrawingRRect(rrect));
}
void RSBorderPathDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.AttachPen(pen_);
canvas.DrawPath(borderPath_);
canvas.DetachPen();
}
RSBorderFourLineRoundCornerDrawable::RSBorderFourLineRoundCornerDrawable(
Drawing::Brush&& brush, Drawing::Pen&& pen, const RSProperties& properties, const bool& drawBorder)
: RSBorderDrawable(std::move(brush), std::move(pen)), drawBorder_(drawBorder)
{
OnBoundsChange(properties);
}
void RSBorderFourLineRoundCornerDrawable::OnBoundsChange(const RSProperties& properties)
{
if (drawBorder_) {
innerRrect_ = RSPropertiesPainter::RRect2DrawingRRect(properties.GetInnerRRect());
rrect_ = RSPropertiesPainter::RRect2DrawingRRect(properties.GetRRect());
} else {
innerRrect_ = RSPropertiesPainter::RRect2DrawingRRect(properties.GetRRect());
RectF rect = properties.GetBoundsRect().MakeOutset(properties.GetOutline()->GetWidthFour());
rrect_ = RSPropertiesPainter::RRect2DrawingRRect(RRect(rect, properties.GetOutline()->GetRadiusFour()));
}
}
void RSBorderFourLineRoundCornerDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto pen = pen_;
Drawing::AutoCanvasRestore acr(canvas, true);
auto& properties = content.GetRenderProperties();
canvas.ClipRoundRect(rrect_,Drawing::ClipOp::INTERSECT, true);
canvas.ClipRoundRect(innerRrect_, Drawing::ClipOp::DIFFERENCE, true);
Drawing::scalar centerX = innerRrect_.GetRect().GetLeft() + innerRrect_.GetRect().GetWidth() / 2;
Drawing::scalar centerY = innerRrect_.GetRect().GetTop() + innerRrect_.GetRect().GetHeight() / 2;
Drawing::Point center = { centerX, centerY };
auto rect = rrect_.GetRect();
Drawing::SaveLayerOps slr(&rect, nullptr);
canvas.SaveLayer(slr);
if (drawBorder_) {
properties.GetBorder()->PaintTopPath(canvas, pen, rrect_, center);
properties.GetBorder()->PaintRightPath(canvas, pen, rrect_, center);
properties.GetBorder()->PaintBottomPath(canvas, pen, rrect_, center);
properties.GetBorder()->PaintLeftPath(canvas, pen, rrect_, center);
} else {
properties.GetOutline()->PaintTopPath(canvas, pen, rrect_, center);
properties.GetOutline()->PaintRightPath(canvas, pen, rrect_, center);
properties.GetOutline()->PaintBottomPath(canvas, pen, rrect_, center);
properties.GetOutline()->PaintLeftPath(canvas, pen, rrect_, center);
}
}
// ============================================================================
// Outline
RSPropertyDrawable::DrawablePtr RSOutlineDrawable::Generate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
auto& outline = properties.GetOutline();
if (!outline || !outline->HasBorder()) {
return nullptr;
}
Drawing::Pen pen;
Drawing::Brush brush;
pen.SetAntiAlias(true);
brush.SetAntiAlias(true);
if (outline->ApplyFillStyle(brush)) {
return std::make_unique<RSBorderDRRectDrawable>(std::move(brush), std::move(pen), properties, false);
} else if (outline->GetRadiusFour().IsZero() && outline->ApplyFourLine(pen)) {
return std::make_unique<RSBorderFourLineDrawable>(std::move(brush), std::move(pen), properties, false);
} else if (outline->ApplyPathStyle(pen)) {
return std::make_unique<RSBorderPathDrawable>(std::move(brush), std::move(pen), properties, false);
} else {
return std::make_unique<RSBorderFourLineRoundCornerDrawable>(
std::move(brush), std::move(pen), properties, false);
}
}
// ============================================================================
// Mask
RSPropertyDrawable::DrawablePtr RSMaskDrawable::Generate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
std::shared_ptr<RSMask> mask = properties.GetMask();
if (mask == nullptr) {
return nullptr;
}
if (mask->IsSvgMask() && !mask->GetSvgDom() && !mask->GetSvgPicture()) {
return nullptr;
}
if (mask->IsSvgMask()) {
if (mask->GetSvgDom()) {
return std::make_unique<RSSvgDomMaskDrawable>(mask);
} else if (mask->GetSvgPicture()) {
return std::make_unique<RSSvgPictureMaskDrawable>(mask);
}
} else if (mask->IsGradientMask()) {
return std::make_unique<RSGradientMaskDrawable>(mask);
} else if (mask->IsPathMask()) {
return std::make_unique<RSPathMaskDrawable>(mask);
}
return nullptr;
}
RSMaskDrawable::RSMaskDrawable(std::shared_ptr<RSMask> mask) : mask_(std::move(mask))
{
maskBrush_.SetBlendMode(Drawing::BlendMode::SRC_IN);
Drawing::Filter filter;
filter.SetColorFilter(Drawing::ColorFilter::CreateComposeColorFilter(
*(Drawing::ColorFilter::CreateLumaColorFilter()), *(Drawing::ColorFilter::CreateSrgbGammaToLinear())));
maskFilterBrush_.SetFilter(filter);
}
RSSvgDomMaskDrawable::RSSvgDomMaskDrawable(std::shared_ptr<RSMask> mask) : RSMaskDrawable(mask) {}
void RSSvgDomMaskDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto& properties = content.GetRenderProperties();
auto bounds = RSPropertiesPainter::Rect2DrawingRect(properties.GetBoundsRect());
canvas.Save();
Drawing::SaveLayerOps slr(&bounds, nullptr);
canvas.SaveLayer(slr);
int tmpLayer = canvas.GetSaveCount();
Drawing::SaveLayerOps slrMask(&bounds, &maskFilterBrush_);
canvas.SaveLayer(slrMask);
{
Drawing::AutoCanvasRestore acr(canvas, true);
canvas.Translate(bounds.GetLeft() + mask_->GetSvgX(), bounds.GetTop() + mask_->GetSvgY());
canvas.Scale(mask_->GetScaleX(), mask_->GetScaleY());
canvas.DrawSVGDOM(mask_->GetSvgDom());
}
canvas.RestoreToCount(tmpLayer);
Drawing::SaveLayerOps slrContent(&bounds, &maskBrush_);
canvas.SaveLayer(slrContent);
canvas.ClipRect(bounds, Drawing::ClipOp::INTERSECT, true);
}
RSSvgPictureMaskDrawable::RSSvgPictureMaskDrawable(std::shared_ptr<RSMask> mask) : RSMaskDrawable(mask) {}
void RSSvgPictureMaskDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto& properties = content.GetRenderProperties();
auto bounds = RSPropertiesPainter::Rect2DrawingRect(properties.GetBoundsRect());
canvas.Save();
Drawing::SaveLayerOps slr(&bounds, nullptr);
canvas.SaveLayer(slr);
int tmpLayer = canvas.GetSaveCount();
Drawing::SaveLayerOps slrMask(&bounds, &maskFilterBrush_);
canvas.SaveLayer(slrMask);
{
Drawing::AutoCanvasRestore acr(canvas, true);
canvas.Translate(bounds.GetLeft() + mask_->GetSvgX(), bounds.GetTop() + mask_->GetSvgY());
canvas.Scale(mask_->GetScaleX(), mask_->GetScaleY());
canvas.DrawPicture(*mask_->GetSvgPicture());
}
canvas.RestoreToCount(tmpLayer);
Drawing::SaveLayerOps slrContent(&bounds, &maskBrush_);
canvas.SaveLayer(slrContent);
canvas.ClipRect(bounds, Drawing::ClipOp::INTERSECT, true);
}
RSGradientMaskDrawable::RSGradientMaskDrawable(std::shared_ptr<RSMask> mask) : RSMaskDrawable(mask) {}
void RSGradientMaskDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto& properties = content.GetRenderProperties();
auto bounds = RSPropertiesPainter::Rect2DrawingRect(properties.GetBoundsRect());
canvas.Save();
Drawing::SaveLayerOps slr(&bounds, nullptr);
canvas.SaveLayer(slr);
int tmpLayer = canvas.GetSaveCount();
Drawing::SaveLayerOps slrMask(&bounds, &maskFilterBrush_);
canvas.SaveLayer(slrMask);
{
Drawing::AutoCanvasRestore acr(canvas, true);
canvas.Translate(bounds.GetLeft(), bounds.GetTop());
Drawing::Rect rect =
Drawing::Rect(0, 0, bounds.GetRight() - bounds.GetLeft(), bounds.GetBottom() - bounds.GetTop());
canvas.AttachBrush(mask_->GetMaskBrush());
canvas.DrawRect(rect);
canvas.DetachBrush();
}
canvas.RestoreToCount(tmpLayer);
Drawing::SaveLayerOps slrContent(&bounds, &maskBrush_);
canvas.SaveLayer(slrContent);
canvas.ClipRect(bounds, Drawing::ClipOp::INTERSECT, true);
}
RSPathMaskDrawable::RSPathMaskDrawable(std::shared_ptr<RSMask> mask) : RSMaskDrawable(mask) {}
void RSPathMaskDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto& properties = content.GetRenderProperties();
auto bounds = RSPropertiesPainter::Rect2DrawingRect(properties.GetBoundsRect());
canvas.Save();
Drawing::SaveLayerOps slr(&bounds, nullptr);
canvas.SaveLayer(slr);
int tmpLayer = canvas.GetSaveCount();
Drawing::SaveLayerOps slrMask(&bounds, &maskFilterBrush_);
canvas.SaveLayer(slrMask);
{
Drawing::AutoCanvasRestore acr(canvas, true);
canvas.Translate(bounds.GetLeft(), bounds.GetTop());
canvas.AttachBrush(mask_->GetMaskBrush());
canvas.AttachPen(mask_->GetMaskPen());
canvas.DrawPath(*mask_->GetMaskPath());
canvas.DetachBrush();
canvas.DetachPen();
}
canvas.RestoreToCount(tmpLayer);
Drawing::SaveLayerOps slrContent(&bounds, &maskBrush_);
canvas.SaveLayer(slrContent);
canvas.ClipRect(bounds, Drawing::ClipOp::INTERSECT, true);
}
// ============================================================================
// Shadow
RSPropertyDrawable::DrawablePtr RSShadowBaseDrawable::Generate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
if (properties.IsSpherizeValid() || !properties.IsShadowValid()) {
return nullptr;
}
if (properties.GetShadowMask()) {
return std::make_unique<RSColorfulShadowDrawable>(properties);
} else {
if (properties.GetShadowElevation() > 0.f) {
return std::make_unique<RSHardwareAccelerationShadowDrawable>(properties);
} else {
return std::make_unique<RSShadowDrawable>(properties);
}
return nullptr;
}
}
RSShadowBaseDrawable::RSShadowBaseDrawable(const RSProperties& properties)
: offsetX_(properties.GetShadowOffsetX()), offsetY_(properties.GetShadowOffsetY()),
color_(properties.GetShadowColor())
{}
RSShadowDrawable::RSShadowDrawable(const RSProperties& properties)
: RSShadowBaseDrawable(properties), radius_(properties.GetShadowRadius())
{}
void RSShadowBaseDrawable::ClipShadowPath(
const RSRenderContent& content, RSPaintFilterCanvas& canvas, Drawing::Path& path) const
{
const auto& properties = content.GetRenderProperties();
if (properties.GetShadowPath() && properties.GetShadowPath()->GetDrawingPath().IsValid()) {
path = properties.GetShadowPath()->GetDrawingPath();
if (!properties.GetShadowIsFilled()) {
canvas.ClipPath(path, Drawing::ClipOp::DIFFERENCE, true);
}
} else if (properties.GetClipBounds()) {
path = properties.GetClipBounds()->GetDrawingPath();
if (!properties.GetShadowIsFilled()) {
canvas.ClipPath(path, Drawing::ClipOp::DIFFERENCE, true);
}
} else {
path.AddRoundRect(RSPropertiesPainter::RRect2DrawingRRect(properties.GetRRect()));
if (!properties.GetShadowIsFilled()) {
canvas.ClipRoundRect(
RSPropertiesPainter::RRect2DrawingRRect(properties.GetRRect()), Drawing::ClipOp::DIFFERENCE, true);
}
}
}
RSColor RSShadowDrawable::GetColorForShadow(const RSRenderContent& content, RSPaintFilterCanvas& canvas,
Drawing::Path& skPath, Drawing::Matrix& matrix, Drawing::RectI& deviceClipBounds) const
{
RSColor colorPicked;
const RSProperties& properties = content.GetRenderProperties();
// shadow alpha follow setting
auto shadowAlpha = color_.GetAlpha();
auto& colorPickerTask = properties.GetColorPickerCacheTaskShadow();
if (colorPickerTask != nullptr &&
properties.GetShadowColorStrategy() != SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE) {
if (RSPropertiesPainter::PickColor(properties, canvas, skPath, matrix, deviceClipBounds, colorPicked)) {
RSPropertiesPainter::GetDarkColor(colorPicked);
} else {
shadowAlpha = 0;
}
if (!colorPickerTask->GetFirstGetColorFinished()) {
shadowAlpha = 0;
}
} else {
shadowAlpha = color_.GetAlpha();
colorPicked = color_;
}
return RSColor(colorPicked.GetRed(), colorPicked.GetGreen(), colorPicked.GetBlue(), shadowAlpha);
}
void RSShadowDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
if (content.GetRenderProperties().GetNeedSkipShadow()) {
RS_TRACE_NAME("RSShadowDrawable::Draw NeedSkipShadow");
return;
}
if (canvas.GetCacheType() == RSPaintFilterCanvas::CacheType::ENABLED) {
return;
}
auto deviceClipBounds = canvas.GetDeviceClipBounds();
Drawing::AutoCanvasRestore acr(canvas, true);
Drawing::Path path;
ClipShadowPath(content, canvas, path);
path.Offset(offsetX_, offsetY_);
auto matrix = canvas.GetTotalMatrix();
matrix.Set(Drawing::Matrix::TRANS_X, std::ceil(matrix.Get(Drawing::Matrix::TRANS_X)));
matrix.Set(Drawing::Matrix::TRANS_Y, std::ceil(matrix.Get(Drawing::Matrix::TRANS_Y)));
canvas.SetMatrix(matrix);
RSColor colorPicked = GetColorForShadow(content, canvas, path, matrix, deviceClipBounds);
Drawing::Brush brush;
brush.SetColor(Drawing::Color::ColorQuadSetARGB(
colorPicked.GetAlpha(), colorPicked.GetRed(), colorPicked.GetGreen(), colorPicked.GetBlue()));
brush.SetAntiAlias(true);
Drawing::Filter filter;
filter.SetMaskFilter(Drawing::MaskFilter::CreateBlurMaskFilter(Drawing::BlurType::NORMAL, radius_));
brush.SetFilter(filter);
canvas.AttachBrush(brush);
canvas.DrawPath(path);
canvas.DetachBrush();
}
RSHardwareAccelerationShadowDrawable::RSHardwareAccelerationShadowDrawable(const RSProperties& properties)
: RSShadowBaseDrawable(properties), shadowElevation_(properties.GetShadowElevation())
{}
void RSHardwareAccelerationShadowDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
if (canvas.GetCacheType() == RSPaintFilterCanvas::CacheType::ENABLED) {
return;
}
Drawing::AutoCanvasRestore acr(canvas, true);
Drawing::Path path;
ClipShadowPath(content, canvas, path);
path.Offset(offsetX_, offsetY_);
RSAutoCanvasRestore rst(&canvas);
auto matrix = canvas.GetTotalMatrix();
matrix.Set(Drawing::Matrix::TRANS_X, std::ceil(matrix.Get(Drawing::Matrix::TRANS_X)));
matrix.Set(Drawing::Matrix::TRANS_Y, std::ceil(matrix.Get(Drawing::Matrix::TRANS_Y)));
canvas.SetMatrix(matrix);
Drawing::Point3 planeParams = { 0.0f, 0.0f, shadowElevation_ };
std::vector<Drawing::Point> pt{{path.GetBounds().GetLeft() + path.GetBounds().GetWidth() / 2,
path.GetBounds().GetTop() + path.GetBounds().GetHeight() / 2}};
canvas.GetTotalMatrix().MapPoints(pt, pt, 1);
Drawing::Point3 lightPos = {pt[0].GetX(), pt[0].GetY(), DEFAULT_LIGHT_HEIGHT};
Color ambientColor = Color::FromArgbInt(DEFAULT_AMBIENT_COLOR);
ambientColor.MultiplyAlpha(canvas.GetAlpha());
Color spotColor = color_;
spotColor.MultiplyAlpha(canvas.GetAlpha());
canvas.DrawShadow(path, planeParams, lightPos, DEFAULT_LIGHT_RADIUS, Drawing::Color(ambientColor.AsArgbInt()),
Drawing::Color(spotColor.AsArgbInt()), Drawing::ShadowFlags::TRANSPARENT_OCCLUDER);
}
RSColorfulShadowDrawable::RSColorfulShadowDrawable(const RSProperties& properties) : RSShadowBaseDrawable(properties)
{
const Drawing::scalar blurRadius =
properties.GetShadowElevation() > 0.f
? 0.25f * properties.GetShadowElevation() * (1 + properties.GetShadowElevation() / 128.0f)
: properties.GetShadowRadius();
Drawing::Filter filter;
filter.SetImageFilter(
Drawing::ImageFilter::CreateBlurImageFilter(blurRadius, blurRadius, Drawing::TileMode::DECAL, nullptr));
blurBrush_.SetFilter(filter);
node_ = properties.backref_;
}
void RSColorfulShadowDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
if (canvas.GetCacheType() == RSPaintFilterCanvas::CacheType::ENABLED) {
return;
}
Drawing::AutoCanvasRestore acr(canvas, true);
Drawing::Path path;
ClipShadowPath(content, canvas, path);
// save layer, draw image with clipPath, blur and draw back
Drawing::SaveLayerOps slr(nullptr, &blurBrush_);
canvas.SaveLayer(slr);
canvas.Translate(offsetX_, offsetY_);
canvas.ClipPath(path, Drawing::ClipOp::INTERSECT, false);
// draw node content as shadow
// [PLANNING]: maybe we should also draw background color / image here, and we should cache the shadow image
if (auto node = RSBaseRenderNode::ReinterpretCast<RSCanvasRenderNode>(node_.lock())) {
node->InternalDrawContent(canvas);
}
}
// ============================================================================
// DynamicLightUp
RSPropertyDrawable::DrawablePtr RSDynamicLightUpDrawable::Generate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
if (!properties.IsDynamicLightUpValid()) {
return nullptr;
}
return std::make_unique<RSDynamicLightUpDrawable>();
}
bool RSDynamicLightUpDrawable::Update(const RSRenderContent& content)
{
return content.GetRenderProperties().IsDynamicLightUpValid();
}
void RSDynamicLightUpDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
RSPropertiesPainter::DrawDynamicLightUp(content.GetRenderProperties(), canvas);
}
// ============================================================================
// LightUpEffect
RSPropertyDrawable::DrawablePtr RSLightUpEffectDrawable::Generate(const RSRenderContent& content)
{
if (!content.GetRenderProperties().IsLightUpEffectValid()) {
return nullptr;
}
return std::make_unique<RSLightUpEffectDrawable>();
}
bool RSLightUpEffectDrawable::Update(const RSRenderContent& content)
{
return content.GetRenderProperties().IsLightUpEffectValid();
}
// ============================================================================
// Binarization
void RSBinarizationDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
RSPropertiesPainter::DrawBinarizationShader(content.GetRenderProperties(), canvas);
}
RSPropertyDrawable::DrawablePtr RSBinarizationDrawable::Generate(const RSRenderContent& content)
{
auto& aiInvert = content.GetRenderProperties().GetAiInvert();
if (!aiInvert.has_value()) {
return nullptr;
}
return std::make_unique<RSBinarizationDrawable>();
}
// ============================================================================
// LightUpEffect
void RSLightUpEffectDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
RSPropertiesPainter::DrawLightUpEffect(content.GetRenderProperties(), canvas);
}
// ============================================================================
// background filter
RSPropertyDrawable::DrawablePtr RSBackgroundFilterDrawable::Generate(const RSRenderContent& content)
{
if (!RSPropertiesPainter::BLUR_ENABLED) {
ROSEN_LOGD("RSBackgroundFilterDrawable::Generate close blur.");
return nullptr;
}
auto& filter = content.GetRenderProperties().GetBackgroundFilter();
if (filter == nullptr) {
return nullptr;
}
if (content.GetType() == RSRenderNodeType::EFFECT_NODE) {
// for RSEffectRenderNode, we just use generates effect data, instead of draw filter
return std::make_unique<RSEffectDataGenerateDrawable>();
}
return std::make_unique<RSBackgroundFilterDrawable>();
}
void RSBackgroundFilterDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
// fix compatibility with Node Group, copied from RSCanvasRenderNode::ProcessAnimatePropertyBeforeChildren
if (canvas.GetCacheType() == RSPaintFilterCanvas::CacheType::OFFSCREEN) {
return;
}
RSPropertiesPainter::DrawFilter(content.GetRenderProperties(), canvas, FilterType::BACKGROUND_FILTER);
}
// foreground filter
RSPropertyDrawable::DrawablePtr RSForegroundFilterDrawable::Generate(const RSRenderContent& content)
{
if (!RSPropertiesPainter::BLUR_ENABLED) {
ROSEN_LOGD("RSForegroundFilterDrawable::Generate close blur.");
return nullptr;
}
auto& filter = content.GetRenderProperties().GetFilter();
if (filter == nullptr) {
return nullptr;
}
return std::make_unique<RSForegroundFilterDrawable>();
}
bool RSForegroundFilterDrawable::Update(const RSRenderContent& content)
{
return content.GetRenderProperties().GetFilter() != nullptr;
}
void RSForegroundFilterDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
RSPropertiesPainter::DrawFilter(content.GetRenderProperties(), canvas, FilterType::FOREGROUND_FILTER);
}
// effect data
bool RSEffectDataGenerateDrawable::Update(const RSRenderContent& content)
{
return content.GetRenderProperties().GetBackgroundFilter() != nullptr;
}
void RSEffectDataGenerateDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
const auto& properties = content.GetRenderProperties();
if (properties.GetHaveEffectRegion() && properties.GetBackgroundFilter() &&
RSSystemProperties::GetEffectMergeEnabled()) {
RSPropertiesPainter::DrawBackgroundEffect(content.GetRenderProperties(), canvas);
}
}
// effect data apply
RSPropertyDrawable::DrawablePtr RSEffectDataApplyDrawable::Generate(const RSRenderContent& content)
{
if (content.GetRenderProperties().GetUseEffect() == false) {
return nullptr;
}
return std::make_unique<RSEffectDataApplyDrawable>();
}
bool RSEffectDataApplyDrawable::Update(const RSRenderContent& content)
{
return content.GetRenderProperties().GetUseEffect();
}
bool RSBackgroundFilterDrawable::Update(const RSRenderContent& content)
{
return content.GetRenderProperties().GetBackgroundFilter() != nullptr;
}
void RSEffectDataApplyDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
// fix compatibility with Node Group, copied from RSCanvasRenderNode::ProcessAnimatePropertyBeforeChildren
if (canvas.GetCacheType() == RSPaintFilterCanvas::CacheType::OFFSCREEN) {
return;
}
RSPropertiesPainter::ApplyBackgroundEffect(content.GetRenderProperties(), canvas);
}
// ============================================================================
// ForegroundColor
void RSForegroundColorDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto& properties = content.GetRenderProperties();
canvas.AttachBrush(brush_);
canvas.DrawRoundRect(RSPropertiesPainter::RRect2DrawingRRect(properties.GetRRect()));
canvas.DetachBrush();
}
bool RSForegroundColorDrawable::Update(const RSRenderContent& content)
{
auto fgColor = content.GetRenderProperties().GetForegroundColor();
brush_.SetColor(fgColor.AsArgbInt());
return fgColor != RgbPalette::Transparent();
}
RSPropertyDrawable::DrawablePtr RSForegroundColorDrawable::Generate(const RSRenderContent& content)
{
auto fgColor = content.GetRenderProperties().GetForegroundColor();
if (fgColor == RgbPalette::Transparent()) {
return nullptr;
}
Drawing::Brush brush;
brush.SetColor(fgColor.AsArgbInt());
brush.SetAntiAlias(true);
return std::make_unique<RSForegroundColorDrawable>(std::move(brush));
}
// ============================================================================
// Particle
RSPropertyDrawable::DrawablePtr RSParticleDrawable::Generate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
const auto& particleVector = properties.GetParticles();
if (particleVector.GetParticleSize() == 0) {
return nullptr;
}
return std::make_unique<RSParticleDrawable>();
}
bool RSParticleDrawable::Update(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
return properties.GetPixelStretch().has_value();
}
void RSParticleDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
RSPropertiesPainter::DrawParticle(content.GetRenderProperties(), canvas);
}
void RSPixelStretchDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
RSPropertiesPainter::DrawPixelStretch(content.GetRenderProperties(), canvas);
}
bool RSPixelStretchDrawable::Update(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
return properties.GetPixelStretch().has_value();
}
RSPropertyDrawable::DrawablePtr RSPixelStretchDrawable::Generate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
auto& pixelStretch = properties.GetPixelStretch();
if (!pixelStretch.has_value()) {
return nullptr;
}
return std::make_unique<RSPixelStretchDrawable>();
}
// ============================================================================
// Background
void RSBackgroundDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto& properties = content.GetRenderProperties();
bool antiAlias = RSPropertiesPainter::GetBgAntiAlias() || !properties.GetCornerRadius().IsZero();
auto borderColorAlpha = properties.GetBorderColor()[0].GetAlpha();
Drawing::Brush brush = brush_;
brush.SetAntiAlias(antiAlias);
canvas.AttachBrush(brush);
// use drawrrect to avoid texture update in phone screen rotation scene
if (RSSystemProperties::IsPhoneType()) {
if (borderColorAlpha < BORDER_TRANSPARENT) {
canvas.DrawRoundRect(RSPropertiesPainter::RRect2DrawingRRect(properties.GetRRect()));
} else {
canvas.DrawRoundRect(RSPropertiesPainter::RRect2DrawingRRect(properties.GetInnerRRect()));
}
} else {
canvas.DrawRect(RSPropertiesPainter::Rect2DrawingRect(properties.GetBoundsRect()));
}
canvas.DetachBrush();
}
RSPropertyDrawable::DrawablePtr RSBackgroundColorDrawable::Generate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
auto& bgColor = properties.GetBackgroundColor();
bool isTransparent = (bgColor == RgbPalette::Transparent());
if (isTransparent) {
return nullptr;
}
return std::make_unique<RSBackgroundColorDrawable>(bgColor.AsArgbInt());
}
bool RSBackgroundColorDrawable::Update(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
auto& bgColor = properties.GetBackgroundColor();
if (bgColor == RgbPalette::Transparent()) {
return false;
}
brush_.SetColor(bgColor.AsArgbInt());
return true;
}
RSPropertyDrawable::DrawablePtr RSBackgroundShaderDrawable::Generate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
auto bgShader = properties.GetBackgroundShader();
if (!bgShader) {
return nullptr;
}
return std::make_unique<RSBackgroundShaderDrawable>(bgShader->GetDrawingShader());
}
bool RSBackgroundShaderDrawable::Update(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
auto bgShader = properties.GetBackgroundShader();
if (!bgShader) {
return false;
}
brush_.SetShaderEffect(bgShader->GetDrawingShader());
return true;
}
RSPropertyDrawable::DrawablePtr RSBackgroundImageDrawable::Generate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
const auto& bgImage = properties.GetBgImage();
if (!bgImage) {
return nullptr;
}
bgImage->SetDstRect(properties.GetBgImageRect());
return std::make_unique<RSBackgroundImageDrawable>();
}
bool RSBackgroundImageDrawable::Update(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
const auto& bgImage = properties.GetBgImage();
if (!bgImage) {
return false;
}
bgImage->SetDstRect(properties.GetBgImageRect());
return true;
}
void RSBackgroundImageDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto& properties = content.GetRenderProperties();
const auto& image = properties.GetBgImage();
auto boundsRect = RSPropertiesPainter::Rect2DrawingRect(properties.GetBoundsRect());
canvas.AttachBrush(brush_);
image->CanvasDrawImage(canvas, boundsRect, Drawing::SamplingOptions(), true);
canvas.DetachBrush();
}
// blend mode save and restore
std::unique_ptr<RSPropertyDrawable> BlendSaveDrawableGenerate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
auto blendMode = properties.GetColorBlendMode();
int blendModeApplyType = properties.GetColorBlendApplyType();
if (blendMode == 0) {
// no blend
return nullptr;
}
if (blendModeApplyType == static_cast<int>(RSColorBlendApplyType::FAST)) {
return std::make_unique<RSBlendFastDrawable>(blendMode);
}
return std::make_unique<RSBlendSaveLayerDrawable>(blendMode);
}
std::unique_ptr<RSPropertyDrawable> BlendRestoreDrawableGenerate(const RSRenderContent& content)
{
auto& properties = content.GetRenderProperties();
auto blendMode = properties.GetColorBlendMode();
int blendModeApplyType = properties.GetColorBlendApplyType();
if (blendMode == 0) {
// no blend
return nullptr;
}
if (blendModeApplyType == static_cast<int>(RSColorBlendApplyType::SAVE_LAYER)) {
return std::make_unique<RSBlendSaveLayerRestoreDrawable>();
}
return std::make_unique<RSBlendFastRestoreDrawable>();
}
RSBlendSaveLayerDrawable::RSBlendSaveLayerDrawable(int blendMode)
{
blendBrush_.SetBlendMode(static_cast<Drawing::BlendMode>(blendMode - 1)); // map blendMode to Drawing::BlendMode
}
void RSBlendSaveLayerDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto matrix = canvas.GetTotalMatrix();
matrix.Set(Drawing::Matrix::TRANS_X, std::ceil(matrix.Get(Drawing::Matrix::TRANS_X)));
matrix.Set(Drawing::Matrix::TRANS_Y, std::ceil(matrix.Get(Drawing::Matrix::TRANS_Y)));
canvas.SetMatrix(matrix);
auto brush = blendBrush_;
brush.SetAlphaF(canvas.GetAlpha());
Drawing::SaveLayerOps maskLayerRec(nullptr, &brush, 0);
canvas.SaveLayer(maskLayerRec);
canvas.SaveBlendMode();
canvas.SetBlendMode(std::nullopt);
canvas.SaveAlpha();
canvas.SetAlpha(1.0f);
}
void RSBlendFastDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.SaveBlendMode();
canvas.SetBlendMode({ blendMode_ - 1 }); // map blendMode to SkBlendMode
}
void RSBlendSaveLayerRestoreDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.RestoreBlendMode();
canvas.RestoreAlpha();
canvas.Restore();
}
void RSBlendFastRestoreDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.RestoreBlendMode();
}
} // namespace OHOS::Rosen

View File

@ -1,97 +0,0 @@
/*
* Copyright (c) 2023 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 "property/rs_property_drawable_frame_geometry.h"
#include "pipeline/rs_paint_filter_canvas.h"
#include "pipeline/rs_render_node.h"
#include "platform/common/rs_log.h"
#include "property/rs_properties.h"
#include "property/rs_properties_painter.h"
#include "src/image/SkImage_Base.h"
namespace OHOS::Rosen {
void RSFrameGeometryDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.Translate(content.GetRenderProperties().GetFrameOffsetX(), content.GetRenderProperties().GetFrameOffsetY());
}
RSPropertyDrawable::DrawablePtr RSFrameGeometryDrawable::Generate(const RSRenderContent& content)
{
return std::make_unique<RSFrameGeometryDrawable>();
}
void RSColorFilterDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto drSurface = canvas.GetSurface();
if (drSurface == nullptr) {
ROSEN_LOGE("RSColorFilterDrawable::Draw drSurface is null");
return;
}
auto clipBounds = canvas.GetDeviceClipBounds();
auto imageSnapshot = drSurface->GetImageSnapshot(clipBounds);
if (imageSnapshot == nullptr) {
ROSEN_LOGD("RSColorFilterDrawable::Draw image is null");
return;
}
imageSnapshot->HintCacheGpuResource();
Drawing::AutoCanvasRestore acr(canvas, true);
canvas.ResetMatrix();
static Drawing::SamplingOptions options(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NONE);
canvas.AttachBrush(brush_);
Drawing::Rect clipBoundsRect = {clipBounds.GetLeft(), clipBounds.GetTop(),
clipBounds.GetRight(), clipBounds.GetBottom()};
canvas.DrawImageRect(*imageSnapshot, clipBoundsRect, options);
canvas.DetachBrush();
}
RSPropertyDrawable::DrawablePtr RSColorFilterDrawable::Generate(const RSRenderContent& content)
{
auto& colorFilter = content.GetRenderProperties().GetColorFilter();
if (colorFilter == nullptr) {
return nullptr;
}
Drawing::Brush brush;
brush.SetAntiAlias(true);
Drawing::Filter filter;
filter.SetColorFilter(colorFilter);
brush.SetFilter(filter);
return std::make_unique<RSColorFilterDrawable>(std::move(brush));
}
bool RSColorFilterDrawable::Update(const RSRenderContent& content)
{
auto& colorFilter = content.GetRenderProperties().GetColorFilter();
if (colorFilter == nullptr) {
return false;
}
Drawing::Filter filter;
filter.SetColorFilter(colorFilter);
brush_.SetFilter(filter);
return true;
}
RSPropertyDrawable::DrawablePtr RSClipFrameDrawable::Generate(const RSRenderContent& content)
{
// PLANNING: cache frame rect, and update when frame rect changed
return content.GetRenderProperties().GetClipToFrame() ? std::make_unique<RSClipFrameDrawable>() : nullptr;
}
void RSClipFrameDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.ClipRect(RSPropertiesPainter::Rect2DrawingRect(content.GetRenderProperties().GetFrameRect()),
Drawing::ClipOp::INTERSECT, false);
}
} // namespace OHOS::Rosen

View File

@ -1,125 +0,0 @@
/*
* Copyright (c) 2023 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 "property/rs_property_drawable_utilities.h"
#include "pipeline/rs_render_node.h"
#include "pipeline/rs_single_frame_composer.h"
#include "property/rs_properties.h"
#include "property/rs_properties_painter.h"
namespace OHOS::Rosen {
// ============================================================================
// alias (reference or soft link) of another drawable
RSAliasDrawable::RSAliasDrawable(RSPropertyDrawableSlot slot) : slot_(slot) {}
void RSAliasDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
content.DrawPropertyDrawable(slot_, canvas);
}
// ============================================================================
// Save and Restore
RSSaveDrawable::RSSaveDrawable(std::shared_ptr<int> content) : content_(std::move(content)) {}
void RSSaveDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
*content_ = canvas.Save();
}
RSRestoreDrawable::RSRestoreDrawable(std::shared_ptr<int> content) : content_(std::move(content)) {}
void RSRestoreDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.RestoreToCount(*content_);
}
RSCustomSaveDrawable::RSCustomSaveDrawable(
std::shared_ptr<RSPaintFilterCanvas::SaveStatus> content, RSPaintFilterCanvas::SaveType type)
: content_(std::move(content)), type_(type)
{}
void RSCustomSaveDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
*content_ = canvas.SaveAllStatus(type_);
}
RSCustomRestoreDrawable::RSCustomRestoreDrawable(std::shared_ptr<RSPaintFilterCanvas::SaveStatus> content)
: content_(std::move(content))
{}
void RSCustomRestoreDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.RestoreStatus(*content_);
}
// ============================================================================
// Adapter for RSRenderModifier
RSModifierDrawable::RSModifierDrawable(RSModifierType type) : type_(type) {}
void RSModifierDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
// single-frame-compose needs to access render node & mutable draw cmd list during the render process
// PLANNING: this is a temporarily workaround, should refactor later
auto nodePtr = content.GetRenderProperties().backref_.lock();
if (nodePtr == nullptr) {
return;
}
auto& drawCmdModifiers = const_cast<RSRenderContent::DrawCmdContainer&>(content.drawCmdModifiers_);
auto itr = drawCmdModifiers.find(type_);
if (itr == drawCmdModifiers.end() || itr->second.empty()) {
return;
}
// temporary fix, will refactor RSRenderModifier::Apply to workaround this issue
RSModifierContext context = { const_cast<RSRenderContent&>(content).renderProperties_, &canvas };
if (RSSystemProperties::GetSingleFrameComposerEnabled()) {
bool needSkip = false;
if (nodePtr->GetNodeIsSingleFrameComposer() && nodePtr->singleFrameComposer_ != nullptr) {
needSkip = nodePtr->singleFrameComposer_->SingleFrameModifierAddToList(type_, itr->second);
}
for (const auto& modifier : itr->second) {
if (nodePtr->singleFrameComposer_ != nullptr &&
nodePtr->singleFrameComposer_->SingleFrameIsNeedSkip(needSkip, modifier)) {
continue;
}
modifier->Apply(context);
}
} else {
for (const auto& modifier : itr->second) {
modifier->Apply(context);
}
}
}
// ============================================================================
// Alpha
RSAlphaDrawable::RSAlphaDrawable(float alpha) : RSPropertyDrawable(), alpha_(alpha) {}
void RSAlphaDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
canvas.MultiplyAlpha(alpha_);
}
RSPropertyDrawable::DrawablePtr RSAlphaDrawable::Generate(const RSRenderContent& content)
{
auto alpha = content.GetRenderProperties().GetAlpha();
if (alpha == 1) {
return nullptr;
}
return content.GetRenderProperties().GetAlphaOffscreen() ? std::make_unique<RSAlphaOffscreenDrawable>(alpha)
: std::make_unique<RSAlphaDrawable>(alpha);
}
RSAlphaOffscreenDrawable::RSAlphaOffscreenDrawable(float alpha) : RSAlphaDrawable(alpha) {}
void RSAlphaOffscreenDrawable::Draw(const RSRenderContent& content, RSPaintFilterCanvas& canvas) const
{
auto rect = RSPropertiesPainter::Rect2DrawingRect(content.GetRenderProperties().GetBoundsRect());
Drawing::Brush brush;
brush.SetAlpha(std::clamp(alpha_, 0.f, 1.f) * UINT8_MAX);
Drawing::SaveLayerOps slr(&rect, &brush);
canvas.SaveLayer(slr);
}
} // namespace OHOS::Rosen