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