1 /* 2 * Copyright (c) 2025 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 16 #ifndef RS_MODIFIERS_DRAW_H 17 #define RS_MODIFIERS_DRAW_H 18 19 #include <unordered_map> 20 #include <unordered_set> 21 22 #include "command/rs_canvas_node_command.h" 23 #include "command/rs_node_command.h" 24 #include "common/rs_optional_trace.h" 25 #include "platform/ohos/backend/native_buffer_utils.h" 26 #include "pipeline/rs_draw_cmd.h" 27 #include "recording/cmd_list_helper.h" 28 #include "recording/draw_cmd_list.h" 29 #include "recording/draw_cmd.h" 30 #include "surface_buffer.h" 31 #include "transaction/rs_irender_client.h" 32 #include "transaction/rs_transaction_data.h" 33 34 constexpr uint32_t DEFAULT_MODIFIERS_DRAW_THREAD_LOOP_NUM = 3; 35 constexpr uint32_t HYBRID_MAX_PIXELMAP_WIDTH = 8192; // max width value from PhysicalDeviceProperties 36 constexpr uint32_t HYBRID_MAX_PIXELMAP_HEIGHT = 8192; // max height value from PhysicalDeviceProperties 37 constexpr uint32_t HYBRID_MAX_ENABLE_OP_CNT = 11; // max value for enable hybrid op 38 constexpr uint32_t HYBRID_MAX_TEXT_ENABLE_OP_CNT = 1; // max value for enable text hybrid op 39 constexpr int64_t FFRT_WAIT_TIMEOUT = 30; // ms 40 namespace OHOS { 41 namespace Rosen { 42 struct DrawOpInfo { 43 bool isRenderWithForegroundColor = false; 44 NodeId nodeId = INVALID_NODEID; 45 VkSemaphore semaphore = VK_NULL_HANDLE; 46 std::shared_ptr<Drawing::DrawCmdList> cmdList = nullptr; 47 std::shared_ptr<Media::PixelMap> pixelMap = nullptr; 48 }; 49 50 class RSModifiersDraw { 51 public: 52 static void ConvertCmdListForCanvas(const std::shared_ptr<Drawing::DrawCmdList>& cmdList, NodeId nodeId); 53 54 static void ConvertCmdList(DrawOpInfo& targetCmd); 55 56 static void RemoveSurfaceByNodeId(NodeId nodeId, bool postTask = false); 57 58 static bool ResetSurfaceByNodeId( 59 int32_t width, int32_t height, NodeId nodeId, bool needResetOpItems = false, bool postTask = false); 60 61 static std::unique_ptr<Media::PixelMap> GetPixelMapByNodeId(NodeId nodeId, bool useDMA = false); 62 63 static void CreateNextFrameSurface(); 64 65 static void ClearOffTreeNodeMemory(NodeId nodeId); 66 67 static void InsertOffTreeNode(NodeId instanceId, NodeId nodeId); 68 69 static void EraseOffTreeNode(NodeId instanceId, NodeId nodeId); 70 71 static void MergeOffTreeNodeSet(); 72 73 static void AddDrawRegions(NodeId nodeId, std::shared_ptr<RectF> rect); 74 75 static void EraseDrawRegions(NodeId nodeId); 76 77 static bool CheckIfModifiersDrawThreadInited(); 78 79 static void InsertForegroundRoot(NodeId nodeId); 80 81 static void EraseForegroundRoot(NodeId nodeId); 82 83 static bool IsBackground(); 84 85 static void ClearBackGroundMemory(); 86 87 static void DestroySemaphore(); 88 89 static void PurgeContextResource(); 90 91 static void GetFenceAndAddDrawOp(std::vector<DrawOpInfo>& targetCmds); 92 93 static bool SeperateHybridRenderCmdList(std::unique_ptr<RSTransactionData>& transactionData, 94 std::vector<DrawOpInfo>& targetCmds, uint32_t& enableTextHybridOpCnt); 95 96 static void TraverseDrawOpInfo(std::vector<DrawOpInfo>& targetCmds, std::atomic<size_t>& cmdIndex); 97 98 static void ConvertTransactionForCanvas(std::unique_ptr<RSTransactionData>& transactionData); 99 100 static void ConvertTransactionWithFFRT(std::unique_ptr<RSTransactionData>& transactionData, 101 std::shared_ptr<RSIRenderClient>& renderServiceClient, bool& isNeedCommit, std::vector<DrawOpInfo>& targetCmds); 102 103 static void ConvertTransactionWithoutFFRT( 104 std::unique_ptr<RSTransactionData>& transactionData, std::vector<DrawOpInfo>& targetCmds); 105 106 static bool IsTargetCommand( 107 Drawing::DrawCmdList::HybridRenderType hybridRenderType, uint16_t type, uint16_t subType, bool cmdListEmpty); 108 private: 109 struct SurfaceEntry { 110 std::shared_ptr<Drawing::Surface> surface = nullptr; 111 std::shared_ptr<Media::PixelMap> pixelMap = nullptr; 112 std::shared_ptr<Drawing::Image> snapshot = nullptr; 113 std::weak_ptr<Media::PixelMap> lastPixelMap; 114 int lastWidth = 0; 115 int lastHeight = 0; 116 sptr<SurfaceBuffer> currentSurfaceBuffer = nullptr; 117 sptr<SurfaceBuffer> preAllocSurfaceBuffer = nullptr; 118 bool isNeedGenSnapshot = false; 119 std::vector<std::shared_ptr<Drawing::DrawOpItem>> preDrawOpItems; 120 uint32_t saveLayerCnt = 0; 121 }; 122 123 static sptr<SurfaceBuffer> DmaMemAlloc( 124 int32_t width, int32_t height, const std::unique_ptr<Media::PixelMap>& pixelMap); 125 126 static sptr<SurfaceBuffer> CreateSurfaceBuffer( 127 const std::unique_ptr<Media::PixelMap>& pixelMap, int32_t width, int32_t height); 128 129 static std::shared_ptr<Drawing::Surface> CreateSurfaceFromGpuContext(sptr<SurfaceBuffer> surfaceBufferTmp); 130 131 static std::shared_ptr<Drawing::Surface> CreateSurfaceFromCpuContext( 132 const std::unique_ptr<Media::PixelMap>& pixelMap); 133 134 static void ClearCanvasDrawingNodeMemory(); 135 136 static void ClearDrawingContextMemory(); 137 138 static std::shared_ptr<Drawing::Surface> CreateSurface(std::unique_ptr<Media::PixelMap>& pixelMap, 139 int32_t width, int32_t height, sptr<SurfaceBuffer> surfaceBufferTmp); 140 141 static bool Playback(const std::shared_ptr<Drawing::Surface>& surface, 142 const std::shared_ptr<Drawing::DrawCmdList>& cmdList, bool isCanvasType, VkSemaphore& semaphore); 143 144 static void FlushSurfaceWithSemaphore(const std::shared_ptr<Drawing::Surface>& surface, 145 VkSemaphore& semaphore); 146 147 static void DrawSnapshot(std::shared_ptr<Drawing::Canvas>& canvas, std::shared_ptr<Drawing::Image>& snapshot); 148 149 static bool CheckAndDrawSnapshot(SurfaceEntry& surfaceEntry, 150 const std::shared_ptr<Drawing::DrawCmdList>& cmdList, NodeId nodeId); 151 152 static void AddPixelMapDrawOp(const std::shared_ptr<Drawing::DrawCmdList>& cmdList, 153 const std::shared_ptr<Media::PixelMap>& pixelMap, int32_t width, int32_t height, 154 bool isRenderWithForegroundColor, sptr<SyncFence> fence = SyncFence::INVALID_FENCE); 155 156 static std::unique_ptr<Media::PixelMap> CreatePixelMap(int32_t width, int32_t height, bool useDMA = true); 157 158 static SurfaceEntry GetSurfaceEntryByNodeId(NodeId nodeId); 159 160 static bool CheckNodeIsOffTree(NodeId nodeId); 161 162 static void UpdateSize(const std::shared_ptr<Drawing::DrawCmdList>& cmdList, int32_t& width, int32_t& height); 163 164 static void ConvertDrawOpItems(const std::vector<std::shared_ptr<Drawing::DrawOpItem>>& drawOpItems, 165 std::vector<std::shared_ptr<Drawing::DrawOpItem>>& dstOpItems, uint32_t& saveLayerCnt); 166 167 static std::unordered_map<NodeId, SurfaceEntry> surfaceEntryMap_; 168 169 static std::mutex surfaceEntryMutex_; 170 171 static std::unordered_set<NodeId> dirtyNodes_; 172 173 static std::mutex dirtyNodeMutex_; 174 175 static std::unordered_map<NodeId, std::unordered_set<NodeId>> offTreeNodes_; 176 177 static bool offTreeNodesChange_; 178 179 static std::unordered_set<NodeId> allOffTreeNodes_; 180 181 static std::mutex nodeStatusMutex_; 182 183 static std::unordered_set<NodeId> foregroundRootSet_; 184 185 static std::mutex foregroundRootSetMutex_; 186 187 static std::mutex semaphoreInfoMutex_; 188 static std::vector<DestroySemaphoreInfo*> semaphoreInfoVec_; 189 190 static std::unordered_map<NodeId, std::shared_ptr<RectF>> drawRegions_; 191 192 static std::unordered_set<uint32_t> typesToSave_; 193 194 // attention : ffrtMutex_ only use for cv_ 195 static std::mutex ffrtMutex_; 196 static std::condition_variable cv_; 197 static std::atomic<uint32_t> ffrtTaskNum_; 198 }; 199 } // namespace Rosen 200 } // namespace OHOS 201 #endif // RS_MODIFIERS_DRAW_H 202