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