Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkPicturePlayback.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
8
13#include "include/core/SkData.h"
21#include "include/core/SkRect.h"
32#include "src/base/SkSafeMath.h"
41
42class SkDrawable;
43class SkPath;
44class SkTextBlob;
45class SkVertices;
46
47namespace sktext { namespace gpu { class Slug; } }
48
49using namespace skia_private;
50
51static const SkRect* get_rect_ptr(SkReadBuffer* reader, SkRect* storage) {
52 if (reader->readBool()) {
53 reader->readRect(storage);
54 return storage;
55 } else {
56 return nullptr;
57 }
58}
59
63 AutoResetOpID aroi(this);
64 SkASSERT(0 == fCurOffset);
65
66 SkReadBuffer reader(fPictureData->opData()->bytes(),
67 fPictureData->opData()->size());
68 reader.setVersion(fPictureData->info().getVersion());
69
70 // Record this, so we can concat w/ it if we encounter a setMatrix()
71 SkM44 initialMatrix = canvas->getLocalToDevice();
72
73 SkAutoCanvasRestore acr(canvas, false);
74
75 while (!reader.eof() && reader.isValid()) {
76 if (callback && callback->abort()) {
77 return;
78 }
79
80 fCurOffset = reader.offset();
81
82 uint32_t bits = reader.readInt();
83 uint32_t op = bits >> 24,
84 size = bits & 0xffffff;
85 if (size == 0xffffff) {
86 size = reader.readInt();
87 }
88
89 if (!reader.validate(size > 0 && op > UNUSED && op <= LAST_DRAWTYPE_ENUM)) {
90 return;
91 }
92
93 this->handleOp(&reader, (DrawType)op, size, canvas, initialMatrix);
94 }
95
96 // need to propagate invalid state to the parent reader
97 if (buffer) {
98 buffer->validate(reader.isValid());
99 }
100}
101
102static void validate_offsetToRestore(SkReadBuffer* reader, size_t offsetToRestore) {
103 if (offsetToRestore) {
104 reader->validate(SkIsAlign4(offsetToRestore) && offsetToRestore >= reader->offset());
105 }
106}
107
108static bool do_clip_op(SkReadBuffer* reader, SkCanvas* canvas, SkRegion::Op op,
109 SkClipOp* clipOpToUse) {
110 switch(op) {
113 // Fully supported, identity mapping between SkClipOp and Region::Op
114 *clipOpToUse = static_cast<SkClipOp>(op);
115 return true;
117 // Emulate the replace by resetting first and following it up with an intersect
120 *clipOpToUse = SkClipOp::kIntersect;
121 return true;
122 default:
123 // An expanding clip op, which if encountered on an old SKP, we just silently ignore
125 return false;
126 }
127}
128
129void SkPicturePlayback::handleOp(SkReadBuffer* reader,
130 DrawType op,
131 uint32_t size,
132 SkCanvas* canvas,
133 const SkM44& initialMatrix) {
134#define BREAK_ON_READ_ERROR(r) if (!r->isValid()) break
135
136 switch (op) {
137 case NOOP: {
138 SkASSERT(size >= 4);
139 reader->skip(size - 4);
140 } break;
141 case FLUSH:
142 break;
143 case CLIP_PATH: {
144 const SkPath& path = fPictureData->getPath(reader);
145 uint32_t packed = reader->readInt();
146 SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed);
147 bool doAA = ClipParams_unpackDoAA(packed);
148 size_t offsetToRestore = reader->readInt();
149 validate_offsetToRestore(reader, offsetToRestore);
150 BREAK_ON_READ_ERROR(reader);
151
152 SkClipOp clipOp;
153 if (do_clip_op(reader, canvas, rgnOp, &clipOp)) {
154 canvas->clipPath(path, clipOp, doAA);
155 }
156 if (canvas->isClipEmpty() && offsetToRestore) {
157 reader->skip(offsetToRestore - reader->offset());
158 }
159 } break;
160 case CLIP_REGION: {
162 reader->readRegion(&region);
163 uint32_t packed = reader->readInt();
164 SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed);
165 size_t offsetToRestore = reader->readInt();
166 validate_offsetToRestore(reader, offsetToRestore);
167 BREAK_ON_READ_ERROR(reader);
168
169 SkClipOp clipOp;
170 if (do_clip_op(reader, canvas, rgnOp, &clipOp)) {
171 canvas->clipRegion(region, clipOp);
172 }
173 if (canvas->isClipEmpty() && offsetToRestore) {
174 reader->skip(offsetToRestore - reader->offset());
175 }
176 } break;
177 case CLIP_RECT: {
178 SkRect rect;
179 reader->readRect(&rect);
180 uint32_t packed = reader->readInt();
181 SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed);
182 bool doAA = ClipParams_unpackDoAA(packed);
183 size_t offsetToRestore = reader->readInt();
184 validate_offsetToRestore(reader, offsetToRestore);
185 BREAK_ON_READ_ERROR(reader);
186
187 SkClipOp clipOp;
188 if (do_clip_op(reader, canvas, rgnOp, &clipOp)) {
189 canvas->clipRect(rect, clipOp, doAA);
190 }
191 if (canvas->isClipEmpty() && offsetToRestore) {
192 reader->skip(offsetToRestore - reader->offset());
193 }
194 } break;
195 case CLIP_RRECT: {
197 reader->readRRect(&rrect);
198 uint32_t packed = reader->readInt();
199 SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed);
200 bool doAA = ClipParams_unpackDoAA(packed);
201 size_t offsetToRestore = reader->readInt();
202 validate_offsetToRestore(reader, offsetToRestore);
203 BREAK_ON_READ_ERROR(reader);
204
205 SkClipOp clipOp;
206 if (do_clip_op(reader, canvas, rgnOp, &clipOp)) {
207 canvas->clipRRect(rrect, clipOp, doAA);
208 }
209 if (canvas->isClipEmpty() && offsetToRestore) {
210 reader->skip(offsetToRestore - reader->offset());
211 }
212 } break;
214 const SkPaint& paint = fPictureData->requiredPaint(reader);
215 // clipShader() was never used in conjunction with deprecated, expanding clip ops, so
216 // it requires the op to just be intersect or difference.
218 BREAK_ON_READ_ERROR(reader);
219
220 canvas->clipShader(paint.refShader(), clipOp);
221 } break;
222 case RESET_CLIP:
223 // For Android, an emulated "replace" clip op appears as a manual reset followed by
224 // an intersect operation (equivalent to the above handling of replace ops encountered
225 // in old serialized pictures).
227 break;
228 case PUSH_CULL: break; // Deprecated, safe to ignore both push and pop.
229 case POP_CULL: break;
230 case CONCAT: {
232 reader->readMatrix(&matrix);
233 BREAK_ON_READ_ERROR(reader);
234
235 canvas->concat(matrix);
236 break;
237 }
238 case CONCAT44: {
239 const SkScalar* colMaj = reader->skipT<SkScalar>(16);
240 BREAK_ON_READ_ERROR(reader);
241 canvas->concat(SkM44::ColMajor(colMaj));
242 break;
243 }
244 case DRAW_ANNOTATION: {
245 SkRect rect;
246 reader->readRect(&rect);
248 reader->readString(&key);
250 BREAK_ON_READ_ERROR(reader);
251 SkASSERT(data);
252
253 canvas->drawAnnotation(rect, key.c_str(), data.get());
254 } break;
255 case DRAW_ARC: {
256 const SkPaint& paint = fPictureData->requiredPaint(reader);
257 SkRect rect;
258 reader->readRect(&rect);
259 SkScalar startAngle = reader->readScalar();
260 SkScalar sweepAngle = reader->readScalar();
261 int useCenter = reader->readInt();
262 BREAK_ON_READ_ERROR(reader);
263
264 canvas->drawArc(rect, startAngle, sweepAngle, SkToBool(useCenter), paint);
265 } break;
266 case DRAW_ATLAS: {
267 const SkPaint* paint = fPictureData->optionalPaint(reader);
268 const SkImage* atlas = fPictureData->getImage(reader);
269 const uint32_t flags = reader->readUInt();
270 const int count = reader->readUInt();
271 const SkRSXform* xform = (const SkRSXform*)reader->skip(count, sizeof(SkRSXform));
272 const SkRect* tex = (const SkRect*)reader->skip(count, sizeof(SkRect));
273 const SkColor* colors = nullptr;
276 colors = (const SkColor*)reader->skip(count, sizeof(SkColor));
278 BREAK_ON_READ_ERROR(reader);
279 }
280 const SkRect* cull = nullptr;
282 cull = (const SkRect*)reader->skip(sizeof(SkRect));
283 }
284 BREAK_ON_READ_ERROR(reader);
285
288 sampling = reader->readSampling();
289 BREAK_ON_READ_ERROR(reader);
290 }
291 canvas->drawAtlas(atlas, xform, tex, colors, count, mode, sampling, cull, paint);
292 } break;
293 case DRAW_CLEAR: {
294 auto c = reader->readInt();
295 BREAK_ON_READ_ERROR(reader);
296
297 canvas->clear(c);
298 } break;
299 case DRAW_DATA: {
300 // This opcode is now dead, just need to skip it for backwards compatibility
301 size_t length = reader->readInt();
302 (void)reader->skip(length);
303 // skip handles padding the read out to a multiple of 4
304 } break;
305 case DRAW_DRAWABLE: {
306 auto* d = fPictureData->getDrawable(reader);
307 BREAK_ON_READ_ERROR(reader);
308
309 canvas->drawDrawable(d);
310 } break;
313 reader->readMatrix(&matrix);
314 SkDrawable* drawable = fPictureData->getDrawable(reader);
315 BREAK_ON_READ_ERROR(reader);
316
317 canvas->drawDrawable(drawable, &matrix);
318 } break;
319 case DRAW_DRRECT: {
320 const SkPaint& paint = fPictureData->requiredPaint(reader);
321 SkRRect outer, inner;
322 reader->readRRect(&outer);
323 reader->readRRect(&inner);
324 BREAK_ON_READ_ERROR(reader);
325
326 canvas->drawDRRect(outer, inner, paint);
327 } break;
328 case DRAW_EDGEAA_QUAD: {
329 SkRect rect;
330 reader->readRect(&rect);
331 SkCanvas::QuadAAFlags aaFlags = static_cast<SkCanvas::QuadAAFlags>(reader->read32());
333 reader->readColor4f(&color);
335 BREAK_ON_READ_ERROR(reader);
336 bool hasClip = reader->readInt();
337 const SkPoint* clip = nullptr;
338 if (hasClip) {
339 clip = (const SkPoint*) reader->skip(4, sizeof(SkPoint));
340 }
341 BREAK_ON_READ_ERROR(reader);
342 canvas->experimental_DrawEdgeAAQuad(rect, clip, aaFlags, color, blend);
343 } break;
346 static const size_t kEntryReadSize =
347 4 * sizeof(uint32_t) + 2 * sizeof(SkRect) + sizeof(SkScalar);
348 static const size_t kMatrixSize = 9 * sizeof(SkScalar); // != sizeof(SkMatrix)
349
350 int cnt = reader->readInt();
351 if (!reader->validate(cnt >= 0)) {
352 break;
353 }
354 const SkPaint* paint = fPictureData->optionalPaint(reader);
355
357 if (op == DRAW_EDGEAA_IMAGE_SET2) {
358 sampling = reader->readSampling();
359 } else {
361 }
362
363 SkCanvas::SrcRectConstraint constraint =
366
367 if (!reader->validate(SkSafeMath::Mul(cnt, kEntryReadSize) <= reader->available())) {
368 break;
369 }
370
371 // Track minimum necessary clip points and matrices that must be provided to satisfy
372 // the entries.
373 int expectedClipPointCount = 0;
374 int maxMatrixIndex = -1;
376 for (int i = 0; i < cnt && reader->isValid(); ++i) {
377 set[i].fImage = sk_ref_sp(fPictureData->getImage(reader));
378 reader->readRect(&set[i].fSrcRect);
379 reader->readRect(&set[i].fDstRect);
380 set[i].fMatrixIndex = reader->readInt();
381 set[i].fAlpha = reader->readScalar();
382 set[i].fAAFlags = reader->readUInt();
383 set[i].fHasClip = reader->readInt();
384
385 expectedClipPointCount += set[i].fHasClip ? 4 : 0; // 4 points per clip quad
386 if (set[i].fMatrixIndex > maxMatrixIndex) {
387 maxMatrixIndex = set[i].fMatrixIndex;
388 }
389 }
390
391 int dstClipPointCount = reader->readInt();
392 const SkPoint* dstClips = nullptr;
393 if (!reader->validate(dstClipPointCount >= 0) ||
394 !reader->validate(expectedClipPointCount == dstClipPointCount)) {
395 // A bad dstClipCount (either negative, or not enough to satisfy entries).
396 // Use exact comparison; the serialized SKP should only have included the exact
397 // amount used by the recorded draw, even if the original array was larger.
398 break;
399 } else if (dstClipPointCount > 0) {
400 dstClips = (const SkPoint*) reader->skip(dstClipPointCount, sizeof(SkPoint));
401 if (dstClips == nullptr) {
402 // Not enough bytes remaining so the reader has been invalidated
403 break;
404 }
405 }
406 int matrixCount = reader->readInt();
407 if (!reader->validate(matrixCount >= 0) ||
408 !reader->validate(maxMatrixIndex == (matrixCount - 1)) ||
409 !reader->validate(
410 SkSafeMath::Mul(matrixCount, kMatrixSize) <= reader->available())) {
411 // Entries access out-of-bound matrix indices, given provided matrices or
412 // there aren't enough bytes to provide that many matrices
413 break;
414 }
415 TArray<SkMatrix> matrices(matrixCount);
416 for (int i = 0; i < matrixCount && reader->isValid(); ++i) {
417 reader->readMatrix(&matrices.push_back());
418 }
419 BREAK_ON_READ_ERROR(reader);
420
421 canvas->experimental_DrawEdgeAAImageSet(set.get(), cnt, dstClips, matrices.begin(),
422 sampling, paint, constraint);
423 } break;
424 case DRAW_IMAGE: {
425 const SkPaint* paint = fPictureData->optionalPaint(reader);
426 const SkImage* image = fPictureData->getImage(reader);
427 SkPoint loc;
428 reader->readPoint(&loc);
429 BREAK_ON_READ_ERROR(reader);
430
431 canvas->drawImage(image, loc.fX, loc.fY,
433 paint);
434 } break;
435 case DRAW_IMAGE2: {
436 const SkPaint* paint = fPictureData->optionalPaint(reader);
437 const SkImage* image = fPictureData->getImage(reader);
438 SkPoint loc;
439 reader->readPoint(&loc);
441 BREAK_ON_READ_ERROR(reader);
442
443 canvas->drawImage(image, loc.fX, loc.fY, sampling, paint);
444 } break;
445 case DRAW_IMAGE_LATTICE: {
446 const SkPaint* paint = fPictureData->optionalPaint(reader);
447 const SkImage* image = fPictureData->getImage(reader);
448 SkCanvas::Lattice lattice;
449 (void)SkCanvasPriv::ReadLattice(*reader, &lattice);
450 const SkRect* dst = reader->skipT<SkRect>();
451 BREAK_ON_READ_ERROR(reader);
452
453 canvas->drawImageLattice(image, lattice, *dst, SkFilterMode::kNearest, paint);
454 } break;
455 case DRAW_IMAGE_LATTICE2: {
456 const SkPaint* paint = fPictureData->optionalPaint(reader);
457 const SkImage* image = fPictureData->getImage(reader);
458 SkCanvas::Lattice lattice;
459 (void)SkCanvasPriv::ReadLattice(*reader, &lattice);
460 const SkRect* dst = reader->skipT<SkRect>();
462 BREAK_ON_READ_ERROR(reader);
463
464 canvas->drawImageLattice(image, lattice, *dst, filter, paint);
465 } break;
466 case DRAW_IMAGE_NINE: {
467 const SkPaint* paint = fPictureData->optionalPaint(reader);
468 const SkImage* image = fPictureData->getImage(reader);
470 reader->readIRect(&center);
471 SkRect dst;
472 reader->readRect(&dst);
473 BREAK_ON_READ_ERROR(reader);
474
476 } break;
477 case DRAW_IMAGE_RECT: {
478 const SkPaint* paint = fPictureData->optionalPaint(reader);
479 const SkImage* image = fPictureData->getImage(reader);
480 SkRect storage;
481 const SkRect* src = get_rect_ptr(reader, &storage); // may be null
482 SkRect dst;
483 reader->readRect(&dst); // required
484 // DRAW_IMAGE_RECT_STRICT assumes this constraint, and doesn't store it
486 if (DRAW_IMAGE_RECT == op) {
487 // newer op-code stores the constraint explicitly
490 }
491 BREAK_ON_READ_ERROR(reader);
492
494 if (src) {
495 canvas->drawImageRect(image, *src, dst, sampling, paint, constraint);
496 } else {
497 canvas->drawImageRect(image, dst, sampling, paint);
498 }
499 } break;
500 case DRAW_IMAGE_RECT2: {
501 const SkPaint* paint = fPictureData->optionalPaint(reader);
502 const SkImage* image = fPictureData->getImage(reader);
503 SkRect src = reader->readRect();
504 SkRect dst = reader->readRect();
506 auto constraint = reader->read32LE(SkCanvas::kFast_SrcRectConstraint);
507 BREAK_ON_READ_ERROR(reader);
508
509 canvas->drawImageRect(image, src, dst, sampling, paint, constraint);
510 } break;
511 case DRAW_OVAL: {
512 const SkPaint& paint = fPictureData->requiredPaint(reader);
513 SkRect rect;
514 reader->readRect(&rect);
515 BREAK_ON_READ_ERROR(reader);
516
517 canvas->drawOval(rect, paint);
518 } break;
519 case DRAW_PAINT: {
520 const SkPaint& paint = fPictureData->requiredPaint(reader);
521 BREAK_ON_READ_ERROR(reader);
522
523 canvas->drawPaint(paint);
524 } break;
525 case DRAW_BEHIND_PAINT: {
526 const SkPaint& paint = fPictureData->requiredPaint(reader);
527 BREAK_ON_READ_ERROR(reader);
528
530 } break;
531 case DRAW_PATCH: {
532 const SkPaint& paint = fPictureData->requiredPaint(reader);
533
534 const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts,
535 sizeof(SkPoint));
536 uint32_t flag = reader->readInt();
537 const SkColor* colors = nullptr;
539 colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners, sizeof(SkColor));
540 }
541 const SkPoint* texCoords = nullptr;
543 texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners,
544 sizeof(SkPoint));
545 }
548 unsigned mode = reader->readInt();
549 if (mode <= (unsigned)SkBlendMode::kLastMode) {
550 bmode = (SkBlendMode)mode;
551 }
552 }
553 BREAK_ON_READ_ERROR(reader);
554
555 canvas->drawPatch(cubics, colors, texCoords, bmode, paint);
556 } break;
557 case DRAW_PATH: {
558 const SkPaint& paint = fPictureData->requiredPaint(reader);
559 const auto& path = fPictureData->getPath(reader);
560 BREAK_ON_READ_ERROR(reader);
561
562 canvas->drawPath(path, paint);
563 } break;
564 case DRAW_PICTURE: {
565 const auto* pic = fPictureData->getPicture(reader);
566 BREAK_ON_READ_ERROR(reader);
567
568 canvas->drawPicture(pic);
569 } break;
571 const SkPaint* paint = fPictureData->optionalPaint(reader);
573 reader->readMatrix(&matrix);
574 const SkPicture* pic = fPictureData->getPicture(reader);
575 BREAK_ON_READ_ERROR(reader);
576
577 canvas->drawPicture(pic, &matrix, paint);
578 } break;
579 case DRAW_POINTS: {
580 const SkPaint& paint = fPictureData->requiredPaint(reader);
583 size_t count = reader->readInt();
584 const SkPoint* pts = (const SkPoint*)reader->skip(count, sizeof(SkPoint));
585 BREAK_ON_READ_ERROR(reader);
586
587 canvas->drawPoints(mode, count, pts, paint);
588 } break;
589 case DRAW_RECT: {
590 const SkPaint& paint = fPictureData->requiredPaint(reader);
591 SkRect rect;
592 reader->readRect(&rect);
593 BREAK_ON_READ_ERROR(reader);
594
595 canvas->drawRect(rect, paint);
596 } break;
597 case DRAW_REGION: {
598 const SkPaint& paint = fPictureData->requiredPaint(reader);
600 reader->readRegion(&region);
601 BREAK_ON_READ_ERROR(reader);
602
603 canvas->drawRegion(region, paint);
604 } break;
605 case DRAW_RRECT: {
606 const SkPaint& paint = fPictureData->requiredPaint(reader);
608 reader->readRRect(&rrect);
609 BREAK_ON_READ_ERROR(reader);
610
611 canvas->drawRRect(rrect, paint);
612 } break;
613 case DRAW_SHADOW_REC: {
614 const auto& path = fPictureData->getPath(reader);
615 SkDrawShadowRec rec;
616 reader->readPoint3(&rec.fZPlaneParams);
617 reader->readPoint3(&rec.fLightPos);
618 rec.fLightRadius = reader->readScalar();
619 rec.fAmbientColor = reader->read32();
620 rec.fSpotColor = reader->read32();
621 rec.fFlags = reader->read32();
622 BREAK_ON_READ_ERROR(reader);
623
624 canvas->private_draw_shadow_rec(path, rec);
625 } break;
626 case DRAW_TEXT_BLOB: {
627 const SkPaint& paint = fPictureData->requiredPaint(reader);
628 const SkTextBlob* blob = fPictureData->getTextBlob(reader);
629 SkScalar x = reader->readScalar();
630 SkScalar y = reader->readScalar();
631 BREAK_ON_READ_ERROR(reader);
632
633 canvas->drawTextBlob(blob, x, y, paint);
634 } break;
635 case DRAW_SLUG: {
636 const SkPaint& paint = fPictureData->requiredPaint(reader);
637 const sktext::gpu::Slug* slug = fPictureData->getSlug(reader);
638 BREAK_ON_READ_ERROR(reader);
639
640 canvas->drawSlug(slug, paint);
641 } break;
643 const SkPaint& paint = fPictureData->requiredPaint(reader);
644 const SkVertices* vertices = fPictureData->getVertices(reader);
645 const int boneCount = reader->readInt();
646 (void)reader->skip(boneCount, sizeof(SkVertices_DeprecatedBone));
648 BREAK_ON_READ_ERROR(reader);
649
650 if (vertices) { // TODO: read error if vertices == null?
651 canvas->drawVertices(vertices, bmode, paint);
652 }
653 } break;
654 case RESTORE:
655 canvas->restore();
656 break;
657 case ROTATE: {
658 auto deg = reader->readScalar();
659 canvas->rotate(deg);
660 } break;
661 case SAVE:
662 canvas->save();
663 break;
664 case SAVE_BEHIND: {
665 uint32_t flags = reader->readInt();
666 const SkRect* subset = nullptr;
667 SkRect storage;
669 reader->readRect(&storage);
670 subset = &storage;
671 }
672 SkCanvasPriv::SaveBehind(canvas, subset);
673 } break;
675 SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, 0);
676 const uint32_t flatFlags = reader->readInt();
679 if (flatFlags & SAVELAYERREC_HAS_BOUNDS) {
680 reader->readRect(&bounds);
681 rec.fBounds = &bounds;
682 }
683 if (flatFlags & SAVELAYERREC_HAS_PAINT) {
684 rec.fPaint = &fPictureData->requiredPaint(reader);
685 }
686 if (flatFlags & SAVELAYERREC_HAS_BACKDROP) {
687 const SkPaint& paint = fPictureData->requiredPaint(reader);
688 rec.fBackdrop = paint.getImageFilter();
689 }
690 if (flatFlags & SAVELAYERREC_HAS_FLAGS) {
691 rec.fSaveLayerFlags = reader->readInt();
692 }
693 if (flatFlags & SAVELAYERREC_HAS_CLIPMASK_OBSOLETE) {
694 (void)fPictureData->getImage(reader);
695 }
696 if (flatFlags & SAVELAYERREC_HAS_CLIPMATRIX_OBSOLETE) {
697 SkMatrix clipMatrix_ignored;
698 reader->readMatrix(&clipMatrix_ignored);
699 }
701 (flatFlags & SAVELAYERREC_HAS_BACKDROP_SCALE)) {
703 }
705 (flatFlags & SAVELAYERREC_HAS_MULTIPLE_FILTERS)) {
706 int filterCount = reader->readUInt();
707 reader->validate(filterCount > 0 && filterCount <= SkCanvas::kMaxFiltersPerLayer);
708 BREAK_ON_READ_ERROR(reader);
709 filters.reset(filterCount);
710 for (int i = 0; i < filterCount; ++i) {
711 const SkPaint& paint = fPictureData->requiredPaint(reader);
712 filters[i] = paint.refImageFilter();
713 }
714 rec.fFilters = filters;
715 }
716 BREAK_ON_READ_ERROR(reader);
717
718 canvas->saveLayer(rec);
719 } break;
720 case SCALE: {
721 SkScalar sx = reader->readScalar();
722 SkScalar sy = reader->readScalar();
723 canvas->scale(sx, sy);
724 } break;
725 case SET_M44: {
726 SkM44 m;
727 reader->read(&m);
728 canvas->setMatrix(initialMatrix * m);
729 } break;
730 case SET_MATRIX: {
732 reader->readMatrix(&matrix);
733 canvas->setMatrix(initialMatrix * SkM44(matrix));
734 } break;
735 case SKEW: {
736 SkScalar sx = reader->readScalar();
737 SkScalar sy = reader->readScalar();
738 canvas->skew(sx, sy);
739 } break;
740 case TRANSLATE: {
741 SkScalar dx = reader->readScalar();
742 SkScalar dy = reader->readScalar();
743 canvas->translate(dx, dy);
744 } break;
745 default:
746 reader->validate(false); // unknown op
747 break;
748 }
749
750#undef BREAK_ON_READ_ERROR
751}
int count
SkColor4f color
static constexpr bool SkIsAlign4(T x)
Definition SkAlign.h:20
#define SkASSERT(cond)
Definition SkAssert.h:116
SkBlendMode
Definition SkBlendMode.h:38
@ kModulate
r = s*d
@ kLastMode
last valid value
SkClipOp
Definition SkClipOp.h:13
uint32_t SkColor
Definition SkColor.h:37
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
@ SAVEBEHIND_HAS_SUBSET
static SkRegion::Op ClipParams_unpackRegionOp(SkReadBuffer *buffer, uint32_t packed)
@ DRAW_EDGEAA_QUAD
@ DRAW_PATH
@ RESTORE
@ SET_M44
@ CLIP_PATH
@ DRAW_PAINT
@ DRAW_SLUG
@ DRAW_PICTURE_MATRIX_PAINT
@ DRAW_EDGEAA_IMAGE_SET
@ DRAW_REGION
@ SET_MATRIX
@ FLUSH
@ DRAW_DATA
@ ROTATE
@ DRAW_DRAWABLE
@ DRAW_IMAGE_RECT2
@ DRAW_IMAGE2
@ DRAW_RRECT
@ DRAW_DRRECT
@ LAST_DRAWTYPE_ENUM
@ DRAW_IMAGE_RECT
@ DRAW_PATCH
@ DRAW_BEHIND_PAINT
@ DRAW_EDGEAA_IMAGE_SET2
@ DRAW_TEXT_BLOB
@ DRAW_PICTURE
@ PUSH_CULL
@ SKEW
@ CONCAT44
@ NOOP
@ SAVE
@ DRAW_IMAGE
@ RESET_CLIP
@ DRAW_DRAWABLE_MATRIX
@ DRAW_ARC
@ DRAW_RECT
@ DRAW_VERTICES_OBJECT
@ DRAW_ANNOTATION
@ CONCAT
@ DRAW_IMAGE_NINE
@ UNUSED
@ SAVE_BEHIND
@ DRAW_IMAGE_LATTICE
@ DRAW_POINTS
@ DRAW_SHADOW_REC
@ SAVE_LAYER_SAVELAYERREC
@ DRAW_ATLAS
@ CLIP_RRECT
@ TRANSLATE
@ DRAW_OVAL
@ CLIP_REGION
@ DRAW_CLEAR
@ CLIP_SHADER_IN_PAINT
@ CLIP_RECT
@ POP_CULL
@ DRAW_IMAGE_LATTICE2
static bool ClipParams_unpackDoAA(uint32_t packed)
@ SAVELAYERREC_HAS_FLAGS
@ SAVELAYERREC_HAS_BACKDROP_SCALE
@ SAVELAYERREC_HAS_MULTIPLE_FILTERS
@ SAVELAYERREC_HAS_PAINT
@ SAVELAYERREC_HAS_CLIPMASK_OBSOLETE
@ SAVELAYERREC_HAS_CLIPMATRIX_OBSOLETE
@ SAVELAYERREC_HAS_BACKDROP
@ SAVELAYERREC_HAS_BOUNDS
@ DRAW_VERTICES_HAS_TEXS
@ DRAW_VERTICES_HAS_XFER
@ DRAW_VERTICES_HAS_COLORS
@ DRAW_ATLAS_HAS_SAMPLING
@ DRAW_ATLAS_HAS_COLORS
@ DRAW_ATLAS_HAS_CULL
static void validate_offsetToRestore(SkReadBuffer *reader, size_t offsetToRestore)
#define BREAK_ON_READ_ERROR(r)
static const SkRect * get_rect_ptr(SkReadBuffer *reader, SkRect *storage)
static bool do_clip_op(SkReadBuffer *reader, SkCanvas *canvas, SkRegion::Op op, SkClipOp *clipOpToUse)
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
SkFilterMode
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
static SkScalar center(float pos0, float pos1)
#define SCALE
static void ResetClip(SkCanvas *canvas)
static void DrawBehind(SkCanvas *canvas, const SkPaint &paint)
static void SetBackdropScaleFactor(SkCanvas::SaveLayerRec *rec, SkScalar scale)
static bool ReadLattice(SkReadBuffer &, SkCanvas::Lattice *)
static int SaveBehind(SkCanvas *canvas, const SkRect *subset)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition SkCanvas.cpp:500
void drawRect(const SkRect &rect, const SkPaint &paint)
void drawOval(const SkRect &oval, const SkPaint &paint)
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint &paint)
virtual bool isClipEmpty() const
void drawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], SkBlendMode mode, const SkPaint &paint)
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
void drawImageNine(const SkImage *image, const SkIRect &center, const SkRect &dst, SkFilterMode filter, const SkPaint *paint=nullptr)
void drawPaint(const SkPaint &paint)
void private_draw_shadow_rec(const SkPath &, const SkDrawShadowRec &)
void drawDrawable(SkDrawable *drawable, const SkMatrix *matrix=nullptr)
void drawAnnotation(const SkRect &rect, const char key[], SkData *value)
static constexpr int kMaxFiltersPerLayer
Definition SkCanvas.h:679
SrcRectConstraint
Definition SkCanvas.h:1541
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition SkCanvas.h:1542
@ kFast_SrcRectConstraint
sample outside bounds; faster
Definition SkCanvas.h:1543
SkM44 getLocalToDevice() const
void clipRegion(const SkRegion &deviceRgn, SkClipOp op=SkClipOp::kIntersect)
void experimental_DrawEdgeAAQuad(const SkRect &rect, const SkPoint clip[4], QuadAAFlags aaFlags, const SkColor4f &color, SkBlendMode mode)
void clear(SkColor color)
Definition SkCanvas.h:1199
void experimental_DrawEdgeAAImageSet(const ImageSetEntry imageSet[], int cnt, const SkPoint dstClips[], const SkMatrix preViewMatrices[], const SkSamplingOptions &, const SkPaint *paint=nullptr, SrcRectConstraint constraint=kStrict_SrcRectConstraint)
void rotate(SkScalar degrees)
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
void drawArc(const SkRect &oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, const SkPaint &paint)
void drawImageLattice(const SkImage *image, const Lattice &lattice, const SkRect &dst, SkFilterMode filter, const SkPaint *paint=nullptr)
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
void drawRegion(const SkRegion &region, const SkPaint &paint)
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
void drawAtlas(const SkImage *atlas, const SkRSXform xform[], const SkRect tex[], const SkColor colors[], int count, SkBlendMode mode, const SkSamplingOptions &sampling, const SkRect *cullRect, const SkPaint *paint)
void setMatrix(const SkM44 &matrix)
void drawDRRect(const SkRRect &outer, const SkRRect &inner, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
void concat(const SkMatrix &matrix)
void drawPicture(const SkPicture *picture)
Definition SkCanvas.h:1961
void clipShader(sk_sp< SkShader >, SkClipOp=SkClipOp::kIntersect)
void drawVertices(const SkVertices *vertices, SkBlendMode mode, const SkPaint &paint)
@ kPolygon_PointMode
draw the array of points as a open polygon
Definition SkCanvas.h:1243
@ kPoints_PointMode
draw each point separately
Definition SkCanvas.h:1241
void skew(SkScalar sx, SkScalar sy)
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
void clipRRect(const SkRRect &rrect, SkClipOp op, bool doAntiAlias)
const uint8_t * bytes() const
Definition SkData.h:43
size_t size() const
Definition SkData.h:30
Definition SkM44.h:150
static SkM44 ColMajor(const SkScalar c[16])
Definition SkM44.h:218
const sktext::gpu::Slug * getSlug(SkReadBuffer *reader) const
const SkPaint * optionalPaint(SkReadBuffer *reader) const
const SkPath & getPath(SkReadBuffer *reader) const
const SkVertices * getVertices(SkReadBuffer *reader) const
const sk_sp< SkData > & opData() const
const SkTextBlob * getTextBlob(SkReadBuffer *reader) const
const SkPaint & requiredPaint(SkReadBuffer *reader) const
const SkImage * getImage(SkReadBuffer *reader) const
const SkPicture * getPicture(SkReadBuffer *reader) const
SkDrawable * getDrawable(SkReadBuffer *reader) const
const SkPictInfo & info() const
void draw(SkCanvas *canvas, SkPicture::AbortCallback *, SkReadBuffer *buffer)
void readRect(SkRect *rect)
void readColor4f(SkColor4f *color)
void readMatrix(SkMatrix *matrix)
void readPoint(SkPoint *point)
bool validate(bool isValid)
uint32_t readUInt()
bool isValid() const
const void * skip(size_t size)
sk_sp< SkData > readByteArrayAsData()
void readIRect(SkIRect *rect)
int32_t read32()
SkSamplingOptions readSampling()
T checkRange(T min, T max)
const T * skipT()
void read(SkM44 *)
size_t available() const
int32_t readInt()
void readString(SkString *string)
void setVersion(int version)
size_t offset() const
void readPoint3(SkPoint3 *point)
void readRRect(SkRRect *rrect)
SkScalar readScalar()
void readRegion(SkRegion *region)
T read32LE(T max)
bool isVersionLT(SkPicturePriv::Version targetVersion) const
@ kReplace_Op
replace target with operand
Definition SkRegion.h:372
@ kIntersect_Op
target intersected with operand
Definition SkRegion.h:368
@ kDifference_Op
target minus operand
Definition SkRegion.h:367
static size_t Mul(size_t x, size_t y)
const Paint & paint
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
sk_sp< SkImage > image
Definition examples.cpp:29
float SkScalar
Definition extension.cpp:12
FlutterSemanticsFlag flag
FlutterSemanticsFlag flags
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
static const uint8_t buffer[]
static SkColor blend(SkColor dst, SkColor src, void(*mode)(float, float, float, float *, float *, float *))
Definition hsl.cpp:142
size_t length
double y
double x
sk_sp< const SkImage > atlas
Definition SkRecords.h:331
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258
Optional< SkRect > bounds
Definition SkRecords.h:189
PODArray< SkPoint > dstClips
Definition SkRecords.h:364
ClipOpAndAA opAA SkRegion region
Definition SkRecords.h:238
SkRRect rrect
Definition SkRecords.h:232
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350
SkScalar startAngle
Definition SkRecords.h:250
SkScalar sweepAngle
Definition SkRecords.h:251
PODArray< SkColor > colors
Definition SkRecords.h:276
SkSamplingOptions sampling
Definition SkRecords.h:337
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition SkRecords.h:208
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition switches.h:228
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition switches.h:76
dst
Definition cp.py:12
uint32_t getVersion() const
float fX
x-axis value
float fY
y-axis value