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