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