• 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 #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