1 /* 2 * Copyright (c) 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 16 #ifndef DRAW_CMD_LIST_H 17 #define DRAW_CMD_LIST_H 18 19 #include "draw/canvas.h" 20 #include "recording/cmd_list.h" 21 22 namespace OHOS { 23 namespace Rosen { 24 namespace Drawing { 25 class DrawOpItem; 26 class DRAWING_API DrawCmdList : public CmdList { 27 public: 28 /** 29 * @brief there are five enable type for Hybrid Render 30 * @param NONE default type, not enable Hybrid Render 31 * @param TEXT text type 32 * @param SVG svg type 33 * @param HMSYMBOL HMSymbol type 34 * @param CANVAS canvasDrawingNode type 35 * @param TYPE_MAX max type 36 * @detail enable type for Hybrid Render 37 */ 38 enum class HybridRenderType : uint32_t { 39 NONE, 40 TEXT, 41 SVG, 42 HMSYMBOL, 43 CANVAS, 44 TYPE_MAX 45 }; 46 47 /** 48 * @brief there are two mode for DrawCmdList to add new op 49 * @param IMMEDIATE add op to continuous buffer immediately, overload will benefit from this 50 * @param DEFERRED add op to vector and then add to contiguous buffer if needed 51 * @detail playback can get all op from continuous buffer in IMMEDIATE mode or vector int DEFERRED mode 52 */ 53 enum class UnmarshalMode { 54 IMMEDIATE, 55 DEFERRED 56 }; 57 58 /** 59 * @brief Creates a DrawCmdList with contiguous buffers. 60 * @param data A contiguous buffers. 61 * @param isCopy Whether to copy data or not. 62 * @detail Called only by Unmarshalling-Thread, the default mode is DEFERRED since all DrawOp store in vector 63 */ 64 static std::shared_ptr<DrawCmdList> CreateFromData(const CmdListData& data, bool isCopy = false); 65 66 /** 67 * @brief Creates a DrawCmdList 68 */ 69 DrawCmdList(UnmarshalMode mode = UnmarshalMode::IMMEDIATE); 70 DrawCmdList(int32_t width, int32_t height, UnmarshalMode mode = UnmarshalMode::IMMEDIATE); 71 72 /** 73 * @brief Destroy a DrawCmdList 74 */ 75 ~DrawCmdList() override; 76 77 /** 78 * @brief Gets cmd list type. 79 * @return Returns DRAW_CMD_LIST 80 */ GetType()81 uint32_t GetType() const override 82 { 83 return Type::DRAW_CMD_LIST; 84 } 85 86 /** 87 * @brief Add DrawOpItem to DrawCmdList, only can be used in IMMEDIATE mode 88 * @param T The name of DrawOpItem class 89 * @param Args Constructs arguments to the DrawOpItem 90 * @return true if add success, false if not in IMMEDIATE mode or create op in contiguous buffer failed 91 */ 92 template<typename T, typename... Args> AddDrawOp(Args &&...args)93 bool AddDrawOp(Args&&... args) 94 { 95 if (mode_ != UnmarshalMode::IMMEDIATE) { 96 return false; 97 } 98 std::lock_guard<std::recursive_mutex> lock(mutex_); 99 T* op = opAllocator_.Allocate<T>(std::forward<Args>(args)...); 100 if (op == nullptr) { 101 return false; 102 } 103 104 uint32_t offset = opAllocator_.AddrToOffset(op); 105 if (lastOpItemOffset_.has_value()) { 106 #ifdef CROSS_PLATFORM 107 auto* lastOpItem = static_cast<OpItem*>( 108 opAllocator_.OffsetToAddr(lastOpItemOffset_.__get(), sizeof(OpItem))); 109 #else 110 auto* lastOpItem = static_cast<OpItem*>( 111 opAllocator_.OffsetToAddr(lastOpItemOffset_.value(), sizeof(OpItem))); 112 #endif 113 if (lastOpItem != nullptr) { 114 lastOpItem->SetNextOpItemOffset(offset); 115 } 116 } 117 lastOpItemOffset_.emplace(offset); 118 opCnt_++; 119 return true; 120 } 121 122 /** 123 * @brief Add DrawOpItem to DrawCmdList, only can be used in DEFERRED mode 124 * @param drawOpItem A real DrawOpItem instance 125 * @return true if add success, false if not in DEFERRED mode 126 */ 127 bool AddDrawOp(std::shared_ptr<DrawOpItem>&& drawOpItem); 128 129 /** 130 * @brief Clear DrawOpItem in contiguous buffer, draw op vector, and other resource associated with draw op 131 */ 132 void ClearOp(); 133 134 /** 135 * @brief Get op vector size 136 */ 137 size_t GetOpItemSize() const; 138 139 /** 140 * @brief for each op in vector, combine there desc together 141 */ 142 std::string GetOpsWithDesc() const; 143 144 /** 145 * @brief Marshalling Draw Ops Param from vector to contiguous buffers. 146 */ 147 void MarshallingDrawOps(); 148 149 /** 150 * @brief Marshalling Draw Ops Param from vector to contiguous buffers. For Profiler Only. 151 */ 152 void ProfilerMarshallingDrawOps(Drawing::DrawCmdList *cmdlist); 153 154 /** 155 * @brief Unmarshalling Draw Ops from contiguous buffers to vector 156 * it is only called by Unmarshalling-Thread, the mode should be set to DEFERRED when create. 157 */ 158 void UnmarshallingDrawOps(uint32_t* opItemCount = nullptr); 159 160 /** 161 * @brief Change typeface ids adding 1 << (30 + 32) - used for profiler replay 162 */ 163 void PatchTypefaceIds(std::shared_ptr<Drawing::DrawCmdList> refDrawCmdList = nullptr); 164 165 /** 166 * @brief Draw cmd is empty or not. 167 */ 168 bool IsEmpty() const; 169 170 /** 171 * @brief Calls the corresponding operations of all opitems in DrawCmdList to the canvas. 172 * @param canvas Implements the playback action of the DrawCmdList in the Canvas. 173 * @param rect Rect used to playback, may be nullptr. 174 */ 175 void Playback(Canvas& canvas, const Rect* rect = nullptr); 176 177 /** 178 * @brief Gets the width of the DrawCmdList. 179 */ 180 int32_t GetWidth() const; 181 182 /** 183 * @brief Gets the height of the DrawCmdList. 184 */ 185 int32_t GetHeight() const; 186 187 /** 188 * @brief Sets the width of the DrawCmdList. 189 */ 190 void SetWidth(int32_t width); 191 192 /** 193 * @brief Sets the height of the DrawCmdList. 194 */ 195 void SetHeight(int32_t height); 196 197 /** 198 * @brief Gets whether DrawCmdList needs to be UICaptured. 199 */ 200 bool GetNoNeedUICaptured() const; 201 202 /** 203 * @brief Sets whether DrawCmdList needs to be UICaptured. 204 */ 205 void SetNoNeedUICaptured(bool noNeedUICaptured); 206 207 /** 208 * @brief Convert Textblob Op to Image Op, it is different for difference mode 209 * IMMEDIATE: the Image Op will add to the end of buffer, and the mapped offset will be recorded in 210 * replacedOpListForBuffer. 211 * DEFERRED: the image Op will replace the Textblob op in vector, and the index-op_ptr will be recorded 212 * in replacedOpListForVector. 213 */ 214 void GenerateCache(Canvas* canvas = nullptr, const Rect* rect = nullptr); 215 216 bool GetIsCache() const; 217 218 void SetIsCache(bool isCached); 219 220 bool GetCachedHighContrast() const; 221 222 void SetCachedHighContrast(bool cachedHighContrast); 223 224 std::vector<std::pair<size_t, size_t>> GetReplacedOpList(); 225 226 void SetReplacedOpList(std::vector<std::pair<size_t, size_t>> replacedOpList); 227 228 DrawCmdList::HybridRenderType GetHybridRenderType() const; 229 230 void SetHybridRenderType(DrawCmdList::HybridRenderType hybridRenderType); 231 232 void UpdateNodeIdToPicture(NodeId nodeId); 233 234 void Dump(std::string& out); 235 236 void Purge(); 237 238 void SetIsNeedUnmarshalOnDestruct(bool isNeedUnmarshalOnDestruct); 239 240 size_t GetSize(); 241 242 void SetCanvasDrawingOpLimitEnable(bool isEnable); 243 244 /** 245 * @brief Gets the pixelmap rect for hybrid render. 246 */ 247 void GetBounds(Rect& rect); 248 SetIsReplayMode(bool mode)249 void SetIsReplayMode(bool mode) 250 { 251 isReplayMode = mode; 252 } 253 254 /** 255 * @brief Check whether enable hybrid render. 256 */ 257 bool IsHybridRenderEnabled(uint32_t maxPixelMapWidth, uint32_t maxPixelMapHeight); 258 259 const std::vector<std::shared_ptr<DrawOpItem>> GetDrawOpItems() const; 260 261 /** 262 * @brief Get cmdlist draw region from opItem. 263 */ 264 RectF GetCmdlistDrawRegion(); 265 266 private: 267 void ClearCache(); 268 void GenerateCacheByVector(Canvas* canvas, const Rect* rect); 269 void GenerateCacheByBuffer(Canvas* canvas, const Rect* rect); 270 271 void PlaybackToDrawCmdList(std::shared_ptr<DrawCmdList> drawCmdList); 272 void PlaybackByVector(Canvas& canvas, const Rect* rect = nullptr); 273 bool UnmarshallingDrawOpsSimple(std::vector<std::shared_ptr<DrawOpItem>>& drawOpItems, size_t& lastOpGenSize); 274 void PlaybackByBuffer(Canvas& canvas, const Rect* rect = nullptr); 275 void CaculatePerformanceOpType(); 276 277 void ProfilerTextBlob(void* handle, uint32_t count, std::shared_ptr<Drawing::DrawCmdList> refDrawCmdList = nullptr); 278 279 int32_t width_; 280 int32_t height_; 281 const UnmarshalMode mode_; 282 const size_t offset_ = 2 * sizeof(int32_t); // 2 is width and height.Offset of first OpItem is behind the w and h 283 std::vector<std::shared_ptr<DrawOpItem>> drawOpItems_; 284 285 size_t lastOpGenSize_ = 0; 286 std::vector<std::pair<size_t, size_t>> replacedOpListForBuffer_; 287 std::vector<std::pair<int, std::shared_ptr<DrawOpItem>>> replacedOpListForVector_; 288 bool isCached_ = false; 289 bool cachedHighContrast_ = false; 290 uint32_t performanceCaculateOpType_ = 0; 291 bool isNeedUnmarshalOnDestruct_ = false; 292 bool noNeedUICaptured_ = false; 293 bool isReplayMode = false; 294 bool isCanvasDrawingOpLimitEnabled_ = false; 295 296 DrawCmdList::HybridRenderType hybridRenderType_ = DrawCmdList::HybridRenderType::NONE; 297 }; 298 299 using DrawCmdListPtr = std::shared_ptr<DrawCmdList>; 300 } // namespace Drawing 301 } // namespace Rosen 302 } // namespace OHOS 303 304 #endif // DRAW_CMD_LIST_H 305