• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.. All rights reserved.
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 "skia_canvas.h"
17 
18 #include "modules/svg/include/SkSVGDOM.h"
19 
20 #ifdef RS_ENABLE_GPU
21 #include "skia_gpu_context.h"
22 #endif
23 #include "skia_convert_utils.h"
24 #include "skia_image_filter.h"
25 #include "skia_path.h"
26 #include "skia_image_info.h"
27 #include "skia_data.h"
28 #include "skia_text_blob.h"
29 #include "skia_surface.h"
30 #include "skia_canvas_autocache.h"
31 #include "skia_oplist_handle.h"
32 
33 #include "draw/core_canvas.h"
34 #include "draw/canvas.h"
35 #include "image/bitmap.h"
36 #include "image/image.h"
37 #include "utils/log.h"
38 #include "utils/performanceCaculate.h"
39 #include "SkOverdrawCanvas.h"
40 #include "include/utils/SkNoDrawCanvas.h"
41 #include "src/core/SkCanvasPriv.h"
42 
43 namespace OHOS {
44 namespace Rosen {
45 namespace Drawing {
46 static constexpr int32_t MAX_PARA_LEN = 15;
SkiaCanvas()47 SkiaCanvas::SkiaCanvas() : skiaCanvas_(std::make_shared<SkCanvas>())
48 {
49     skCanvas_ = skiaCanvas_.get();
50 }
51 
SkiaCanvas(DrawingType type)52 SkiaCanvas::SkiaCanvas(DrawingType type)
53 {
54     switch (type) {
55         case DrawingType::OVER_DRAW:
56         case DrawingType::NO_DRAW:
57             skiaCanvas_ = nullptr;
58             skCanvas_ = nullptr;
59             break;
60         default:
61             SkiaCanvas();
62     }
63 }
64 
SkiaCanvas(const std::shared_ptr<SkCanvas> & skCanvas)65 SkiaCanvas::SkiaCanvas(const std::shared_ptr<SkCanvas>& skCanvas) : skiaCanvas_(skCanvas)
66 {
67     skCanvas_ = skiaCanvas_.get();
68 }
69 
SkiaCanvas(int32_t width,int32_t height)70 SkiaCanvas::SkiaCanvas(int32_t width, int32_t height)
71     : skiaCanvas_(std::make_shared<SkCanvas>(width, height))
72 {
73     skCanvas_ = skiaCanvas_.get();
74 }
75 
ExportSkCanvas() const76 SkCanvas* SkiaCanvas::ExportSkCanvas() const
77 {
78     return skCanvas_;
79 }
80 
ImportSkCanvas(SkCanvas * skCanvas)81 void SkiaCanvas::ImportSkCanvas(SkCanvas* skCanvas)
82 {
83     skCanvas_ = skCanvas;
84 }
85 
Bind(const Bitmap & bitmap)86 void SkiaCanvas::Bind(const Bitmap& bitmap)
87 {
88     auto skBitmapImpl = bitmap.GetImpl<SkiaBitmap>();
89     if (skBitmapImpl != nullptr) {
90         skiaCanvas_ = std::make_shared<SkCanvas>(skBitmapImpl->ExportSkiaBitmap());
91         skCanvas_ = skiaCanvas_.get();
92     }
93 }
94 
GetTotalMatrix() const95 Matrix SkiaCanvas::GetTotalMatrix() const
96 {
97     if (skCanvas_ == nullptr) {
98         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
99         return Matrix();
100     }
101     Matrix matrix;
102     matrix.GetImpl<SkiaMatrix>()->ImportMatrix(skCanvas_->getTotalMatrix());
103     return matrix;
104 }
105 
GetLocalClipBounds() const106 Rect SkiaCanvas::GetLocalClipBounds() const
107 {
108     if (skCanvas_ == nullptr) {
109         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
110         return Rect();
111     }
112     auto rect = skCanvas_->getLocalClipBounds();
113     return Rect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
114 }
115 
GetDeviceClipBounds() const116 RectI SkiaCanvas::GetDeviceClipBounds() const
117 {
118     if (skCanvas_ == nullptr) {
119         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
120         return RectI();
121     }
122     auto iRect = skCanvas_->getDeviceClipBounds();
123     return RectI(iRect.fLeft, iRect.fTop, iRect.fRight, iRect.fBottom);
124 }
125 
InheriteState(Canvas * canvas)126 void SkiaCanvas::InheriteState(Canvas* canvas)
127 {
128 }
129 
RecordState(Canvas * canvas)130 void SkiaCanvas::RecordState(Canvas* canvas)
131 {
132     LOGD("skia does not support RecordState.");
133 }
134 
SetParallelRender(bool parallelEnable)135 void SkiaCanvas::SetParallelRender(bool parallelEnable)
136 {
137     LOGD("skia does not support subtree parallel render.");
138 }
139 
BuildStateRecord(int32_t width,int32_t height)140 void SkiaCanvas::BuildStateRecord(int32_t width, int32_t height)
141 {
142     LOGD("skia does not support build state record.");
143 }
144 
GetRoundInDeviceClipBounds() const145 RectI SkiaCanvas::GetRoundInDeviceClipBounds() const
146 {
147     if (skCanvas_ == nullptr) {
148         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
149         return RectI();
150     }
151     auto iRect = skCanvas_->getRoundInDeviceClipBounds();
152     return RectI(iRect.fLeft, iRect.fTop, iRect.fRight, iRect.fBottom);
153 }
154 
155 #ifdef RS_ENABLE_GPU
GetGPUContext() const156 std::shared_ptr<GPUContext> SkiaCanvas::GetGPUContext() const
157 {
158     if (skCanvas_ == nullptr || skCanvas_->recordingContext() == nullptr ||
159         GrAsDirectContext(skCanvas_->recordingContext()) == nullptr) {
160         LOGD("skCanvas_ or grContext is null, return on line %{public}d", __LINE__);
161         return nullptr;
162     }
163     auto grContext = GrAsDirectContext(skCanvas_->recordingContext());
164 
165     auto gpuContext = std::make_shared<GPUContext>();
166     gpuContext->GetImpl<SkiaGPUContext>()->SetGrContext(sk_ref_sp(grContext));
167 
168     return gpuContext;
169 }
170 #endif
171 
GetWidth() const172 int32_t SkiaCanvas::GetWidth() const
173 {
174     return (skCanvas_ != nullptr) ? skCanvas_->imageInfo().width() : 0;
175 }
176 
GetHeight() const177 int32_t SkiaCanvas::GetHeight() const
178 {
179     return (skCanvas_ != nullptr) ? skCanvas_->imageInfo().height() : 0;
180 }
181 
GetImageInfo()182 ImageInfo SkiaCanvas::GetImageInfo()
183 {
184     if (skCanvas_ == nullptr) {
185         return {};
186     }
187     return SkiaImageInfo::ConvertToRSImageInfo(skCanvas_->imageInfo());
188 }
189 
ReadPixels(const ImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY)190 bool SkiaCanvas::ReadPixels(const ImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
191     int srcX, int srcY)
192 {
193     if (!skCanvas_) {
194         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
195         return false;
196     }
197     auto colorSpace = dstInfo.GetColorSpace();
198     auto colorSpaceImpl = colorSpace ? colorSpace->GetImpl<SkiaColorSpace>() : nullptr;
199     SkImageInfo info = SkImageInfo::Make(dstInfo.GetWidth(), dstInfo.GetHeight(),
200                                          SkiaImageInfo::ConvertToSkColorType(dstInfo.GetColorType()),
201                                          SkiaImageInfo::ConvertToSkAlphaType(dstInfo.GetAlphaType()),
202                                          colorSpaceImpl ? colorSpaceImpl->GetColorSpace() : nullptr);
203     return skCanvas_->readPixels(info, dstPixels, dstRowBytes, srcX, srcY);
204 }
205 
ReadPixels(const Bitmap & dstBitmap,int srcX,int srcY)206 bool SkiaCanvas::ReadPixels(const Bitmap& dstBitmap, int srcX, int srcY)
207 {
208     if (!skCanvas_) {
209         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
210         return false;
211     }
212     const SkBitmap& skBitmap = dstBitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
213     return skCanvas_->readPixels(skBitmap, srcX, srcY);
214 }
215 
AddSdfPara(SkRuntimeShaderBuilder & builder,const SDFShapeBase & shape)216 bool SkiaCanvas::AddSdfPara(SkRuntimeShaderBuilder& builder, const SDFShapeBase& shape)
217 {
218     std::vector<float> para = shape.GetPara();
219     std::vector<float> transPara = shape.GetTransPara();
220     uint64_t transCount = transPara.size();
221     uint64_t paraCount = para.size();
222     for (uint64_t i = 1; i <= paraCount; i++) {
223         char buf[MAX_PARA_LEN] = {0}; // maximum length of string needed is 10.
224         if (sprintf_s(buf, sizeof(buf), "para%lu", i) != -1) {
225             builder.uniform(buf) = para[i-1];
226         } else {
227             LOGE("sdf splicing para error.");
228             return false;
229         }
230     }
231     for (uint64_t i = 1; i <= transCount; i++) {
232         char buf[MAX_PARA_LEN] = {0}; // maximum length of string needed is 15.
233         if (sprintf_s(buf, sizeof(buf), "transpara%lu", i) != -1) {
234             builder.uniform(buf) = transPara[i-1];
235         } else {
236             LOGE("sdf splicing para error.");
237             return false;
238         }
239     }
240     std::vector<float> color = shape.GetColorPara();
241     builder.uniform("sdfalpha") = color[0]; // color_[0] is color alpha channel.
242     for (uint64_t i = 1; i < color.size(); i++) {
243         char buf[MAX_PARA_LEN] = {0}; // maximum length of string needed is 15.
244         if (sprintf_s(buf, sizeof(buf), "colpara%lu", i) != -1) {
245             builder.uniform(buf) = color[i];
246         } else {
247             LOGE("sdf splicing para error.");
248             return false;
249         }
250     }
251     builder.uniform("sdfsize") = shape.GetSize();
252     builder.uniform("filltype") = shape.GetFillType();
253     builder.uniform("translatex") = shape.GetTranslateX();
254     builder.uniform("translatey") = shape.GetTranslateY();
255     return true;
256 }
257 
DrawSdf(const SDFShapeBase & shape)258 void SkiaCanvas::DrawSdf(const SDFShapeBase& shape)
259 {
260     std::string shaderString = shape.Getshader();
261     if (skCanvas_ == nullptr || skCanvas_->getSurface() == nullptr || shaderString.size() == 0) {
262         LOGE("skCanvas_ or surface is null, or sdf shape is empty. return on line %{public}d", __LINE__);
263         return;
264     }
265 
266     SkAutoCanvasRestore acr(skCanvas_, true);
267     auto [effect, err] = SkRuntimeEffect::MakeForShader(static_cast<SkString>(shaderString));
268     if (effect == nullptr) {
269         LOGE("sdf make shader fail : %{public}s", err.c_str());
270         return;
271     }
272     float width = skCanvas_->imageInfo().width();
273     SkRuntimeShaderBuilder builder(effect);
274     if (shape.GetParaNum() <= 0 || !AddSdfPara(builder, shape)) {
275         LOGE("sdf para error.");
276         return;
277     }
278     builder.uniform("width") = width;
279 #ifndef USE_M133_SKIA
280     auto shader = builder.makeShader(nullptr, false);
281 #else
282     auto shader = builder.makeShader(nullptr);
283 #endif
284     SkPaint paint;
285     paint.setShader(shader);
286     skCanvas_->drawPaint(paint);
287 }
288 
DrawPoint(const Point & point,const Paint & paint)289 void SkiaCanvas::DrawPoint(const Point& point, const Paint& paint)
290 {
291     if (!skCanvas_) {
292         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
293         return;
294     }
295     const SkPoint* skPoint = reinterpret_cast<const SkPoint*>(&point);
296     skPaint_ = defaultPaint_;
297     SkiaPaint::PaintToSkPaint(paint, skPaint_);
298     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
299     skCanvas_->drawPoint(*skPoint, skPaint_);
300 }
301 
DrawPoints(PointMode mode,size_t count,const Point pts[],const Paint & paint)302 void SkiaCanvas::DrawPoints(PointMode mode, size_t count, const Point pts[], const Paint& paint)
303 {
304     if (!skCanvas_) {
305         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
306         return;
307     }
308 
309     const SkPoint* skPts = reinterpret_cast<const SkPoint*>(pts);
310     skPaint_ = defaultPaint_;
311     SkiaPaint::PaintToSkPaint(paint, skPaint_);
312     skCanvas_->drawPoints(static_cast<SkCanvas::PointMode>(mode), count, skPts, skPaint_);
313 }
314 
DrawLine(const Point & startPt,const Point & endPt,const Paint & paint)315 void SkiaCanvas::DrawLine(const Point& startPt, const Point& endPt, const Paint& paint)
316 {
317     if (!skCanvas_) {
318         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
319         return;
320     }
321     const SkPoint* skStartPt = reinterpret_cast<const SkPoint*>(&startPt);
322     const SkPoint* skEndPt = reinterpret_cast<const SkPoint*>(&endPt);
323     skPaint_ = defaultPaint_;
324     SkiaPaint::PaintToSkPaint(paint, skPaint_);
325     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
326     skCanvas_->drawLine(*skStartPt, *skEndPt, skPaint_);
327 }
328 
DrawRect(const Rect & rect,const Paint & paint)329 void SkiaCanvas::DrawRect(const Rect& rect, const Paint& paint)
330 {
331     if (!skCanvas_) {
332         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
333         return;
334     }
335     const SkRect* skRect = reinterpret_cast<const SkRect*>(&rect);
336     skPaint_ = defaultPaint_;
337     SkiaPaint::PaintToSkPaint(paint, skPaint_);
338     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
339     skCanvas_->drawRect(*skRect, skPaint_);
340 }
341 
DrawRoundRect(const RoundRect & roundRect,const Paint & paint)342 void SkiaCanvas::DrawRoundRect(const RoundRect& roundRect, const Paint& paint)
343 {
344     if (!skCanvas_) {
345         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
346         return;
347     }
348     SkRRect rRect;
349     RoundRectCastToSkRRect(roundRect, rRect);
350     skPaint_ = defaultPaint_;
351     SkiaPaint::PaintToSkPaint(paint, skPaint_);
352     skCanvas_->drawRRect(rRect, skPaint_);
353 }
354 
DrawNestedRoundRect(const RoundRect & outer,const RoundRect & inner,const Paint & paint)355 void SkiaCanvas::DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner, const Paint& paint)
356 {
357     if (!skCanvas_) {
358         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
359         return;
360     }
361     SkRRect outerRRect;
362     RoundRectCastToSkRRect(outer, outerRRect);
363 
364     SkRRect innerRRect;
365     RoundRectCastToSkRRect(inner, innerRRect);
366 
367     skPaint_ = defaultPaint_;
368     SkiaPaint::PaintToSkPaint(paint, skPaint_);
369     skCanvas_->drawDRRect(outerRRect, innerRRect, skPaint_);
370 }
371 
DrawArc(const Rect & oval,scalar startAngle,scalar sweepAngle,const Paint & paint)372 void SkiaCanvas::DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle, const Paint& paint)
373 {
374     if (!skCanvas_) {
375         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
376         return;
377     }
378     const SkRect* arcRect = reinterpret_cast<const SkRect*>(&oval);
379     skPaint_ = defaultPaint_;
380     SkiaPaint::PaintToSkPaint(paint, skPaint_);
381     skCanvas_->drawArc(*arcRect, startAngle, sweepAngle, false, skPaint_);
382 }
383 
DrawPie(const Rect & oval,scalar startAngle,scalar sweepAngle,const Paint & paint)384 void SkiaCanvas::DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle, const Paint& paint)
385 {
386     if (!skCanvas_) {
387         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
388         return;
389     }
390     const SkRect* pieRect = reinterpret_cast<const SkRect*>(&oval);
391     skPaint_ = defaultPaint_;
392     SkiaPaint::PaintToSkPaint(paint, skPaint_);
393     skCanvas_->drawArc(*pieRect, startAngle, sweepAngle, true, skPaint_);
394 }
395 
DrawOval(const Rect & oval,const Paint & paint)396 void SkiaCanvas::DrawOval(const Rect& oval, const Paint& paint)
397 {
398     if (!skCanvas_) {
399         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
400         return;
401     }
402     const SkRect* ovalRect = reinterpret_cast<const SkRect*>(&oval);
403     skPaint_ = defaultPaint_;
404     SkiaPaint::PaintToSkPaint(paint, skPaint_);
405     skCanvas_->drawOval(*ovalRect, skPaint_);
406 }
407 
DrawCircle(const Point & centerPt,scalar radius,const Paint & paint)408 void SkiaCanvas::DrawCircle(const Point& centerPt, scalar radius, const Paint& paint)
409 {
410     if (!skCanvas_) {
411         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
412         return;
413     }
414     skPaint_ = defaultPaint_;
415     SkiaPaint::PaintToSkPaint(paint, skPaint_);
416     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
417     skCanvas_->drawCircle(centerPt.GetX(), centerPt.GetY(), radius, skPaint_);
418 }
419 
DrawPath(const Path & path,const Paint & paint)420 void SkiaCanvas::DrawPath(const Path& path, const Paint& paint)
421 {
422     if (!skCanvas_) {
423         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
424         return;
425     }
426     auto skPathImpl = path.GetImpl<SkiaPath>();
427     if (skPathImpl == nullptr) {
428         return;
429     }
430     skPaint_ = defaultPaint_;
431     SkiaPaint::PaintToSkPaint(paint, skPaint_);
432     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
433     skCanvas_->drawPath(skPathImpl->GetPath(), skPaint_);
434 }
435 
DrawPathWithStencil(const Path & path,uint32_t stencilVal,const Paint & paint)436 void SkiaCanvas::DrawPathWithStencil(const Path& path, uint32_t stencilVal, const Paint& paint)
437 {
438 #ifdef SK_ENABLE_STENCIL_CULLING_OHOS
439     if (!skCanvas_) {
440         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
441         return;
442     }
443     auto skPathImpl = path.GetImpl<SkiaPath>();
444     if (skPathImpl == nullptr) {
445         LOGE("skPathImpl is null, return on line %{public}d", __LINE__);
446         return;
447     }
448     skPaint_ = defaultPaint_;
449     SkiaPaint::PaintToSkPaint(paint, skPaint_);
450     DRAWING_PERFORMANCE_TEST_SKIA_NO_PARAM_RETURN;
451     skCanvas_->drawPathWithStencil(skPathImpl->GetPath(), skPaint_, stencilVal);
452 #else
453     (void)stencilVal;
454     DrawPath(path, paint);
455 #endif
456 }
457 
DrawBackground(const Brush & brush)458 void SkiaCanvas::DrawBackground(const Brush& brush)
459 {
460     if (!skCanvas_) {
461         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
462         return;
463     }
464     SkPaint paint;
465     SkiaPaint::BrushToSkPaint(brush, paint);
466     skCanvas_->drawPaint(paint);
467 }
468 
DrawShadow(const Path & path,const Point3 & planeParams,const Point3 & devLightPos,scalar lightRadius,Color ambientColor,Color spotColor,ShadowFlags flag)469 void SkiaCanvas::DrawShadow(const Path& path, const Point3& planeParams, const Point3& devLightPos, scalar lightRadius,
470     Color ambientColor, Color spotColor, ShadowFlags flag)
471 {
472     if (!skCanvas_) {
473         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
474         return;
475     }
476     auto skPathImpl = path.GetImpl<SkiaPath>();
477     const SkPoint3* point1 = reinterpret_cast<const SkPoint3*>(&planeParams);
478     const SkPoint3* point2 = reinterpret_cast<const SkPoint3*>(&devLightPos);
479     SkColor color1 = ambientColor.CastToColorQuad();
480     SkColor color2 = spotColor.CastToColorQuad();
481     SkShadowFlags flags = static_cast<SkShadowFlags>(flag);
482     if (skPathImpl != nullptr) {
483         SkShadowUtils::DrawShadow(
484             skCanvas_, skPathImpl->GetPath(), *point1, *point2, lightRadius, color1, color2, flags);
485     }
486 }
487 
DrawShadowStyle(const Path & path,const Point3 & planeParams,const Point3 & devLightPos,scalar lightRadius,Color ambientColor,Color spotColor,ShadowFlags flag,bool isLimitElevation)488 void SkiaCanvas::DrawShadowStyle(const Path& path, const Point3& planeParams, const Point3& devLightPos,
489     scalar lightRadius, Color ambientColor, Color spotColor, ShadowFlags flag, bool isLimitElevation)
490 {
491     if (!skCanvas_) {
492         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
493         return;
494     }
495     auto skPathImpl = path.GetImpl<SkiaPath>();
496     const SkPoint3* point1 = reinterpret_cast<const SkPoint3*>(&planeParams);
497     const SkPoint3* point2 = reinterpret_cast<const SkPoint3*>(&devLightPos);
498     SkColor color1 = ambientColor.CastToColorQuad();
499     SkColor color2 = spotColor.CastToColorQuad();
500     SkShadowFlags flags = static_cast<SkShadowFlags>(flag);
501     if (skPathImpl != nullptr) {
502         SkShadowUtils::DrawShadowStyle(
503             skCanvas_, skPathImpl->GetPath(), *point1, *point2, lightRadius, color1, color2, flags, isLimitElevation);
504     }
505 }
506 
DrawColor(ColorQuad color,BlendMode mode)507 void SkiaCanvas::DrawColor(ColorQuad color, BlendMode mode)
508 {
509     if (!skCanvas_) {
510         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
511         return;
512     }
513 
514     skCanvas_->drawColor(static_cast<SkColor>(color), static_cast<SkBlendMode>(mode));
515 }
516 
DrawRegion(const Region & region,const Paint & paint)517 void SkiaCanvas::DrawRegion(const Region& region, const Paint& paint)
518 {
519     if (!skCanvas_) {
520         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
521         return;
522     }
523 
524     skPaint_ = defaultPaint_;
525     SkiaPaint::PaintToSkPaint(paint, skPaint_);
526     skCanvas_->drawRegion(*region.GetImpl<SkiaRegion>()->GetSkRegion(), skPaint_);
527 }
528 
DrawPatch(const Point cubics[12],const ColorQuad colors[4],const Point texCoords[4],BlendMode mode,const Paint & paint)529 void SkiaCanvas::DrawPatch(const Point cubics[12], const ColorQuad colors[4],
530     const Point texCoords[4], BlendMode mode, const Paint& paint)
531 {
532     if (!skCanvas_) {
533         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
534         return;
535     }
536 
537     const size_t cubicsPointCount = 12;
538     std::vector<SkPoint> skiaCubics = {};
539     if (cubics != nullptr) {
540         skiaCubics.resize(cubicsPointCount);
541         // Tell compiler there is no alias, and unroll 2 times to 128 bits to use vector instructions.
542         for (size_t i = 0; i < cubicsPointCount; i += 2) {
543             scalar fX0 = cubics[i].GetX();
544             scalar fY0 = cubics[i].GetY();
545             scalar fX1 = cubics[i + 1].GetX();
546             scalar fY1 = cubics[i + 1].GetY();
547             skiaCubics[i].fX = fX0;
548             skiaCubics[i].fY = fY0;
549             skiaCubics[i + 1].fX = fX1;
550             skiaCubics[i + 1].fY = fY1;
551         }
552     }
553 
554     const size_t colorCount = 4;
555     std::vector<SkColor> skiaColors = {};
556     if (colors != nullptr) {
557         skiaColors.resize(colorCount);
558         for (size_t i = 0; i < colorCount; ++i) {
559             skiaColors[i] = static_cast<SkColor>(colors[i]);
560         }
561     }
562 
563     const size_t texCoordCount = 4;
564     std::vector<SkPoint> skiaTexCoords = {};
565     if (texCoords != nullptr) {
566         skiaTexCoords.resize(texCoordCount);
567         for (size_t i = 0; i < texCoordCount; ++i) {
568             scalar fX0 = texCoords[i].GetX();
569             scalar fY0 = texCoords[i].GetY();
570             skiaTexCoords[i].fX = fX0;
571             skiaTexCoords[i].fY = fY0;
572         }
573     }
574 
575     skPaint_ = defaultPaint_;
576     SkiaPaint::PaintToSkPaint(paint, skPaint_);
577     skCanvas_->drawPatch(
578         skiaCubics.empty() ? nullptr : skiaCubics.data(),
579         skiaColors.empty() ? nullptr : skiaColors.data(),
580         skiaTexCoords.empty() ? nullptr : skiaTexCoords.data(),
581         static_cast<SkBlendMode>(mode), skPaint_);
582 }
583 
DrawVertices(const Vertices & vertices,BlendMode mode,const Paint & paint)584 void SkiaCanvas::DrawVertices(const Vertices& vertices, BlendMode mode, const Paint& paint)
585 {
586     if (!skCanvas_) {
587         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
588         return;
589     }
590 
591     sk_sp<SkVertices> verts;
592     auto skVerticesImpl = vertices.GetImpl<SkiaVertices>();
593     if (skVerticesImpl != nullptr) {
594         verts = skVerticesImpl->GetVertices();
595     }
596 
597     skPaint_ = defaultPaint_;
598     SkiaPaint::PaintToSkPaint(paint, skPaint_);
599     skCanvas_->drawVertices(verts, static_cast<SkBlendMode>(mode), skPaint_);
600 }
601 
DrawImageNine(const Image * image,const RectI & center,const Rect & dst,FilterMode filter,const Brush * brush)602 void SkiaCanvas::DrawImageNine(const Image* image, const RectI& center, const Rect& dst,
603     FilterMode filter, const Brush* brush)
604 {
605     if (!skCanvas_) {
606         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
607         return;
608     }
609 
610     if (!image) {
611         LOGD("image is null, return on line %{public}d", __LINE__);
612         return;
613     }
614 
615     auto skImageImpl = image->GetImpl<SkiaImage>();
616     sk_sp<SkImage> img = nullptr;
617     if (skImageImpl != nullptr) {
618         img = skImageImpl->GetImage();
619         if (img == nullptr) {
620             LOGD("img is null, return on line %{public}d", __LINE__);
621             return;
622         }
623     }
624 
625     const SkIRect* skCenter = reinterpret_cast<const SkIRect*>(&center);
626     const SkRect* skDst = reinterpret_cast<const SkRect*>(&dst);
627 
628     SkFilterMode skFilterMode = static_cast<SkFilterMode>(filter);
629 
630     std::unique_ptr<SkPaint> paint = nullptr;
631     if (brush != nullptr) {
632         paint = std::make_unique<SkPaint>();
633         SkiaPaint::BrushToSkPaint(*brush, *paint);
634     }
635     skCanvas_->drawImageNine(img.get(), *skCenter, *skDst, skFilterMode, paint.get());
636 }
637 
DrawImageLattice(const Image * image,const Lattice & lattice,const Rect & dst,FilterMode filter,const Paint & paint)638 void SkiaCanvas::DrawImageLattice(const Image* image, const Lattice& lattice, const Rect& dst,
639     FilterMode filter, const Paint& paint)
640 {
641     if (!skCanvas_) {
642         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
643         return;
644     }
645 
646     if (!image) {
647         LOGD("image is null, return on line %{public}d", __LINE__);
648         return;
649     }
650 
651     auto skImageImpl = image->GetImpl<SkiaImage>();
652     sk_sp<SkImage> img = nullptr;
653     if (skImageImpl != nullptr) {
654         img = skImageImpl->GetImage();
655         if (img == nullptr) {
656             LOGD("img is null, return on line %{public}d", __LINE__);
657             return;
658         }
659     }
660 
661     int count = (lattice.fXCount + 1) * (lattice.fYCount + 1);
662     std::vector<SkCanvas::Lattice::RectType> skRectTypes = {};
663     if (!lattice.fRectTypes.empty()) {
664         skRectTypes.resize(count);
665         for (int i = 0; i < count; ++i) {
666             skRectTypes[i] = static_cast<SkCanvas::Lattice::RectType>(lattice.fRectTypes[i]);
667         }
668     }
669     std::vector<SkColor> skColors = {};
670     if (!lattice.fColors.empty()) {
671         skColors.resize(count);
672         for (int i = 0; i < count; ++i) {
673             skColors[i] = static_cast<SkColor>(lattice.fColors[i].CastToColorQuad());
674         }
675     }
676     SkCanvas::Lattice skLattice = {lattice.fXDivs.empty() ? nullptr : lattice.fXDivs.data(),
677         lattice.fYDivs.empty() ? nullptr : lattice.fYDivs.data(),
678         skRectTypes.empty() ? nullptr : skRectTypes.data(),
679         lattice.fXCount, lattice.fYCount,
680         lattice.fBounds.empty() ? nullptr : reinterpret_cast<const SkIRect*>(lattice.fBounds.data()),
681         skColors.empty() ? nullptr : skColors.data()};
682 
683     const SkRect* skDst = reinterpret_cast<const SkRect*>(&dst);
684     SkFilterMode skFilterMode = static_cast<SkFilterMode>(filter);
685 
686     skPaint_ = defaultPaint_;
687     SkiaPaint::PaintToSkPaint(paint, skPaint_);
688     skCanvas_->drawImageLattice(img.get(), skLattice, *skDst, skFilterMode, &skPaint_);
689 }
690 
OpCalculateBefore(const Matrix & matrix)691 bool SkiaCanvas::OpCalculateBefore(const Matrix& matrix)
692 {
693     if (!skCanvas_) {
694         LOGD("opinc before is null");
695         return false;
696     }
697     if (skiaCanvasOp_ || skCanvasBackup_) {
698         LOGD("opinc PreOpListDrawArea is nested");
699         return false;
700     }
701     auto m = matrix.GetImpl<SkiaMatrix>();
702     if (!m) {
703         LOGD("opinc get matrix null");
704         return false;
705     }
706     auto tmp = std::make_shared<SkiaCanvasAutoCache>(skCanvas_);
707     tmp->Init(m->ExportSkiaMatrix());
708     skiaCanvasOp_ = tmp;
709     skCanvasBackup_ = skiaCanvasOp_.get();
710     std::swap(skCanvas_, skCanvasBackup_);
711     return true;
712 }
713 
OpCalculateAfter(const Rect & bound)714 std::shared_ptr<Drawing::OpListHandle> SkiaCanvas::OpCalculateAfter(const Rect& bound)
715 {
716     std::shared_ptr<Drawing::OpListHandle> handle = nullptr;
717     if (!skCanvas_ || !skiaCanvasOp_) {
718         LOGD("opinc after is null");
719         return handle;
720     }
721 
722     do {
723         auto nodeBound = SkRect::MakeLTRB(bound.GetLeft(), bound.GetTop(), bound.GetRight(), bound.GetBottom());
724         if (!skiaCanvasOp_->OpCanCache(nodeBound)) {
725             LOGD("opinc opCanCache false");
726             break;
727         }
728 
729         int opNum = skiaCanvasOp_->GetOpsNum();
730         int percent = skiaCanvasOp_->GetOpsPercent();
731         auto& skUnionRect = skiaCanvasOp_->GetOpUnionRect();
732         auto& skOpListDrawArea = skiaCanvasOp_->GetOpListDrawArea();
733         if (skUnionRect.isEmpty() || opNum == 0 || percent == 0 || skOpListDrawArea.size() == 0) {
734             LOGD("opinc opNum is zero");
735             break;
736         }
737         Drawing::Rect unionRect(skUnionRect.left(), skUnionRect.top(), skUnionRect.right(), skUnionRect.bottom());
738         std::vector<Drawing::Rect> rects;
739         for (auto &item : skOpListDrawArea) {
740             rects.emplace_back(Drawing::Rect(item.left(), item.top(), item.right(), item.bottom()));
741         }
742         Drawing::OpListHandle::OpInfo opinfo{ true, opNum, percent, std::move(unionRect), std::move(rects) };
743         handle = std::make_shared<Drawing::OpListHandle>(std::move(opinfo));
744     } while (false);
745 
746     std::swap(skCanvas_, skCanvasBackup_); // restore canvas
747     skiaCanvasOp_ = nullptr;
748     skCanvasBackup_ = nullptr;
749     return handle;
750 }
751 
DrawAtlas(const Image * atlas,const RSXform xform[],const Rect tex[],const ColorQuad colors[],int count,BlendMode mode,const SamplingOptions & sampling,const Rect * cullRect,const Paint & paint)752 void SkiaCanvas::DrawAtlas(const Image* atlas, const RSXform xform[], const Rect tex[], const ColorQuad colors[],
753     int count, BlendMode mode, const SamplingOptions& sampling, const Rect* cullRect, const Paint& paint)
754 {
755     if (!skCanvas_ || !atlas || !xform || !tex) {
756         LOGD("skCanvas_ or atlas, xform or tex is null, return on line %{public}d", __LINE__);
757         return;
758     }
759     const int maxCount = 2000; // max count supported is 2000
760     if (count <= 0 || count > maxCount) {
761         LOGD("invalid count for atlas, return on line %{public}d", __LINE__);
762         return;
763     }
764 
765     auto skImageImpl = atlas->GetImpl<SkiaImage>();
766     if (skImageImpl == nullptr) {
767         LOGD("skImageImpl is null, return on line %{public}d", __LINE__);
768         return;
769     }
770     sk_sp<SkImage> img = skImageImpl->GetImage();
771     if (img == nullptr) {
772         LOGD("img is null, return on line %{public}d", __LINE__);
773         return;
774     }
775 
776     SkRSXform skRSXform[count];
777     SkRect skTex[count];
778     for (int i = 0; i < count; ++i) {
779         SkiaConvertUtils::DrawingRSXformCastToSkXform(xform[i], skRSXform[i]);
780         SkiaConvertUtils::DrawingRectCastToSkRect(tex[i], skTex[i]);
781     }
782 
783     std::vector<SkColor> skColors = {};
784     if (colors != nullptr) {
785         skColors.resize(count);
786         for (int i = 0; i < count; ++i) {
787             skColors[i] = static_cast<SkColor>(colors[i]);
788         }
789     }
790 
791 #ifdef USE_M133_SKIA
792     SamplingOptionsUtils tempSamplingOptions;
793     ConvertSamplingOptions(tempSamplingOptions, sampling);
794     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&tempSamplingOptions);
795 #else
796     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
797 #endif
798     const SkRect* skCullRect = reinterpret_cast<const SkRect*>(cullRect);
799     skPaint_ = defaultPaint_;
800     SkiaPaint::PaintToSkPaint(paint, skPaint_);
801     skCanvas_->drawAtlas(img.get(), skRSXform, skTex, skColors.empty() ? nullptr : skColors.data(), count,
802         static_cast<SkBlendMode>(mode), *samplingOptions, skCullRect, &skPaint_);
803 }
804 
DrawBitmap(const Bitmap & bitmap,const scalar px,const scalar py,const Paint & paint)805 void SkiaCanvas::DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py, const Paint& paint)
806 {
807     if (!skCanvas_) {
808         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
809         return;
810     }
811     SkBitmap bmp;
812     auto skBitmapImpl = bitmap.GetImpl<SkiaBitmap>();
813     if (skBitmapImpl != nullptr) {
814         bmp = skBitmapImpl->ExportSkiaBitmap();
815     }
816 
817     skPaint_ = defaultPaint_;
818     SkiaPaint::PaintToSkPaint(paint, skPaint_);
819     skCanvas_->drawImage(bmp.asImage(), px, py, SkSamplingOptions(), &skPaint_);
820 }
821 
DrawImage(const Image & image,const scalar px,const scalar py,const SamplingOptions & sampling,const Paint & paint)822 void SkiaCanvas::DrawImage(const Image& image, const scalar px, const scalar py,
823     const SamplingOptions& sampling, const Paint& paint)
824 {
825     if (!skCanvas_) {
826         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
827         return;
828     }
829     sk_sp<SkImage> img;
830 
831     auto skImageImpl = image.GetImpl<SkiaImage>();
832     if (skImageImpl != nullptr) {
833         img = skImageImpl->GetImage();
834         if (img == nullptr) {
835             LOGD("img is null, return on line %{public}d", __LINE__);
836             return;
837         }
838     }
839 
840 #ifdef USE_M133_SKIA
841     SamplingOptionsUtils tempSamplingOptions;
842     ConvertSamplingOptions(tempSamplingOptions, sampling);
843     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&tempSamplingOptions);
844 #else
845     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
846 #endif
847     skPaint_ = defaultPaint_;
848     SkiaPaint::PaintToSkPaint(paint, skPaint_);
849     skCanvas_->drawImage(img, px, py, *samplingOptions, &skPaint_);
850 }
851 
DrawImageWithStencil(const Image & image,const scalar px,const scalar py,const SamplingOptions & sampling,uint32_t stencilVal,const Paint & paint)852 void SkiaCanvas::DrawImageWithStencil(const Image& image, const scalar px, const scalar py,
853     const SamplingOptions& sampling, uint32_t stencilVal, const Paint& paint)
854 {
855 #ifdef SK_ENABLE_STENCIL_CULLING_OHOS
856     if (!skCanvas_) {
857         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
858         return;
859     }
860 
861     sk_sp<SkImage> img;
862     auto skImageImpl = image.GetImpl<SkiaImage>();
863     if (skImageImpl != nullptr) {
864         img = skImageImpl->GetImage();
865     }
866     if (img == nullptr) {
867         LOGD("img is null, return on line %{public}d", __LINE__);
868         return;
869     }
870 
871 #ifdef USE_M133_SKIA
872     SamplingOptionsUtils tempSamplingOptions;
873     ConvertSamplingOptions(tempSamplingOptions, sampling);
874     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&tempSamplingOptions);
875 #else
876     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
877 #endif
878     skPaint_ = defaultPaint_;
879     SkiaPaint::PaintToSkPaint(paint, skPaint_);
880     skCanvas_->drawImageWithStencil(img, px, py, *samplingOptions, &skPaint_, stencilVal);
881 #else
882     (void)stencilVal;
883     DrawImage(image, px, py, sampling, paint);
884 #endif
885 }
886 
DrawImageRect(const Image & image,const Rect & src,const Rect & dst,const SamplingOptions & sampling,SrcRectConstraint constraint,const Paint & paint)887 void SkiaCanvas::DrawImageRect(const Image& image, const Rect& src, const Rect& dst,
888     const SamplingOptions& sampling, SrcRectConstraint constraint, const Paint& paint)
889 {
890     if (!skCanvas_) {
891         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
892         return;
893     }
894     sk_sp<SkImage> img;
895     auto skImageImpl = image.GetImpl<SkiaImage>();
896     if (skImageImpl != nullptr) {
897         img = skImageImpl->GetImage();
898         if (img == nullptr) {
899             LOGD("img is null, return on line %{public}d", __LINE__);
900             return;
901         }
902     }
903 
904     const SkRect* srcRect = reinterpret_cast<const SkRect*>(&src);
905     const SkRect* dstRect = reinterpret_cast<const SkRect*>(&dst);
906 #ifdef USE_M133_SKIA
907     SamplingOptionsUtils tempSamplingOptions;
908     ConvertSamplingOptions(tempSamplingOptions, sampling);
909     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&tempSamplingOptions);
910 #else
911     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
912 #endif
913 
914     skPaint_ = defaultPaint_;
915     SkiaPaint::PaintToSkPaint(paint, skPaint_);
916     skCanvas_->drawImageRect(img, *srcRect, *dstRect, *samplingOptions, &skPaint_,
917         static_cast<SkCanvas::SrcRectConstraint>(constraint));
918 }
919 
DrawImageRect(const Image & image,const Rect & dst,const SamplingOptions & sampling,const Paint & paint)920 void SkiaCanvas::DrawImageRect(const Image& image, const Rect& dst,
921     const SamplingOptions& sampling, const Paint& paint)
922 {
923     if (!skCanvas_) {
924         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
925         return;
926     }
927     sk_sp<SkImage> img;
928     auto skImageImpl = image.GetImpl<SkiaImage>();
929     if (skImageImpl != nullptr) {
930         img = skImageImpl->GetImage();
931         if (img == nullptr) {
932             LOGD("img is null, return on line %{public}d", __LINE__);
933             return;
934         }
935     }
936 
937     const SkRect* dstRect = reinterpret_cast<const SkRect*>(&dst);
938 #ifdef USE_M133_SKIA
939     SamplingOptionsUtils tempSamplingOptions;
940     ConvertSamplingOptions(tempSamplingOptions, sampling);
941     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&tempSamplingOptions);
942 #else
943     const SkSamplingOptions* samplingOptions = reinterpret_cast<const SkSamplingOptions*>(&sampling);
944 #endif
945     skPaint_ = defaultPaint_;
946     SkiaPaint::PaintToSkPaint(paint, skPaint_);
947     skCanvas_->drawImageRect(img, *dstRect, *samplingOptions, &skPaint_);
948 }
949 
DrawPicture(const Picture & picture)950 void SkiaCanvas::DrawPicture(const Picture& picture)
951 {
952     if (!skCanvas_) {
953         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
954         return;
955     }
956     sk_sp<SkPicture> p;
957 
958     auto skPictureImpl = picture.GetImpl<SkiaPicture>();
959     if (skPictureImpl != nullptr) {
960         p = skPictureImpl->GetPicture();
961         skCanvas_->drawPicture(p.get());
962     }
963 }
964 
DrawSVGDOM(const sk_sp<SkSVGDOM> & svgDom)965 void SkiaCanvas::DrawSVGDOM(const sk_sp<SkSVGDOM>& svgDom)
966 {
967     if (!skCanvas_) {
968         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
969         return;
970     }
971     if (!svgDom) {
972         LOGD("svgDom is null, return on line %{public}d", __LINE__);
973         return;
974     }
975     svgDom->render(skCanvas_);
976 }
977 
DrawTextBlob(const TextBlob * blob,const scalar x,const scalar y,const Paint & paint)978 void SkiaCanvas::DrawTextBlob(const TextBlob* blob, const scalar x, const scalar y, const Paint& paint)
979 {
980     if (!skCanvas_) {
981         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
982         return;
983     }
984     if (!blob) {
985         LOGD("blob is null, return on line %{public}d", __LINE__);
986         return;
987     }
988     auto skiaTextBlob = blob->GetImpl<SkiaTextBlob>();
989     if (!skiaTextBlob) {
990         LOGD("skiaTextBlob is null, return on line %{public}d", __LINE__);
991         return;
992     }
993     SkTextBlob* skTextBlob = skiaTextBlob->GetTextBlob().get();
994     if (!skTextBlob) {
995         LOGD("skTextBlob is null, return on line %{public}d", __LINE__);
996         return;
997     }
998 
999     skPaint_ = defaultPaint_;
1000     SkiaPaint::PaintToSkPaint(paint, skPaint_);
1001     skCanvas_->drawTextBlob(skTextBlob, x, y, skPaint_);
1002 }
1003 
DrawSymbol(const DrawingHMSymbolData & symbol,Point locate,const Paint & paint)1004 void SkiaCanvas::DrawSymbol(const DrawingHMSymbolData& symbol, Point locate, const Paint& paint)
1005 {
1006     if (!skCanvas_) {
1007         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1008         return;
1009     }
1010 
1011 #ifndef TODO_M133_SKIA
1012     HMSymbolData skSymbol;
1013     if (!ConvertToHMSymbolData(symbol, skSymbol)) {
1014         LOGD("ConvertToHMSymbolData failed, return on line %{public}d", __LINE__);
1015         return;
1016     }
1017 
1018     const SkPoint* skLocate = reinterpret_cast<const SkPoint*>(&locate);
1019 
1020     skPaint_ = defaultPaint_;
1021     SkiaPaint::PaintToSkPaint(paint, skPaint_);
1022     skCanvas_->drawSymbol(skSymbol, *skLocate, skPaint_);
1023 #endif
1024 }
1025 
ClearStencil(const RectI & rect,uint32_t stencilVal)1026 void SkiaCanvas::ClearStencil(const RectI& rect, uint32_t stencilVal)
1027 {
1028 #ifdef SK_ENABLE_STENCIL_CULLING_OHOS
1029     if (!skCanvas_) {
1030         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1031         return;
1032     }
1033     const SkIRect* skIRect = reinterpret_cast<const SkIRect*>(&rect);
1034     skCanvas_->clearStencil(*skIRect, stencilVal);
1035 #else
1036     (void)rect;
1037     (void)stencilVal;
1038 #endif
1039 }
1040 
ClipRect(const Rect & rect,ClipOp op,bool doAntiAlias)1041 void SkiaCanvas::ClipRect(const Rect& rect, ClipOp op, bool doAntiAlias)
1042 {
1043     if (!skCanvas_) {
1044         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1045         return;
1046     }
1047     const SkRect* clipRect = reinterpret_cast<const SkRect*>(&rect);
1048     SkClipOp clipOp = static_cast<SkClipOp>(op);
1049     skCanvas_->clipRect(*clipRect, clipOp, doAntiAlias);
1050 }
1051 
ClipIRect(const RectI & rect,ClipOp op)1052 void SkiaCanvas::ClipIRect(const RectI& rect, ClipOp op)
1053 {
1054     if (!skCanvas_) {
1055         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1056         return;
1057     }
1058     SkRect clipRect = SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
1059     SkClipOp clipOp = static_cast<SkClipOp>(op);
1060     skCanvas_->clipRect(clipRect, clipOp, false);
1061 }
1062 
ClipRoundRect(const RoundRect & roundRect,ClipOp op,bool doAntiAlias)1063 void SkiaCanvas::ClipRoundRect(const RoundRect& roundRect, ClipOp op, bool doAntiAlias)
1064 {
1065     if (!skCanvas_) {
1066         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1067         return;
1068     }
1069     SkRRect rRect;
1070     RoundRectCastToSkRRect(roundRect, rRect);
1071     SkClipOp clipOp = static_cast<SkClipOp>(op);
1072     skCanvas_->clipRRect(rRect, clipOp, doAntiAlias);
1073 }
1074 
ClipRoundRect(const Rect & rect,std::vector<Point> & pts,bool doAntiAlias)1075 void SkiaCanvas::ClipRoundRect(const Rect& rect, std::vector<Point>& pts, bool doAntiAlias)
1076 {
1077     if (!skCanvas_) {
1078         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1079         return;
1080     }
1081     SkRRect rRect;
1082     rRect.setRectRadii(SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom()),
1083         reinterpret_cast<const SkVector *>(pts.data()));
1084     skCanvas_->clipRRect(rRect, doAntiAlias);
1085 }
1086 
ClipPath(const Path & path,ClipOp op,bool doAntiAlias)1087 void SkiaCanvas::ClipPath(const Path& path, ClipOp op, bool doAntiAlias)
1088 {
1089     if (!skCanvas_) {
1090         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1091         return;
1092     }
1093     auto skPathImpl = path.GetImpl<SkiaPath>();
1094     if (skPathImpl != nullptr) {
1095         SkClipOp clipOp = static_cast<SkClipOp>(op);
1096         skCanvas_->clipPath(skPathImpl->GetPath(), clipOp, doAntiAlias);
1097     }
1098 }
1099 
ClipRegion(const Region & region,ClipOp op)1100 void SkiaCanvas::ClipRegion(const Region& region, ClipOp op)
1101 {
1102     if (!skCanvas_) {
1103         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1104         return;
1105     }
1106     auto skRegionImpl = region.GetImpl<SkiaRegion>();
1107     if (skRegionImpl != nullptr) {
1108         SkClipOp clipOp = static_cast<SkClipOp>(op);
1109         skCanvas_->clipRegion(*(skRegionImpl->GetSkRegion()), clipOp);
1110     }
1111 }
1112 
IsClipEmpty()1113 bool SkiaCanvas::IsClipEmpty()
1114 {
1115     if (!skCanvas_) {
1116         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1117         return false;
1118     }
1119     return skCanvas_->isClipEmpty();
1120 }
1121 
IsClipRect()1122 bool SkiaCanvas::IsClipRect()
1123 {
1124     if (!skCanvas_) {
1125         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1126         return false;
1127     }
1128     return skCanvas_->isClipRect();
1129 }
1130 
ResetClip()1131 void SkiaCanvas::ResetClip()
1132 {
1133     if (!skCanvas_) {
1134         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1135         return;
1136     }
1137     return SkCanvasPriv::ResetClip(skCanvas_);
1138 }
1139 
QuickReject(const Path & path)1140 bool SkiaCanvas::QuickReject(const Path& path)
1141 {
1142     if (!skCanvas_) {
1143         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1144         return false;
1145     }
1146     const SkPath& clipPath = path.GetImpl<SkiaPath>()->GetPath();
1147     DRAWING_PERFORMANCE_TEST_SKIA_RETURN(false);
1148     return skCanvas_->quickReject(clipPath);
1149 }
1150 
QuickReject(const Rect & rect)1151 bool SkiaCanvas::QuickReject(const Rect& rect)
1152 {
1153     if (!skCanvas_) {
1154         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1155         return false;
1156     }
1157     const SkRect* clipRect = reinterpret_cast<const SkRect*>(&rect);
1158     return skCanvas_->quickReject(*clipRect);
1159 }
1160 
SetMatrix(const Matrix & matrix)1161 void SkiaCanvas::SetMatrix(const Matrix& matrix)
1162 {
1163     if (!skCanvas_) {
1164         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1165         return;
1166     }
1167     auto m = matrix.GetImpl<SkiaMatrix>();
1168     if (m != nullptr) {
1169         skCanvas_->setMatrix(m->ExportSkiaMatrix());
1170     }
1171 }
1172 
ResetMatrix()1173 void SkiaCanvas::ResetMatrix()
1174 {
1175     if (!skCanvas_) {
1176         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1177         return;
1178     }
1179     skCanvas_->resetMatrix();
1180 }
1181 
ConcatMatrix(const Matrix & matrix)1182 void SkiaCanvas::ConcatMatrix(const Matrix& matrix)
1183 {
1184     if (!skCanvas_) {
1185         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1186         return;
1187     }
1188     auto m = matrix.GetImpl<SkiaMatrix>();
1189     if (m != nullptr) {
1190         skCanvas_->concat(m->ExportSkiaMatrix());
1191     }
1192 }
1193 
Translate(scalar dx,scalar dy)1194 void SkiaCanvas::Translate(scalar dx, scalar dy)
1195 {
1196     if (!skCanvas_) {
1197         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1198         return;
1199     }
1200     skCanvas_->translate(dx, dy);
1201 }
1202 
Scale(scalar sx,scalar sy)1203 void SkiaCanvas::Scale(scalar sx, scalar sy)
1204 {
1205     if (!skCanvas_) {
1206         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1207         return;
1208     }
1209     skCanvas_->scale(sx, sy);
1210 }
1211 
Rotate(scalar deg,scalar sx,scalar sy)1212 void SkiaCanvas::Rotate(scalar deg, scalar sx, scalar sy)
1213 {
1214     if (!skCanvas_) {
1215         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1216         return;
1217     }
1218     skCanvas_->rotate(deg, sx, sy);
1219 }
1220 
Shear(scalar sx,scalar sy)1221 void SkiaCanvas::Shear(scalar sx, scalar sy)
1222 {
1223     if (!skCanvas_) {
1224         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1225         return;
1226     }
1227     skCanvas_->skew(sx, sy);
1228 }
1229 
Flush()1230 void SkiaCanvas::Flush()
1231 {
1232     if (!skCanvas_) {
1233         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1234         return;
1235     }
1236 #ifdef USE_M133_SKIA
1237     if (auto dContext = GrAsDirectContext(skCanvas_->recordingContext())) {
1238         dContext->flushAndSubmit();
1239     }
1240 #else
1241     skCanvas_->flush();
1242 #endif
1243 }
1244 
Clear(ColorQuad color)1245 void SkiaCanvas::Clear(ColorQuad color)
1246 {
1247     if (!skCanvas_) {
1248         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1249         return;
1250     }
1251     skCanvas_->clear(color);
1252 }
1253 
Save()1254 uint32_t SkiaCanvas::Save()
1255 {
1256     if (!skCanvas_) {
1257         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1258         return 0;
1259     }
1260     return static_cast<uint32_t>(skCanvas_->save());
1261 }
1262 
SaveLayer(const SaveLayerOps & saveLayerOps)1263 void SkiaCanvas::SaveLayer(const SaveLayerOps& saveLayerOps)
1264 {
1265     if (!skCanvas_) {
1266         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1267         return;
1268     }
1269     std::unique_ptr<SkRect> skBounds = nullptr;
1270     auto bounds = saveLayerOps.GetBounds();
1271     if (bounds != nullptr) {
1272         skBounds = std::make_unique<SkRect>();
1273         skBounds->setLTRB(bounds->GetLeft(), bounds->GetTop(), bounds->GetRight(), bounds->GetBottom());
1274     }
1275     std::unique_ptr<SkPaint> paint = nullptr;
1276     auto brush = saveLayerOps.GetBrush();
1277     if (brush != nullptr) {
1278         paint = std::make_unique<SkPaint>();
1279         SkiaPaint::BrushToSkPaint(*brush, *paint);
1280     }
1281 
1282     SkCanvas::SaveLayerRec slr(skBounds.get(), paint.get(), nullptr,
1283         static_cast<SkCanvas::SaveLayerFlags>(saveLayerOps.GetSaveLayerFlags() << 1));  // Offset 1 bit
1284     skCanvas_->saveLayer(slr);
1285 }
1286 
Restore()1287 void SkiaCanvas::Restore()
1288 {
1289     if (!skCanvas_) {
1290         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1291         return;
1292     }
1293     skCanvas_->restore();
1294 }
1295 
GetSaveCount() const1296 uint32_t SkiaCanvas::GetSaveCount() const
1297 {
1298     return (skCanvas_ != nullptr) ? skCanvas_->getSaveCount() : 0;
1299 }
1300 
Discard()1301 void SkiaCanvas::Discard()
1302 {
1303     if (!skCanvas_) {
1304         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1305         return;
1306     }
1307     skCanvas_->discard();
1308 }
1309 
RoundRectCastToSkRRect(const RoundRect & roundRect,SkRRect & skRRect) const1310 void SkiaCanvas::RoundRectCastToSkRRect(const RoundRect& roundRect, SkRRect& skRRect) const
1311 {
1312     const SkRect* outer = reinterpret_cast<const SkRect*>(&roundRect.GetRect());
1313     if (roundRect.IsSimpleRoundRect()) {
1314         skRRect.setRectXY(*outer, roundRect.GetSimpleX(), roundRect.GetSimpleY());
1315         return;
1316     }
1317 
1318     const SkVector* radii = reinterpret_cast<const SkVector*>(&roundRect.GetCornerRadius(RoundRect::TOP_LEFT_POS));
1319     skRRect.setRectRadii(*outer, radii);
1320 }
1321 
ConvertToHMSymbolData(const DrawingHMSymbolData & symbol,HMSymbolData & skSymbol)1322 bool SkiaCanvas::ConvertToHMSymbolData(const DrawingHMSymbolData& symbol, HMSymbolData& skSymbol)
1323 {
1324     Path path = symbol.path_;
1325     auto skPathImpl = path.GetImpl<SkiaPath>();
1326     if (skPathImpl == nullptr) {
1327         return false;
1328     }
1329     skSymbol.path_ = skPathImpl->GetPath();
1330 
1331     skSymbol.symbolInfo_.symbolGlyphId = symbol.symbolInfo_.symbolGlyphId;
1332     skSymbol.symbolInfo_.layers = symbol.symbolInfo_.layers;
1333 
1334     std::vector<RenderGroup> groups;
1335     auto drawingGroup = symbol.symbolInfo_.renderGroups;
1336     for (size_t i = 0; i < drawingGroup.size(); i++) {
1337         RenderGroup group;
1338         group.color.a = drawingGroup.at(i).color.a;
1339         group.color.r = drawingGroup.at(i).color.r;
1340         group.color.g = drawingGroup.at(i).color.g;
1341         group.color.b = drawingGroup.at(i).color.b;
1342         auto drawingGroupInfos = drawingGroup.at(i).groupInfos;
1343         std::vector<GroupInfo> infos;
1344         for (size_t j = 0; j < drawingGroupInfos.size(); j++) {
1345             GroupInfo info;
1346             info.layerIndexes = drawingGroupInfos.at(j).layerIndexes;
1347             info.maskIndexes = drawingGroupInfos.at(j).maskIndexes;
1348             infos.push_back(info);
1349         }
1350         group.groupInfos = infos;
1351         groups.push_back(group);
1352     }
1353     skSymbol.symbolInfo_.renderGroups = groups;
1354     return true;
1355 }
1356 
BuildOverDraw(std::shared_ptr<Canvas> canvas)1357 void SkiaCanvas::BuildOverDraw(std::shared_ptr<Canvas> canvas)
1358 {
1359     auto skiaCanvas = canvas->GetImpl<SkiaCanvas>();
1360     skiaCanvas_ = std::make_shared<SkOverdrawCanvas>(skiaCanvas->ExportSkCanvas());
1361     skCanvas_ = skiaCanvas_.get();
1362 }
1363 
BuildNoDraw(int32_t width,int32_t height)1364 void SkiaCanvas::BuildNoDraw(int32_t width, int32_t height)
1365 {
1366     skiaCanvas_ = std::make_shared<SkNoDrawCanvas>(width, height);
1367     skCanvas_ = skiaCanvas_.get();
1368 }
1369 
BuildStateInherite(int32_t width,int32_t height)1370 void SkiaCanvas::BuildStateInherite(int32_t width, int32_t height)
1371 {
1372 }
1373 
Reset(int32_t width,int32_t height)1374 void SkiaCanvas::Reset(int32_t width, int32_t height)
1375 {
1376     SkNoDrawCanvas* noDraw = reinterpret_cast<SkNoDrawCanvas*>(skCanvas_);
1377     noDraw->resetCanvas(width, height);
1378 }
1379 
DrawBlurImage(const Image & image,const Drawing::HpsBlurParameter & blurParams)1380 bool SkiaCanvas::DrawBlurImage(const Image& image, const Drawing::HpsBlurParameter& blurParams)
1381 {
1382     if (!skCanvas_) {
1383         LOGD("skCanvas_ is null, return on line %{public}d", __LINE__);
1384         return false;
1385     }
1386 
1387     auto skImageImpl = image.GetImpl<SkiaImage>();
1388     if (skImageImpl == nullptr) {
1389         LOGE("skImageImpl is null, return on line %{public}d", __LINE__);
1390         return false;
1391     }
1392 
1393     sk_sp<SkImage> img = skImageImpl->GetImage();
1394     if (img == nullptr) {
1395         LOGE("img is null, return on line %{public}d", __LINE__);
1396         return false;
1397     }
1398 
1399 #ifdef USE_M133_SKIA
1400     return false;
1401 #else
1402     SkRect srcRect = SkRect::MakeLTRB(blurParams.src.GetLeft(), blurParams.src.GetTop(),
1403         blurParams.src.GetRight(), blurParams.src.GetBottom());
1404     SkRect dstRect = SkRect::MakeLTRB(blurParams.dst.GetLeft(), blurParams.dst.GetTop(),
1405         blurParams.dst.GetRight(), blurParams.dst.GetBottom());
1406 
1407     SkBlurArg blurArg(srcRect, dstRect, blurParams.sigma, blurParams.saturation, blurParams.brightness);
1408     return skCanvas_->drawBlurImage(img.get(), blurArg);
1409 #endif
1410 }
1411 
DrawImageEffectHPS(const Image & image,const std::vector<std::shared_ptr<Drawing::HpsEffectParameter>> & hpsEffectParams)1412 bool SkiaCanvas::DrawImageEffectHPS(const Image& image,
1413     const std::vector<std::shared_ptr<Drawing::HpsEffectParameter>>& hpsEffectParams)
1414 {
1415     LOGD("skia does not support DrawImageEffectHPS");
1416     return false;
1417 }
1418 
CalcHpsBluredImageDimension(const Drawing::HpsBlurParameter & blurParams)1419 std::array<int, 2> SkiaCanvas::CalcHpsBluredImageDimension(const Drawing::HpsBlurParameter& blurParams)
1420 {
1421     if (!skCanvas_) {
1422         LOGD("SkiaCanvas::CalcHpsBluredImageDimension, skCanvas_ is nullptr");
1423         return {0, 0};
1424     }
1425 
1426 #ifdef USE_M133_SKIA
1427     return {0, 0};
1428 #else
1429     SkRect srcRect = SkRect::MakeLTRB(blurParams.src.GetLeft(), blurParams.src.GetTop(),
1430         blurParams.src.GetRight(), blurParams.src.GetBottom());
1431     SkRect dstRect = SkRect::MakeLTRB(blurParams.dst.GetLeft(), blurParams.dst.GetTop(),
1432         blurParams.dst.GetRight(), blurParams.dst.GetBottom());
1433 
1434     SkBlurArg blurArg(srcRect, dstRect, blurParams.sigma, blurParams.saturation, blurParams.brightness);
1435     return skCanvas_->CalcHpsBluredImageDimension(blurArg);
1436 #endif
1437 }
1438 } // namespace Drawing
1439 } // namespace Rosen
1440 } // namespace OHOS
1441