mirror of
https://gitee.com/openharmony/graphic_graphic_2d
synced 2024-11-23 07:02:25 +00:00
!40 UpdateDrawableContentVec 接入ApplyModifiers,实现ApplyModifiers中计算matrix并传入RenderParam
Merge pull request !40 from ZhangPeng/DEV-new-drawable-6-v2
This commit is contained in:
commit
5ca4892d9b
@ -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");
|
||||
|
@ -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>;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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>;
|
||||
|
@ -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");
|
||||
|
@ -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>;
|
||||
|
@ -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;
|
||||
|
@ -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>;
|
||||
|
@ -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");
|
||||
|
@ -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>;
|
||||
|
@ -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");
|
||||
|
@ -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>;
|
||||
|
@ -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",
|
||||
|
@ -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
|
@ -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_;
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
@ -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();
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
Loading…
Reference in New Issue
Block a user