• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 #ifndef RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_DIRTY_REGION_MANAGER_H
16 #define RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_DIRTY_REGION_MANAGER_H
17 
18 #include <map>
19 #include <vector>
20 
21 #include "common/rs_macros.h"
22 #include "common/rs_rect.h"
23 #include "platform/common/rs_system_properties.h"
24 
25 namespace OHOS {
26 namespace Rosen {
27 // classify dfx debug options
28 enum DebugRegionType {
29     CURRENT_SUB = 0,
30     CURRENT_WHOLE,
31     MULTI_HISTORY,
32     EGL_DAMAGE,
33     TYPE_MAX
34 };
35 
36 // classify types that cause region dirty
37 enum DirtyRegionType {
38     UPDATE_DIRTY_REGION = 0,
39     OVERLAY_RECT,
40     FILTER_RECT,
41     SHADOW_RECT,
42     PREPARE_CLIP_RECT,
43     REMOVE_CHILD_RECT,
44     RENDER_PROPERTIES_RECT,
45     CANVAS_NODE_SKIP_RECT,
46     OUTLINE_RECT,
47     SUBTREE_SKIP_RECT,
48     SUBTREE_SKIP_OUT_OF_PARENT_RECT,
49     TYPE_AMOUNT
50 };
51 
52 class RSB_EXPORT RSDirtyRegionManager final {
53     friend class RSFilterCacheManager;
54 public:
55     static constexpr int32_t ALIGNED_BITS = 32;
56     RSDirtyRegionManager();
57     RSDirtyRegionManager(bool isDisplayDirtyManager);
58     ~RSDirtyRegionManager() = default;
59     // update/expand current frame dirtyregion
60     void MergeDirtyRect(const RectI& rect, bool isDebugRect = false);
61     // update/expand current frame dirtyregion if intersect
62     bool MergeDirtyRectIfIntersect(const RectI& rect);
63     // update/expand dirtyregion after merge history
64     void MergeDirtyRectAfterMergeHistory(const RectI& rect);
65     // clip dirtyregion in current frame
66     void IntersectDirtyRect(const RectI& rect);
67     // Clip currentframe dirtyRegion intersected with surfaceRect
68     void ClipDirtyRectWithinSurface();
69     // clear allinfo except dirtyregion history
70     void Clear();
71     // record hwc region for virtual screen
72     void MergeHwcDirtyRect(const RectI& rect);
73 
74     // update current frame's visited dirtyregion
75     void UpdateVisitedDirtyRects(const std::vector<RectI>& rects);
76     RectI GetIntersectedVisitedDirtyRect(const RectI& absRect) const;
77     void UpdateCacheableFilterRect(const RectI& rect);
78     bool IfCacheableFilterRectFullyCover(const RectI& targetRect);
IsCacheableFilterRectEmpty()79     bool IsCacheableFilterRectEmpty() const
80     {
81         return cacheableFilterRects_.empty();
82     }
83 
InvalidateFilterCacheRect()84     void InvalidateFilterCacheRect()
85     {
86         isFilterCacheRectValid_ = false;
87     }
88 
IsFilterCacheRectValid()89     bool IsFilterCacheRectValid()
90     {
91         return isFilterCacheRectValid_;
92     }
93 
94     // return current frame dirtyregion, can be changed in prepare and process (displaynode) stage
95     const RectI& GetCurrentFrameDirtyRegion();
96     // return merged historical region
97     const RectI& GetDirtyRegion() const;
98     // return mapAbs dirtyRegion
99     const RectI& GetCurrentFrameMpsAbsDirtyRect() const;
100 
GetCurrentFrameAdvancedDirtyRegion()101     std::vector<RectI> GetCurrentFrameAdvancedDirtyRegion() const
102     {
103         return currentFrameAdvancedDirtyRegion_;
104     }
105 
GetAdvancedDirtyRegion()106     std::vector<RectI> GetAdvancedDirtyRegion() const
107     {
108         return advancedDirtyRegion_;
109     }
110 
GetDirtyRegionForQuickReject()111     std::vector<RectI> GetDirtyRegionForQuickReject() const
112     {
113         return dirtyRegionForQuickReject_;
114     }
115 
SetDirtyRegionForQuickReject(std::vector<RectI> region)116     void SetDirtyRegionForQuickReject(std::vector<RectI> region)
117     {
118         dirtyRegionForQuickReject_ = region;
119     }
120 
121     void SetCurrentFrameDirtyRect(const RectI& dirtyRect);
122     /*  return merged historical region upside down in left-bottom origin coordinate
123         reason: when use OpenGL SetDamageRegion, coordinate system conversion exists.
124     */
125     RectI GetDirtyRegionFlipWithinSurface() const;
126     std::vector<RectI> GetAdvancedDirtyRegionFlipWithinSurface() const;
127     // return current frame's region from dirtyregion history
128     const RectI& GetLatestDirtyRegion() const;
129     // return merged historical region upside down in left-bottom origin coordinate
130     RectI GetRectFlipWithinSurface(const RectI& rect) const;
131     // get aligned rect as times of alignedBits
132     static RectI GetPixelAlignedRect(const RectI& rect, int32_t alignedBits = ALIGNED_BITS);
133     // return true if current frame dirtyregion is not empty
134     bool IsCurrentFrameDirty() const;
135     // return true if dirtyregion after merge history is not empty
136     bool IsDirty() const;
137     // push currentframe dirtyregion into history, and merge history according to bufferage
138     void UpdateDirty(bool enableAligned = false);
139     // align current frame dirtyregion before merge history
140     void UpdateDirtyByAligned(int32_t alignedBits = ALIGNED_BITS);
141     bool SetBufferAge(const int age);
142 
SetActiveSurfaceRect(const RectI & rect)143     void SetActiveSurfaceRect(const RectI& rect)
144     {
145         auto dstRect = surfaceRect_.IntersectRect(rect);
146         lastActiveSurfaceRect_ = activeSurfaceRect_;
147         activeSurfaceRect_ = dstRect;
148     }
149 
IsActiveSurfaceRectChanged()150     bool IsActiveSurfaceRectChanged() const
151     {
152         return lastActiveSurfaceRect_ != activeSurfaceRect_;
153     }
154 
GetLastActiveSurfaceRect()155     const RectI& GetLastActiveSurfaceRect() const
156     {
157         return lastActiveSurfaceRect_;
158     }
159 
GetActiveSurfaceRect()160     const RectI& GetActiveSurfaceRect() const
161     {
162         return activeSurfaceRect_;
163     }
164 
SetSurfaceRect(const RectI & rect)165     bool SetSurfaceRect(const RectI& rect)
166     {
167         if (rect.IsEmpty()) {
168             return false;
169         }
170         surfaceRect_ = rect;
171         return true;
172     }
173 
SetSurfaceSize(const int32_t width,const int32_t height)174     bool SetSurfaceSize(const int32_t width, const int32_t height)
175     {
176         return SetSurfaceRect(RectI(0, 0, width, height));
177     }
178 
GetSurfaceRect()179     RectI GetSurfaceRect() const
180     {
181         return surfaceRect_;
182     }
183     void MergeSurfaceRect();
184     // Reset current frame dirtyregion to surfacerect to realize full refreshing
185     void ResetDirtyAsSurfaceSize();
186 
187     void UpdateDebugRegionTypeEnable(DirtyRegionDebugType dirtyDebugType);
188 
IsDebugRegionTypeEnable(DebugRegionType var)189     inline bool IsDebugRegionTypeEnable(DebugRegionType var) const
190     {
191         if (var < DebugRegionType::TYPE_MAX) {
192             return debugRegionEnabled_[var];
193         }
194         return false;
195     }
196     // OnSync must be Executed after UpdateDirty API
197     void OnSync(std::shared_ptr<RSDirtyRegionManager> targetManager);
198 
199     // added for dirty region dfx
200     void UpdateDirtyRegionInfoForDfx(NodeId id, RSRenderNodeType nodeType = RSRenderNodeType::CANVAS_NODE,
201         DirtyRegionType dirtyType = DirtyRegionType::UPDATE_DIRTY_REGION, const RectI& rect = RectI());
202     void GetDirtyRegionInfo(std::map<NodeId, RectI>& target,
203         RSRenderNodeType nodeType = RSRenderNodeType::CANVAS_NODE,
204         DirtyRegionType dirtyType = DirtyRegionType::UPDATE_DIRTY_REGION) const;
205 
MarkAsTargetForDfx()206     void MarkAsTargetForDfx()
207     {
208         isDfxTarget_ = true;
209     }
210 
IsTargetForDfx()211     bool IsTargetForDfx() {
212         return isDfxTarget_;
213     }
214 
215     bool HasOffset();
216     void SetOffset(int offsetX, int offsetY);
217     RectI GetOffsetedDirtyRegion() const;
218 
GetMergedDirtyRegions()219     const std::vector<RectI>& GetMergedDirtyRegions() const
220     {
221         return mergedDirtyRegions_;
222     }
223 
MergeDirtyHistoryInVirtual(unsigned int age)224     void MergeDirtyHistoryInVirtual(unsigned int age)
225     {
226         mergedDirtyInVirtualScreen_ = MergeHistory(age, currentFrameDirtyRegion_);
227     }
228 
GetDirtyRegionInVirtual()229     RectI GetDirtyRegionInVirtual() const
230     {
231         return mergedDirtyInVirtualScreen_;
232     }
233 
GetHwcDirtyRegion()234     RectI GetHwcDirtyRegion() const
235     {
236         return hwcDirtyRegion_;
237     }
238 
239     const RectI& GetUifirstFrameDirtyRegion();
240     void SetUifirstFrameDirtyRect(const RectI& dirtyRect);
241 
SetMaxNumOfDirtyRects(int maxNumOfDirtyRects)242     void SetMaxNumOfDirtyRects(int maxNumOfDirtyRects)
243     {
244         maxNumOfDirtyRects_ = maxNumOfDirtyRects;
245     }
246 
SetAdvancedDirtyRegionType(AdvancedDirtyRegionType advancedDirtyRegionType)247     void SetAdvancedDirtyRegionType(AdvancedDirtyRegionType advancedDirtyRegionType)
248     {
249         advancedDirtyRegionType_ = advancedDirtyRegionType;
250     }
251 
252 private:
253     void UpdateMaxNumOfDirtyRectByState();
254     void UpdateCurrentFrameAdvancedDirtyRegion(RectI rect);
255     void MergeAdvancedDirtyHistory(unsigned int age);
256     std::vector<RectI> GetAdvancedDirtyHistory(unsigned int i) const;
257     RectI MergeHistory(unsigned int age, RectI rect) const;
258     void PushHistory(RectI rect);
259     // get his rect according to index offset
260     RectI GetHistory(unsigned int i) const;
261     void AlignHistory();
262 
263     bool isDfxTarget_ = false;
264     bool isDirtyRegionAlignedEnable_ = false;
265     bool isFilterCacheRectValid_ = true;
266     bool isDisplayDirtyManager_ = false;
267     bool hasOffset_ = false;
268     std::atomic<bool> isSync_ = false;
269     int historyHead_ = -1;
270     unsigned int historySize_ = 0;
271     const unsigned HISTORY_QUEUE_MAX_SIZE = 10;
272     int maxNumOfDirtyRects_ = 1;
273     AdvancedDirtyRegionType advancedDirtyRegionType_ = AdvancedDirtyRegionType::DISABLED;
274     // may add new set function for bufferAge
275     unsigned int bufferAge_ = 0;
276     // Used for coordinate switch, i.e. dirtyRegion = dirtyRegion + offset.
277     // For example when dirtymanager is used in cachesurface when surfacenode's
278     // shadow and surfacenode are cached in a surface, dirty region's coordinate should start
279     // from shadow's left-top rather than that of displaynode.
280     // Normally, this value should be set to:
281     //      offsetX_ =  - surfacePos.x + shadowWidth
282     //      offsetY_ =  - surfacePos.y + shadowHeight
283     int offsetX_ = 0;
284     int offsetY_ = 0;
285     RectI lastActiveSurfaceRect_;   // active rect of the canvas surface in the last frame
286     RectI activeSurfaceRect_;       // active rect of the canvas surface
287     RectI surfaceRect_;             // rect of the canvas surface
288     RectI dirtyRegion_;             // dirtyregion after merge history
289     RectI currentFrameDirtyRegion_; // dirtyRegion in current frame
290     RectI uifirstFrameDirtyRegion_; // dirtyRegion in current frame
291     RectI hwcDirtyRegion_;          // hwc dirty region used in virtual screen
292     RectI debugRect_;               // dirtyRegion for showing currentFreshRate debug
293     RectI mergedDirtyInVirtualScreen_;
294     std::vector<RectI> visitedDirtyRegions_ = {};  // visited app's dirtyRegion
295     std::vector<RectI> cacheableFilterRects_ = {};  // node's region if filter cachable
296     std::vector<RectI> mergedDirtyRegions_ = {};
297 
298     std::vector<RectI> advancedDirtyRegion_ = {};
299     std::vector<RectI> currentFrameAdvancedDirtyRegion_ = {};
300     std::vector<RectI> dirtyRegionForQuickReject_ = {};
301     std::vector<std::vector<RectI>> advancedDirtyHistory_ = {};
302 
303     // added for dfx
304     std::vector<std::map<NodeId, RectI>> dirtyCanvasNodeInfo_;
305     std::vector<std::map<NodeId, RectI>> dirtySurfaceNodeInfo_;
306     std::vector<bool> debugRegionEnabled_;
307     std::vector<RectI> dirtyHistory_;
308 };
309 } // namespace Rosen
310 } // namespace OHOS
311 
312 #endif // RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_DIRTY_REGION_MANAGER_H
313