• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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