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