1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H
17 #define RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H
18 
19 #include <bitset>
20 #include <cstdint>
21 #include <functional>
22 #include <memory>
23 #include <unordered_set>
24 
25 #include "recording/recording_canvas.h"
26 
27 #include "modifier/rs_modifier_type.h"
28 
29 namespace OHOS::Rosen {
30 class RSRenderNode;
31 class RSRenderContent;
32 
33 // NOTE: MUST update DrawableGeneratorLut in rs_drawable_content.cpp when new slots are added
34 enum class RSDrawableSlot : int8_t {
35     INVALID = -1,
36     SAVE_ALL = 0,
37 
38     // Bounds Geometry
39     MASK,
40     TRANSITION,
41     ENV_FOREGROUND_COLOR,
42     SHADOW,
43     FOREGROUND_FILTER,
44     OUTLINE,
45 
46     // BG properties in Bounds Clip
47     BG_SAVE_BOUNDS,
48     CLIP_TO_BOUNDS,
49     BLENDER,
50     BACKGROUND_COLOR,
51     BACKGROUND_SHADER,
52     BACKGROUND_IMAGE,
53     BACKGROUND_FILTER,
54     USE_EFFECT,
55     BACKGROUND_STYLE,
56     DYNAMIC_LIGHT_UP,
57     ENV_FOREGROUND_COLOR_STRATEGY,
58     BG_RESTORE_BOUNDS,
59 
60     // Frame Geometry
61     SAVE_FRAME,
62     FRAME_OFFSET,
63     CLIP_TO_FRAME,
64     CUSTOM_CLIP_TO_FRAME,
65     CONTENT_STYLE,
66     CHILDREN,
67     FOREGROUND_STYLE,
68     RESTORE_FRAME,
69 
70     // FG properties in Bounds clip
71     FG_SAVE_BOUNDS,
72     FG_CLIP_TO_BOUNDS,
73     BINARIZATION,
74     COLOR_FILTER,
75     LIGHT_UP_EFFECT,
76     DYNAMIC_DIM,
77     COMPOSITING_FILTER,
78     FOREGROUND_COLOR,
79     FG_RESTORE_BOUNDS,
80 
81     // No clip (unless ClipToBounds is set)
82     POINT_LIGHT,
83     BORDER,
84     OVERLAY,
85     PARTICLE_EFFECT,
86     PIXEL_STRETCH,
87 
88     // Restore state
89     RESTORE_BLENDER,
90     RESTORE_FOREGROUND_FILTER,
91     RESTORE_ALL,
92 
93     // Annotations: Please remember to update this when new slots are added.
94     // properties before Background, not clipped
95     TRANSITION_PROPERTIES_BEGIN = SHADOW,
96     TRANSITION_PROPERTIES_END   = OUTLINE,
97     // background properties, clipped by bounds by default
98     BG_PROPERTIES_BEGIN         = BLENDER,
99     BG_PROPERTIES_END           = ENV_FOREGROUND_COLOR_STRATEGY,
100     // content properties, can be clipped by ClipToFrame and ClipToBounds
101     CONTENT_BEGIN               = FRAME_OFFSET,
102     CONTENT_END                 = FOREGROUND_STYLE,
103     // foreground properties, clipped by bounds by default
104     FG_PROPERTIES_BEGIN         = BINARIZATION,
105     FG_PROPERTIES_END           = FOREGROUND_COLOR,
106     // post-foreground properties, can be clipped by ClipToBounds
107     EXTRA_PROPERTIES_BEGIN      = POINT_LIGHT,
108     EXTRA_PROPERTIES_END        = PIXEL_STRETCH,
109 
110     MAX = RESTORE_ALL + 1,
111 };
112 
113 // pure virtual base class
114 class RSDrawable : public std::enable_shared_from_this<RSDrawable> {
115 public:
116     RSDrawable() = default;
117     virtual ~RSDrawable() = default;
118 
119     // Not copyable and moveable
120     RSDrawable(const RSDrawable&) = delete;
121     RSDrawable(const RSDrawable&&) = delete;
122     RSDrawable& operator=(const RSDrawable&) = delete;
123     RSDrawable& operator=(const RSDrawable&&) = delete;
124 
125     // Type definitions
126     using Ptr = std::shared_ptr<RSDrawable>;
127     using Vec = std::array<Ptr, static_cast<size_t>(RSDrawableSlot::MAX)>;
128     using Generator = std::function<Ptr(const RSRenderNode&)>;
129 
130     // UI methods: OnUpdate and OnGenerate (static method defined in every subclass) can only access the UI (staging)
131     // members, else may cause crash.
132     // OnUpdate and OnGenerate will be invoked if related property has changed, if false is returned, the drawable will
133     // be erased.
OnUpdate(const RSRenderNode & content)134     virtual bool OnUpdate(const RSRenderNode& content)
135     {
136         return true;
137     }
138 
139     // Render helper methods: This func is called in UI thread, but the generated DrawFunc will be called in RT thread,
140     // they can only access the RT members, else may cause crash
141     virtual Drawing::RecordingCanvas::DrawFunc CreateDrawFunc() const = 0;
142 
143     // Sync methods, then can access all members and do UI->RT sync
144     virtual void OnSync() = 0;
145 
OnPurge()146     virtual void OnPurge() {};
147 
148     // static generate & update helper methods
149     // Step 1, calculate dirtySlots based on dirty modifiers
150     static std::unordered_set<RSDrawableSlot> CalculateDirtySlots(
151         const ModifierDirtyTypes& dirtyTypes, const Vec& drawableVec);
152     // Step 2, for every dirtySlot, update or generate RSDrawable
153     static bool UpdateDirtySlots(
154         const RSRenderNode& node, Vec& drawableVec, std::unordered_set<RSDrawableSlot>& dirtySlots);
155     // Step 2-1 (optional), fuze some drawables
156     static bool FuzeDrawableSlots(const RSRenderNode& node, Vec& drawableVec);
157     // Step 3, insert necessary Clip/Save/Restore into drawableVec
158     static void UpdateSaveRestore(RSRenderNode& node, Vec& drawableVec, uint8_t& drawableVecStatus);
159 };
160 } // namespace OHOS::Rosen
161 #endif // RENDER_SERVICE_BASE_DRAWABLE_RS_DRAWABLE_H
162