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