• 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     TYPE_AMOUNT
48 };
49 
50 class RSB_EXPORT RSDirtyRegionManager final {
51     friend class RSFilterCacheManager;
52 public:
53     static constexpr int32_t ALIGNED_BITS = 32;
54     RSDirtyRegionManager();
55     RSDirtyRegionManager(bool isDisplayDirtyManager);
56     ~RSDirtyRegionManager() = default;
57     // update/expand current frame dirtyregion
58     void MergeDirtyRect(const RectI& rect);
59     // update/expand dirtyregion after merge history
60     void MergeDirtyRectAfterMergeHistory(const RectI& rect);
61     // clip dirtyregion in current frame
62     void IntersectDirtyRect(const RectI& rect);
63     // Clip currentframe dirtyRegion intersected with surfaceRect
64     void ClipDirtyRectWithinSurface();
65     // clear allinfo except dirtyregion history
66     void Clear();
67 
68     // update current frame's visited dirtyregion
69     void UpdateVisitedDirtyRects(const std::vector<RectI>& rects);
70     RectI GetIntersectedVisitedDirtyRect(const RectI& absRect) const;
71     void UpdateCacheableFilterRect(const RectI& rect);
72     bool IfCacheableFilterRectFullyCover(const RectI& targetRect);
IsCacheableFilterRectEmpty()73     bool IsCacheableFilterRectEmpty() const
74     {
75         return cacheableFilterRects_.empty();
76     }
77 
InvalidateFilterCacheRect()78     void InvalidateFilterCacheRect()
79     {
80         isFilterCacheRectValid_ = false;
81     }
82 
IsFilterCacheRectValid()83     bool IsFilterCacheRectValid()
84     {
85         return isFilterCacheRectValid_;
86     }
87 
88     // return current frame dirtyregion, can be changed in prepare and process (displaynode) stage
89     const RectI& GetCurrentFrameDirtyRegion();
90     // return merged historical region
91     const RectI& GetDirtyRegion() const;
92     /*  return merged historical region upside down in left-bottom origin coordinate
93         reason: when use OpenGL SetDamageRegion, coordinate system conversion exists.
94     */
95     RectI GetDirtyRegionFlipWithinSurface() const;
96     // return current frame's region from dirtyregion history
97     const RectI& GetLatestDirtyRegion() const;
98     // return merged historical region upside down in left-bottom origin coordinate
99     RectI GetRectFlipWithinSurface(const RectI& rect) const;
100     // get aligned rect as times of alignedBits
101     static RectI GetPixelAlignedRect(const RectI& rect, int32_t alignedBits = ALIGNED_BITS);
102     // return true if current frame dirtyregion is not empty
103     bool IsCurrentFrameDirty() const;
104     // return true if dirtyregion after merge history is not empty
105     bool IsDirty() const;
106     // push currentframe dirtyregion into history, and merge history according to bufferage
107     void UpdateDirty(bool enableAligned = false);
108     // align current frame dirtyregion before merge history
109     void UpdateDirtyByAligned(int32_t alignedBits = ALIGNED_BITS);
110     bool SetBufferAge(const int age);
111     bool SetSurfaceSize(const int32_t width, const int32_t height);
GetSurfaceRect()112     RectI GetSurfaceRect() const
113     {
114         return surfaceRect_;
115     }
116     void MergeSurfaceRect();
117     // Reset current frame dirtyregion to surfacerect to realize full refreshing
118     void ResetDirtyAsSurfaceSize();
119 
120     void UpdateDebugRegionTypeEnable(DirtyRegionDebugType dirtyDebugType);
121 
IsDebugRegionTypeEnable(DebugRegionType var)122     inline bool IsDebugRegionTypeEnable(DebugRegionType var) const
123     {
124         if (var < DebugRegionType::TYPE_MAX) {
125             return debugRegionEnabled_[var];
126         }
127         return false;
128     }
129 
130     // added for dirty region dfx
131     void UpdateDirtyRegionInfoForDfx(NodeId id, RSRenderNodeType nodeType = RSRenderNodeType::CANVAS_NODE,
132         DirtyRegionType dirtyType = DirtyRegionType::UPDATE_DIRTY_REGION, const RectI& rect = RectI());
133     void GetDirtyRegionInfo(std::map<NodeId, RectI>& target,
134         RSRenderNodeType nodeType = RSRenderNodeType::CANVAS_NODE,
135         DirtyRegionType dirtyType = DirtyRegionType::UPDATE_DIRTY_REGION) const;
136 
MarkAsTargetForDfx()137     void MarkAsTargetForDfx()
138     {
139         isDfxTarget_ = true;
140     }
141 
IsTargetForDfx()142     bool IsTargetForDfx() {
143         return isDfxTarget_;
144     }
145 
146     bool HasOffset();
147     void SetOffset(int offsetX, int offsetY);
148     RectI GetOffsetedDirtyRegion() const;
149 
GetMergedDirtyRegions()150     const std::vector<RectI>& GetMergedDirtyRegions() const
151     {
152         return mergedDirtyRegions_;
153     }
154 
155 private:
156     RectI MergeHistory(unsigned int age, RectI rect) const;
157     void PushHistory(RectI rect);
158     // get his rect according to index offset
159     RectI GetHistory(unsigned int i) const;
160     void AlignHistory();
161 
162     RectI surfaceRect_;             // dirtyregion clipbounds
163     RectI dirtyRegion_;             // dirtyregion after merge history
164     RectI currentFrameDirtyRegion_; // dirtyRegion in current frame
165     std::vector<RectI> visitedDirtyRegions_ = {};  // visited app's dirtyRegion
166     std::vector<RectI> cacheableFilterRects_ = {};  // node's region if filter cachable
167     std::vector<RectI> mergedDirtyRegions_ = {};
168 
169     // added for dfx
170     std::vector<std::map<NodeId, RectI>> dirtyCanvasNodeInfo_;
171     std::vector<std::map<NodeId, RectI>> dirtySurfaceNodeInfo_;
172     std::vector<bool> debugRegionEnabled_;
173     bool isDfxTarget_ = false;
174     std::vector<RectI> dirtyHistory_;
175     int historyHead_ = -1;
176     unsigned int historySize_ = 0;
177     const unsigned HISTORY_QUEUE_MAX_SIZE = 5;
178     // may add new set function for bufferAge
179     unsigned int bufferAge_ = HISTORY_QUEUE_MAX_SIZE;
180     bool isDirtyRegionAlignedEnable_ = false;
181     bool isFilterCacheRectValid_ = true;
182     bool isDisplayDirtyManager_ = false;
183 
184     // Used for coordinate switch, i.e. dirtyRegion = dirtyRegion + offset.
185     // For example when dirtymanager is used in cachesurface when surfacenode's
186     // shadow and surfacenode are cached in a surface, dirty region's coordinate should start
187     // from shadow's left-top rather than that of displaynode.
188     // Normally, this value should be set to:
189     //      offsetX_ =  - surfacePos.x + shadowWidth
190     //      offsetY_ =  - surfacePos.y + shadowHeight
191     bool hasOffset_ = false;
192     int offsetX_ = 0;
193     int offsetY_ = 0;
194 };
195 } // namespace Rosen
196 } // namespace OHOS
197 
198 #endif // RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_DIRTY_REGION_MANAGER_H
199