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*>(¢er);
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