1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "skia_canvas_autocache.h"
17
18 #include <algorithm>
19 #include "include/core/SkPaint.h"
20 #include "include/core/SkPixmap.h"
21 #include "include/core/SkSurface.h"
22 #include "include/core/SkRRect.h"
23 #include "include/core/SkRegion.h"
24 #include "include/core/SkPath.h"
25 #include "include/core/SkVertices.h"
26 #include "include/core/SkPathEffect.h"
27 #include "include/core/SkImageFilter.h"
28 #include "include/core/SkColorFilter.h"
29 #include "include/core/SkImage.h"
30 #include "include/core/SkMaskFilter.h"
31 #include "include/core/SkPicture.h"
32 #include "include/core/SkTextBlob.h"
33 #include "include/core/SkDrawable.h"
34 #ifdef USE_M133_SKIA
35 #include "src/text/GlyphRun.h"
36 #else
37 #include "src/core/SkGlyphRun.h"
38 #endif
39 #include "src/utils/SkPatchUtils.h"
40 #include "src/core/SkCanvasPriv.h"
41 #ifdef USE_M133_SKIA
42 #include "src/base/SkTLazy.h"
43 #else
44 #include "src/core/SkTLazy.h"
45 #endif
46 #include "src/core/SkMatrixPriv.h"
47
48 #include "utils/log.h"
49
50 namespace OHOS {
51 namespace Rosen {
52 namespace Drawing {
53
54 static constexpr int32_t MAX_PERCENTAGE = 8;
55 static constexpr int32_t MIN_OPS_NUM = 3;
56 static constexpr int32_t MAX_OPS_NUM = 8;
57 static constexpr int32_t PERCENT = 100;
58 static constexpr int MAX_DRAW_RECT = 32768;
59
SkiaCanvasAutoCache(SkCanvas * canvas)60 SkiaCanvasAutoCache::SkiaCanvasAutoCache(SkCanvas* canvas)
61 : SkiaCanvasOp(canvas)
62 {
63 SkMatrix originMatrix = canvas->getTotalMatrix();
64 if (!originMatrix.invert(&originMatrixInvert_)) {
65 LOGE("opinc originMatrix cannot invert");
66 opCanCache_ = false;
67 }
68 rejectBounds_ = canvas->getTotalMatrix().mapRect(canvas->getLocalClipBounds());
69 this->clipRect(SkRect::Make(canvas->getDeviceClipBounds()));
70 this->setMatrix(originMatrix);
71 this->addCanvas(canvas);
72 }
73
Init(const SkMatrix & m)74 void SkiaCanvasAutoCache::Init(const SkMatrix& m)
75 {
76 nodeMatrix_.preConcat(originMatrixInvert_);
77 }
78
OpCanCache(const SkRect & bound)79 bool SkiaCanvasAutoCache::OpCanCache(const SkRect& bound)
80 {
81 #ifdef OPINC_ENABLE_FEATURE_DEBUG
82 MergeDrawAreaRects();
83 #endif
84 do {
85 if (!opCanCache_ || totalOpNums_ == 0 || drawAreaRects_.size() == 0) {
86 opCanCache_ = false;
87 calNotSupport_ = __LINE__;
88 break;
89 }
90 MergeDrawAreaRects(); // get unionDrawArea_
91 int unionWidth = static_cast<int>(unionDrawArea_.width());
92 int unionHeight = static_cast<int>(unionDrawArea_.height());
93 if ((unionWidth > static_cast<int>(bound.width())) || (unionHeight > static_cast<int>(bound.height()))) {
94 opCanCache_ = false;
95 calNotSupport_ = __LINE__;
96 break;
97 }
98 if (unionWidth != 0 && unionHeight != 0) {
99 percent_ = (totalDrawAreas_ * PERCENT) / (unionWidth * unionHeight);
100 }
101 if (totalOpNums_ >= MAX_OPS_NUM ||
102 (percent_ > MAX_PERCENTAGE && totalOpNums_ > MIN_OPS_NUM)) {
103 opCanCache_ = true;
104 break;
105 }
106 opCanCache_ = false;
107 calNotSupport_ = __LINE__;
108 } while (false);
109 #ifdef OPINC_ENABLE_FEATURE_DEBUG
110 ShowDrawResult(bound);
111 #endif
112 return opCanCache_;
113 }
114
GetOpListDrawArea()115 std::vector<SkRect>& SkiaCanvasAutoCache::GetOpListDrawArea()
116 {
117 return drawAreaRects_;
118 }
119
GetOpUnionRect()120 SkRect& SkiaCanvasAutoCache::GetOpUnionRect()
121 {
122 return unionDrawArea_;
123 }
124
OpShouldRecord() const125 bool SkiaCanvasAutoCache::OpShouldRecord() const
126 {
127 return opCanCache_;
128 }
129
RecordUnsupportOp(const char * name)130 void SkiaCanvasAutoCache::RecordUnsupportOp(const char* name)
131 {
132 SkPaint paint;
133 RecordUnsupportOp(name, paint);
134 }
135
RecordUnsupportOp(const char * name,const SkPaint & paint)136 void SkiaCanvasAutoCache::RecordUnsupportOp(const char* name, const SkPaint& paint)
137 {
138 #ifdef OPINC_ENABLE_FEATURE_DEBUG
139 if (name != nullptr) {
140 std::string ret(name);
141 ret.append("_");
142 if (paint.asBlendMode().has_value()) {
143 ret.append(std::string(SkBlendMode_Name(paint.asBlendMode().value())));
144 } else {
145 ret.append("noblend");
146 }
147 ret.append("_");
148 ret.append(std::to_string(paint.getAlpha()));
149 debugNotSupportOps_[ret.c_str()]++;
150 }
151 #endif
152 opCanCache_ = false;
153 }
154
CmpSkRectLTRB(const SkRect & a,const SkRect & b)155 static bool CmpSkRectLTRB(const SkRect& a, const SkRect& b)
156 {
157 if (a.left() < b.left()) {
158 return true;
159 }
160 if (a.left() > b.left()) {
161 return false;
162 }
163 if (a.top() < b.top()) {
164 return true;
165 }
166 if (a.top() > b.top()) {
167 return false;
168 }
169 if (a.right() < b.right()) {
170 return true;
171 }
172 if (a.right() > b.right()) {
173 return false;
174 }
175 if (a.bottom() < b.bottom()) {
176 return true;
177 }
178 if (a.bottom() > b.bottom()) {
179 return false;
180 }
181 return false;
182 }
183
184 /* The intersecting regins are merged into one rect. The disjoint regions are not merged. */
MergeDrawAreaRects()185 void SkiaCanvasAutoCache::MergeDrawAreaRects()
186 {
187 std::vector<SkRect>& drawAreaRects = drawAreaRects_;
188 for (uint32_t i = 0; i < drawAreaRects.size(); i++) {
189 for (uint32_t j = 0; j < drawAreaRects.size(); j++) {
190 if (i != j && drawAreaRects[i].intersects(drawAreaRects[j])) {
191 drawAreaRects[i].join(drawAreaRects[j]);
192 drawAreaRects[j] = drawAreaRects[i];
193 }
194 }
195 }
196 std::sort(drawAreaRects.begin(), drawAreaRects.end(), CmpSkRectLTRB);
197 drawAreaRects.erase(std::unique(drawAreaRects.begin(), drawAreaRects.end()), drawAreaRects.end());
198
199 for (uint32_t i = 0; i < drawAreaRects.size(); i++) {
200 for (uint32_t j = i + 1; j < drawAreaRects.size(); j++) {
201 if (drawAreaRects[i].intersects(drawAreaRects[j])) {
202 opCanCache_ = false;
203 return;
204 }
205 }
206 }
207
208 SkRect unionDrawAreaTemp = SkRect::MakeEmpty();
209 for (uint32_t i = 0; i < drawAreaRects.size(); i++) {
210 drawAreaRects[i] = nodeMatrix_.mapRect(drawAreaRects[i]);
211 unionDrawAreaTemp.join(drawAreaRects[i]);
212 }
213 unionDrawAreaTemp.roundOut(&unionDrawArea_);
214 }
215
ShowDrawResult(const SkRect & bound)216 void SkiaCanvasAutoCache::ShowDrawResult(const SkRect& bound)
217 {
218 #ifdef OPINC_ENABLE_FEATURE_DEBUG
219 std::vector<SkRect>& drawAreaRects = drawAreaRects_;
220 LOGD("opinc draw result %d, canvas w%d h%d, opNum%d, percent%d, cal%d, "
221 "bound[%.2f %.2f %.2f %.2f] unionDrawArea[%.2f %.2f %.2f %.2f]"
222 "rect num %d not support %d",
223 opCanCache_, proxy()->imageInfo().width(), proxy()->imageInfo().height(),
224 totalOpNums_, percent_, calNotSupport_,
225 bound.x(), bound.y(), bound.width(), bound.height(),
226 unionDrawArea_.x(), unionDrawArea_.y(), unionDrawArea_.width(), unionDrawArea_.height(),
227 static_cast<int>(drawAreaRects.size()), static_cast<int>(debugNotSupportOps_.size()));
228 for (uint32_t i = 0; i < drawAreaRects.size(); i++) {
229 SkRect &rect = drawAreaRects[i];
230 LOGD("opinc rect[%u], [%.2f %.2f %.2f %.2f]", i, rect.x(), rect.y(), rect.width(), rect.height());
231 }
232 int j = 0;
233 for (auto& iter : debugNotSupportOps_) {
234 LOGD("opinc ops[%d] [%s %d]", j, iter.first.c_str(), iter.second);
235 j++;
236 }
237 #endif
238 }
239
ProcessPaintForImage(const SkPaint * paint)240 static SkPaint ProcessPaintForImage(const SkPaint* paint)
241 {
242 SkPaint ret;
243 if (paint) {
244 ret = *paint;
245 ret.setStyle(SkPaint::kFill_Style);
246 ret.setPathEffect(nullptr);
247 }
248 return ret;
249 }
250
ProcessPaintForVertices(SkPaint paint)251 static SkPaint ProcessPaintForVertices(SkPaint paint)
252 {
253 paint.setStyle(SkPaint::kFill_Style);
254 paint.setMaskFilter(nullptr);
255 paint.setPathEffect(nullptr);
256 return paint;
257 }
258
BlendModeCanCache(SkBlendMode mode)259 static inline bool BlendModeCanCache(SkBlendMode mode)
260 {
261 return (mode == SkBlendMode::kSrcOver) || (mode == SkBlendMode::kSrc);
262 }
263
PaintCanCache(const SkPaint & paint)264 static inline bool PaintCanCache(const SkPaint& paint)
265 {
266 const auto bm = paint.asBlendMode();
267 if (bm && !BlendModeCanCache(bm.value())) {
268 return false;
269 }
270 return true;
271 }
272
RecordDrawArea(const SkRect & bounds,const SkPaint & paint,const SkMatrix * matrix)273 bool SkiaCanvasAutoCache::RecordDrawArea(const SkRect& bounds, const SkPaint& paint, const SkMatrix* matrix)
274 {
275 if (!bounds.isFinite() || paint.nothingToDraw()) {
276 return true;
277 }
278
279 if (PaintCanCache(paint) && paint.canComputeFastBounds()) {
280 SkRect oriBound = matrix ? matrix->mapRect(bounds) : bounds;
281 SkRect devRect = getTotalMatrix().mapRect(paint.computeFastBounds(oriBound, &oriBound));
282 if (!devRect.isEmpty()) {
283 drawAreaRects_.push_back(devRect);
284 totalOpNums_++;
285 totalDrawAreas_ += std::min(std::max(static_cast<int>(devRect.width()), 0), MAX_DRAW_RECT) *
286 std::min(std::max(static_cast<int>(devRect.height()), 0), MAX_DRAW_RECT);
287 }
288 return true;
289 }
290 return false;
291 }
292
getSaveLayerStrategy(const SaveLayerRec & rec)293 SkCanvas::SaveLayerStrategy SkiaCanvasAutoCache::getSaveLayerStrategy(const SaveLayerRec& rec)
294 {
295 if (OpShouldRecord()) {
296 if (rec.fPaint && !PaintCanCache(*rec.fPaint)) {
297 RecordUnsupportOp(__func__, *rec.fPaint);
298 }
299 }
300 return this->SkNWayCanvas::getSaveLayerStrategy(rec);
301 }
302
onDoSaveBehind(const SkRect * rect)303 bool SkiaCanvasAutoCache::onDoSaveBehind(const SkRect* rect)
304 {
305 RecordUnsupportOp(__func__);
306 return this->SkNWayCanvas::onDoSaveBehind(rect);
307 }
308
onDrawPaint(const SkPaint & paint)309 void SkiaCanvasAutoCache::onDrawPaint(const SkPaint& paint)
310 {
311 if ((!paint.nothingToDraw()) && !this->isClipEmpty()) {
312 RecordUnsupportOp(__func__, paint);
313 }
314 this->SkNWayCanvas::onDrawPaint(paint);
315 }
316
onDrawBehind(const SkPaint & paint)317 void SkiaCanvasAutoCache::onDrawBehind(const SkPaint& paint)
318 {
319 RecordUnsupportOp(__func__, paint);
320 this->SkNWayCanvas::onDrawBehind(paint);
321 }
322
onDrawPoints(PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)323 void SkiaCanvasAutoCache::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
324 const SkPaint& paint)
325 {
326 if (count <= 0 || paint.nothingToDraw()) {
327 return;
328 }
329
330 if (OpShouldRecord()) {
331 SkRect bounds;
332 if (count == 2) { // 2: two points
333 bounds.set(pts[0], pts[1]);
334 } else {
335 bounds.setBounds(pts, SkToInt(count));
336 }
337 SkPaint strokePaint = paint;
338 strokePaint.setStyle(SkPaint::kStroke_Style);
339 if (!RecordDrawArea(bounds, strokePaint)) {
340 RecordUnsupportOp(__func__, strokePaint);
341 }
342 }
343 this->SkNWayCanvas::onDrawPoints(mode, count, pts, paint);
344 }
345
onDrawRect(const SkRect & rect,const SkPaint & paint)346 void SkiaCanvasAutoCache::onDrawRect(const SkRect& rect, const SkPaint& paint)
347 {
348 if (OpShouldRecord()) {
349 if (!RecordDrawArea(rect, paint)) {
350 RecordUnsupportOp(__func__, paint);
351 }
352 }
353 this->SkNWayCanvas::onDrawRect(rect, paint);
354 }
355
onDrawRRect(const SkRRect & rrect,const SkPaint & paint)356 void SkiaCanvasAutoCache::onDrawRRect(const SkRRect& rrect, const SkPaint& paint)
357 {
358 if (OpShouldRecord()) {
359 const SkRect& bounds = rrect.getBounds();
360 if (!RecordDrawArea(bounds, paint)) {
361 RecordUnsupportOp(__func__, paint);
362 }
363 }
364 this->SkNWayCanvas::onDrawRRect(rrect, paint);
365 }
366
onDrawDRRect(const SkRRect & outer,const SkRRect & inner,const SkPaint & paint)367 void SkiaCanvasAutoCache::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
368 const SkPaint& paint)
369 {
370 if (OpShouldRecord()) {
371 if (!RecordDrawArea(outer.getBounds(), paint)) {
372 RecordUnsupportOp(__func__, paint);
373 }
374 }
375 this->SkNWayCanvas::onDrawDRRect(outer, inner, paint);
376 }
377
onDrawRegion(const SkRegion & region,const SkPaint & paint)378 void SkiaCanvasAutoCache::onDrawRegion(const SkRegion& region, const SkPaint& paint)
379 {
380 if (OpShouldRecord()) {
381 const SkRect bounds = SkRect::Make(region.getBounds());
382 if (!RecordDrawArea(bounds, paint)) {
383 RecordUnsupportOp(__func__, paint);
384 }
385 }
386 this->SkNWayCanvas::onDrawRegion(region, paint);
387 }
388
onDrawOval(const SkRect & rect,const SkPaint & paint)389 void SkiaCanvasAutoCache::onDrawOval(const SkRect& rect, const SkPaint& paint)
390 {
391 if (OpShouldRecord()) {
392 if (!RecordDrawArea(rect, paint)) {
393 RecordUnsupportOp(__func__, paint);
394 }
395 }
396 this->SkNWayCanvas::onDrawOval(rect, paint);
397 }
398
onDrawArc(const SkRect & rect,SkScalar startAngle,SkScalar sweepAngle,bool useCenter,const SkPaint & paint)399 void SkiaCanvasAutoCache::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
400 bool useCenter, const SkPaint& paint)
401 {
402 if (OpShouldRecord()) {
403 if (!RecordDrawArea(rect, paint)) {
404 RecordUnsupportOp(__func__, paint);
405 }
406 }
407 this->SkNWayCanvas::onDrawArc(rect, startAngle, sweepAngle, useCenter, paint);
408 }
409
onDrawPath(const SkPath & path,const SkPaint & paint)410 void SkiaCanvasAutoCache::onDrawPath(const SkPath& path, const SkPaint& paint)
411 {
412 if (OpShouldRecord()) {
413 if (!path.isInverseFillType()) {
414 const SkRect& pathBounds = path.getBounds();
415 if (!RecordDrawArea(pathBounds, paint)) {
416 RecordUnsupportOp(__func__, paint);
417 }
418 } else {
419 RecordUnsupportOp(__func__, paint);
420 }
421 }
422 this->SkNWayCanvas::onDrawPath(path, paint);
423 }
424
425 /* image not null, SkCanvas::drawImage will RETURN_ON_NULL(image) */
onDrawImage2(const SkImage * image,SkScalar left,SkScalar top,const SkSamplingOptions & sampling,const SkPaint * paint)426 void SkiaCanvasAutoCache::onDrawImage2(const SkImage* image, SkScalar left, SkScalar top,
427 const SkSamplingOptions& sampling, const SkPaint* paint)
428 {
429 SkPaint realPaint = paint ? *paint : SkPaint();
430 if (OpShouldRecord()) {
431 SkRect bounds = SkRect::MakeXYWH(left, top, image->width(), image->height());
432 if (!RecordDrawArea(bounds, realPaint)) {
433 RecordUnsupportOp(__func__, realPaint);
434 }
435 }
436 this->SkNWayCanvas::onDrawImage2(image, left, top, sampling, paint);
437 }
438
onDrawImageRect2(const SkImage * image,const SkRect & src,const SkRect & dst,const SkSamplingOptions & sampling,const SkPaint * paint,SrcRectConstraint constraint)439 void SkiaCanvasAutoCache::onDrawImageRect2(const SkImage* image, const SkRect& src,
440 const SkRect& dst, const SkSamplingOptions& sampling,
441 const SkPaint* paint, SrcRectConstraint constraint)
442 {
443 if (OpShouldRecord()) {
444 SkPaint realPaint = ProcessPaintForImage(paint);
445 if (!RecordDrawArea(dst, realPaint)) {
446 RecordUnsupportOp(__func__, realPaint);
447 }
448 }
449 this->SkNWayCanvas::onDrawImageRect2(image, src, dst, sampling, paint, constraint);
450 }
451
onDrawImageLattice2(const SkImage * image,const Lattice & lattice,const SkRect & dst,SkFilterMode filter,const SkPaint * paint)452 void SkiaCanvasAutoCache::onDrawImageLattice2(const SkImage* image, const Lattice& lattice,
453 const SkRect& dst, SkFilterMode filter,
454 const SkPaint* paint)
455 {
456 if (OpShouldRecord()) {
457 SkPaint realPaint = ProcessPaintForImage(paint);
458 if (!RecordDrawArea(dst, realPaint)) {
459 RecordUnsupportOp(__func__, realPaint);
460 }
461 }
462 this->SkNWayCanvas::onDrawImageLattice2(image, lattice, dst, filter, paint);
463 }
464
465 /* vertices not null, SkCanvas::drawVertices() will RETURN_ON_NULL(vertices) */
onDrawVerticesObject(const SkVertices * vertices,SkBlendMode bmode,const SkPaint & paint)466 void SkiaCanvasAutoCache::onDrawVerticesObject(const SkVertices* vertices,
467 SkBlendMode bmode, const SkPaint& paint)
468 {
469 if (OpShouldRecord()) {
470 SkPaint realPaint = ProcessPaintForVertices(paint);
471 if (!BlendModeCanCache(bmode) || !RecordDrawArea(vertices->bounds(), realPaint)) {
472 RecordUnsupportOp(__func__, realPaint);
473 }
474 }
475 this->SkNWayCanvas::onDrawVerticesObject(vertices, bmode, paint);
476 }
477
onDrawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],SkBlendMode bmode,const SkPaint & paint)478 void SkiaCanvasAutoCache::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
479 const SkPoint texCoords[4], SkBlendMode bmode,
480 const SkPaint& paint)
481 {
482 if (OpShouldRecord()) {
483 SkPaint realPaint = ProcessPaintForVertices(paint);
484 SkRect bounds;
485 bounds.setBounds(cubics, SkPatchUtils::kNumCtrlPts);
486 if (!BlendModeCanCache(bmode) || !RecordDrawArea(bounds, realPaint)) {
487 RecordUnsupportOp(__func__, realPaint);
488 }
489 }
490 this->SkNWayCanvas::onDrawPatch(cubics, colors, texCoords, bmode, paint);
491 }
492
493 /* picture not null, SkCanvas::drawPicture() will RETURN_ON_NULL(picture) */
onDrawPicture(const SkPicture * picture,const SkMatrix * m,const SkPaint * originalPaint)494 void SkiaCanvasAutoCache::onDrawPicture(const SkPicture* picture, const SkMatrix* m,
495 const SkPaint* originalPaint)
496 {
497 SkPaint tmpPaint = originalPaint ? *originalPaint : SkPaint();
498 const SkPaint* newPaint = &tmpPaint;
499 if ((picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) ||
500 !RecordDrawArea(picture->cullRect(), tmpPaint, m)) {
501 RecordUnsupportOp(__func__, tmpPaint);
502 }
503
504 if (!originalPaint) {
505 if ((std::fabs(newPaint->getAlphaf() - 1.0f) <= std::numeric_limits<float>::epsilon()) &&
506 newPaint->getColorFilter() == nullptr &&
507 newPaint->getImageFilter() == nullptr && newPaint->asBlendMode() == SkBlendMode::kSrcOver) {
508 newPaint = nullptr;
509 }
510 }
511 this->SkNWayCanvas::onDrawPicture(picture, m, newPaint);
512 }
513
onDrawDrawable(SkDrawable * drawable,const SkMatrix * matrix)514 void SkiaCanvasAutoCache::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix)
515 {
516 this->SkNWayCanvas::onDrawDrawable(drawable, matrix);
517 }
518
519 #ifdef USE_M133_SKIA
onDrawGlyphRunList(const sktext::GlyphRunList & list,const SkPaint & paint)520 void SkiaCanvasAutoCache::onDrawGlyphRunList(const sktext::GlyphRunList& list, const SkPaint& paint)
521 #else
522 void SkiaCanvasAutoCache::onDrawGlyphRunList(const SkGlyphRunList& list, const SkPaint& paint)
523 #endif
524 {
525 if (OpShouldRecord()) {
526 SkRect bounds = list.sourceBounds();
527 if (!RecordDrawArea(bounds, paint)) {
528 RecordUnsupportOp(__func__, paint);
529 }
530 }
531 this->SkNWayCanvas::onDrawGlyphRunList(list, paint);
532 }
533
534 /* blob not null, SkCanvas::drawTextBlob() will RETURN_ON_NULL(blob) */
onDrawTextBlob(const SkTextBlob * blob,SkScalar x,SkScalar y,const SkPaint & paint)535 void SkiaCanvasAutoCache::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
536 const SkPaint& paint)
537 {
538 if (OpShouldRecord()) {
539 if (!RecordDrawArea(blob->bounds().makeOffset({x, y}), paint)) {
540 RecordUnsupportOp(__func__, paint);
541 }
542 }
543 this->SkNWayCanvas::onDrawTextBlob(blob, x, y, paint);
544 }
545
onDrawAtlas2(const SkImage * image,const SkRSXform xform[],const SkRect tex[],const SkColor colors[],int count,SkBlendMode bmode,const SkSamplingOptions & sampling,const SkRect * cull,const SkPaint * paint)546 void SkiaCanvasAutoCache::onDrawAtlas2(const SkImage* image, const SkRSXform xform[],
547 const SkRect tex[], const SkColor colors[], int count,
548 SkBlendMode bmode, const SkSamplingOptions& sampling,
549 const SkRect* cull, const SkPaint* paint)
550 {
551 if (OpShouldRecord()) {
552 SkPaint realPaint = ProcessPaintForVertices(ProcessPaintForImage(paint));
553 if (!cull || !BlendModeCanCache(bmode) || !RecordDrawArea(*cull, realPaint)) {
554 RecordUnsupportOp(__func__, realPaint);
555 }
556 }
557 this->SkNWayCanvas::onDrawAtlas2(image, xform, tex, colors, count, bmode, sampling, cull, paint);
558 }
559
onDrawAnnotation(const SkRect & rect,const char key[],SkData * value)560 void SkiaCanvasAutoCache::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value)
561 {
562 // enable onDrawAnnotation for skp when debug
563 RecordUnsupportOp(__func__);
564 this->SkNWayCanvas::onDrawAnnotation(rect, key, value);
565 }
566
onDrawShadowRec(const SkPath & path,const SkDrawShadowRec & rec)567 void SkiaCanvasAutoCache::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec)
568 {
569 RecordUnsupportOp(__func__);
570 this->SkNWayCanvas::onDrawShadowRec(path, rec);
571 }
572
onDrawEdgeAAQuad(const SkRect & rect,const SkPoint clip[4],QuadAAFlags aa,const SkColor4f & color,SkBlendMode mode)573 void SkiaCanvasAutoCache::onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
574 QuadAAFlags aa, const SkColor4f& color, SkBlendMode mode)
575 {
576 if (OpShouldRecord()) {
577 SkPaint paint;
578 paint.setColor(color);
579 paint.setBlendMode(mode);
580 if (!BlendModeCanCache(mode) || !RecordDrawArea(rect, paint)) {
581 RecordUnsupportOp(__func__, paint);
582 }
583 }
584 this->SkNWayCanvas::onDrawEdgeAAQuad(rect, clip, aa, color, mode);
585 }
586
onDrawEdgeAAImageSet2(const ImageSetEntry set[],int count,const SkPoint dstClips[],const SkMatrix preViewMatrices[],const SkSamplingOptions & sampling,const SkPaint * paint,SrcRectConstraint constraint)587 void SkiaCanvasAutoCache::onDrawEdgeAAImageSet2(const ImageSetEntry set[], int count,
588 const SkPoint dstClips[],
589 const SkMatrix preViewMatrices[],
590 const SkSamplingOptions& sampling,
591 const SkPaint* paint,
592 SrcRectConstraint constraint)
593 {
594 RecordUnsupportOp(__func__);
595 this->SkNWayCanvas::onDrawEdgeAAImageSet2(
596 set, count, dstClips, preViewMatrices, sampling, paint, constraint);
597 }
598
onNewSurface(const SkImageInfo & info,const SkSurfaceProps & props)599 sk_sp<SkSurface> SkiaCanvasAutoCache::onNewSurface(const SkImageInfo& info,
600 const SkSurfaceProps& props)
601 {
602 return this->proxy()->makeSurface(info, &props);
603 }
604
onPeekPixels(SkPixmap * pixmap)605 bool SkiaCanvasAutoCache::onPeekPixels(SkPixmap* pixmap)
606 {
607 return this->proxy()->peekPixels(pixmap);
608 }
609
onAccessTopLayerPixels(SkPixmap * pixmap)610 bool SkiaCanvasAutoCache::onAccessTopLayerPixels(SkPixmap* pixmap)
611 {
612 SkImageInfo info;
613 size_t rowByteSize;
614
615 void* addr = this->proxy()->accessTopLayerPixels(&info, &rowByteSize);
616 if (!addr) {
617 return false;
618 }
619
620 if (pixmap) {
621 pixmap->reset(info, addr, rowByteSize);
622 }
623 return true;
624 }
625
onImageInfo() const626 SkImageInfo SkiaCanvasAutoCache::onImageInfo() const
627 {
628 return this->proxy()->imageInfo();
629 }
630
631 #ifdef USE_M133_SKIA
onGetProps(SkSurfaceProps * props,bool top) const632 bool SkiaCanvasAutoCache::onGetProps(SkSurfaceProps* props, bool top) const
633 #else
634 bool SkiaCanvasAutoCache::onGetProps(SkSurfaceProps* props) const
635 #endif
636 {
637 return this->proxy()->getProps(props);
638 }
639 } // namespace Drawing
640 } // namespace Rosen
641 } // namespace OHOS
642