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