• 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 #include "recording/draw_cmd.h"
17 
18 #include <cstdint>
19 #include <sstream>
20 
21 #include "recording/cmd_list_helper.h"
22 #include "recording/draw_cmd_list.h"
23 #include "recording/mem_allocator.h"
24 #include "recording/op_item.h"
25 
26 #include "draw/brush.h"
27 #include "draw/color.h"
28 #include "draw/path.h"
29 #include "draw/surface.h"
30 #include "effect/color_filter.h"
31 #include "effect/color_space.h"
32 #include "effect/image_filter.h"
33 #include "effect/mask_filter.h"
34 #include "effect/path_effect.h"
35 #include "effect/shader_effect.h"
36 #include "utils/log.h"
37 #include "utils/scalar.h"
38 #include "utils/system_properties.h"
39 #include "sandbox_utils.h"
40 
41 namespace OHOS {
42 namespace Rosen {
43 namespace Drawing {
44 std::unordered_map<uint32_t, std::string> typeOpDes = {
45     { DrawOpItem::OPITEM_HEAD,              "OPITEM_HEAD"},
46     { DrawOpItem::POINT_OPITEM,             "POINT_OPITEM" },
47     { DrawOpItem::POINTS_OPITEM,            "POINTS_OPITEM" },
48     { DrawOpItem::LINE_OPITEM,              "LINE_OPITEM" },
49     { DrawOpItem::RECT_OPITEM,              "RECT_OPITEM" },
50     { DrawOpItem::ROUND_RECT_OPITEM,        "ROUND_RECT_OPITEM" },
51     { DrawOpItem::NESTED_ROUND_RECT_OPITEM, "NESTED_ROUND_RECT_OPITEM" },
52     { DrawOpItem::ARC_OPITEM,               "ARC_OPITEM" },
53     { DrawOpItem::PIE_OPITEM,               "PIE_OPITEM" },
54     { DrawOpItem::OVAL_OPITEM,              "OVAL_OPITEM" },
55     { DrawOpItem::CIRCLE_OPITEM,            "CIRCLE_OPITEM" },
56     { DrawOpItem::PATH_OPITEM,              "PATH_OPITEM" },
57     { DrawOpItem::BACKGROUND_OPITEM,        "BACKGROUND_OPITEM" },
58     { DrawOpItem::SHADOW_OPITEM,            "SHADOW_OPITEM" },
59     { DrawOpItem::SHADOW_STYLE_OPITEM,      "SHADOW_STYLE_OPITEM" },
60     { DrawOpItem::COLOR_OPITEM,             "COLOR_OPITEM" },
61     { DrawOpItem::IMAGE_NINE_OPITEM,        "IMAGE_NINE_OPITEM" },
62     { DrawOpItem::IMAGE_LATTICE_OPITEM,     "IMAGE_LATTICE_OPITEM" },
63     { DrawOpItem::ATLAS_OPITEM,             "ATLAS_OPITEM" },
64     { DrawOpItem::BITMAP_OPITEM,            "BITMAP_OPITEM" },
65     { DrawOpItem::IMAGE_OPITEM,             "IMAGE_OPITEM" },
66     { DrawOpItem::IMAGE_RECT_OPITEM,        "IMAGE_RECT_OPITEM" },
67     { DrawOpItem::PICTURE_OPITEM,           "PICTURE_OPITEM" },
68     { DrawOpItem::TEXT_BLOB_OPITEM,         "TEXT_BLOB_OPITEM" },
69     { DrawOpItem::SYMBOL_OPITEM,            "SYMBOL_OPITEM" },
70     { DrawOpItem::CLIP_RECT_OPITEM,         "CLIP_RECT_OPITEM" },
71     { DrawOpItem::CLIP_IRECT_OPITEM,        "CLIP_IRECT_OPITEM" },
72     { DrawOpItem::CLIP_ROUND_RECT_OPITEM,   "CLIP_ROUND_RECT_OPITEM" },
73     { DrawOpItem::CLIP_PATH_OPITEM,         "CLIP_PATH_OPITEM" },
74     { DrawOpItem::CLIP_REGION_OPITEM,       "CLIP_REGION_OPITEM" },
75     { DrawOpItem::SET_MATRIX_OPITEM,        "SET_MATRIX_OPITEM" },
76     { DrawOpItem::RESET_MATRIX_OPITEM,      "RESET_MATRIX_OPITEM" },
77     { DrawOpItem::CONCAT_MATRIX_OPITEM,     "CONCAT_MATRIX_OPITEM" },
78     { DrawOpItem::TRANSLATE_OPITEM,         "TRANSLATE_OPITEM" },
79     { DrawOpItem::SCALE_OPITEM,             "SCALE_OPITEM" },
80     { DrawOpItem::ROTATE_OPITEM,            "ROTATE_OPITEM" },
81     { DrawOpItem::SHEAR_OPITEM,             "SHEAR_OPITEM" },
82     { DrawOpItem::FLUSH_OPITEM,             "FLUSH_OPITEM" },
83     { DrawOpItem::CLEAR_OPITEM,             "CLEAR_OPITEM" },
84     { DrawOpItem::SAVE_OPITEM,              "SAVE_OPITEM" },
85     { DrawOpItem::SAVE_LAYER_OPITEM,        "SAVE_LAYER_OPITEM" },
86     { DrawOpItem::RESTORE_OPITEM,           "RESTORE_OPITEM" },
87     { DrawOpItem::DISCARD_OPITEM,           "DISCARD_OPITEM" },
88     { DrawOpItem::CLIP_ADAPTIVE_ROUND_RECT_OPITEM,  "CLIP_ADAPTIVE_ROUND_RECT_OPITEM" },
89     { DrawOpItem::IMAGE_WITH_PARM_OPITEM,   "IMAGE_WITH_PARM_OPITEM" },
90     { DrawOpItem::PIXELMAP_WITH_PARM_OPITEM, "PIXELMAP_WITH_PARM_OPITEM" },
91     { DrawOpItem::PIXELMAP_RECT_OPITEM,     "PIXELMAP_RECT_OPITEM" },
92     { DrawOpItem::PIXELMAP_NINE_OPITEM,     "PIXELMAP_NINE_OPITEM" },
93     { DrawOpItem::PIXELMAP_LATTICE_OPITEM,  "PIXELMAP_LATTICE_OPITEM" },
94     { DrawOpItem::REGION_OPITEM,            "REGION_OPITEM" },
95     { DrawOpItem::PATCH_OPITEM,             "PATCH_OPITEM" },
96     { DrawOpItem::EDGEAAQUAD_OPITEM,        "EDGEAAQUAD_OPITEM" },
97     { DrawOpItem::VERTICES_OPITEM,          "VERTICES_OPITEM" },
98     { DrawOpItem::IMAGE_SNAPSHOT_OPITEM,    "IMAGE_SNAPSHOT_OPITEM" },
99     { DrawOpItem::SURFACEBUFFER_OPITEM,     "SURFACEBUFFER_OPITEM"},
100     { DrawOpItem::DRAW_FUNC_OPITEM,         "DRAW_FUNC_OPITEM"},
101 };
102 
103 namespace {
104 constexpr int TEXT_BLOB_CACHE_MARGIN = 10;
105 constexpr float HIGH_CONTRAST_OFFSCREEN_THREASHOLD = 0.99f;
106 
107 template<class A, class F>
DumpArray(std::string & out,const A & array,F func)108 void DumpArray(std::string& out, const A& array, F func)
109 {
110     out += "[";
111     auto end = std::end(array);
112     for (auto begin = std::begin(array); begin != end; begin++) {
113         func(out, *begin);
114         out += " ";
115     }
116     if (std::begin(array) != end) {
117         out.pop_back();
118     }
119     out += "]";
120 }
121 }
122 
123 std::function<void (std::shared_ptr<Drawing::Image> image)> DrawOpItem::holdDrawingImagefunc_ = nullptr;
SetBaseCallback(std::function<void (std::shared_ptr<Drawing::Image> image)> holdDrawingImagefunc)124 void DrawOpItem::SetBaseCallback(
125     std::function<void (std::shared_ptr<Drawing::Image> image)> holdDrawingImagefunc)
126 {
127     holdDrawingImagefunc_ = holdDrawingImagefunc;
128 }
129 
130 std::function<std::shared_ptr<Drawing::Typeface>(uint64_t)> DrawOpItem::customTypefaceQueryfunc_ = nullptr;
SetTypefaceQueryCallBack(std::function<std::shared_ptr<Drawing::Typeface> (uint64_t)> customTypefaceQueryfunc)131 void DrawOpItem::SetTypefaceQueryCallBack(
132     std::function<std::shared_ptr<Drawing::Typeface>(uint64_t)> customTypefaceQueryfunc)
133 {
134     customTypefaceQueryfunc_ = customTypefaceQueryfunc;
135 }
136 
BrushHandleToBrush(const BrushHandle & brushHandle,const DrawCmdList & cmdList,Brush & brush)137 void DrawOpItem::BrushHandleToBrush(const BrushHandle& brushHandle, const DrawCmdList& cmdList, Brush& brush)
138 {
139     brush.SetBlendMode(brushHandle.mode);
140     brush.SetAntiAlias(brushHandle.isAntiAlias);
141     brush.SetBlenderEnabled(brushHandle.blenderEnabled);
142 
143     if (brushHandle.colorSpaceHandle.size) {
144         auto colorSpace = CmdListHelper::GetColorSpaceFromCmdList(cmdList, brushHandle.colorSpaceHandle);
145         const Color4f color4f = { brushHandle.color.GetRedF(), brushHandle.color.GetGreenF(),
146                                   brushHandle.color.GetBlueF(), brushHandle.color.GetAlphaF() };
147         brush.SetColor(color4f, colorSpace);
148     } else {
149         brush.SetColor(brushHandle.color);
150     }
151 
152     if (brushHandle.shaderEffectHandle.size) {
153         auto shaderEffect = CmdListHelper::GetShaderEffectFromCmdList(cmdList, brushHandle.shaderEffectHandle);
154         brush.SetShaderEffect(shaderEffect);
155     }
156 
157     if (brushHandle.blenderHandle.size) {
158         auto blender = CmdListHelper::GetBlenderFromCmdList(cmdList, brushHandle.blenderHandle);
159         brush.SetBlender(blender);
160     }
161 
162     Filter filter;
163     bool hasFilter = false;
164     if (brushHandle.colorFilterHandle.size) {
165         auto colorFilter = CmdListHelper::GetColorFilterFromCmdList(cmdList, brushHandle.colorFilterHandle);
166         filter.SetColorFilter(colorFilter);
167         hasFilter = true;
168     }
169     if (brushHandle.imageFilterHandle.size) {
170         auto imageFilter = CmdListHelper::GetImageFilterFromCmdList(cmdList, brushHandle.imageFilterHandle);
171         filter.SetImageFilter(imageFilter);
172         hasFilter = true;
173     }
174     if (brushHandle.maskFilterHandle.size) {
175         auto maskFilter = CmdListHelper::GetMaskFilterFromCmdList(cmdList, brushHandle.maskFilterHandle);
176         filter.SetMaskFilter(maskFilter);
177         hasFilter = true;
178     }
179 
180     if (hasFilter) {
181         filter.SetFilterQuality(brushHandle.filterQuality);
182         brush.SetFilter(filter);
183     }
184 }
185 
BrushToBrushHandle(const Brush & brush,DrawCmdList & cmdList,BrushHandle & brushHandle)186 void DrawOpItem::BrushToBrushHandle(const Brush& brush, DrawCmdList& cmdList, BrushHandle& brushHandle)
187 {
188     const Filter& filter = brush.GetFilter();
189     brushHandle.color = brush.GetColor();
190     brushHandle.mode = brush.GetBlendMode();
191     brushHandle.isAntiAlias = brush.IsAntiAlias();
192     brushHandle.blenderEnabled = brush.GetBlenderEnabled();
193     brushHandle.filterQuality = filter.GetFilterQuality();
194     brushHandle.colorSpaceHandle = CmdListHelper::AddColorSpaceToCmdList(cmdList, brush.GetColorSpace());
195     brushHandle.shaderEffectHandle = CmdListHelper::AddShaderEffectToCmdList(cmdList, brush.GetShaderEffect());
196     brushHandle.colorFilterHandle = CmdListHelper::AddColorFilterToCmdList(cmdList, filter.GetColorFilter());
197     brushHandle.imageFilterHandle = CmdListHelper::AddImageFilterToCmdList(cmdList, filter.GetImageFilter());
198     brushHandle.maskFilterHandle = CmdListHelper::AddMaskFilterToCmdList(cmdList, filter.GetMaskFilter());
199 }
200 
GeneratePaintFromHandle(const PaintHandle & paintHandle,const DrawCmdList & cmdList,Paint & paint)201 void DrawOpItem::GeneratePaintFromHandle(const PaintHandle& paintHandle, const DrawCmdList& cmdList, Paint& paint)
202 {
203     paint.SetBlendMode(paintHandle.mode);
204     paint.SetAntiAlias(paintHandle.isAntiAlias);
205     paint.SetBlenderEnabled(paintHandle.blenderEnabled);
206     paint.SetStyle(paintHandle.style);
207 
208     if (paintHandle.colorSpaceHandle.size) {
209         auto colorSpace = CmdListHelper::GetColorSpaceFromCmdList(cmdList, paintHandle.colorSpaceHandle);
210         const Color4f color4f = { paintHandle.color.GetRedF(), paintHandle.color.GetGreenF(),
211                                   paintHandle.color.GetBlueF(), paintHandle.color.GetAlphaF() };
212         paint.SetColor(color4f, colorSpace);
213     } else {
214         paint.SetColor(paintHandle.color);
215     }
216 
217     if (paintHandle.shaderEffectHandle.size) {
218         auto shaderEffect = CmdListHelper::GetShaderEffectFromCmdList(cmdList, paintHandle.shaderEffectHandle);
219         paint.SetShaderEffect(shaderEffect);
220     }
221 
222     if (paintHandle.blenderHandle.size) {
223         auto blender = CmdListHelper::GetBlenderFromCmdList(cmdList, paintHandle.blenderHandle);
224         paint.SetBlender(blender);
225     }
226 
227     Filter filter;
228     bool hasFilter = false;
229     if (paintHandle.colorFilterHandle.size) {
230         auto colorFilter = CmdListHelper::GetColorFilterFromCmdList(cmdList, paintHandle.colorFilterHandle);
231         filter.SetColorFilter(colorFilter);
232         hasFilter = true;
233     }
234     if (paintHandle.imageFilterHandle.size) {
235         auto imageFilter = CmdListHelper::GetImageFilterFromCmdList(cmdList, paintHandle.imageFilterHandle);
236         filter.SetImageFilter(imageFilter);
237         hasFilter = true;
238     }
239     if (paintHandle.maskFilterHandle.size) {
240         auto maskFilter = CmdListHelper::GetMaskFilterFromCmdList(cmdList, paintHandle.maskFilterHandle);
241         filter.SetMaskFilter(maskFilter);
242         hasFilter = true;
243     }
244 
245     if (hasFilter) {
246         filter.SetFilterQuality(paintHandle.filterQuality);
247         paint.SetFilter(filter);
248     }
249 
250     if (paintHandle.blurDrawLooperHandle.size) {
251         auto blurDrawLooper = CmdListHelper::GetBlurDrawLooperFromCmdList(cmdList,
252             paintHandle.blurDrawLooperHandle);
253         paint.SetLooper(blurDrawLooper);
254     }
255 
256     if (!paint.HasStrokeStyle()) {
257         return;
258     }
259 
260     paint.SetWidth(paintHandle.width);
261     paint.SetMiterLimit(paintHandle.miterLimit);
262     paint.SetCapStyle(paintHandle.capStyle);
263     paint.SetJoinStyle(paintHandle.joinStyle);
264     if (paintHandle.pathEffectHandle.size) {
265         auto pathEffect = CmdListHelper::GetPathEffectFromCmdList(cmdList, paintHandle.pathEffectHandle);
266         paint.SetPathEffect(pathEffect);
267     }
268 }
269 
GenerateHandleFromPaint(CmdList & cmdList,const Paint & paint,PaintHandle & paintHandle)270 void DrawOpItem::GenerateHandleFromPaint(CmdList& cmdList, const Paint& paint, PaintHandle& paintHandle)
271 {
272     paintHandle.isAntiAlias = paint.IsAntiAlias();
273     paintHandle.blenderEnabled = paint.GetBlenderEnabled();
274     paintHandle.style = paint.GetStyle();
275     paintHandle.color = paint.GetColor();
276     paintHandle.mode = paint.GetBlendMode();
277 
278     if (paint.HasFilter()) {
279         const Filter& filter = paint.GetFilter();
280         paintHandle.filterQuality = filter.GetFilterQuality();
281         paintHandle.colorFilterHandle = CmdListHelper::AddColorFilterToCmdList(cmdList, filter.GetColorFilter());
282         paintHandle.imageFilterHandle = CmdListHelper::AddImageFilterToCmdList(cmdList, filter.GetImageFilter());
283         paintHandle.maskFilterHandle = CmdListHelper::AddMaskFilterToCmdList(cmdList, filter.GetMaskFilter());
284     }
285 
286     if (paint.GetColorSpace()) {
287         paintHandle.colorSpaceHandle = CmdListHelper::AddColorSpaceToCmdList(cmdList, paint.GetColorSpace());
288     }
289 
290     if (paint.GetShaderEffect()) {
291         paintHandle.shaderEffectHandle = CmdListHelper::AddShaderEffectToCmdList(cmdList, paint.GetShaderEffect());
292     }
293 
294     if (paint.GetBlender()) {
295         paintHandle.blenderHandle = CmdListHelper::AddBlenderToCmdList(cmdList, paint.GetBlender());
296     }
297 
298     if (paint.GetLooper()) {
299         paintHandle.blurDrawLooperHandle = CmdListHelper::AddBlurDrawLooperToCmdList(cmdList,
300             paint.GetLooper());
301     }
302 
303     if (!paint.HasStrokeStyle()) {
304         return;
305     }
306 
307     paintHandle.width = paint.GetWidth();
308     paintHandle.miterLimit = paint.GetMiterLimit();
309     paintHandle.capStyle = paint.GetCapStyle();
310     paintHandle.joinStyle = paint.GetJoinStyle();
311     if (paint.GetPathEffect()) {
312         paintHandle.pathEffectHandle = CmdListHelper::AddPathEffectToCmdList(cmdList, paint.GetPathEffect());
313     }
314 }
315 
GetOpDesc() const316 std::string DrawOpItem::GetOpDesc() const
317 {
318     return typeOpDes[GetType()];
319 }
320 
Dump(std::string & out) const321 void DrawOpItem::Dump(std::string& out) const
322 {
323     out += typeOpDes[GetType()];
324 }
325 
GetOpSize()326 size_t DrawOpItem::GetOpSize()
327 {
328     size_t totoalSize = sizeof(*this);
329     const auto unmarshallingPair = UnmarshallingHelper::Instance().GetFuncAndSize(GetType());
330     totoalSize += unmarshallingPair.second;
331     return totoalSize;
332 }
333 
GenerateCachedOpItemPlayer(DrawCmdList & cmdList,Canvas * canvas,const Rect * rect)334 GenerateCachedOpItemPlayer::GenerateCachedOpItemPlayer(DrawCmdList &cmdList, Canvas* canvas, const Rect* rect)
335     : canvas_(canvas), rect_(rect), cmdList_(cmdList) {}
336 
GenerateCachedOpItem(uint32_t type,void * handle,size_t avaliableSize)337 bool GenerateCachedOpItemPlayer::GenerateCachedOpItem(uint32_t type, void* handle, size_t avaliableSize)
338 {
339     if (handle == nullptr) {
340         return false;
341     }
342 
343     if (type == DrawOpItem::TEXT_BLOB_OPITEM && avaliableSize >= sizeof(DrawTextBlobOpItem::ConstructorHandle)) {
344         auto* op = static_cast<DrawTextBlobOpItem::ConstructorHandle*>(handle);
345         return op->GenerateCachedOpItem(cmdList_, canvas_);
346     }
347     return false;
348 }
349 
350 /* UnmarshallingPlayer */
Instance()351 UnmarshallingHelper& UnmarshallingHelper::Instance()
352 {
353     static UnmarshallingHelper instance;
354     return instance;
355 }
356 
Register(uint32_t type,UnmarshallingHelper::UnmarshallingFunc func,size_t unmarshallingSize)357 bool UnmarshallingHelper::Register(uint32_t type, UnmarshallingHelper::UnmarshallingFunc func, size_t unmarshallingSize)
358 {
359     std::unique_lock lck(mtx_);
360     opUnmarshallingFuncLUT_.emplace(type, func);
361     opUnmarshallingSize_.emplace(type, unmarshallingSize);
362     return true;
363 }
364 
GetFuncAndSize(uint32_t type)365 std::pair<UnmarshallingHelper::UnmarshallingFunc, size_t> UnmarshallingHelper::GetFuncAndSize(uint32_t type)
366 {
367     std::shared_lock lck(mtx_);
368     auto funcIt = opUnmarshallingFuncLUT_.find(type);
369     auto sizeIt = opUnmarshallingSize_.find(type);
370     if (funcIt == opUnmarshallingFuncLUT_.end() || sizeIt == opUnmarshallingSize_.end()) {
371         return { nullptr, 0 };
372     }
373     /* unmarshalling func, desirable size for unmarshalling*/
374     return { funcIt->second, sizeIt->second };
375 }
376 
UnmarshallingPlayer(const DrawCmdList & cmdList)377 UnmarshallingPlayer::UnmarshallingPlayer(const DrawCmdList& cmdList) : cmdList_(cmdList) {}
378 
Unmarshalling(uint32_t type,void * handle,size_t avaliableSize)379 std::shared_ptr<DrawOpItem> UnmarshallingPlayer::Unmarshalling(uint32_t type, void* handle, size_t avaliableSize)
380 {
381     if (type == DrawOpItem::OPITEM_HEAD) {
382         return nullptr;
383     }
384 
385     const auto unmarshallingPair = UnmarshallingHelper::Instance().GetFuncAndSize(type);
386     /* if unmarshalling func is null or avaliable size < desirable unmarshalling size, then return nullptr*/
387     if (unmarshallingPair.first == nullptr || unmarshallingPair.second > avaliableSize) {
388         return nullptr;
389     }
390     return (*unmarshallingPair.first)(this->cmdList_, handle);
391 }
392 
393 /* DrawWithPaintOpItem */
DrawWithPaintOpItem(const DrawCmdList & cmdList,const PaintHandle & paintHandle,uint32_t type)394 DrawWithPaintOpItem::DrawWithPaintOpItem(const DrawCmdList& cmdList, const PaintHandle& paintHandle, uint32_t type)
395     : DrawOpItem(type)
396 {
397     GeneratePaintFromHandle(paintHandle, cmdList, paint_);
398 }
399 
Dump(std::string & out) const400 void DrawWithPaintOpItem::Dump(std::string& out) const
401 {
402     DrawOpItem::Dump(out);
403     out += "[paint";
404     paint_.Dump(out);
405     DumpItems(out);
406     out += ']';
407 }
408 
409 /* DrawPointOpItem */
410 UNMARSHALLING_REGISTER(DrawPoint, DrawOpItem::POINT_OPITEM,
411     DrawPointOpItem::Unmarshalling, sizeof(DrawPointOpItem::ConstructorHandle));
412 
DrawPointOpItem(const DrawCmdList & cmdList,DrawPointOpItem::ConstructorHandle * handle)413 DrawPointOpItem::DrawPointOpItem(const DrawCmdList& cmdList, DrawPointOpItem::ConstructorHandle* handle)
414     : DrawWithPaintOpItem(cmdList, handle->paintHandle, POINT_OPITEM), point_(handle->point) {}
415 
Unmarshalling(const DrawCmdList & cmdList,void * handle)416 std::shared_ptr<DrawOpItem> DrawPointOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
417 {
418     return std::make_shared<DrawPointOpItem>(cmdList, static_cast<DrawPointOpItem::ConstructorHandle*>(handle));
419 }
420 
Marshalling(DrawCmdList & cmdList)421 void DrawPointOpItem::Marshalling(DrawCmdList& cmdList)
422 {
423     PaintHandle paintHandle;
424     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
425     cmdList.AddOp<ConstructorHandle>(point_, paintHandle);
426 }
427 
Playback(Canvas * canvas,const Rect * rect)428 void DrawPointOpItem::Playback(Canvas* canvas, const Rect* rect)
429 {
430     canvas->AttachPaint(paint_);
431     canvas->DrawPoint(point_);
432 }
433 
DumpItems(std::string & out) const434 void DrawPointOpItem::DumpItems(std::string& out) const
435 {
436     out += " point";
437     point_.Dump(out);
438 }
439 
440 /* DrawPointsOpItem */
441 UNMARSHALLING_REGISTER(DrawPoints, DrawOpItem::POINTS_OPITEM,
442     DrawPointsOpItem::Unmarshalling, sizeof(DrawPointsOpItem::ConstructorHandle));
443 
DrawPointsOpItem(const DrawCmdList & cmdList,DrawPointsOpItem::ConstructorHandle * handle)444 DrawPointsOpItem::DrawPointsOpItem(const DrawCmdList& cmdList, DrawPointsOpItem::ConstructorHandle* handle)
445     : DrawWithPaintOpItem(cmdList, handle->paintHandle, POINTS_OPITEM), mode_(handle->mode)
446 {
447     pts_ = CmdListHelper::GetVectorFromCmdList<Point>(cmdList, handle->pts);
448 }
449 
Unmarshalling(const DrawCmdList & cmdList,void * handle)450 std::shared_ptr<DrawOpItem> DrawPointsOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
451 {
452     return std::make_shared<DrawPointsOpItem>(cmdList, static_cast<DrawPointsOpItem::ConstructorHandle*>(handle));
453 }
454 
Marshalling(DrawCmdList & cmdList)455 void DrawPointsOpItem::Marshalling(DrawCmdList& cmdList)
456 {
457     PaintHandle paintHandle;
458     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
459     auto pointsData = CmdListHelper::AddVectorToCmdList<Point>(cmdList, pts_);
460     cmdList.AddOp<ConstructorHandle>(mode_, pointsData, paintHandle);
461 }
462 
Playback(Canvas * canvas,const Rect * rect)463 void DrawPointsOpItem::Playback(Canvas* canvas, const Rect* rect)
464 {
465     canvas->AttachPaint(paint_);
466     canvas->DrawPoints(mode_, pts_.size(), pts_.data());
467 }
468 
469 /* DrawLineOpItem */
470 UNMARSHALLING_REGISTER(DrawLine, DrawOpItem::LINE_OPITEM,
471     DrawLineOpItem::Unmarshalling, sizeof(DrawLineOpItem::ConstructorHandle));
472 
DrawLineOpItem(const DrawCmdList & cmdList,DrawLineOpItem::ConstructorHandle * handle)473 DrawLineOpItem::DrawLineOpItem(const DrawCmdList& cmdList, DrawLineOpItem::ConstructorHandle* handle)
474     : DrawWithPaintOpItem(cmdList, handle->paintHandle, LINE_OPITEM),
475       startPt_(handle->startPt), endPt_(handle->endPt) {}
476 
Unmarshalling(const DrawCmdList & cmdList,void * handle)477 std::shared_ptr<DrawOpItem> DrawLineOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
478 {
479     return std::make_shared<DrawLineOpItem>(cmdList, static_cast<DrawLineOpItem::ConstructorHandle*>(handle));
480 }
481 
Marshalling(DrawCmdList & cmdList)482 void DrawLineOpItem::Marshalling(DrawCmdList& cmdList)
483 {
484     PaintHandle paintHandle;
485     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
486     cmdList.AddOp<ConstructorHandle>(startPt_, endPt_, paintHandle);
487 }
488 
Playback(Canvas * canvas,const Rect * rect)489 void DrawLineOpItem::Playback(Canvas* canvas, const Rect* rect)
490 {
491     canvas->AttachPaint(paint_);
492     canvas->DrawLine(startPt_, endPt_);
493 }
494 
DumpItems(std::string & out) const495 void DrawLineOpItem::DumpItems(std::string& out) const
496 {
497     out += " startPt";
498     startPt_.Dump(out);
499     out += " endPt";
500     endPt_.Dump(out);
501 }
502 
503 /* DrawRectOpItem */
504 UNMARSHALLING_REGISTER(DrawRect, DrawOpItem::RECT_OPITEM,
505     DrawRectOpItem::Unmarshalling, sizeof(DrawRectOpItem::ConstructorHandle));
506 
DrawRectOpItem(const DrawCmdList & cmdList,DrawRectOpItem::ConstructorHandle * handle)507 DrawRectOpItem::DrawRectOpItem(const DrawCmdList& cmdList, DrawRectOpItem::ConstructorHandle* handle)
508     : DrawWithPaintOpItem(cmdList, handle->paintHandle, RECT_OPITEM), rect_(handle->rect) {}
509 
Unmarshalling(const DrawCmdList & cmdList,void * handle)510 std::shared_ptr<DrawOpItem> DrawRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
511 {
512     return std::make_shared<DrawRectOpItem>(cmdList, static_cast<DrawRectOpItem::ConstructorHandle*>(handle));
513 }
514 
Marshalling(DrawCmdList & cmdList)515 void DrawRectOpItem::Marshalling(DrawCmdList& cmdList)
516 {
517     PaintHandle paintHandle;
518     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
519     cmdList.AddOp<ConstructorHandle>(rect_, paintHandle);
520 }
521 
Playback(Canvas * canvas,const Rect * rect)522 void DrawRectOpItem::Playback(Canvas* canvas, const Rect* rect)
523 {
524     canvas->AttachPaint(paint_);
525     canvas->DrawRect(rect_);
526 }
527 
DumpItems(std::string & out) const528 void DrawRectOpItem::DumpItems(std::string& out) const
529 {
530     out += " rect";
531     rect_.Dump(out);
532 }
533 
534 /* DrawRoundRectOpItem */
535 UNMARSHALLING_REGISTER(DrawRoundRect, DrawOpItem::ROUND_RECT_OPITEM,
536     DrawRoundRectOpItem::Unmarshalling, sizeof(DrawRoundRectOpItem::ConstructorHandle));
537 
DrawRoundRectOpItem(const DrawCmdList & cmdList,DrawRoundRectOpItem::ConstructorHandle * handle)538 DrawRoundRectOpItem::DrawRoundRectOpItem(const DrawCmdList& cmdList, DrawRoundRectOpItem::ConstructorHandle* handle)
539     : DrawWithPaintOpItem(cmdList, handle->paintHandle, ROUND_RECT_OPITEM), rrect_(handle->rrect) {}
540 
Unmarshalling(const DrawCmdList & cmdList,void * handle)541 std::shared_ptr<DrawOpItem> DrawRoundRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
542 {
543     return std::make_shared<DrawRoundRectOpItem>(cmdList, static_cast<DrawRoundRectOpItem::ConstructorHandle*>(handle));
544 }
545 
Marshalling(DrawCmdList & cmdList)546 void DrawRoundRectOpItem::Marshalling(DrawCmdList& cmdList)
547 {
548     PaintHandle paintHandle;
549     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
550     cmdList.AddOp<ConstructorHandle>(rrect_, paintHandle);
551 }
552 
Playback(Canvas * canvas,const Rect * rect)553 void DrawRoundRectOpItem::Playback(Canvas* canvas, const Rect* rect)
554 {
555     canvas->AttachPaint(paint_);
556     canvas->DrawRoundRect(rrect_);
557 }
558 
DumpItems(std::string & out) const559 void DrawRoundRectOpItem::DumpItems(std::string& out) const
560 {
561     out += " rrect";
562     rrect_.Dump(out);
563 }
564 
565 /* DrawNestedRoundRectOpItem */
566 UNMARSHALLING_REGISTER(DrawNestedRoundRect, DrawOpItem::NESTED_ROUND_RECT_OPITEM,
567     DrawNestedRoundRectOpItem::Unmarshalling, sizeof(DrawNestedRoundRectOpItem::ConstructorHandle));
568 
DrawNestedRoundRectOpItem(const DrawCmdList & cmdList,DrawNestedRoundRectOpItem::ConstructorHandle * handle)569 DrawNestedRoundRectOpItem::DrawNestedRoundRectOpItem(
570     const DrawCmdList& cmdList, DrawNestedRoundRectOpItem::ConstructorHandle* handle)
571     : DrawWithPaintOpItem(cmdList, handle->paintHandle, NESTED_ROUND_RECT_OPITEM),
572       outerRRect_(handle->outerRRect), innerRRect_(handle->innerRRect) {}
573 
Unmarshalling(const DrawCmdList & cmdList,void * handle)574 std::shared_ptr<DrawOpItem> DrawNestedRoundRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
575 {
576     return std::make_shared<DrawNestedRoundRectOpItem>(
577         cmdList, static_cast<DrawNestedRoundRectOpItem::ConstructorHandle*>(handle));
578 }
579 
Marshalling(DrawCmdList & cmdList)580 void DrawNestedRoundRectOpItem::Marshalling(DrawCmdList& cmdList)
581 {
582     PaintHandle paintHandle;
583     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
584     cmdList.AddOp<ConstructorHandle>(outerRRect_, innerRRect_, paintHandle);
585 }
586 
Playback(Canvas * canvas,const Rect * rect)587 void DrawNestedRoundRectOpItem::Playback(Canvas* canvas, const Rect* rect)
588 {
589     canvas->AttachPaint(paint_);
590     canvas->DrawNestedRoundRect(outerRRect_, innerRRect_);
591 }
592 
DumpItems(std::string & out) const593 void DrawNestedRoundRectOpItem::DumpItems(std::string& out) const
594 {
595     out += " outerRRect";
596     outerRRect_.Dump(out);
597     out += " innerRRect";
598     innerRRect_.Dump(out);
599 }
600 
601 /* DrawArcOpItem */
602 UNMARSHALLING_REGISTER(DrawArc, DrawOpItem::ARC_OPITEM,
603     DrawArcOpItem::Unmarshalling, sizeof(DrawArcOpItem::ConstructorHandle));
604 
DrawArcOpItem(const DrawCmdList & cmdList,DrawArcOpItem::ConstructorHandle * handle)605 DrawArcOpItem::DrawArcOpItem(const DrawCmdList& cmdList, DrawArcOpItem::ConstructorHandle* handle)
606     : DrawWithPaintOpItem(cmdList, handle->paintHandle, ARC_OPITEM), rect_(handle->rect),
607       startAngle_(handle->startAngle), sweepAngle_(handle->sweepAngle) {}
608 
Unmarshalling(const DrawCmdList & cmdList,void * handle)609 std::shared_ptr<DrawOpItem> DrawArcOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
610 {
611     return std::make_shared<DrawArcOpItem>(cmdList, static_cast<DrawArcOpItem::ConstructorHandle*>(handle));
612 }
613 
Marshalling(DrawCmdList & cmdList)614 void DrawArcOpItem::Marshalling(DrawCmdList& cmdList)
615 {
616     PaintHandle paintHandle;
617     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
618     cmdList.AddOp<ConstructorHandle>(rect_, startAngle_, sweepAngle_, paintHandle);
619 }
620 
Playback(Canvas * canvas,const Rect * rect)621 void DrawArcOpItem::Playback(Canvas* canvas, const Rect* rect)
622 {
623     canvas->AttachPaint(paint_);
624     canvas->DrawArc(rect_, startAngle_, sweepAngle_);
625 }
626 
DumpItems(std::string & out) const627 void DrawArcOpItem::DumpItems(std::string& out) const
628 {
629     out += " rect";
630     rect_.Dump(out);
631     out += " startAngle:" + std::to_string(startAngle_);
632     out += " sweepAngle:" + std::to_string(sweepAngle_);
633 }
634 
635 /* DrawPieOpItem */
636 UNMARSHALLING_REGISTER(DrawPie, DrawOpItem::PIE_OPITEM,
637     DrawPieOpItem::Unmarshalling, sizeof(DrawPieOpItem::ConstructorHandle));
638 
DrawPieOpItem(const DrawCmdList & cmdList,DrawPieOpItem::ConstructorHandle * handle)639 DrawPieOpItem::DrawPieOpItem(const DrawCmdList& cmdList, DrawPieOpItem::ConstructorHandle* handle)
640     : DrawWithPaintOpItem(cmdList, handle->paintHandle, PIE_OPITEM), rect_(handle->rect),
641       startAngle_(handle->startAngle), sweepAngle_(handle->sweepAngle) {}
642 
Unmarshalling(const DrawCmdList & cmdList,void * handle)643 std::shared_ptr<DrawOpItem> DrawPieOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
644 {
645     return std::make_shared<DrawPieOpItem>(cmdList, static_cast<DrawPieOpItem::ConstructorHandle*>(handle));
646 }
647 
Marshalling(DrawCmdList & cmdList)648 void DrawPieOpItem::Marshalling(DrawCmdList& cmdList)
649 {
650     PaintHandle paintHandle;
651     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
652     cmdList.AddOp<ConstructorHandle>(rect_, startAngle_, sweepAngle_, paintHandle);
653 }
654 
Playback(Canvas * canvas,const Rect * rect)655 void DrawPieOpItem::Playback(Canvas* canvas, const Rect* rect)
656 {
657     canvas->AttachPaint(paint_);
658     canvas->DrawPie(rect_, startAngle_, sweepAngle_);
659 }
660 
DumpItems(std::string & out) const661 void DrawPieOpItem::DumpItems(std::string& out) const
662 {
663     out += " rect";
664     rect_.Dump(out);
665     out += " startAngle:" + std::to_string(startAngle_);
666     out += " sweepAngle:" + std::to_string(sweepAngle_);
667 }
668 
669 /* DrawOvalOpItem */
670 UNMARSHALLING_REGISTER(DrawOval, DrawOpItem::OVAL_OPITEM,
671     DrawOvalOpItem::Unmarshalling, sizeof(DrawOvalOpItem::ConstructorHandle));
672 
DrawOvalOpItem(const DrawCmdList & cmdList,DrawOvalOpItem::ConstructorHandle * handle)673 DrawOvalOpItem::DrawOvalOpItem(const DrawCmdList& cmdList, DrawOvalOpItem::ConstructorHandle* handle)
674     : DrawWithPaintOpItem(cmdList, handle->paintHandle, OVAL_OPITEM), rect_(handle->rect) {}
675 
Unmarshalling(const DrawCmdList & cmdList,void * handle)676 std::shared_ptr<DrawOpItem> DrawOvalOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
677 {
678     return std::make_shared<DrawOvalOpItem>(cmdList, static_cast<DrawOvalOpItem::ConstructorHandle*>(handle));
679 }
680 
Marshalling(DrawCmdList & cmdList)681 void DrawOvalOpItem::Marshalling(DrawCmdList& cmdList)
682 {
683     PaintHandle paintHandle;
684     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
685     cmdList.AddOp<ConstructorHandle>(rect_, paintHandle);
686 }
687 
Playback(Canvas * canvas,const Rect * rect)688 void DrawOvalOpItem::Playback(Canvas* canvas, const Rect* rect)
689 {
690     canvas->AttachPaint(paint_);
691     canvas->DrawOval(rect_);
692 }
693 
DumpItems(std::string & out) const694 void DrawOvalOpItem::DumpItems(std::string& out) const
695 {
696     out += " rect";
697     rect_.Dump(out);
698 }
699 
700 /* DrawCircleOpItem */
701 UNMARSHALLING_REGISTER(DrawCircle, DrawOpItem::CIRCLE_OPITEM,
702     DrawCircleOpItem::Unmarshalling, sizeof(DrawCircleOpItem::ConstructorHandle));
703 
DrawCircleOpItem(const DrawCmdList & cmdList,DrawCircleOpItem::ConstructorHandle * handle)704 DrawCircleOpItem::DrawCircleOpItem(const DrawCmdList& cmdList, DrawCircleOpItem::ConstructorHandle* handle)
705     : DrawWithPaintOpItem(cmdList, handle->paintHandle, CIRCLE_OPITEM),
706       centerPt_(handle->centerPt), radius_(handle->radius) {}
707 
Unmarshalling(const DrawCmdList & cmdList,void * handle)708 std::shared_ptr<DrawOpItem> DrawCircleOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
709 {
710     return std::make_shared<DrawCircleOpItem>(cmdList, static_cast<DrawCircleOpItem::ConstructorHandle*>(handle));
711 }
712 
Marshalling(DrawCmdList & cmdList)713 void DrawCircleOpItem::Marshalling(DrawCmdList& cmdList)
714 {
715     PaintHandle paintHandle;
716     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
717     cmdList.AddOp<ConstructorHandle>(centerPt_, radius_, paintHandle);
718 }
719 
Playback(Canvas * canvas,const Rect * rect)720 void DrawCircleOpItem::Playback(Canvas* canvas, const Rect* rect)
721 {
722     canvas->AttachPaint(paint_);
723     canvas->DrawCircle(centerPt_, radius_);
724 }
725 
DumpItems(std::string & out) const726 void DrawCircleOpItem::DumpItems(std::string& out) const
727 {
728     out += " centerPt";
729     centerPt_.Dump(out);
730     out += " radius:" + std::to_string(radius_);
731 }
732 
733 /* DrawPathOpItem */
734 UNMARSHALLING_REGISTER(DrawPath, DrawOpItem::PATH_OPITEM,
735     DrawPathOpItem::Unmarshalling, sizeof(DrawPathOpItem::ConstructorHandle));
736 
DrawPathOpItem(const DrawCmdList & cmdList,DrawPathOpItem::ConstructorHandle * handle)737 DrawPathOpItem::DrawPathOpItem(const DrawCmdList& cmdList, DrawPathOpItem::ConstructorHandle* handle)
738     : DrawWithPaintOpItem(cmdList, handle->paintHandle, PATH_OPITEM)
739 {
740     path_ = CmdListHelper::GetPathFromCmdList(cmdList, handle->path);
741 }
742 
Unmarshalling(const DrawCmdList & cmdList,void * handle)743 std::shared_ptr<DrawOpItem> DrawPathOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
744 {
745     return std::make_shared<DrawPathOpItem>(cmdList, static_cast<DrawPathOpItem::ConstructorHandle*>(handle));
746 }
747 
Marshalling(DrawCmdList & cmdList)748 void DrawPathOpItem::Marshalling(DrawCmdList& cmdList)
749 {
750     PaintHandle paintHandle;
751     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
752     OpDataHandle pathHandle;
753     if (path_) {
754         pathHandle = CmdListHelper::AddPathToCmdList(cmdList, *path_);
755     }
756     cmdList.AddOp<ConstructorHandle>(pathHandle, paintHandle);
757 }
758 
Playback(Canvas * canvas,const Rect * rect)759 void DrawPathOpItem::Playback(Canvas* canvas, const Rect* rect)
760 {
761     if (path_ == nullptr) {
762         LOGD("DrawPathOpItem path is null!");
763         return;
764     }
765     canvas->AttachPaint(paint_);
766     canvas->DrawPath(*path_);
767 }
768 
DumpItems(std::string & out) const769 void DrawPathOpItem::DumpItems(std::string& out) const
770 {
771     if (path_ != nullptr) {
772         out += " Path";
773         path_->Dump(out);
774     }
775 }
776 
777 /* DrawBackgroundOpItem */
778 UNMARSHALLING_REGISTER(DrawBackground, DrawOpItem::BACKGROUND_OPITEM,
779     DrawBackgroundOpItem::Unmarshalling, sizeof(DrawBackgroundOpItem::ConstructorHandle));
780 
DrawBackgroundOpItem(const DrawCmdList & cmdList,DrawBackgroundOpItem::ConstructorHandle * handle)781 DrawBackgroundOpItem::DrawBackgroundOpItem(const DrawCmdList& cmdList, DrawBackgroundOpItem::ConstructorHandle* handle)
782     : DrawOpItem(BACKGROUND_OPITEM)
783 {
784     BrushHandleToBrush(handle->brushHandle, cmdList, brush_);
785 }
786 
Unmarshalling(const DrawCmdList & cmdList,void * handle)787 std::shared_ptr<DrawOpItem> DrawBackgroundOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
788 {
789     return std::make_shared<DrawBackgroundOpItem>(
790         cmdList, static_cast<DrawBackgroundOpItem::ConstructorHandle*>(handle));
791 }
792 
Marshalling(DrawCmdList & cmdList)793 void DrawBackgroundOpItem::Marshalling(DrawCmdList& cmdList)
794 {
795     BrushHandle brushHandle;
796     BrushToBrushHandle(brush_, cmdList, brushHandle);
797     cmdList.AddOp<ConstructorHandle>(brushHandle);
798 }
799 
Playback(Canvas * canvas,const Rect * rect)800 void DrawBackgroundOpItem::Playback(Canvas* canvas, const Rect* rect)
801 {
802     canvas->DrawBackground(brush_);
803 }
804 
805 /* DrawShadowStyleOpItem */
806 UNMARSHALLING_REGISTER(DrawShadowStyle, DrawOpItem::SHADOW_STYLE_OPITEM,
807     DrawShadowStyleOpItem::Unmarshalling, sizeof(DrawShadowStyleOpItem::ConstructorHandle));
808 
DrawShadowStyleOpItem(const DrawCmdList & cmdList,DrawShadowStyleOpItem::ConstructorHandle * handle)809 DrawShadowStyleOpItem::DrawShadowStyleOpItem(
810     const DrawCmdList& cmdList, DrawShadowStyleOpItem::ConstructorHandle* handle)
811     : DrawOpItem(SHADOW_STYLE_OPITEM),
812       planeParams_(handle->planeParams),
813       devLightPos_(handle->devLightPos),
814       lightRadius_(handle->lightRadius),
815       ambientColor_(handle->ambientColor),
816       spotColor_(handle->spotColor),
817       flag_(handle->flag),
818       isLimitElevation_(handle->isLimitElevation)
819 {
820     path_ = CmdListHelper::GetPathFromCmdList(cmdList, handle->path);
821 }
822 
Unmarshalling(const DrawCmdList & cmdList,void * handle)823 std::shared_ptr<DrawOpItem> DrawShadowStyleOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
824 {
825     return std::make_shared<DrawShadowStyleOpItem>(
826         cmdList, static_cast<DrawShadowStyleOpItem::ConstructorHandle*>(handle));
827 }
828 
Marshalling(DrawCmdList & cmdList)829 void DrawShadowStyleOpItem::Marshalling(DrawCmdList& cmdList)
830 {
831     OpDataHandle pathHandle;
832     if (path_) {
833         pathHandle = CmdListHelper::AddPathToCmdList(cmdList, *path_);
834     }
835     cmdList.AddOp<ConstructorHandle>(
836         pathHandle, planeParams_, devLightPos_, lightRadius_, ambientColor_, spotColor_, flag_, isLimitElevation_);
837 }
838 
Playback(Canvas * canvas,const Rect * rect)839 void DrawShadowStyleOpItem::Playback(Canvas* canvas, const Rect* rect)
840 {
841     if (path_ == nullptr) {
842         LOGD("DrawShadowStyleOpItem path is null!");
843         return;
844     }
845     canvas->DrawShadowStyle(
846         *path_, planeParams_, devLightPos_, lightRadius_, ambientColor_, spotColor_, flag_, isLimitElevation_);
847 }
848 
Dump(std::string & out) const849 void DrawShadowStyleOpItem::Dump(std::string& out) const
850 {
851     out += GetOpDesc() + "[plane";
852     planeParams_.Dump(out);
853     out += " lightPos";
854     devLightPos_.Dump(out);
855     out += " lightRadius:" + std::to_string(lightRadius_);
856     out += " ambientColor";
857     ambientColor_.Dump(out);
858     out += " spotColor_";
859     spotColor_.Dump(out);
860     out += " shadowFlags:" + std::to_string(static_cast<int>(flag_));
861     out += " isLimitElevation:" + std::string(isLimitElevation_ ? "true" : "false");
862     out += "]";
863 }
864 
865 /* DrawShadowOpItem */
866 UNMARSHALLING_REGISTER(DrawShadow, DrawOpItem::SHADOW_OPITEM,
867     DrawShadowOpItem::Unmarshalling, sizeof(DrawShadowOpItem::ConstructorHandle));
868 
DrawShadowOpItem(const DrawCmdList & cmdList,DrawShadowOpItem::ConstructorHandle * handle)869 DrawShadowOpItem::DrawShadowOpItem(const DrawCmdList& cmdList, DrawShadowOpItem::ConstructorHandle* handle)
870     : DrawOpItem(SHADOW_OPITEM), planeParams_(handle->planeParams), devLightPos_(handle->devLightPos),
871     lightRadius_(handle->lightRadius), ambientColor_(handle->ambientColor),
872     spotColor_(handle->spotColor), flag_(handle->flag)
873 {
874     path_ = CmdListHelper::GetPathFromCmdList(cmdList, handle->path);
875 }
876 
Unmarshalling(const DrawCmdList & cmdList,void * handle)877 std::shared_ptr<DrawOpItem> DrawShadowOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
878 {
879     return std::make_shared<DrawShadowOpItem>(cmdList, static_cast<DrawShadowOpItem::ConstructorHandle*>(handle));
880 }
881 
Marshalling(DrawCmdList & cmdList)882 void DrawShadowOpItem::Marshalling(DrawCmdList& cmdList)
883 {
884     OpDataHandle pathHandle;
885     if (path_) {
886         pathHandle = CmdListHelper::AddPathToCmdList(cmdList, *path_);
887     }
888     cmdList.AddOp<ConstructorHandle>(
889         pathHandle, planeParams_, devLightPos_, lightRadius_, ambientColor_, spotColor_, flag_);
890 }
891 
Playback(Canvas * canvas,const Rect * rect)892 void DrawShadowOpItem::Playback(Canvas* canvas, const Rect* rect)
893 {
894     if (path_ == nullptr) {
895         LOGD("DrawShadowOpItem path is null!");
896         return;
897     }
898     canvas->DrawShadow(*path_, planeParams_, devLightPos_, lightRadius_,
899                        ambientColor_, spotColor_, flag_);
900 }
901 
Dump(std::string & out) const902 void DrawShadowOpItem::Dump(std::string& out) const
903 {
904     out += GetOpDesc() + "[plane";
905     planeParams_.Dump(out);
906     out += " lightPos";
907     devLightPos_.Dump(out);
908     out += " lightRadius:" + std::to_string(lightRadius_);
909     out += " ambientColor";
910     ambientColor_.Dump(out);
911     out += " spotColor_";
912     spotColor_.Dump(out);
913     out += " shadowFlags:" + std::to_string(static_cast<int>(flag_));
914     out += " path";
915     if (path_) {
916         path_->Dump(out);
917     } else {
918         out += "[null]";
919     }
920     out += "]";
921 }
922 
923 /* DrawRegionOpItem */
924 UNMARSHALLING_REGISTER(DrawRegion, DrawOpItem::REGION_OPITEM,
925     DrawRegionOpItem::Unmarshalling, sizeof(DrawRegionOpItem::ConstructorHandle));
926 
DrawRegionOpItem(const DrawCmdList & cmdList,DrawRegionOpItem::ConstructorHandle * handle)927 DrawRegionOpItem::DrawRegionOpItem(const DrawCmdList& cmdList, DrawRegionOpItem::ConstructorHandle* handle)
928     : DrawWithPaintOpItem(cmdList, handle->paintHandle, REGION_OPITEM)
929 {
930     region_ = CmdListHelper::GetRegionFromCmdList(cmdList, handle->region);
931 }
932 
Unmarshalling(const DrawCmdList & cmdList,void * handle)933 std::shared_ptr<DrawOpItem> DrawRegionOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
934 {
935     return std::make_shared<DrawRegionOpItem>(cmdList, static_cast<DrawRegionOpItem::ConstructorHandle*>(handle));
936 }
937 
Marshalling(DrawCmdList & cmdList)938 void DrawRegionOpItem::Marshalling(DrawCmdList& cmdList)
939 {
940     PaintHandle paintHandle;
941     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
942     OpDataHandle regionHandle;
943     if (region_) {
944         regionHandle = CmdListHelper::AddRegionToCmdList(cmdList, *region_);
945     }
946     cmdList.AddOp<ConstructorHandle>(regionHandle, paintHandle);
947 }
948 
Playback(Canvas * canvas,const Rect * rect)949 void DrawRegionOpItem::Playback(Canvas* canvas, const Rect* rect)
950 {
951     if (region_ == nullptr) {
952         LOGD("DrawRegionOpItem region is nullptr!");
953         return;
954     }
955     canvas->AttachPaint(paint_);
956     canvas->DrawRegion(*region_);
957 }
958 
DumpItems(std::string & out) const959 void DrawRegionOpItem::DumpItems(std::string& out) const
960 {
961     if (region_ != nullptr) {
962         out += " Region";
963         region_->Dump(out);
964     }
965 }
966 
967 /* DrawVerticesOpItem */
968 UNMARSHALLING_REGISTER(DrawVertices, DrawOpItem::VERTICES_OPITEM,
969     DrawVerticesOpItem::Unmarshalling, sizeof(DrawVerticesOpItem::ConstructorHandle));
970 
DrawVerticesOpItem(const DrawCmdList & cmdList,DrawVerticesOpItem::ConstructorHandle * handle)971 DrawVerticesOpItem::DrawVerticesOpItem(const DrawCmdList& cmdList, DrawVerticesOpItem::ConstructorHandle* handle)
972     : DrawWithPaintOpItem(cmdList, handle->paintHandle, VERTICES_OPITEM), mode_(handle->mode)
973 {
974     vertices_ = CmdListHelper::GetVerticesFromCmdList(cmdList, handle->vertices);
975 }
976 
Unmarshalling(const DrawCmdList & cmdList,void * handle)977 std::shared_ptr<DrawOpItem> DrawVerticesOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
978 {
979     return std::make_shared<DrawVerticesOpItem>(cmdList, static_cast<DrawVerticesOpItem::ConstructorHandle*>(handle));
980 }
981 
Marshalling(DrawCmdList & cmdList)982 void DrawVerticesOpItem::Marshalling(DrawCmdList& cmdList)
983 {
984     PaintHandle paintHandle;
985     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
986     OpDataHandle opDataHandle;
987     if (vertices_) {
988         opDataHandle = CmdListHelper::AddVerticesToCmdList(cmdList, *vertices_);
989     }
990     cmdList.AddOp<ConstructorHandle>(opDataHandle, mode_, paintHandle);
991 }
992 
Playback(Canvas * canvas,const Rect * rect)993 void DrawVerticesOpItem::Playback(Canvas* canvas, const Rect* rect)
994 {
995     if (vertices_ == nullptr) {
996         LOGD("DrawVerticesOpItem vertices is null");
997         return;
998     }
999     canvas->AttachPaint(paint_);
1000     canvas->DrawVertices(*vertices_, mode_);
1001 }
1002 
DumpItems(std::string & out) const1003 void DrawVerticesOpItem::DumpItems(std::string& out) const
1004 {
1005     out += " blend_mode:" + std::to_string(static_cast<int>(mode_));
1006     out += " vertices:";
1007     std::stringstream stream;
1008     stream << std::hex << vertices_.get();
1009     out += std::string(stream.str());
1010 }
1011 
1012 /* DrawColorOpItem */
1013 UNMARSHALLING_REGISTER(DrawColor, DrawOpItem::COLOR_OPITEM,
1014     DrawColorOpItem::Unmarshalling, sizeof(DrawColorOpItem::ConstructorHandle));
1015 
DrawColorOpItem(DrawColorOpItem::ConstructorHandle * handle)1016 DrawColorOpItem::DrawColorOpItem(DrawColorOpItem::ConstructorHandle* handle)
1017     : DrawOpItem(COLOR_OPITEM), color_(handle->color), mode_(handle->mode) {}
1018 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1019 std::shared_ptr<DrawOpItem> DrawColorOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1020 {
1021     return std::make_shared<DrawColorOpItem>(static_cast<DrawColorOpItem::ConstructorHandle*>(handle));
1022 }
1023 
Marshalling(DrawCmdList & cmdList)1024 void DrawColorOpItem::Marshalling(DrawCmdList& cmdList)
1025 {
1026     cmdList.AddOp<ConstructorHandle>(color_, mode_);
1027 }
1028 
Playback(Canvas * canvas,const Rect * rect)1029 void DrawColorOpItem::Playback(Canvas* canvas, const Rect* rect)
1030 {
1031     canvas->DrawColor(color_, mode_);
1032 }
1033 
Dump(std::string & out) const1034 void DrawColorOpItem::Dump(std::string& out) const
1035 {
1036     out += GetOpDesc() + "[color";
1037     Color(color_).Dump(out);
1038     out += " blendMode:" + std::to_string(static_cast<int>(mode_));
1039     out += "]";
1040 }
1041 
1042 /* DrawImageNineOpItem */
1043 UNMARSHALLING_REGISTER(DrawImageNine, DrawOpItem::IMAGE_NINE_OPITEM,
1044     DrawImageNineOpItem::Unmarshalling, sizeof(DrawImageNineOpItem::ConstructorHandle));
1045 
DrawImageNineOpItem(const DrawCmdList & cmdList,DrawImageNineOpItem::ConstructorHandle * handle)1046 DrawImageNineOpItem::DrawImageNineOpItem(const DrawCmdList& cmdList, DrawImageNineOpItem::ConstructorHandle* handle)
1047     : DrawOpItem(IMAGE_NINE_OPITEM), center_(handle->center), dst_(handle->dst), filter_(handle->filter),
1048     hasBrush_(handle->hasBrush)
1049 {
1050     image_ = CmdListHelper::GetImageFromCmdList(cmdList, handle->image);
1051     if (DrawOpItem::holdDrawingImagefunc_) {
1052         DrawOpItem::holdDrawingImagefunc_(image_);
1053     }
1054     if (hasBrush_) {
1055         BrushHandleToBrush(handle->brushHandle, cmdList, brush_);
1056     }
1057 }
1058 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1059 std::shared_ptr<DrawOpItem> DrawImageNineOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1060 {
1061     return std::make_shared<DrawImageNineOpItem>(cmdList, static_cast<DrawImageNineOpItem::ConstructorHandle*>(handle));
1062 }
1063 
Marshalling(DrawCmdList & cmdList)1064 void DrawImageNineOpItem::Marshalling(DrawCmdList& cmdList)
1065 {
1066     OpDataHandle imageHandle;
1067     if (image_) {
1068         imageHandle = CmdListHelper::AddImageToCmdList(cmdList, *image_);
1069     }
1070     BrushHandle brushHandle;
1071     if (hasBrush_) {
1072         BrushToBrushHandle(brush_, cmdList, brushHandle);
1073     }
1074 
1075     cmdList.AddOp<ConstructorHandle>(imageHandle, center_, dst_, filter_, brushHandle, hasBrush_);
1076 }
1077 
Playback(Canvas * canvas,const Rect * rect)1078 void DrawImageNineOpItem::Playback(Canvas* canvas, const Rect* rect)
1079 {
1080     if (image_ == nullptr) {
1081         LOGD("DrawImageNineOpItem image is null");
1082         return;
1083     }
1084     Brush* brushPtr = hasBrush_ ? &brush_ : nullptr;
1085     canvas->DrawImageNine(image_.get(), center_, dst_, filter_, brushPtr);
1086 }
1087 
Dump(std::string & out) const1088 void DrawImageNineOpItem::Dump(std::string& out) const
1089 {
1090     out += GetOpDesc() + "[center";
1091     center_.Dump(out);
1092     out += " dst";
1093     dst_.Dump(out);
1094     out += " filterMode:" + std::to_string(static_cast<int>(filter_));
1095     out += " brush";
1096     if (hasBrush_) {
1097         brush_.Dump(out);
1098     } else {
1099         out += "[null]";
1100     }
1101     out += " image";
1102     if (image_) {
1103         image_->Dump(out);
1104     } else {
1105         out += "[null]";
1106     }
1107     out += "]";
1108 }
1109 
1110 /* DrawImageLatticeOpItem */
1111 UNMARSHALLING_REGISTER(DrawImageLattice, DrawOpItem::IMAGE_LATTICE_OPITEM,
1112     DrawImageLatticeOpItem::Unmarshalling, sizeof(DrawImageLatticeOpItem::ConstructorHandle));
1113 
DrawImageLatticeOpItem(const DrawCmdList & cmdList,DrawImageLatticeOpItem::ConstructorHandle * handle)1114 DrawImageLatticeOpItem::DrawImageLatticeOpItem(
1115     const DrawCmdList& cmdList, DrawImageLatticeOpItem::ConstructorHandle* handle)
1116     : DrawWithPaintOpItem(cmdList, handle->paintHandle, IMAGE_LATTICE_OPITEM),
1117     dst_(handle->dst), filter_(handle->filter)
1118 {
1119     image_ = CmdListHelper::GetImageFromCmdList(cmdList, handle->image);
1120     if (DrawOpItem::holdDrawingImagefunc_) {
1121         DrawOpItem::holdDrawingImagefunc_(image_);
1122     }
1123     lattice_ = CmdListHelper::GetLatticeFromCmdList(cmdList, handle->latticeHandle);
1124 }
1125 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1126 std::shared_ptr<DrawOpItem> DrawImageLatticeOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1127 {
1128     return std::make_shared<DrawImageLatticeOpItem>(
1129         cmdList, static_cast<DrawImageLatticeOpItem::ConstructorHandle*>(handle));
1130 }
1131 
Marshalling(DrawCmdList & cmdList)1132 void DrawImageLatticeOpItem::Marshalling(DrawCmdList& cmdList)
1133 {
1134     PaintHandle paintHandle;
1135     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
1136     OpDataHandle imageHandle;
1137     if (image_) {
1138         imageHandle = CmdListHelper::AddImageToCmdList(cmdList, *image_);
1139     }
1140     auto latticeHandle =  CmdListHelper::AddLatticeToCmdList(cmdList, lattice_);
1141     cmdList.AddOp<ConstructorHandle>(imageHandle, latticeHandle, dst_, filter_, paintHandle);
1142 }
1143 
Playback(Canvas * canvas,const Rect * rect)1144 void DrawImageLatticeOpItem::Playback(Canvas* canvas, const Rect* rect)
1145 {
1146     if (image_ == nullptr) {
1147         LOGD("DrawImageNineOpItem image is null");
1148         return;
1149     }
1150     canvas->AttachPaint(paint_);
1151     canvas->DrawImageLattice(image_.get(), lattice_, dst_, filter_);
1152 }
1153 
Dump(std::string & out) const1154 void DrawImageLatticeOpItem::Dump(std::string& out) const
1155 {
1156     out += GetOpDesc() + "[lattice[";
1157     out += "xCount:" + std::to_string(lattice_.fXCount);
1158     out += " yCount:" + std::to_string(lattice_.fYCount);
1159     out += " xDivs";
1160     DumpArray(out, lattice_.fXDivs, [](std::string& out, int n) {
1161         out += std::to_string(n);
1162     });
1163     out += " yDivs";
1164     DumpArray(out, lattice_.fYDivs, [](std::string& out, int n) {
1165         out += std::to_string(n);
1166     });
1167     out += " rectTypes";
1168     DumpArray(out, lattice_.fRectTypes, [](std::string& out, Lattice::RectType n) {
1169         out += std::to_string(static_cast<int>(n));
1170     });
1171     out += " bounds";
1172     DumpArray(out, lattice_.fBounds, [](std::string& out, const RectI& n) {
1173         n.Dump(out);
1174     });
1175     out += " colors";
1176     DumpArray(out, lattice_.fColors, [](std::string& out, const Color& c) {
1177         c.Dump(out);
1178     });
1179     out += " dst";
1180     dst_.Dump(out);
1181     out += " filterMode:" + std::to_string(static_cast<int>(filter_));
1182     out += " image";
1183     if (image_) {
1184         image_->Dump(out);
1185     } else {
1186         out += "[null]";
1187     }
1188     out += "]";
1189 }
1190 
1191 /* DrawAtlasOpItem */
1192 UNMARSHALLING_REGISTER(DrawAtlas, DrawOpItem::ATLAS_OPITEM,
1193     DrawAtlasOpItem::Unmarshalling, sizeof(DrawAtlasOpItem::ConstructorHandle));
1194 
DrawAtlasOpItem(const DrawCmdList & cmdList,DrawAtlasOpItem::ConstructorHandle * handle)1195 DrawAtlasOpItem::DrawAtlasOpItem(const DrawCmdList& cmdList, DrawAtlasOpItem::ConstructorHandle* handle)
1196     : DrawWithPaintOpItem(cmdList, handle->paintHandle, ATLAS_OPITEM), mode_(handle->mode),
1197       samplingOptions_(handle->samplingOptions), hasCullRect_(handle->hasCullRect), cullRect_(handle->cullRect)
1198 {
1199     atlas_ = CmdListHelper::GetImageFromCmdList(cmdList, handle->atlas);
1200     if (DrawOpItem::holdDrawingImagefunc_) {
1201         DrawOpItem::holdDrawingImagefunc_(atlas_);
1202     }
1203     xform_ = CmdListHelper::GetVectorFromCmdList<RSXform>(cmdList, handle->xform);
1204     tex_ = CmdListHelper::GetVectorFromCmdList<Rect>(cmdList, handle->tex);
1205     colors_ = CmdListHelper::GetVectorFromCmdList<ColorQuad>(cmdList, handle->colors);
1206 }
1207 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1208 std::shared_ptr<DrawOpItem> DrawAtlasOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1209 {
1210     return std::make_shared<DrawAtlasOpItem>(cmdList, static_cast<DrawAtlasOpItem::ConstructorHandle*>(handle));
1211 }
1212 
Marshalling(DrawCmdList & cmdList)1213 void DrawAtlasOpItem::Marshalling(DrawCmdList& cmdList)
1214 {
1215     PaintHandle paintHandle;
1216     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
1217     OpDataHandle imageHandle;
1218     if (atlas_) {
1219         imageHandle = CmdListHelper::AddImageToCmdList(cmdList, *atlas_);
1220     }
1221     auto xformData = CmdListHelper::AddVectorToCmdList<RSXform>(cmdList, xform_);
1222     auto texData = CmdListHelper::AddVectorToCmdList<Rect>(cmdList, tex_);
1223     auto colorData = CmdListHelper::AddVectorToCmdList<ColorQuad>(cmdList, colors_);
1224     cmdList.AddOp<ConstructorHandle>(imageHandle, xformData, texData, colorData, mode_, samplingOptions_,
1225         hasCullRect_, cullRect_, paintHandle);
1226 }
1227 
Playback(Canvas * canvas,const Rect * rect)1228 void DrawAtlasOpItem::Playback(Canvas* canvas, const Rect* rect)
1229 {
1230     if (atlas_ == nullptr) {
1231         LOGD("DrawAtlasOpItem atlas is null");
1232         return;
1233     }
1234     canvas->AttachPaint(paint_);
1235     Rect* rectPtr = hasCullRect_ ? &cullRect_ : nullptr;
1236     canvas->DrawAtlas(atlas_.get(), xform_.data(), tex_.data(), colors_.data(), xform_.size(), mode_,
1237         samplingOptions_, rectPtr);
1238 }
1239 
DumpItems(std::string & out) const1240 void DrawAtlasOpItem::DumpItems(std::string& out) const
1241 {
1242     out += " Xform[";
1243     for (auto& e: xform_) {
1244         e.Dump(out);
1245         out += ' ';
1246     }
1247     if (xform_.size() > 0) {
1248         out.pop_back();
1249     }
1250     out += ']';
1251 
1252     out += " Tex[";
1253     for (auto& e: tex_) {
1254         e.Dump(out);
1255         out += ' ';
1256     }
1257     if (tex_.size() > 0) {
1258         out.pop_back();
1259     }
1260     out += ']';
1261 
1262     out += " Colors[";
1263     for (auto e: colors_) {
1264         Color color(e);
1265         color.Dump(out);
1266         out += ' ';
1267     }
1268     if (colors_.size() > 0) {
1269         out.pop_back();
1270     }
1271     out += ']';
1272 
1273     out += " mode:" + std::to_string(static_cast<int>(mode_));
1274     out += " SamplingOption";
1275     samplingOptions_.Dump(out);
1276     out += " hasCullRect:" + std::string(hasCullRect_ ? "true" : "false");
1277     out += " CullRect";
1278     cullRect_.Dump(out);
1279     if (atlas_ != nullptr) {
1280         out += " Atlas";
1281         atlas_->Dump(out);
1282     }
1283 }
1284 
1285 /* DrawBitmapOpItem */
1286 UNMARSHALLING_REGISTER(DrawBitmap, DrawOpItem::BITMAP_OPITEM,
1287     DrawBitmapOpItem::Unmarshalling, sizeof(DrawBitmapOpItem::ConstructorHandle));
1288 
DrawBitmapOpItem(const DrawCmdList & cmdList,DrawBitmapOpItem::ConstructorHandle * handle)1289 DrawBitmapOpItem::DrawBitmapOpItem(const DrawCmdList& cmdList, DrawBitmapOpItem::ConstructorHandle* handle)
1290     : DrawWithPaintOpItem(cmdList, handle->paintHandle, BITMAP_OPITEM), px_(handle->px), py_(handle->py)
1291 {
1292     bitmap_ = CmdListHelper::GetBitmapFromCmdList(cmdList, handle->bitmap);
1293 }
1294 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1295 std::shared_ptr<DrawOpItem> DrawBitmapOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1296 {
1297     return std::make_shared<DrawBitmapOpItem>(cmdList, static_cast<DrawBitmapOpItem::ConstructorHandle*>(handle));
1298 }
1299 
Marshalling(DrawCmdList & cmdList)1300 void DrawBitmapOpItem::Marshalling(DrawCmdList& cmdList)
1301 {
1302     PaintHandle paintHandle;
1303     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
1304     ImageHandle bitmapHandle;
1305     if (bitmap_) {
1306         bitmapHandle = CmdListHelper::AddBitmapToCmdList(cmdList, *bitmap_);
1307     }
1308     cmdList.AddOp<ConstructorHandle>(bitmapHandle, px_, py_, paintHandle);
1309 }
1310 
Playback(Canvas * canvas,const Rect * rect)1311 void DrawBitmapOpItem::Playback(Canvas* canvas, const Rect* rect)
1312 {
1313     if (bitmap_ == nullptr) {
1314         LOGD("DrawBitmapOpItem bitmap is null");
1315         return;
1316     }
1317     canvas->AttachPaint(paint_);
1318     canvas->DrawBitmap(*bitmap_, px_, py_);
1319 }
1320 
DumpItems(std::string & out) const1321 void DrawBitmapOpItem::DumpItems(std::string& out) const
1322 {
1323     out += " px:" + std::to_string(px_) + " py:" + std::to_string(py_);
1324     if (bitmap_ != nullptr) {
1325         out += " Bitmap";
1326         bitmap_->Dump(out);
1327     }
1328 }
1329 
1330 /* DrawImageOpItem */
1331 UNMARSHALLING_REGISTER(DrawImage, DrawOpItem::IMAGE_OPITEM,
1332     DrawImageOpItem::Unmarshalling, sizeof(DrawImageOpItem::ConstructorHandle));
1333 
DrawImageOpItem(const DrawCmdList & cmdList,DrawImageOpItem::ConstructorHandle * handle)1334 DrawImageOpItem::DrawImageOpItem(const DrawCmdList& cmdList, DrawImageOpItem::ConstructorHandle* handle)
1335     : DrawWithPaintOpItem(cmdList, handle->paintHandle, IMAGE_OPITEM), px_(handle->px), py_(handle->py),
1336       samplingOptions_(handle->samplingOptions)
1337 {
1338     image_ = CmdListHelper::GetImageFromCmdList(cmdList, handle->image);
1339     if (DrawOpItem::holdDrawingImagefunc_) {
1340         DrawOpItem::holdDrawingImagefunc_(image_);
1341     }
1342 }
1343 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1344 std::shared_ptr<DrawOpItem> DrawImageOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1345 {
1346     return std::make_shared<DrawImageOpItem>(cmdList, static_cast<DrawImageOpItem::ConstructorHandle*>(handle));
1347 }
1348 
Marshalling(DrawCmdList & cmdList)1349 void DrawImageOpItem::Marshalling(DrawCmdList& cmdList)
1350 {
1351     PaintHandle paintHandle;
1352     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
1353     OpDataHandle imageHandle;
1354     if (image_) {
1355         imageHandle = CmdListHelper::AddImageToCmdList(cmdList, *image_);
1356     }
1357     cmdList.AddOp<ConstructorHandle>(imageHandle, px_, py_, samplingOptions_, paintHandle);
1358 }
1359 
Playback(Canvas * canvas,const Rect * rect)1360 void DrawImageOpItem::Playback(Canvas* canvas, const Rect* rect)
1361 {
1362     if (image_ == nullptr) {
1363         LOGD("DrawImageOpItem image is null");
1364         return;
1365     }
1366     canvas->AttachPaint(paint_);
1367     canvas->DrawImage(*image_, px_, py_, samplingOptions_);
1368 }
1369 
DumpItems(std::string & out) const1370 void DrawImageOpItem::DumpItems(std::string& out) const
1371 {
1372     out += " px:" + std::to_string(px_) + " py:" + std::to_string(py_);
1373     out += " SamplingOptions";
1374     samplingOptions_.Dump(out);
1375     if (image_ != nullptr) {
1376         out += " Image";
1377         image_->Dump(out);
1378     }
1379 }
1380 
1381 /* DrawImageRectOpItem */
1382 UNMARSHALLING_REGISTER(DrawImageRect, DrawOpItem::IMAGE_RECT_OPITEM,
1383     DrawImageRectOpItem::Unmarshalling, sizeof(DrawImageRectOpItem::ConstructorHandle));
1384 
DrawImageRectOpItem(const DrawCmdList & cmdList,DrawImageRectOpItem::ConstructorHandle * handle)1385 DrawImageRectOpItem::DrawImageRectOpItem(const DrawCmdList& cmdList, DrawImageRectOpItem::ConstructorHandle* handle)
1386     : DrawWithPaintOpItem(cmdList, handle->paintHandle, IMAGE_RECT_OPITEM), src_(handle->src), dst_(handle->dst),
1387       sampling_(handle->sampling), constraint_(handle->constraint), isForeground_(handle->isForeground)
1388 {
1389     image_ = CmdListHelper::GetImageFromCmdList(cmdList, handle->image);
1390     if (DrawOpItem::holdDrawingImagefunc_) {
1391         DrawOpItem::holdDrawingImagefunc_(image_);
1392     }
1393 }
1394 
DrawImageRectOpItem(const Image & image,const Rect & src,const Rect & dst,const SamplingOptions & sampling,SrcRectConstraint constraint,const Paint & paint,bool isForeground)1395 DrawImageRectOpItem::DrawImageRectOpItem(const Image& image, const Rect& src,
1396     const Rect& dst, const SamplingOptions& sampling,
1397     SrcRectConstraint constraint, const Paint& paint, bool isForeground)
1398     : DrawWithPaintOpItem(paint, DrawOpItem::IMAGE_RECT_OPITEM), src_(src), dst_(dst), sampling_(sampling),
1399     constraint_(constraint), image_(std::make_shared<Image>(image)), isForeground_(isForeground)
1400 {
1401     if (DrawOpItem::holdDrawingImagefunc_) {
1402         DrawOpItem::holdDrawingImagefunc_(image_);
1403     }
1404 }
1405 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1406 std::shared_ptr<DrawOpItem> DrawImageRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1407 {
1408     return std::make_shared<DrawImageRectOpItem>(cmdList, static_cast<DrawImageRectOpItem::ConstructorHandle*>(handle));
1409 }
1410 
Marshalling(DrawCmdList & cmdList)1411 void DrawImageRectOpItem::Marshalling(DrawCmdList& cmdList)
1412 {
1413     PaintHandle paintHandle;
1414     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
1415     OpDataHandle imageHandle;
1416     if (image_) {
1417         imageHandle = CmdListHelper::AddImageToCmdList(cmdList, *image_);
1418     }
1419     cmdList.AddOp<ConstructorHandle>(imageHandle, src_, dst_, sampling_, constraint_, paintHandle);
1420 }
1421 
Playback(Canvas * canvas,const Rect * rect)1422 void DrawImageRectOpItem::Playback(Canvas* canvas, const Rect* rect)
1423 {
1424     if (image_ == nullptr) {
1425         LOGD("DrawImageRectOpItem image is null");
1426         return;
1427     }
1428     if (isForeground_) {
1429         AutoCanvasRestore acr(*canvas, false);
1430         SaveLayerOps ops;
1431         canvas->SaveLayer(ops);
1432         canvas->AttachPaint(paint_);
1433         canvas->DrawImageRect(*image_, src_, dst_, sampling_, constraint_);
1434         Brush brush;
1435         brush.SetColor(canvas->GetEnvForegroundColor());
1436         brush.SetBlendMode(Drawing::BlendMode::SRC_IN);
1437         canvas->DrawBackground(brush);
1438         return;
1439     }
1440     canvas->AttachPaint(paint_);
1441     canvas->DrawImageRect(*image_, src_, dst_, sampling_, constraint_);
1442 }
1443 
DumpItems(std::string & out) const1444 void DrawImageRectOpItem::DumpItems(std::string& out) const
1445 {
1446     out += " Src";
1447     src_.Dump(out);
1448     out += " Dst";
1449     src_.Dump(out);
1450     out += " Sampling";
1451     sampling_.Dump(out);
1452     out += " constraint:" + std::to_string(static_cast<int>(constraint_));
1453     if (image_ != nullptr) {
1454         out += " Image";
1455         image_->Dump(out);
1456     }
1457     out += " isForeground:" + std::string(isForeground_ ? "true" : "false");
1458 }
1459 
1460 /* DrawRecordCmdOpItem */
1461 UNMARSHALLING_REGISTER(DrawRecordCmd, DrawOpItem::RECORD_CMD_OPITEM,
1462     DrawRecordCmdOpItem::Unmarshalling, sizeof(DrawRecordCmdOpItem::ConstructorHandle));
1463 
DrawRecordCmdOpItem(const DrawCmdList & cmdList,DrawRecordCmdOpItem::ConstructorHandle * handle)1464 DrawRecordCmdOpItem::DrawRecordCmdOpItem(
1465     const DrawCmdList& cmdList, DrawRecordCmdOpItem::ConstructorHandle* handle)
1466     : DrawOpItem(RECORD_CMD_OPITEM), hasBrush_(handle->hasBrush)
1467 {
1468     recordCmd_ = CmdListHelper::GetRecordCmdFromCmdList(cmdList, handle->recordCmdHandle);
1469     matrix_.SetAll(handle->matrixBuffer);
1470     if (hasBrush_) {
1471         BrushHandleToBrush(handle->brushHandle, cmdList, brush_);
1472     }
1473 }
1474 
DrawRecordCmdOpItem(const std::shared_ptr<RecordCmd> & recordCmd,const Matrix * matrix,const Brush * brush)1475 DrawRecordCmdOpItem::DrawRecordCmdOpItem(const std::shared_ptr<RecordCmd>& recordCmd,
1476     const Matrix* matrix, const Brush* brush)
1477     : DrawOpItem(RECORD_CMD_OPITEM), recordCmd_(recordCmd)
1478 {
1479     if (matrix != nullptr) {
1480         matrix_ = *matrix;
1481     }
1482     if (brush != nullptr) {
1483         hasBrush_ = true;
1484         brush_ = *brush;
1485     }
1486 }
1487 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1488 std::shared_ptr<DrawOpItem> DrawRecordCmdOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1489 {
1490     return std::make_shared<DrawRecordCmdOpItem>(
1491         cmdList, static_cast<DrawRecordCmdOpItem::ConstructorHandle*>(handle));
1492 }
1493 
Marshalling(DrawCmdList & cmdList)1494 void DrawRecordCmdOpItem::Marshalling(DrawCmdList& cmdList)
1495 {
1496     auto recordCmdHandle = CmdListHelper::AddRecordCmdToCmdList(cmdList, recordCmd_);
1497     Matrix::Buffer matrixBuffer;
1498     matrix_.GetAll(matrixBuffer);
1499     BrushHandle brushHandle;
1500     if (hasBrush_) {
1501         BrushToBrushHandle(brush_, cmdList, brushHandle);
1502     }
1503     cmdList.AddOp<ConstructorHandle>(recordCmdHandle,
1504         matrixBuffer, hasBrush_, brushHandle);
1505 }
1506 
Playback(Canvas * canvas,const Rect * rect)1507 void DrawRecordCmdOpItem::Playback(Canvas* canvas, const Rect* rect)
1508 {
1509     Brush* brushPtr = hasBrush_ ? &brush_ : nullptr;
1510     canvas->DrawRecordCmd(recordCmd_, &matrix_, brushPtr);
1511 }
1512 
1513 /* DrawPictureOpItem */
1514 UNMARSHALLING_REGISTER(DrawPicture, DrawOpItem::PICTURE_OPITEM,
1515     DrawPictureOpItem::Unmarshalling, sizeof(DrawPictureOpItem::ConstructorHandle));
1516 
DrawPictureOpItem(const DrawCmdList & cmdList,DrawPictureOpItem::ConstructorHandle * handle)1517 DrawPictureOpItem::DrawPictureOpItem(const DrawCmdList& cmdList, DrawPictureOpItem::ConstructorHandle* handle)
1518     : DrawOpItem(PICTURE_OPITEM)
1519 {
1520     picture_ = CmdListHelper::GetPictureFromCmdList(cmdList, handle->picture);
1521 }
1522 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1523 std::shared_ptr<DrawOpItem> DrawPictureOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1524 {
1525     return std::make_shared<DrawPictureOpItem>(cmdList, static_cast<DrawPictureOpItem::ConstructorHandle*>(handle));
1526 }
1527 
Marshalling(DrawCmdList & cmdList)1528 void DrawPictureOpItem::Marshalling(DrawCmdList& cmdList)
1529 {
1530     OpDataHandle pictureHandle;
1531     if (picture_) {
1532         pictureHandle = CmdListHelper::AddPictureToCmdList(cmdList, *picture_);
1533     }
1534     cmdList.AddOp<ConstructorHandle>(pictureHandle);
1535 }
1536 
Playback(Canvas * canvas,const Rect * rect)1537 void DrawPictureOpItem::Playback(Canvas* canvas, const Rect* rect)
1538 {
1539     if (picture_ == nullptr) {
1540         LOGD("DrawPictureOpItem picture is null");
1541         return;
1542     }
1543     canvas->DrawPicture(*picture_);
1544 }
1545 
1546 /* DrawTextBlobOpItem */
1547 UNMARSHALLING_REGISTER(DrawTextBlob, DrawOpItem::TEXT_BLOB_OPITEM,
1548     DrawTextBlobOpItem::Unmarshalling, sizeof(DrawTextBlobOpItem::ConstructorHandle));
1549 
SimplifyPaint(ColorQuad colorQuad,Paint & paint)1550 void SimplifyPaint(ColorQuad colorQuad, Paint& paint)
1551 {
1552     Color color{colorQuad};
1553     paint.SetColor(color);
1554     paint.SetShaderEffect(nullptr);
1555     if (paint.HasFilter()) {
1556         Filter filter = paint.GetFilter();
1557         if (filter.GetColorFilter() != nullptr) {
1558             filter.SetColorFilter(nullptr);
1559             paint.SetFilter(filter);
1560         }
1561     }
1562     paint.SetWidth(1.04); // 1.04 is empirical value
1563     paint.SetJoinStyle(Pen::JoinStyle::ROUND_JOIN);
1564 }
1565 
DrawTextBlobOpItem(const DrawCmdList & cmdList,DrawTextBlobOpItem::ConstructorHandle * handle)1566 DrawTextBlobOpItem::DrawTextBlobOpItem(const DrawCmdList& cmdList, DrawTextBlobOpItem::ConstructorHandle* handle)
1567     : DrawWithPaintOpItem(cmdList, handle->paintHandle, TEXT_BLOB_OPITEM), x_(handle->x), y_(handle->y)
1568 {
1569     textBlob_ = CmdListHelper::GetTextBlobFromCmdList(cmdList, handle->textBlob, handle->globalUniqueId);
1570 }
1571 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1572 std::shared_ptr<DrawOpItem> DrawTextBlobOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1573 {
1574     return std::make_shared<DrawTextBlobOpItem>(cmdList, static_cast<DrawTextBlobOpItem::ConstructorHandle*>(handle));
1575 }
1576 
Marshalling(DrawCmdList & cmdList)1577 void DrawTextBlobOpItem::Marshalling(DrawCmdList& cmdList)
1578 {
1579     static uint64_t shiftedPid = static_cast<uint64_t>(GetRealPid()) << 32; // 32 for 64-bit unsignd number shift
1580     PaintHandle paintHandle;
1581     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
1582     TextBlob::Context ctx {nullptr, false};
1583     auto textBlobHandle = CmdListHelper::AddTextBlobToCmdList(cmdList, textBlob_.get(), &ctx);
1584     uint64_t globalUniqueId = 0;
1585     if (ctx.GetTypeface() != nullptr) {
1586         uint32_t typefaceId = ctx.GetTypeface()->GetUniqueID();
1587         globalUniqueId = (shiftedPid | typefaceId);
1588     }
1589 
1590     cmdList.AddOp<ConstructorHandle>(textBlobHandle, globalUniqueId, x_, y_, paintHandle);
1591 }
1592 
Playback(Canvas * canvas,const Rect * rect)1593 void DrawTextBlobOpItem::Playback(Canvas* canvas, const Rect* rect)
1594 {
1595     if (textBlob_ == nullptr) {
1596         LOGD("DrawTextBlobOpItem textBlob is null");
1597         return;
1598     }
1599     RectI globalClipBounds = canvas->GetDeviceClipBounds();
1600     bool saveFlag = false;
1601     if (globalClipBounds.GetWidth() == 1 || globalClipBounds.GetHeight() == 1) {
1602         // In this case, the clip area for textblob must have AA.
1603         Matrix m = canvas->GetTotalMatrix();
1604         canvas->Save();
1605         canvas->SetMatrix(m);
1606         auto bounds = textBlob_->Bounds();
1607         if (bounds && bounds->IsValid()) {
1608             canvas->ClipRect(*bounds, ClipOp::INTERSECT, true);
1609         }
1610         saveFlag = true;
1611     }
1612     if (canvas->isHighContrastEnabled()) {
1613         LOGD("DrawTextBlobOpItem::Playback highContrastEnabled, %{public}s, %{public}d", __FUNCTION__, __LINE__);
1614         DrawHighContrastEnabled(canvas);
1615     } else {
1616         canvas->AttachPaint(paint_);
1617         canvas->DrawTextBlob(textBlob_.get(), x_, y_);
1618     }
1619     if (saveFlag) {
1620         canvas->Restore();
1621     }
1622 }
1623 
GetOffScreenSurfaceAndCanvas(const Canvas & canvas,std::shared_ptr<Drawing::Surface> & offScreenSurface,std::shared_ptr<Canvas> & offScreenCanvas) const1624 bool DrawTextBlobOpItem::GetOffScreenSurfaceAndCanvas(const Canvas& canvas,
1625     std::shared_ptr<Drawing::Surface>& offScreenSurface, std::shared_ptr<Canvas>& offScreenCanvas) const
1626 {
1627     auto surface = canvas.GetSurface();
1628     auto textBlobBounds = textBlob_->Bounds();
1629     if (!surface || !textBlobBounds) {
1630         return false;
1631     }
1632     offScreenSurface = surface->MakeSurface(textBlobBounds->GetWidth(), textBlobBounds->GetHeight());
1633     if (!offScreenSurface) {
1634         return false;
1635     }
1636     offScreenCanvas = offScreenSurface->GetCanvas();
1637     if (!offScreenCanvas) {
1638         return false;
1639     }
1640     offScreenCanvas->Translate(-textBlobBounds->GetLeft(), -textBlobBounds->GetTop());
1641     return true;
1642 }
1643 
DrawHighContrastEnabled(Canvas * canvas) const1644 void DrawTextBlobOpItem::DrawHighContrastEnabled(Canvas* canvas) const
1645 {
1646     ColorQuad colorQuad = paint_.GetColor().CastToColorQuad();
1647     if (Color::ColorQuadGetA(colorQuad) == 0 || paint_.HasFilter()) {
1648         canvas->AttachPaint(paint_);
1649         canvas->DrawTextBlob(textBlob_.get(), x_, y_);
1650         return;
1651     }
1652     // in case of perceptible transparent, text should be drawn offscreen to avoid stroke and content overlap.
1653     if (canvas->GetAlphaSaveCount() > 0 && canvas->GetAlpha() < HIGH_CONTRAST_OFFSCREEN_THREASHOLD) {
1654         std::shared_ptr<Drawing::Surface> offScreenSurface;
1655         std::shared_ptr<Canvas> offScreenCanvas;
1656         if (GetOffScreenSurfaceAndCanvas(*canvas, offScreenSurface, offScreenCanvas)) {
1657             DrawHighContrast(offScreenCanvas.get(), true);
1658             offScreenCanvas->Flush();
1659             auto image = offScreenSurface->GetImageSnapshot();
1660             if (image == nullptr) {
1661                 return;
1662             }
1663             Drawing::Brush paint;
1664             paint.SetAntiAlias(true);
1665             canvas->AttachBrush(paint);
1666             Drawing::SamplingOptions sampling =
1667                 Drawing::SamplingOptions(Drawing::FilterMode::NEAREST, Drawing::MipmapMode::NEAREST);
1668             canvas->DrawImage(*image, x_ + textBlob_->Bounds()->GetLeft(),
1669                 y_ + textBlob_->Bounds()->GetTop(), sampling);
1670             canvas->DetachBrush();
1671             return;
1672         }
1673     }
1674     DrawHighContrast(canvas);
1675 }
1676 
DrawHighContrast(Canvas * canvas,bool offScreen) const1677 void DrawTextBlobOpItem::DrawHighContrast(Canvas* canvas, bool offScreen) const
1678 {
1679     ColorQuad colorQuad = paint_.GetColor().CastToColorQuad();
1680     uint32_t channelSum = Color::ColorQuadGetR(colorQuad) + Color::ColorQuadGetG(colorQuad) +
1681         Color::ColorQuadGetB(colorQuad);
1682     bool flag = channelSum < 594; // 594 is empirical value
1683 
1684     // draw outline stroke with pen
1685     Drawing::Pen outlinePen;
1686     outlinePen.SetColor(flag ? Color::COLOR_WHITE : Color::COLOR_BLACK);
1687     outlinePen.SetAntiAlias(true);
1688     outlinePen.SetBlenderEnabled(false);
1689     canvas->AttachPen(outlinePen);
1690     offScreen ? canvas->DrawTextBlob(textBlob_.get(), 0, 0) : canvas->DrawTextBlob(textBlob_.get(), x_, y_);
1691 
1692     // draw inner content with brush
1693     Drawing::Brush innerBrush;
1694     innerBrush.SetColor(flag ? Color::COLOR_BLACK : Color::COLOR_WHITE);
1695     canvas->DetachPen();
1696     canvas->AttachBrush(innerBrush);
1697     offScreen ? canvas->DrawTextBlob(textBlob_.get(), 0, 0) : canvas->DrawTextBlob(textBlob_.get(), x_, y_);
1698     canvas->DetachBrush();
1699 }
1700 
GenerateCachedOpItem(DrawCmdList & cmdList,const TextBlob * textBlob,scalar x,scalar y,Paint & p)1701 bool DrawTextBlobOpItem::ConstructorHandle::GenerateCachedOpItem(
1702     DrawCmdList& cmdList, const TextBlob* textBlob, scalar x, scalar y, Paint& p)
1703 {
1704     if (!textBlob) {
1705         LOGD("textBlob nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
1706         return false;
1707     }
1708 
1709     auto bounds = textBlob->Bounds();
1710     if (!bounds || !bounds->IsValid()) {
1711         return false;
1712     }
1713     bounds->Offset(x, y);
1714     bounds->MakeOutset(TEXT_BLOB_CACHE_MARGIN, TEXT_BLOB_CACHE_MARGIN);
1715     // create CPU raster surface
1716     Drawing::ImageInfo offscreenInfo { bounds->GetWidth(), bounds->GetHeight(),
1717         Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL, nullptr};
1718     std::shared_ptr<Surface> offscreenSurface = Surface::MakeRaster(offscreenInfo);
1719     if (offscreenSurface == nullptr) {
1720         return false;
1721     }
1722     auto offscreenCanvas = offscreenSurface->GetCanvas();
1723     if (offscreenCanvas == nullptr) {
1724         return false;
1725     }
1726     if (bounds->GetLeft() != 0 || bounds->GetTop() != 0) {
1727         offscreenCanvas->Translate(-bounds->GetLeft(), -bounds->GetTop());
1728     }
1729 
1730     //OffscreenCanvas used once, detach is unnecessary, FakeBrush/Pen avoid affecting ImageRectOp, attach is necessary.
1731     bool isForeground = false;
1732     if (p.GetColor() == Drawing::Color::COLOR_FOREGROUND) {
1733         isForeground = true;
1734         p.SetColor(Drawing::Color::COLOR_BLACK);
1735     }
1736     offscreenCanvas->AttachPaint(p);
1737     offscreenCanvas->DrawTextBlob(textBlob, x, y);
1738 
1739     std::shared_ptr<Image> image = offscreenSurface->GetImageSnapshot();
1740     if (image == nullptr) {
1741         return false;
1742     }
1743     Drawing::Rect src(0, 0, image->GetWidth(), image->GetHeight());
1744     Drawing::Rect dst(bounds->GetLeft(), bounds->GetTop(),
1745         bounds->GetLeft() + image->GetWidth(), bounds->GetTop() + image->GetHeight());
1746     SamplingOptions sampling(FilterMode::LINEAR, MipmapMode::LINEAR);
1747     auto imageHandle = CmdListHelper::AddImageToCmdList(cmdList, image);
1748     PaintHandle fakePaintHandle;
1749     fakePaintHandle.isAntiAlias = true;
1750     fakePaintHandle.style = Paint::PaintStyle::PAINT_FILL;
1751     cmdList.AddOp<DrawImageRectOpItem::ConstructorHandle>(
1752         imageHandle, src, dst, sampling, SrcRectConstraint::STRICT_SRC_RECT_CONSTRAINT, fakePaintHandle, isForeground);
1753     return true;
1754 }
1755 
GenerateCachedOpItem(DrawCmdList & cmdList,Canvas * canvas)1756 bool DrawTextBlobOpItem::ConstructorHandle::GenerateCachedOpItem(DrawCmdList& cmdList, Canvas* canvas)
1757 {
1758     std::shared_ptr<TextBlob> textBlob_ = CmdListHelper::GetTextBlobFromCmdList(cmdList, textBlob, globalUniqueId);
1759     if (!textBlob_) {
1760         LOGD("textBlob nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
1761         return false;
1762     }
1763 
1764     auto bounds = textBlob_->Bounds();
1765     if (!bounds || !bounds->IsValid()) {
1766         return false;
1767     }
1768     bounds->Offset(x, y);
1769 
1770     std::shared_ptr<Surface> offscreenSurface = nullptr;
1771 
1772     if (auto surface = canvas != nullptr ? canvas->GetSurface() : nullptr) {
1773         // create GPU accelerated surface if possible
1774         offscreenSurface = surface->MakeSurface(bounds->GetWidth(), bounds->GetHeight());
1775     } else {
1776         // create CPU raster surface
1777         Drawing::ImageInfo offscreenInfo { bounds->GetWidth(), bounds->GetHeight(),
1778             Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL, nullptr};
1779         offscreenSurface = Surface::MakeRaster(offscreenInfo);
1780     }
1781     if (offscreenSurface == nullptr) {
1782         return false;
1783     }
1784 
1785     Canvas* offscreenCanvas = offscreenSurface->GetCanvas().get();
1786     if (!offscreenCanvas) {
1787         return false;
1788     }
1789 
1790     // align draw op to [0, 0]
1791     if (bounds->GetLeft() != 0 || bounds->GetTop() != 0) {
1792         offscreenCanvas->Translate(-bounds->GetLeft(), -bounds->GetTop());
1793     }
1794 
1795     Paint p;
1796     GeneratePaintFromHandle(paintHandle, cmdList, p);
1797     offscreenCanvas->AttachPaint(p);
1798     offscreenCanvas->DrawTextBlob(textBlob_.get(), x, y);
1799 
1800     std::shared_ptr<Image> image = offscreenSurface->GetImageSnapshot();
1801     if (image == nullptr) {
1802         return false;
1803     }
1804     Drawing::Rect src(0, 0, image->GetWidth(), image->GetHeight());
1805     Drawing::Rect dst(bounds->GetLeft(), bounds->GetTop(),
1806         bounds->GetLeft() + image->GetWidth(), bounds->GetTop() + image->GetHeight());
1807     SamplingOptions sampling;
1808     auto imageHandle = CmdListHelper::AddImageToCmdList(cmdList, image);
1809     PaintHandle fakePaintHandle;
1810     fakePaintHandle.isAntiAlias = true;
1811     fakePaintHandle.style = Paint::PaintStyle::PAINT_FILL;
1812     cmdList.AddOp<DrawImageRectOpItem::ConstructorHandle>(imageHandle, src, dst, sampling,
1813         SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT, fakePaintHandle);
1814     return true;
1815 }
1816 
GenerateCachedOpItem(Canvas * canvas)1817 std::shared_ptr<DrawImageRectOpItem> DrawTextBlobOpItem::GenerateCachedOpItem(Canvas* canvas)
1818 {
1819     if (!textBlob_) {
1820         LOGD("textBlob nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
1821         return nullptr;
1822     }
1823 
1824     auto bounds = textBlob_->Bounds();
1825     if (!bounds || !bounds->IsValid()) {
1826         return nullptr;
1827     }
1828     bounds->Offset(x_, y_);
1829 
1830     std::shared_ptr<Surface> offscreenSurface = nullptr;
1831 
1832     if (auto surface = canvas != nullptr ? canvas->GetSurface() : nullptr) {
1833         // create GPU accelerated surface if possible
1834         offscreenSurface = surface->MakeSurface(bounds->GetWidth(), bounds->GetHeight());
1835     } else {
1836         // create CPU raster surface
1837         Drawing::ImageInfo offscreenInfo { bounds->GetWidth(), bounds->GetHeight(),
1838             Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_PREMUL, nullptr};
1839         offscreenSurface = Surface::MakeRaster(offscreenInfo);
1840     }
1841     if (offscreenSurface == nullptr) {
1842         return nullptr;
1843     }
1844 
1845     Canvas* offscreenCanvas = offscreenSurface->GetCanvas().get();
1846     if (!offscreenCanvas) {
1847         return nullptr;
1848     }
1849 
1850     // align draw op to [0, 0]
1851     if (bounds->GetLeft() != 0 || bounds->GetTop() != 0) {
1852         offscreenCanvas->Translate(-bounds->GetLeft(), -bounds->GetTop());
1853     }
1854 
1855     Playback(offscreenCanvas, nullptr);
1856 
1857     std::shared_ptr<Image> image = offscreenSurface->GetImageSnapshot();
1858     if (image == nullptr) {
1859         return nullptr;
1860     }
1861     Drawing::Rect src(0, 0, image->GetWidth(), image->GetHeight());
1862     Drawing::Rect dst(bounds->GetLeft(), bounds->GetTop(), bounds->GetRight(), bounds->GetBottom());
1863     Paint fakePaint;
1864     fakePaint.SetStyle(Paint::PaintStyle::PAINT_FILL);
1865     fakePaint.SetAntiAlias(true);
1866     return std::make_shared<DrawImageRectOpItem>(*image, src, dst, SamplingOptions(),
1867         SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT, fakePaint);
1868 }
1869 
DumpItems(std::string & out) const1870 void DrawTextBlobOpItem::DumpItems(std::string& out) const
1871 {
1872     out += " scalarX:" + std::to_string(x_) + " scalarY:" + std::to_string(y_);
1873     if (textBlob_ != nullptr) {
1874         out += " TextBlob[";
1875         out += "UniqueID:" + std::to_string(textBlob_->UniqueID());
1876         auto bounds = textBlob_->Bounds();
1877         if (bounds != nullptr) {
1878             out += " Bounds";
1879             bounds->Dump(out);
1880         }
1881         out += " isEmoji:" + std::string(textBlob_->IsEmoji() ? "true" : "false");
1882         out += ']';
1883     }
1884 }
1885 
1886 /* DrawSymbolOpItem */
1887 UNMARSHALLING_REGISTER(DrawSymbol, DrawOpItem::SYMBOL_OPITEM,
1888     DrawSymbolOpItem::Unmarshalling, sizeof(DrawSymbolOpItem::ConstructorHandle));
1889 
DrawSymbolOpItem(const DrawCmdList & cmdList,DrawSymbolOpItem::ConstructorHandle * handle)1890 DrawSymbolOpItem::DrawSymbolOpItem(const DrawCmdList& cmdList, DrawSymbolOpItem::ConstructorHandle* handle)
1891     : DrawWithPaintOpItem(cmdList, handle->paintHandle, SYMBOL_OPITEM), locate_(handle->locate)
1892 {
1893     symbol_ = CmdListHelper::GetSymbolFromCmdList(cmdList, handle->symbolHandle);
1894 }
1895 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1896 std::shared_ptr<DrawOpItem> DrawSymbolOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1897 {
1898     return std::make_shared<DrawSymbolOpItem>(cmdList, static_cast<DrawSymbolOpItem::ConstructorHandle*>(handle));
1899 }
1900 
Marshalling(DrawCmdList & cmdList)1901 void DrawSymbolOpItem::Marshalling(DrawCmdList& cmdList)
1902 {
1903     PaintHandle paintHandle;
1904     GenerateHandleFromPaint(cmdList, paint_, paintHandle);
1905     auto symbolHandle = CmdListHelper::AddSymbolToCmdList(cmdList, symbol_);
1906     cmdList.AddOp<ConstructorHandle>(symbolHandle, locate_, paintHandle);
1907 }
1908 
Playback(Canvas * canvas,const Rect * rect)1909 void DrawSymbolOpItem::Playback(Canvas* canvas, const Rect* rect)
1910 {
1911     if (!canvas) {
1912         LOGD("SymbolOpItem::Playback failed cause by canvas is nullptr");
1913         return;
1914     }
1915     Path path(symbol_.path_);
1916 
1917     // 1.0 move path
1918     path.Offset(locate_.GetX(), locate_.GetY());
1919 
1920     // 2.0 split path
1921     std::vector<Path> paths;
1922     DrawingHMSymbol::PathOutlineDecompose(path, paths);
1923     std::vector<Path> pathLayers;
1924     DrawingHMSymbol::MultilayerPath(symbol_.symbolInfo_.layers, paths, pathLayers);
1925 
1926     // 3.0 set paint
1927     Paint paintCopy = paint_;
1928     paintCopy.SetAntiAlias(true);
1929     paintCopy.SetStyle(Paint::PaintStyle::PAINT_FILL_STROKE);
1930     paintCopy.SetWidth(0.0f);
1931     paintCopy.SetJoinStyle(Pen::JoinStyle::ROUND_JOIN);
1932 
1933     // draw path
1934     std::vector<DrawingRenderGroup> groups = symbol_.symbolInfo_.renderGroups;
1935     LOGD("SymbolOpItem::Draw RenderGroup size %{public}d", static_cast<int>(groups.size()));
1936     if (groups.size() == 0) {
1937         canvas->AttachPaint(paintCopy);
1938         canvas->DrawPath(path);
1939     }
1940     for (auto group : groups) {
1941         Path multPath;
1942         MergeDrawingPath(multPath, group, pathLayers);
1943         // color
1944         paintCopy.SetColor(Color::ColorQuadSetARGB(0xFF, group.color.r, group.color.g, group.color.b));
1945         paintCopy.SetAlphaF(group.color.a);
1946         canvas->AttachPaint(paintCopy);
1947         canvas->DrawPath(multPath);
1948     }
1949 }
1950 
MergeDrawingPath(Drawing::Path & multPath,Drawing::DrawingRenderGroup & group,std::vector<Drawing::Path> & pathLayers)1951 void DrawSymbolOpItem::MergeDrawingPath(
1952     Drawing::Path& multPath, Drawing::DrawingRenderGroup& group, std::vector<Drawing::Path>& pathLayers)
1953 {
1954     for (auto groupInfo : group.groupInfos) {
1955         Drawing::Path pathTemp;
1956         for (auto k : groupInfo.layerIndexes) {
1957             if (k >= pathLayers.size()) {
1958                 continue;
1959             }
1960             pathTemp.AddPath(pathLayers[k]);
1961         }
1962         for (size_t h : groupInfo.maskIndexes) {
1963             if (h >= pathLayers.size()) {
1964                 continue;
1965             }
1966             Drawing::Path outPath;
1967             auto isOk = outPath.Op(pathTemp, pathLayers[h], Drawing::PathOp::DIFFERENCE);
1968             if (isOk) {
1969                 pathTemp = outPath;
1970             }
1971         }
1972         multPath.AddPath(pathTemp);
1973     }
1974 }
1975 
DumpItems(std::string & out) const1976 void DrawSymbolOpItem::DumpItems(std::string& out) const
1977 {
1978     out += " symbol[symbolId:" + std::to_string(symbol_.symbolId);
1979     out += " DrawingType:" + std::to_string(static_cast<int>(symbol_.path_.GetDrawingType()));
1980     auto rect = symbol_.path_.GetBounds();
1981     out += " path";
1982     rect.Dump(out);
1983     out += " symbolGlyphId:" + std::to_string(symbol_.symbolInfo_.symbolGlyphId);
1984     out += "]";
1985     out += " locate";
1986     locate_.Dump(out);
1987 }
1988 
1989 /* ClipRectOpItem */
1990 UNMARSHALLING_REGISTER(ClipRect, DrawOpItem::CLIP_RECT_OPITEM,
1991     ClipRectOpItem::Unmarshalling, sizeof(ClipRectOpItem::ConstructorHandle));
1992 
ClipRectOpItem(ClipRectOpItem::ConstructorHandle * handle)1993 ClipRectOpItem::ClipRectOpItem(ClipRectOpItem::ConstructorHandle* handle)
1994     : DrawOpItem(CLIP_RECT_OPITEM), rect_(handle->rect), clipOp_(handle->clipOp), doAntiAlias_(handle->doAntiAlias) {}
1995 
Unmarshalling(const DrawCmdList & cmdList,void * handle)1996 std::shared_ptr<DrawOpItem> ClipRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
1997 {
1998     return std::make_shared<ClipRectOpItem>(static_cast<ClipRectOpItem::ConstructorHandle*>(handle));
1999 }
2000 
Marshalling(DrawCmdList & cmdList)2001 void ClipRectOpItem::Marshalling(DrawCmdList& cmdList)
2002 {
2003     cmdList.AddOp<ConstructorHandle>(rect_, clipOp_, doAntiAlias_);
2004 }
2005 
Playback(Canvas * canvas,const Rect * rect)2006 void ClipRectOpItem::Playback(Canvas* canvas, const Rect* rect)
2007 {
2008     canvas->ClipRect(rect_, clipOp_, doAntiAlias_);
2009 }
2010 
Dump(std::string & out) const2011 void ClipRectOpItem::Dump(std::string& out) const
2012 {
2013     out += GetOpDesc() + "[rect";
2014     rect_.Dump(out);
2015     out += " clipOp:" + std::to_string(static_cast<int>(clipOp_));
2016     out += " antiAlias:" + std::string(doAntiAlias_ ? "true" : "false");
2017     out += "]";
2018 }
2019 
2020 /* ClipIRectOpItem */
2021 UNMARSHALLING_REGISTER(ClipIRect, DrawOpItem::CLIP_IRECT_OPITEM,
2022     ClipIRectOpItem::Unmarshalling, sizeof(ClipIRectOpItem::ConstructorHandle));
2023 
ClipIRectOpItem(ClipIRectOpItem::ConstructorHandle * handle)2024 ClipIRectOpItem::ClipIRectOpItem(ClipIRectOpItem::ConstructorHandle* handle)
2025     : DrawOpItem(CLIP_IRECT_OPITEM), rect_(handle->rect), clipOp_(handle->clipOp) {}
2026 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2027 std::shared_ptr<DrawOpItem> ClipIRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2028 {
2029     return std::make_shared<ClipIRectOpItem>(static_cast<ClipIRectOpItem::ConstructorHandle*>(handle));
2030 }
2031 
Marshalling(DrawCmdList & cmdList)2032 void ClipIRectOpItem::Marshalling(DrawCmdList& cmdList)
2033 {
2034     cmdList.AddOp<ConstructorHandle>(rect_, clipOp_);
2035 }
2036 
Playback(Canvas * canvas,const Rect * rect)2037 void ClipIRectOpItem::Playback(Canvas* canvas, const Rect* rect)
2038 {
2039     canvas->ClipIRect(rect_, clipOp_);
2040 }
2041 
Dump(std::string & out) const2042 void ClipIRectOpItem::Dump(std::string& out) const
2043 {
2044     out += GetOpDesc() + "[rect";
2045     rect_.Dump(out);
2046     out += " clipOp:" + std::to_string(static_cast<int>(clipOp_));
2047     out += "]";
2048 }
2049 
2050 /* ClipRoundRectOpItem */
2051 UNMARSHALLING_REGISTER(ClipRoundRect, DrawOpItem::CLIP_ROUND_RECT_OPITEM,
2052     ClipRoundRectOpItem::Unmarshalling, sizeof(ClipRoundRectOpItem::ConstructorHandle));
2053 
ClipRoundRectOpItem(ClipRoundRectOpItem::ConstructorHandle * handle)2054 ClipRoundRectOpItem::ClipRoundRectOpItem(ClipRoundRectOpItem::ConstructorHandle* handle)
2055     : DrawOpItem(CLIP_ROUND_RECT_OPITEM), rrect_(handle->rrect), clipOp_(handle->clipOp),
2056     doAntiAlias_(handle->doAntiAlias) {}
2057 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2058 std::shared_ptr<DrawOpItem> ClipRoundRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2059 {
2060     return std::make_shared<ClipRoundRectOpItem>(static_cast<ClipRoundRectOpItem::ConstructorHandle*>(handle));
2061 }
2062 
Marshalling(DrawCmdList & cmdList)2063 void ClipRoundRectOpItem::Marshalling(DrawCmdList& cmdList)
2064 {
2065     cmdList.AddOp<ConstructorHandle>(rrect_, clipOp_, doAntiAlias_);
2066 }
2067 
Playback(Canvas * canvas,const Rect * rect)2068 void ClipRoundRectOpItem::Playback(Canvas* canvas, const Rect* rect)
2069 {
2070     canvas->ClipRoundRect(rrect_, clipOp_, doAntiAlias_);
2071 }
2072 
Dump(std::string & out) const2073 void ClipRoundRectOpItem::Dump(std::string& out) const
2074 {
2075     out += GetOpDesc() + "[rrect";
2076     rrect_.Dump(out);
2077     out += " clipOp:" + std::to_string(static_cast<int>(clipOp_));
2078     out += " antiAlias:" + std::string(doAntiAlias_ ? "true" : "false");
2079     out += "]";
2080 }
2081 
2082 /* ClipPathOpItem */
2083 UNMARSHALLING_REGISTER(ClipPath, DrawOpItem::CLIP_PATH_OPITEM,
2084     ClipPathOpItem::Unmarshalling, sizeof(ClipPathOpItem::ConstructorHandle));
2085 
ClipPathOpItem(const DrawCmdList & cmdList,ClipPathOpItem::ConstructorHandle * handle)2086 ClipPathOpItem::ClipPathOpItem(const DrawCmdList& cmdList, ClipPathOpItem::ConstructorHandle* handle)
2087     : DrawOpItem(CLIP_PATH_OPITEM), clipOp_(handle->clipOp), doAntiAlias_(handle->doAntiAlias)
2088 {
2089     path_ = CmdListHelper::GetPathFromCmdList(cmdList, handle->path);
2090 }
2091 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2092 std::shared_ptr<DrawOpItem> ClipPathOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2093 {
2094     return std::make_shared<ClipPathOpItem>(cmdList, static_cast<ClipPathOpItem::ConstructorHandle*>(handle));
2095 }
2096 
Marshalling(DrawCmdList & cmdList)2097 void ClipPathOpItem::Marshalling(DrawCmdList& cmdList)
2098 {
2099     OpDataHandle pathHandle;
2100     if (path_) {
2101         pathHandle = CmdListHelper::AddPathToCmdList(cmdList, *path_);
2102     }
2103     cmdList.AddOp<ConstructorHandle>(pathHandle, clipOp_, doAntiAlias_);
2104 }
2105 
Playback(Canvas * canvas,const Rect * rect)2106 void ClipPathOpItem::Playback(Canvas* canvas, const Rect* rect)
2107 {
2108     if (path_ == nullptr) {
2109         LOGD("ClipPathOpItem path is null!");
2110         return;
2111     }
2112     canvas->ClipPath(*path_, clipOp_, doAntiAlias_);
2113 }
2114 
2115 /* ClipRegionOpItem */
2116 UNMARSHALLING_REGISTER(ClipRegion, DrawOpItem::CLIP_REGION_OPITEM,
2117     ClipRegionOpItem::Unmarshalling, sizeof(ClipRegionOpItem::ConstructorHandle));
2118 
ClipRegionOpItem(const DrawCmdList & cmdList,ClipRegionOpItem::ConstructorHandle * handle)2119 ClipRegionOpItem::ClipRegionOpItem(const DrawCmdList& cmdList, ClipRegionOpItem::ConstructorHandle* handle)
2120     : DrawOpItem(CLIP_REGION_OPITEM), clipOp_(handle->clipOp)
2121 {
2122     region_ = CmdListHelper::GetRegionFromCmdList(cmdList, handle->region);
2123 }
2124 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2125 std::shared_ptr<DrawOpItem> ClipRegionOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2126 {
2127     return std::make_shared<ClipRegionOpItem>(cmdList, static_cast<ClipRegionOpItem::ConstructorHandle*>(handle));
2128 }
2129 
Marshalling(DrawCmdList & cmdList)2130 void ClipRegionOpItem::Marshalling(DrawCmdList& cmdList)
2131 {
2132     OpDataHandle regionHandle;
2133     if (region_) {
2134         regionHandle = CmdListHelper::AddRegionToCmdList(cmdList, *region_);
2135     }
2136     cmdList.AddOp<ConstructorHandle>(regionHandle, clipOp_);
2137 }
2138 
Playback(Canvas * canvas,const Rect * rect)2139 void ClipRegionOpItem::Playback(Canvas* canvas, const Rect* rect)
2140 {
2141     if (region_ == nullptr) {
2142         LOGD("ClipRegionOpItem region is null!");
2143         return;
2144     }
2145     canvas->ClipRegion(*region_, clipOp_);
2146 }
2147 
Dump(std::string & out) const2148 void ClipRegionOpItem::Dump(std::string& out) const
2149 {
2150     out += GetOpDesc() + "[clipOp:";
2151     out += std::to_string(static_cast<int>(clipOp_)) + " region";
2152     if (region_) {
2153         region_->Dump(out);
2154     } else {
2155         out += "[null]";
2156     }
2157     out += "]";
2158 }
2159 
2160 /* SetMatrixOpItem */
2161 UNMARSHALLING_REGISTER(SetMatrix, DrawOpItem::SET_MATRIX_OPITEM,
2162     SetMatrixOpItem::Unmarshalling, sizeof(SetMatrixOpItem::ConstructorHandle));
2163 
SetMatrixOpItem(SetMatrixOpItem::ConstructorHandle * handle)2164 SetMatrixOpItem::SetMatrixOpItem(SetMatrixOpItem::ConstructorHandle* handle) : DrawOpItem(SET_MATRIX_OPITEM)
2165 {
2166     matrix_.SetAll(handle->matrixBuffer);
2167 }
2168 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2169 std::shared_ptr<DrawOpItem> SetMatrixOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2170 {
2171     return std::make_shared<SetMatrixOpItem>(static_cast<SetMatrixOpItem::ConstructorHandle*>(handle));
2172 }
2173 
Marshalling(DrawCmdList & cmdList)2174 void SetMatrixOpItem::Marshalling(DrawCmdList& cmdList)
2175 {
2176     Matrix::Buffer matrixBuffer;
2177     matrix_.GetAll(matrixBuffer);
2178     cmdList.AddOp<ConstructorHandle>(matrixBuffer);
2179 }
2180 
Playback(Canvas * canvas,const Rect * rect)2181 void SetMatrixOpItem::Playback(Canvas* canvas, const Rect* rect)
2182 {
2183     canvas->SetMatrix(matrix_);
2184 }
2185 
Dump(std::string & out) const2186 void SetMatrixOpItem::Dump(std::string& out) const
2187 {
2188     out += GetOpDesc() + "[matrix";
2189     Matrix::Buffer buffer;
2190     matrix_.GetAll(buffer);
2191     DumpArray(out, buffer, [](std::string& out, float v) {
2192         out += std::to_string(v);
2193     });
2194     out += "]";
2195 }
2196 
2197 /* ResetMatrixOpItem */
2198 UNMARSHALLING_REGISTER(ResetMatrix, DrawOpItem::RESET_MATRIX_OPITEM,
2199     ResetMatrixOpItem::Unmarshalling, sizeof(ResetMatrixOpItem::ConstructorHandle));
2200 
ResetMatrixOpItem()2201 ResetMatrixOpItem::ResetMatrixOpItem() : DrawOpItem(RESET_MATRIX_OPITEM) {}
2202 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2203 std::shared_ptr<DrawOpItem> ResetMatrixOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2204 {
2205     return std::make_shared<ResetMatrixOpItem>();
2206 }
2207 
Marshalling(DrawCmdList & cmdList)2208 void ResetMatrixOpItem::Marshalling(DrawCmdList& cmdList)
2209 {
2210     cmdList.AddOp<ConstructorHandle>();
2211 }
2212 
Playback(Canvas * canvas,const Rect * rect)2213 void ResetMatrixOpItem::Playback(Canvas* canvas, const Rect* rect)
2214 {
2215     canvas->ResetMatrix();
2216 }
2217 
2218 /* ConcatMatrixOpItem */
2219 UNMARSHALLING_REGISTER(ConcatMatrix, DrawOpItem::CONCAT_MATRIX_OPITEM,
2220     ConcatMatrixOpItem::Unmarshalling, sizeof(ConcatMatrixOpItem::ConstructorHandle));
2221 
ConcatMatrixOpItem(ConcatMatrixOpItem::ConstructorHandle * handle)2222 ConcatMatrixOpItem::ConcatMatrixOpItem(ConcatMatrixOpItem::ConstructorHandle* handle) : DrawOpItem(CONCAT_MATRIX_OPITEM)
2223 {
2224     matrix_.SetAll(handle->matrixBuffer);
2225 }
2226 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2227 std::shared_ptr<DrawOpItem> ConcatMatrixOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2228 {
2229     return std::make_shared<ConcatMatrixOpItem>(static_cast<ConcatMatrixOpItem::ConstructorHandle*>(handle));
2230 }
2231 
Marshalling(DrawCmdList & cmdList)2232 void ConcatMatrixOpItem::Marshalling(DrawCmdList& cmdList)
2233 {
2234     Matrix::Buffer matrixBuffer;
2235     matrix_.GetAll(matrixBuffer);
2236     cmdList.AddOp<ConstructorHandle>(matrixBuffer);
2237 }
2238 
Playback(Canvas * canvas,const Rect * rect)2239 void ConcatMatrixOpItem::Playback(Canvas* canvas, const Rect* rect)
2240 {
2241     canvas->ConcatMatrix(matrix_);
2242 }
2243 
Dump(std::string & out) const2244 void ConcatMatrixOpItem::Dump(std::string& out) const
2245 {
2246     out += GetOpDesc() + "[matrix";
2247     Matrix::Buffer buffer;
2248     matrix_.GetAll(buffer);
2249     DumpArray(out, buffer, [](std::string& out, float v) {
2250         out += std::to_string(v);
2251     });
2252     out += "]";
2253 }
2254 
2255 /* TranslateOpItem */
2256 UNMARSHALLING_REGISTER(Translate, DrawOpItem::TRANSLATE_OPITEM,
2257     TranslateOpItem::Unmarshalling, sizeof(TranslateOpItem::ConstructorHandle));
2258 
TranslateOpItem(TranslateOpItem::ConstructorHandle * handle)2259 TranslateOpItem::TranslateOpItem(TranslateOpItem::ConstructorHandle* handle)
2260     : DrawOpItem(TRANSLATE_OPITEM), dx_(handle->dx), dy_(handle->dy) {}
2261 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2262 std::shared_ptr<DrawOpItem> TranslateOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2263 {
2264     return std::make_shared<TranslateOpItem>(static_cast<TranslateOpItem::ConstructorHandle*>(handle));
2265 }
2266 
Marshalling(DrawCmdList & cmdList)2267 void TranslateOpItem::Marshalling(DrawCmdList& cmdList)
2268 {
2269     cmdList.AddOp<ConstructorHandle>(dx_, dy_);
2270 }
2271 
Playback(Canvas * canvas,const Rect * rect)2272 void TranslateOpItem::Playback(Canvas* canvas, const Rect* rect)
2273 {
2274     canvas->Translate(dx_, dy_);
2275 }
2276 
Dump(std::string & out) const2277 void TranslateOpItem::Dump(std::string& out) const
2278 {
2279     out += GetOpDesc() + "[x:";
2280     out += std::to_string(dx_) + " y:";
2281     out += std::to_string(dy_);
2282     out += "]";
2283 }
2284 
2285 /* ScaleOpItem */
2286 UNMARSHALLING_REGISTER(Scale, DrawOpItem::SCALE_OPITEM,
2287     ScaleOpItem::Unmarshalling, sizeof(ScaleOpItem::ConstructorHandle));
2288 
ScaleOpItem(ScaleOpItem::ConstructorHandle * handle)2289 ScaleOpItem::ScaleOpItem(ScaleOpItem::ConstructorHandle* handle)
2290     : DrawOpItem(SCALE_OPITEM), sx_(handle->sx), sy_(handle->sy) {}
2291 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2292 std::shared_ptr<DrawOpItem> ScaleOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2293 {
2294     return std::make_shared<ScaleOpItem>(static_cast<ScaleOpItem::ConstructorHandle*>(handle));
2295 }
2296 
Marshalling(DrawCmdList & cmdList)2297 void ScaleOpItem::Marshalling(DrawCmdList& cmdList)
2298 {
2299     cmdList.AddOp<ConstructorHandle>(sx_, sy_);
2300 }
2301 
Playback(Canvas * canvas,const Rect * rect)2302 void ScaleOpItem::Playback(Canvas* canvas, const Rect* rect)
2303 {
2304     canvas->Scale(sx_, sy_);
2305 }
2306 
Dump(std::string & out) const2307 void ScaleOpItem::Dump(std::string& out) const
2308 {
2309     out += GetOpDesc() + "[x:";
2310     out += std::to_string(sx_) + " y:";
2311     out += std::to_string(sy_);
2312     out += "]";
2313 }
2314 
2315 /* RotateOpItem */
2316 UNMARSHALLING_REGISTER(Rotate, DrawOpItem::ROTATE_OPITEM,
2317     RotateOpItem::Unmarshalling, sizeof(RotateOpItem::ConstructorHandle));
2318 
RotateOpItem(RotateOpItem::ConstructorHandle * handle)2319 RotateOpItem::RotateOpItem(RotateOpItem::ConstructorHandle* handle)
2320     : DrawOpItem(ROTATE_OPITEM), deg_(handle->deg), sx_(handle->sx), sy_(handle->sy) {}
2321 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2322 std::shared_ptr<DrawOpItem> RotateOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2323 {
2324     return std::make_shared<RotateOpItem>(static_cast<RotateOpItem::ConstructorHandle*>(handle));
2325 }
2326 
Marshalling(DrawCmdList & cmdList)2327 void RotateOpItem::Marshalling(DrawCmdList& cmdList)
2328 {
2329     cmdList.AddOp<ConstructorHandle>(deg_, sx_, sy_);
2330 }
2331 
Playback(Canvas * canvas,const Rect * rect)2332 void RotateOpItem::Playback(Canvas* canvas, const Rect* rect)
2333 {
2334     canvas->Rotate(deg_, sx_, sy_);
2335 }
2336 
Dump(std::string & out) const2337 void RotateOpItem::Dump(std::string& out) const
2338 {
2339     out += GetOpDesc() + "[degree:";
2340     out += std::to_string(deg_) + " x:";
2341     out += std::to_string(sx_) + " y:";
2342     out += std::to_string(sy_);
2343     out += "]";
2344 }
2345 
2346 /* ShearOpItem */
2347 UNMARSHALLING_REGISTER(Shear, DrawOpItem::SHEAR_OPITEM,
2348     ShearOpItem::Unmarshalling, sizeof(ShearOpItem::ConstructorHandle));
2349 
ShearOpItem(ShearOpItem::ConstructorHandle * handle)2350 ShearOpItem::ShearOpItem(ShearOpItem::ConstructorHandle* handle)
2351     : DrawOpItem(SHEAR_OPITEM), sx_(handle->sx), sy_(handle->sy) {}
2352 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2353 std::shared_ptr<DrawOpItem> ShearOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2354 {
2355     return std::make_shared<ShearOpItem>(static_cast<ShearOpItem::ConstructorHandle*>(handle));
2356 }
2357 
Marshalling(DrawCmdList & cmdList)2358 void ShearOpItem::Marshalling(DrawCmdList& cmdList)
2359 {
2360     cmdList.AddOp<ConstructorHandle>(sx_, sy_);
2361 }
2362 
Playback(Canvas * canvas,const Rect * rect)2363 void ShearOpItem::Playback(Canvas* canvas, const Rect* rect)
2364 {
2365     canvas->Shear(sx_, sy_);
2366 }
2367 
Dump(std::string & out) const2368 void ShearOpItem::Dump(std::string& out) const
2369 {
2370     out += GetOpDesc() + "[x:";
2371     out += std::to_string(sx_) + " y:";
2372     out += std::to_string(sy_);
2373     out += "]";
2374 }
2375 
2376 /* FlushOpItem */
2377 UNMARSHALLING_REGISTER(Flush, DrawOpItem::FLUSH_OPITEM,
2378     FlushOpItem::Unmarshalling, sizeof(FlushOpItem::ConstructorHandle));
2379 
FlushOpItem()2380 FlushOpItem::FlushOpItem() : DrawOpItem(FLUSH_OPITEM) {}
2381 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2382 std::shared_ptr<DrawOpItem> FlushOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2383 {
2384     return std::make_shared<FlushOpItem>();
2385 }
2386 
Marshalling(DrawCmdList & cmdList)2387 void FlushOpItem::Marshalling(DrawCmdList& cmdList)
2388 {
2389     cmdList.AddOp<ConstructorHandle>();
2390 }
2391 
Playback(Canvas * canvas,const Rect * rect)2392 void FlushOpItem::Playback(Canvas* canvas, const Rect* rect)
2393 {
2394     canvas->Flush();
2395 }
2396 
2397 /* ClearOpItem */
2398 UNMARSHALLING_REGISTER(Clear, DrawOpItem::CLEAR_OPITEM,
2399     ClearOpItem::Unmarshalling, sizeof(ClearOpItem::ConstructorHandle));
2400 
ClearOpItem(ClearOpItem::ConstructorHandle * handle)2401 ClearOpItem::ClearOpItem(ClearOpItem::ConstructorHandle* handle)
2402     : DrawOpItem(CLEAR_OPITEM), color_(handle->color) {}
2403 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2404 std::shared_ptr<DrawOpItem> ClearOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2405 {
2406     return std::make_shared<ClearOpItem>(static_cast<ClearOpItem::ConstructorHandle*>(handle));
2407 }
2408 
Marshalling(DrawCmdList & cmdList)2409 void ClearOpItem::Marshalling(DrawCmdList& cmdList)
2410 {
2411     cmdList.AddOp<ConstructorHandle>(color_);
2412 }
2413 
Playback(Canvas * canvas,const Rect * rect)2414 void ClearOpItem::Playback(Canvas* canvas, const Rect* rect)
2415 {
2416     canvas->Clear(color_);
2417 }
2418 
Dump(std::string & out) const2419 void ClearOpItem::Dump(std::string& out) const
2420 {
2421     out += GetOpDesc();
2422     Color(color_).Dump(out);
2423 }
2424 
2425 /* SaveOpItem */
2426 UNMARSHALLING_REGISTER(Save, DrawOpItem::SAVE_OPITEM,
2427     SaveOpItem::Unmarshalling, sizeof(SaveOpItem::ConstructorHandle));
2428 
SaveOpItem()2429 SaveOpItem::SaveOpItem() : DrawOpItem(SAVE_OPITEM) {}
2430 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2431 std::shared_ptr<DrawOpItem> SaveOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2432 {
2433     return std::make_shared<SaveOpItem>();
2434 }
2435 
Marshalling(DrawCmdList & cmdList)2436 void SaveOpItem::Marshalling(DrawCmdList& cmdList)
2437 {
2438     cmdList.AddOp<ConstructorHandle>();
2439 }
2440 
Playback(Canvas * canvas,const Rect * rect)2441 void SaveOpItem::Playback(Canvas* canvas, const Rect* rect)
2442 {
2443     canvas->Save();
2444 }
2445 
2446 /* SaveLayerOpItem */
2447 UNMARSHALLING_REGISTER(SaveLayer, DrawOpItem::SAVE_LAYER_OPITEM,
2448     SaveLayerOpItem::Unmarshalling, sizeof(SaveLayerOpItem::ConstructorHandle));
2449 
SaveLayerOpItem(const DrawCmdList & cmdList,SaveLayerOpItem::ConstructorHandle * handle)2450 SaveLayerOpItem::SaveLayerOpItem(const DrawCmdList& cmdList, SaveLayerOpItem::ConstructorHandle* handle)
2451     : DrawOpItem(SAVE_LAYER_OPITEM), saveLayerFlags_(handle->saveLayerFlags), rect_(handle->rect),
2452     hasBrush_(handle->hasBrush)
2453 {
2454     if (hasBrush_) {
2455         BrushHandleToBrush(handle->brushHandle, cmdList, brush_);
2456     }
2457 }
2458 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2459 std::shared_ptr<DrawOpItem> SaveLayerOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2460 {
2461     return std::make_shared<SaveLayerOpItem>(cmdList, static_cast<SaveLayerOpItem::ConstructorHandle*>(handle));
2462 }
2463 
Marshalling(DrawCmdList & cmdList)2464 void SaveLayerOpItem::Marshalling(DrawCmdList& cmdList)
2465 {
2466     BrushHandle brushHandle;
2467     if (hasBrush_) {
2468         BrushToBrushHandle(brush_, cmdList, brushHandle);
2469     }
2470     cmdList.AddOp<ConstructorHandle>(rect_, hasBrush_, brushHandle, saveLayerFlags_);
2471 }
2472 
Playback(Canvas * canvas,const Rect * rect)2473 void SaveLayerOpItem::Playback(Canvas* canvas, const Rect* rect)
2474 {
2475     const Rect* rectPtr = nullptr;
2476     if (rect_.IsValid()) {
2477         rectPtr = &rect_;
2478     }
2479     Brush* brushPtr = hasBrush_ ? &brush_ : nullptr;
2480     SaveLayerOps slo(rectPtr, brushPtr, saveLayerFlags_);
2481     canvas->SaveLayer(slo);
2482 }
2483 
Dump(std::string & out) const2484 void SaveLayerOpItem::Dump(std::string& out) const
2485 {
2486     out += GetOpDesc() + "[flags:";
2487     out += std::to_string(saveLayerFlags_) + " rect";
2488     rect_.Dump(out);
2489     out += " brush";
2490     if (hasBrush_) {
2491         brush_.Dump(out);
2492     } else {
2493         out += "[null]";
2494     }
2495     out += "]";
2496 }
2497 
2498 /* RestoreOpItem */
2499 UNMARSHALLING_REGISTER(Restore, DrawOpItem::RESTORE_OPITEM,
2500     RestoreOpItem::Unmarshalling, sizeof(RestoreOpItem::ConstructorHandle));
2501 
RestoreOpItem()2502 RestoreOpItem::RestoreOpItem() : DrawOpItem(RESTORE_OPITEM) {}
2503 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2504 std::shared_ptr<DrawOpItem> RestoreOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2505 {
2506     return std::make_shared<RestoreOpItem>();
2507 }
2508 
Marshalling(DrawCmdList & cmdList)2509 void RestoreOpItem::Marshalling(DrawCmdList& cmdList)
2510 {
2511     cmdList.AddOp<ConstructorHandle>();
2512 }
2513 
Playback(Canvas * canvas,const Rect * rect)2514 void RestoreOpItem::Playback(Canvas* canvas, const Rect* rect)
2515 {
2516     canvas->Restore();
2517 }
2518 
2519 /* DiscardOpItem */
2520 UNMARSHALLING_REGISTER(Discard, DrawOpItem::DISCARD_OPITEM,
2521     DiscardOpItem::Unmarshalling, sizeof(DiscardOpItem::ConstructorHandle));
2522 
DiscardOpItem()2523 DiscardOpItem::DiscardOpItem() : DrawOpItem(DISCARD_OPITEM) {}
2524 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2525 std::shared_ptr<DrawOpItem> DiscardOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2526 {
2527     return std::make_shared<DiscardOpItem>();
2528 }
2529 
Marshalling(DrawCmdList & cmdList)2530 void DiscardOpItem::Marshalling(DrawCmdList& cmdList)
2531 {
2532     cmdList.AddOp<ConstructorHandle>();
2533 }
2534 
Playback(Canvas * canvas,const Rect * rect)2535 void DiscardOpItem::Playback(Canvas* canvas, const Rect* rect)
2536 {
2537     canvas->Discard();
2538 }
2539 
2540 /* ClipAdaptiveRoundRectOpItem */
2541 UNMARSHALLING_REGISTER(ClipAdaptiveRoundRect, DrawOpItem::CLIP_ADAPTIVE_ROUND_RECT_OPITEM,
2542     ClipAdaptiveRoundRectOpItem::Unmarshalling, sizeof(ClipAdaptiveRoundRectOpItem::ConstructorHandle));
2543 
ClipAdaptiveRoundRectOpItem(const DrawCmdList & cmdList,ClipAdaptiveRoundRectOpItem::ConstructorHandle * handle)2544 ClipAdaptiveRoundRectOpItem::ClipAdaptiveRoundRectOpItem(
2545     const DrawCmdList& cmdList, ClipAdaptiveRoundRectOpItem::ConstructorHandle* handle)
2546     : DrawOpItem(CLIP_ADAPTIVE_ROUND_RECT_OPITEM)
2547 {
2548     radiusData_ = CmdListHelper::GetVectorFromCmdList<Point>(cmdList, handle->radiusData);
2549 }
2550 
Unmarshalling(const DrawCmdList & cmdList,void * handle)2551 std::shared_ptr<DrawOpItem> ClipAdaptiveRoundRectOpItem::Unmarshalling(const DrawCmdList& cmdList, void* handle)
2552 {
2553     return std::make_shared<ClipAdaptiveRoundRectOpItem>(
2554         cmdList, static_cast<ClipAdaptiveRoundRectOpItem::ConstructorHandle*>(handle));
2555 }
2556 
Marshalling(DrawCmdList & cmdList)2557 void ClipAdaptiveRoundRectOpItem::Marshalling(DrawCmdList& cmdList)
2558 {
2559     auto radiusData = CmdListHelper::AddVectorToCmdList<Point>(cmdList, radiusData_);
2560     cmdList.AddOp<ConstructorHandle>(radiusData);
2561 }
2562 
Playback(Canvas * canvas,const Rect * rect)2563 void ClipAdaptiveRoundRectOpItem::Playback(Canvas* canvas, const Rect* rect)
2564 {
2565     canvas->ClipRoundRect(*rect, radiusData_, true);
2566 }
2567 
Dump(std::string & out) const2568 void ClipAdaptiveRoundRectOpItem::Dump(std::string& out) const
2569 {
2570     out += GetOpDesc() + "[radius";
2571     DumpArray(out, radiusData_, [](std::string& out, const Point& p) {
2572         out += "[";
2573         out += std::to_string(p.GetX()) + " ";
2574         out += std::to_string(p.GetY());
2575         out += "]";
2576     });
2577     out += "]";
2578 }
2579 } // namespace Drawing
2580 } // namespace Rosen
2581 } // namespace OHOS
2582