• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     int j = 0;
225     for (auto& iter : debugNotSupportOps_) {
226         LOGD("opinc ops[%d] [%s %d]", j, iter.first.c_str(), iter.second);
227         j++;
228     }
229 #endif
230 }
231 
ProcessPaintForImage(const SkPaint * paint)232 static SkPaint ProcessPaintForImage(const SkPaint* paint)
233 {
234     SkPaint ret;
235     if (paint) {
236         ret = *paint;
237         ret.setStyle(SkPaint::kFill_Style);
238         ret.setPathEffect(nullptr);
239     }
240     return ret;
241 }
242 
ProcessPaintForVertices(SkPaint paint)243 static SkPaint ProcessPaintForVertices(SkPaint paint)
244 {
245     paint.setStyle(SkPaint::kFill_Style);
246     paint.setMaskFilter(nullptr);
247     paint.setPathEffect(nullptr);
248     return paint;
249 }
250 
BlendModeCanCache(SkBlendMode mode)251 static inline bool BlendModeCanCache(SkBlendMode mode)
252 {
253     return (mode == SkBlendMode::kSrcOver) || (mode == SkBlendMode::kSrc);
254 }
255 
PaintCanCache(const SkPaint & paint)256 static inline bool PaintCanCache(const SkPaint& paint)
257 {
258     const auto bm = paint.asBlendMode();
259     if (bm && !BlendModeCanCache(bm.value())) {
260         return false;
261     }
262     return true;
263 }
264 
RecordDrawArea(const SkRect & bounds,const SkPaint & paint,const SkMatrix * matrix)265 bool SkiaCanvasAutoCache::RecordDrawArea(const SkRect& bounds, const SkPaint& paint, const SkMatrix* matrix)
266 {
267     if (!bounds.isFinite() || paint.nothingToDraw()) {
268         return true;
269     }
270 
271     if (PaintCanCache(paint) && paint.canComputeFastBounds()) {
272         SkRect oriBound = matrix ? matrix->mapRect(bounds) : bounds;
273         SkRect devRect = getTotalMatrix().mapRect(paint.computeFastBounds(oriBound, &oriBound));
274         if (!devRect.isEmpty()) {
275             drawAreaRects_.push_back(devRect);
276             totalOpNums_++;
277             totalDrawAreas_ += std::min(std::max(static_cast<int>(devRect.width()), 0), MAX_DRAW_RECT) *
278                 std::min(std::max(static_cast<int>(devRect.height()), 0), MAX_DRAW_RECT);
279         }
280         return true;
281     }
282     return false;
283 }
284 
getSaveLayerStrategy(const SaveLayerRec & rec)285 SkCanvas::SaveLayerStrategy SkiaCanvasAutoCache::getSaveLayerStrategy(const SaveLayerRec& rec)
286 {
287     if (OpShouldRecord()) {
288         if (rec.fPaint && !PaintCanCache(*rec.fPaint)) {
289             RecordUnsupportOp(__func__, *rec.fPaint);
290         }
291     }
292     return this->SkNWayCanvas::getSaveLayerStrategy(rec);
293 }
294 
onDoSaveBehind(const SkRect * rect)295 bool SkiaCanvasAutoCache::onDoSaveBehind(const SkRect* rect)
296 {
297     RecordUnsupportOp(__func__);
298     return this->SkNWayCanvas::onDoSaveBehind(rect);
299 }
300 
onDrawPaint(const SkPaint & paint)301 void SkiaCanvasAutoCache::onDrawPaint(const SkPaint& paint)
302 {
303     if ((!paint.nothingToDraw()) && !this->isClipEmpty()) {
304         RecordUnsupportOp(__func__, paint);
305     }
306     this->SkNWayCanvas::onDrawPaint(paint);
307 }
308 
onDrawBehind(const SkPaint & paint)309 void SkiaCanvasAutoCache::onDrawBehind(const SkPaint& paint)
310 {
311     RecordUnsupportOp(__func__, paint);
312     this->SkNWayCanvas::onDrawBehind(paint);
313 }
314 
onDrawPoints(PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)315 void SkiaCanvasAutoCache::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
316                                        const SkPaint& paint)
317 {
318     if (count <= 0 || paint.nothingToDraw()) {
319         return;
320     }
321 
322     if (OpShouldRecord()) {
323         SkRect bounds;
324         if (count == 2) { // 2: two points
325             bounds.set(pts[0], pts[1]);
326         } else {
327             bounds.setBounds(pts, SkToInt(count));
328         }
329         SkPaint strokePaint = paint;
330         strokePaint.setStyle(SkPaint::kStroke_Style);
331         if (!RecordDrawArea(bounds, strokePaint)) {
332             RecordUnsupportOp(__func__, strokePaint);
333         }
334     }
335     this->SkNWayCanvas::onDrawPoints(mode, count, pts, paint);
336 }
337 
onDrawRect(const SkRect & rect,const SkPaint & paint)338 void SkiaCanvasAutoCache::onDrawRect(const SkRect& rect, const SkPaint& paint)
339 {
340     if (OpShouldRecord()) {
341         if (!RecordDrawArea(rect, paint)) {
342             RecordUnsupportOp(__func__, paint);
343         }
344     }
345     this->SkNWayCanvas::onDrawRect(rect, paint);
346 }
347 
onDrawRRect(const SkRRect & rrect,const SkPaint & paint)348 void SkiaCanvasAutoCache::onDrawRRect(const SkRRect& rrect, const SkPaint& paint)
349 {
350     if (OpShouldRecord()) {
351         const SkRect& bounds = rrect.getBounds();
352         if (!RecordDrawArea(bounds, paint)) {
353             RecordUnsupportOp(__func__, paint);
354         }
355     }
356     this->SkNWayCanvas::onDrawRRect(rrect, paint);
357 }
358 
onDrawDRRect(const SkRRect & outer,const SkRRect & inner,const SkPaint & paint)359 void SkiaCanvasAutoCache::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
360                                        const SkPaint& paint)
361 {
362     if (OpShouldRecord()) {
363         if (!RecordDrawArea(outer.getBounds(), paint)) {
364             RecordUnsupportOp(__func__, paint);
365         }
366     }
367     this->SkNWayCanvas::onDrawDRRect(outer, inner, paint);
368 }
369 
onDrawRegion(const SkRegion & region,const SkPaint & paint)370 void SkiaCanvasAutoCache::onDrawRegion(const SkRegion& region, const SkPaint& paint)
371 {
372     if (OpShouldRecord()) {
373         const SkRect bounds = SkRect::Make(region.getBounds());
374         if (!RecordDrawArea(bounds, paint)) {
375             RecordUnsupportOp(__func__, paint);
376         }
377     }
378     this->SkNWayCanvas::onDrawRegion(region, paint);
379 }
380 
onDrawOval(const SkRect & rect,const SkPaint & paint)381 void SkiaCanvasAutoCache::onDrawOval(const SkRect& rect, const SkPaint& paint)
382 {
383     if (OpShouldRecord()) {
384         if (!RecordDrawArea(rect, paint)) {
385             RecordUnsupportOp(__func__, paint);
386         }
387     }
388     this->SkNWayCanvas::onDrawOval(rect, paint);
389 }
390 
onDrawArc(const SkRect & rect,SkScalar startAngle,SkScalar sweepAngle,bool useCenter,const SkPaint & paint)391 void SkiaCanvasAutoCache::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
392                                     bool useCenter, const SkPaint& paint)
393 {
394     if (OpShouldRecord()) {
395         if (!RecordDrawArea(rect, paint)) {
396             RecordUnsupportOp(__func__, paint);
397         }
398     }
399     this->SkNWayCanvas::onDrawArc(rect, startAngle, sweepAngle, useCenter, paint);
400 }
401 
onDrawPath(const SkPath & path,const SkPaint & paint)402 void SkiaCanvasAutoCache::onDrawPath(const SkPath& path, const SkPaint& paint)
403 {
404     if (OpShouldRecord()) {
405         if (!path.isInverseFillType()) {
406             const SkRect& pathBounds = path.getBounds();
407             if (!RecordDrawArea(pathBounds, paint)) {
408                 RecordUnsupportOp(__func__, paint);
409             }
410         } else {
411             RecordUnsupportOp(__func__, paint);
412         }
413     }
414     this->SkNWayCanvas::onDrawPath(path, paint);
415 }
416 
417 /* image not null, SkCanvas::drawImage will RETURN_ON_NULL(image) */
onDrawImage2(const SkImage * image,SkScalar left,SkScalar top,const SkSamplingOptions & sampling,const SkPaint * paint)418 void SkiaCanvasAutoCache::onDrawImage2(const SkImage* image, SkScalar left, SkScalar top,
419                                        const SkSamplingOptions& sampling, const SkPaint* paint)
420 {
421     SkPaint realPaint = paint ? *paint : SkPaint();
422     if (OpShouldRecord()) {
423         SkRect bounds = SkRect::MakeXYWH(left, top, image->width(), image->height());
424         if (!RecordDrawArea(bounds, realPaint)) {
425             RecordUnsupportOp(__func__, realPaint);
426         }
427     }
428     this->SkNWayCanvas::onDrawImage2(image, left, top, sampling, paint);
429 }
430 
onDrawImageRect2(const SkImage * image,const SkRect & src,const SkRect & dst,const SkSamplingOptions & sampling,const SkPaint * paint,SrcRectConstraint constraint)431 void SkiaCanvasAutoCache::onDrawImageRect2(const SkImage* image, const SkRect& src,
432                                            const SkRect& dst, const SkSamplingOptions& sampling,
433                                            const SkPaint* paint, SrcRectConstraint constraint)
434 {
435     if (OpShouldRecord()) {
436         SkPaint realPaint = ProcessPaintForImage(paint);
437         if (!RecordDrawArea(dst, realPaint)) {
438             RecordUnsupportOp(__func__, realPaint);
439         }
440     }
441     this->SkNWayCanvas::onDrawImageRect2(image, src, dst, sampling, paint, constraint);
442 }
443 
onDrawImageLattice2(const SkImage * image,const Lattice & lattice,const SkRect & dst,SkFilterMode filter,const SkPaint * paint)444 void SkiaCanvasAutoCache::onDrawImageLattice2(const SkImage* image, const Lattice& lattice,
445                                               const SkRect& dst, SkFilterMode filter,
446                                               const SkPaint* paint)
447 {
448     if (OpShouldRecord()) {
449         SkPaint realPaint = ProcessPaintForImage(paint);
450         if (!RecordDrawArea(dst, realPaint)) {
451             RecordUnsupportOp(__func__, realPaint);
452         }
453     }
454     this->SkNWayCanvas::onDrawImageLattice2(image, lattice, dst, filter, paint);
455 }
456 
457 /* vertices not null, SkCanvas::drawVertices() will RETURN_ON_NULL(vertices) */
onDrawVerticesObject(const SkVertices * vertices,SkBlendMode bmode,const SkPaint & paint)458 void SkiaCanvasAutoCache::onDrawVerticesObject(const SkVertices* vertices,
459                                                SkBlendMode bmode, const SkPaint& paint)
460 {
461     if (OpShouldRecord()) {
462         SkPaint realPaint = ProcessPaintForVertices(paint);
463         if (!BlendModeCanCache(bmode) || !RecordDrawArea(vertices->bounds(), realPaint)) {
464             RecordUnsupportOp(__func__, realPaint);
465         }
466     }
467     this->SkNWayCanvas::onDrawVerticesObject(vertices, bmode, paint);
468 }
469 
onDrawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],SkBlendMode bmode,const SkPaint & paint)470 void SkiaCanvasAutoCache::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
471                                       const SkPoint texCoords[4], SkBlendMode bmode,
472                                       const SkPaint& paint)
473 {
474     if (OpShouldRecord()) {
475         SkPaint realPaint = ProcessPaintForVertices(paint);
476         SkRect bounds;
477         bounds.setBounds(cubics, SkPatchUtils::kNumCtrlPts);
478         if (!BlendModeCanCache(bmode) || !RecordDrawArea(bounds, realPaint)) {
479             RecordUnsupportOp(__func__, realPaint);
480         }
481     }
482     this->SkNWayCanvas::onDrawPatch(cubics, colors, texCoords, bmode, paint);
483 }
484 
485 /* picture not null, SkCanvas::drawPicture() will RETURN_ON_NULL(picture) */
onDrawPicture(const SkPicture * picture,const SkMatrix * m,const SkPaint * originalPaint)486 void SkiaCanvasAutoCache::onDrawPicture(const SkPicture* picture, const SkMatrix* m,
487                                         const SkPaint* originalPaint)
488 {
489     SkPaint tmpPaint = originalPaint ? *originalPaint : SkPaint();
490     const SkPaint* newPaint = &tmpPaint;
491     if ((picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) ||
492         !RecordDrawArea(picture->cullRect(), tmpPaint, m)) {
493         RecordUnsupportOp(__func__, tmpPaint);
494     }
495 
496     if (!originalPaint) {
497         if ((std::fabs(newPaint->getAlphaf() - 1.0f) <= std::numeric_limits<float>::epsilon()) &&
498             newPaint->getColorFilter() == nullptr &&
499             newPaint->getImageFilter() == nullptr && newPaint->asBlendMode() == SkBlendMode::kSrcOver) {
500             newPaint = nullptr;
501         }
502     }
503     this->SkNWayCanvas::onDrawPicture(picture, m, newPaint);
504 }
505 
onDrawDrawable(SkDrawable * drawable,const SkMatrix * matrix)506 void SkiaCanvasAutoCache::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix)
507 {
508     this->SkNWayCanvas::onDrawDrawable(drawable, matrix);
509 }
510 
onDrawGlyphRunList(const SkGlyphRunList & list,const SkPaint & paint)511 void SkiaCanvasAutoCache::onDrawGlyphRunList(const SkGlyphRunList& list, const SkPaint& paint)
512 {
513     if (OpShouldRecord()) {
514         SkRect bounds = list.sourceBounds();
515         if (!RecordDrawArea(bounds, paint)) {
516             RecordUnsupportOp(__func__, paint);
517         }
518     }
519     this->SkNWayCanvas::onDrawGlyphRunList(list, paint);
520 }
521 
522 /* blob not null, SkCanvas::drawTextBlob() will RETURN_ON_NULL(blob) */
onDrawTextBlob(const SkTextBlob * blob,SkScalar x,SkScalar y,const SkPaint & paint)523 void SkiaCanvasAutoCache::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
524                                          const SkPaint& paint)
525 {
526     if (OpShouldRecord()) {
527         if (!RecordDrawArea(blob->bounds().makeOffset({x, y}), paint)) {
528             RecordUnsupportOp(__func__, paint);
529         }
530     }
531     this->SkNWayCanvas::onDrawTextBlob(blob, x, y, paint);
532 }
533 
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)534 void SkiaCanvasAutoCache::onDrawAtlas2(const SkImage* image, const SkRSXform xform[],
535                                        const SkRect tex[], const SkColor colors[], int count,
536                                        SkBlendMode bmode, const SkSamplingOptions& sampling,
537                                        const SkRect* cull, const SkPaint* paint)
538 {
539     if (OpShouldRecord()) {
540         SkPaint realPaint = ProcessPaintForVertices(ProcessPaintForImage(paint));
541         if (!cull || !BlendModeCanCache(bmode) || !RecordDrawArea(*cull, realPaint)) {
542             RecordUnsupportOp(__func__, realPaint);
543         }
544     }
545     this->SkNWayCanvas::onDrawAtlas2(image, xform, tex, colors, count, bmode, sampling, cull, paint);
546 }
547 
onDrawAnnotation(const SkRect & rect,const char key[],SkData * value)548 void SkiaCanvasAutoCache::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value)
549 {
550     // enable onDrawAnnotation for skp when debug
551     RecordUnsupportOp(__func__);
552     this->SkNWayCanvas::onDrawAnnotation(rect, key, value);
553 }
554 
onDrawShadowRec(const SkPath & path,const SkDrawShadowRec & rec)555 void SkiaCanvasAutoCache::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec)
556 {
557     RecordUnsupportOp(__func__);
558     this->SkNWayCanvas::onDrawShadowRec(path, rec);
559 }
560 
onDrawEdgeAAQuad(const SkRect & rect,const SkPoint clip[4],QuadAAFlags aa,const SkColor4f & color,SkBlendMode mode)561 void SkiaCanvasAutoCache::onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
562                                            QuadAAFlags aa, const SkColor4f& color, SkBlendMode mode)
563 {
564     if (OpShouldRecord()) {
565         SkPaint paint;
566         paint.setColor(color);
567         paint.setBlendMode(mode);
568         if (!BlendModeCanCache(mode) || !RecordDrawArea(rect, paint)) {
569             RecordUnsupportOp(__func__, paint);
570         }
571     }
572     this->SkNWayCanvas::onDrawEdgeAAQuad(rect, clip, aa, color, mode);
573 }
574 
onDrawEdgeAAImageSet2(const ImageSetEntry set[],int count,const SkPoint dstClips[],const SkMatrix preViewMatrices[],const SkSamplingOptions & sampling,const SkPaint * paint,SrcRectConstraint constraint)575 void SkiaCanvasAutoCache::onDrawEdgeAAImageSet2(const ImageSetEntry set[], int count,
576                                                 const SkPoint dstClips[],
577                                                 const SkMatrix preViewMatrices[],
578                                                 const SkSamplingOptions& sampling,
579                                                 const SkPaint* paint,
580                                                 SrcRectConstraint constraint)
581 {
582     RecordUnsupportOp(__func__);
583     this->SkNWayCanvas::onDrawEdgeAAImageSet2(
584         set, count, dstClips, preViewMatrices, sampling, paint, constraint);
585 }
586 
onNewSurface(const SkImageInfo & info,const SkSurfaceProps & props)587 sk_sp<SkSurface> SkiaCanvasAutoCache::onNewSurface(const SkImageInfo& info,
588                                                    const SkSurfaceProps& props)
589 {
590     return this->proxy()->makeSurface(info, &props);
591 }
592 
onPeekPixels(SkPixmap * pixmap)593 bool SkiaCanvasAutoCache::onPeekPixels(SkPixmap* pixmap)
594 {
595     return this->proxy()->peekPixels(pixmap);
596 }
597 
onAccessTopLayerPixels(SkPixmap * pixmap)598 bool SkiaCanvasAutoCache::onAccessTopLayerPixels(SkPixmap* pixmap)
599 {
600     SkImageInfo info;
601     size_t rowByteSize;
602 
603     void* addr = this->proxy()->accessTopLayerPixels(&info, &rowByteSize);
604     if (!addr) {
605         return false;
606     }
607 
608     if (pixmap) {
609         pixmap->reset(info, addr, rowByteSize);
610     }
611     return true;
612 }
613 
onImageInfo() const614 SkImageInfo SkiaCanvasAutoCache::onImageInfo() const
615 {
616     return this->proxy()->imageInfo();
617 }
618 
onGetProps(SkSurfaceProps * props) const619 bool SkiaCanvasAutoCache::onGetProps(SkSurfaceProps* props) const
620 {
621     return this->proxy()->getProps(props);
622 }
623 } // namespace Drawing
624 } // namespace Rosen
625 } // namespace OHOS
626