blob: dc467c41baed136eff785145a9308018ae1d0c15 [file] [log] [blame]
John Reck8f45d4a2018-08-15 10:17:12 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "RecordingCanvas.h"
18
Stan Ilievff2c36b2019-08-19 10:48:31 -040019#include "pipeline/skia/FunctorDrawable.h"
John Reck08ee8152018-09-20 16:27:46 -070020#include "VectorDrawable.h"
21
Derek Sollenberger24fc9012018-12-07 14:12:12 -050022#include "SkAndroidFrameworkUtils.h"
John Reck8f45d4a2018-08-15 10:17:12 -070023#include "SkCanvas.h"
Derek Sollenbergerac33a482019-04-22 16:28:09 -040024#include "SkCanvasPriv.h"
John Reck8f45d4a2018-08-15 10:17:12 -070025#include "SkData.h"
26#include "SkDrawShadowInfo.h"
27#include "SkImage.h"
28#include "SkImageFilter.h"
John Reck3b4510cd2018-09-27 17:39:45 -070029#include "SkLatticeIter.h"
John Reck8f45d4a2018-08-15 10:17:12 -070030#include "SkMath.h"
31#include "SkPicture.h"
32#include "SkRSXform.h"
33#include "SkRegion.h"
34#include "SkTextBlob.h"
35#include "SkVertices.h"
36
37#include <experimental/type_traits>
38
39namespace android {
40namespace uirenderer {
41
42#ifndef SKLITEDL_PAGE
43#define SKLITEDL_PAGE 4096
44#endif
45
46// A stand-in for an optional SkRect which was not set, e.g. bounds for a saveLayer().
47static const SkRect kUnset = {SK_ScalarInfinity, 0, 0, 0};
48static const SkRect* maybe_unset(const SkRect& r) {
49 return r.left() == SK_ScalarInfinity ? nullptr : &r;
50}
51
52// copy_v(dst, src,n, src,n, ...) copies an arbitrary number of typed srcs into dst.
53static void copy_v(void* dst) {}
54
55template <typename S, typename... Rest>
56static void copy_v(void* dst, const S* src, int n, Rest&&... rest) {
57 SkASSERTF(((uintptr_t)dst & (alignof(S) - 1)) == 0,
58 "Expected %p to be aligned for at least %zu bytes.", dst, alignof(S));
59 sk_careful_memcpy(dst, src, n * sizeof(S));
60 copy_v(SkTAddOffset<void>(dst, n * sizeof(S)), std::forward<Rest>(rest)...);
61}
62
63// Helper for getting back at arrays which have been copy_v'd together after an Op.
64template <typename D, typename T>
65static const D* pod(const T* op, size_t offset = 0) {
66 return SkTAddOffset<const D>(op + 1, offset);
67}
68
69namespace {
70
71#define X(T) T,
72enum class Type : uint8_t {
73#include "DisplayListOps.in"
74};
75#undef X
76
77struct Op {
78 uint32_t type : 8;
79 uint32_t skip : 24;
80};
81static_assert(sizeof(Op) == 4, "");
82
83struct Flush final : Op {
84 static const auto kType = Type::Flush;
85 void draw(SkCanvas* c, const SkMatrix&) const { c->flush(); }
86};
87
88struct Save final : Op {
89 static const auto kType = Type::Save;
90 void draw(SkCanvas* c, const SkMatrix&) const { c->save(); }
91};
92struct Restore final : Op {
93 static const auto kType = Type::Restore;
94 void draw(SkCanvas* c, const SkMatrix&) const { c->restore(); }
95};
96struct SaveLayer final : Op {
97 static const auto kType = Type::SaveLayer;
98 SaveLayer(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
99 const SkImage* clipMask, const SkMatrix* clipMatrix, SkCanvas::SaveLayerFlags flags) {
100 if (bounds) {
101 this->bounds = *bounds;
102 }
103 if (paint) {
104 this->paint = *paint;
105 }
106 this->backdrop = sk_ref_sp(backdrop);
107 this->clipMask = sk_ref_sp(clipMask);
108 this->clipMatrix = clipMatrix ? *clipMatrix : SkMatrix::I();
109 this->flags = flags;
110 }
111 SkRect bounds = kUnset;
112 SkPaint paint;
113 sk_sp<const SkImageFilter> backdrop;
114 sk_sp<const SkImage> clipMask;
115 SkMatrix clipMatrix;
116 SkCanvas::SaveLayerFlags flags;
117 void draw(SkCanvas* c, const SkMatrix&) const {
118 c->saveLayer({maybe_unset(bounds), &paint, backdrop.get(), clipMask.get(),
119 clipMatrix.isIdentity() ? nullptr : &clipMatrix, flags});
120 }
121};
Derek Sollenberger24fc9012018-12-07 14:12:12 -0500122struct SaveBehind final : Op {
123 static const auto kType = Type::SaveBehind;
124 SaveBehind(const SkRect* subset) {
125 if (subset) { this->subset = *subset; }
126 }
127 SkRect subset = kUnset;
128 void draw(SkCanvas* c, const SkMatrix&) const {
129 SkAndroidFrameworkUtils::SaveBehind(c, &subset);
130 }
131};
John Reck8f45d4a2018-08-15 10:17:12 -0700132
Mike Reeda4973d82020-01-22 10:10:37 -0500133struct Concat44 final : Op {
134 static const auto kType = Type::Concat44;
135 Concat44(const SkScalar m[16]) { memcpy(colMajor, m, sizeof(colMajor)); }
136 SkScalar colMajor[16];
137 void draw(SkCanvas* c, const SkMatrix&) const { c->experimental_concat44(colMajor); }
138};
John Reck8f45d4a2018-08-15 10:17:12 -0700139struct Concat final : Op {
140 static const auto kType = Type::Concat;
141 Concat(const SkMatrix& matrix) : matrix(matrix) {}
142 SkMatrix matrix;
143 void draw(SkCanvas* c, const SkMatrix&) const { c->concat(matrix); }
144};
145struct SetMatrix final : Op {
146 static const auto kType = Type::SetMatrix;
147 SetMatrix(const SkMatrix& matrix) : matrix(matrix) {}
148 SkMatrix matrix;
149 void draw(SkCanvas* c, const SkMatrix& original) const {
150 c->setMatrix(SkMatrix::Concat(original, matrix));
151 }
152};
Mike Reeda4973d82020-01-22 10:10:37 -0500153struct Scale final : Op {
154 static const auto kType = Type::Scale;
155 Scale(SkScalar sx, SkScalar sy) : sx(sx), sy(sy) {}
156 SkScalar sx, sy;
157 void draw(SkCanvas* c, const SkMatrix&) const { c->scale(sx, sy); }
158};
John Reck8f45d4a2018-08-15 10:17:12 -0700159struct Translate final : Op {
160 static const auto kType = Type::Translate;
161 Translate(SkScalar dx, SkScalar dy) : dx(dx), dy(dy) {}
162 SkScalar dx, dy;
163 void draw(SkCanvas* c, const SkMatrix&) const { c->translate(dx, dy); }
164};
165
166struct ClipPath final : Op {
167 static const auto kType = Type::ClipPath;
168 ClipPath(const SkPath& path, SkClipOp op, bool aa) : path(path), op(op), aa(aa) {}
169 SkPath path;
170 SkClipOp op;
171 bool aa;
172 void draw(SkCanvas* c, const SkMatrix&) const { c->clipPath(path, op, aa); }
173};
174struct ClipRect final : Op {
175 static const auto kType = Type::ClipRect;
176 ClipRect(const SkRect& rect, SkClipOp op, bool aa) : rect(rect), op(op), aa(aa) {}
177 SkRect rect;
178 SkClipOp op;
179 bool aa;
180 void draw(SkCanvas* c, const SkMatrix&) const { c->clipRect(rect, op, aa); }
181};
182struct ClipRRect final : Op {
183 static const auto kType = Type::ClipRRect;
184 ClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) : rrect(rrect), op(op), aa(aa) {}
185 SkRRect rrect;
186 SkClipOp op;
187 bool aa;
188 void draw(SkCanvas* c, const SkMatrix&) const { c->clipRRect(rrect, op, aa); }
189};
190struct ClipRegion final : Op {
191 static const auto kType = Type::ClipRegion;
192 ClipRegion(const SkRegion& region, SkClipOp op) : region(region), op(op) {}
193 SkRegion region;
194 SkClipOp op;
195 void draw(SkCanvas* c, const SkMatrix&) const { c->clipRegion(region, op); }
196};
197
198struct DrawPaint final : Op {
199 static const auto kType = Type::DrawPaint;
200 DrawPaint(const SkPaint& paint) : paint(paint) {}
201 SkPaint paint;
202 void draw(SkCanvas* c, const SkMatrix&) const { c->drawPaint(paint); }
203};
Derek Sollenbergerac33a482019-04-22 16:28:09 -0400204struct DrawBehind final : Op {
205 static const auto kType = Type::DrawBehind;
206 DrawBehind(const SkPaint& paint) : paint(paint) {}
207 SkPaint paint;
208 void draw(SkCanvas* c, const SkMatrix&) const { SkCanvasPriv::DrawBehind(c, paint); }
209};
John Reck8f45d4a2018-08-15 10:17:12 -0700210struct DrawPath final : Op {
211 static const auto kType = Type::DrawPath;
212 DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(paint) {}
213 SkPath path;
214 SkPaint paint;
215 void draw(SkCanvas* c, const SkMatrix&) const { c->drawPath(path, paint); }
216};
217struct DrawRect final : Op {
218 static const auto kType = Type::DrawRect;
219 DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(paint) {}
220 SkRect rect;
221 SkPaint paint;
222 void draw(SkCanvas* c, const SkMatrix&) const { c->drawRect(rect, paint); }
223};
224struct DrawRegion final : Op {
225 static const auto kType = Type::DrawRegion;
226 DrawRegion(const SkRegion& region, const SkPaint& paint) : region(region), paint(paint) {}
227 SkRegion region;
228 SkPaint paint;
229 void draw(SkCanvas* c, const SkMatrix&) const { c->drawRegion(region, paint); }
230};
231struct DrawOval final : Op {
232 static const auto kType = Type::DrawOval;
233 DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(paint) {}
234 SkRect oval;
235 SkPaint paint;
236 void draw(SkCanvas* c, const SkMatrix&) const { c->drawOval(oval, paint); }
237};
238struct DrawArc final : Op {
239 static const auto kType = Type::DrawArc;
240 DrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
241 const SkPaint& paint)
242 : oval(oval)
243 , startAngle(startAngle)
244 , sweepAngle(sweepAngle)
245 , useCenter(useCenter)
246 , paint(paint) {}
247 SkRect oval;
248 SkScalar startAngle;
249 SkScalar sweepAngle;
250 bool useCenter;
251 SkPaint paint;
252 void draw(SkCanvas* c, const SkMatrix&) const {
253 c->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
254 }
255};
256struct DrawRRect final : Op {
257 static const auto kType = Type::DrawRRect;
258 DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), paint(paint) {}
259 SkRRect rrect;
260 SkPaint paint;
261 void draw(SkCanvas* c, const SkMatrix&) const { c->drawRRect(rrect, paint); }
262};
263struct DrawDRRect final : Op {
264 static const auto kType = Type::DrawDRRect;
265 DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
266 : outer(outer), inner(inner), paint(paint) {}
267 SkRRect outer, inner;
268 SkPaint paint;
269 void draw(SkCanvas* c, const SkMatrix&) const { c->drawDRRect(outer, inner, paint); }
270};
271
272struct DrawAnnotation final : Op {
273 static const auto kType = Type::DrawAnnotation;
274 DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk_ref_sp(value)) {}
275 SkRect rect;
276 sk_sp<SkData> value;
277 void draw(SkCanvas* c, const SkMatrix&) const {
278 c->drawAnnotation(rect, pod<char>(this), value.get());
279 }
280};
281struct DrawDrawable final : Op {
282 static const auto kType = Type::DrawDrawable;
283 DrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) : drawable(sk_ref_sp(drawable)) {
284 if (matrix) {
285 this->matrix = *matrix;
286 }
287 }
288 sk_sp<SkDrawable> drawable;
289 SkMatrix matrix = SkMatrix::I();
Nathaniel Nifong31fee3a2019-07-11 16:27:14 -0400290 // It is important that we call drawable->draw(c) here instead of c->drawDrawable(drawable).
291 // Drawables are mutable and in cases, like RenderNodeDrawable, are not expected to produce the
292 // same content if retained outside the duration of the frame. Therefore we resolve
293 // them now and do not allow the canvas to take a reference to the drawable and potentially
294 // keep it alive for longer than the frames duration (e.g. SKP serialization).
295 void draw(SkCanvas* c, const SkMatrix&) const { drawable->draw(c, &matrix); }
John Reck8f45d4a2018-08-15 10:17:12 -0700296};
297struct DrawPicture final : Op {
298 static const auto kType = Type::DrawPicture;
299 DrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
300 : picture(sk_ref_sp(picture)) {
301 if (matrix) {
302 this->matrix = *matrix;
303 }
304 if (paint) {
305 this->paint = *paint;
306 has_paint = true;
307 }
308 }
309 sk_sp<const SkPicture> picture;
310 SkMatrix matrix = SkMatrix::I();
311 SkPaint paint;
312 bool has_paint = false; // TODO: why is a default paint not the same?
313 void draw(SkCanvas* c, const SkMatrix&) const {
314 c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr);
315 }
316};
317
318struct DrawImage final : Op {
319 static const auto kType = Type::DrawImage;
John Reck3b4510cd2018-09-27 17:39:45 -0700320 DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint,
321 BitmapPalette palette)
John Reckf3c724f2018-09-20 13:00:04 -0700322 : image(std::move(image)), x(x), y(y), palette(palette) {
John Reck8f45d4a2018-08-15 10:17:12 -0700323 if (paint) {
324 this->paint = *paint;
325 }
326 }
327 sk_sp<const SkImage> image;
328 SkScalar x, y;
329 SkPaint paint;
John Reckf3c724f2018-09-20 13:00:04 -0700330 BitmapPalette palette;
John Reck8f45d4a2018-08-15 10:17:12 -0700331 void draw(SkCanvas* c, const SkMatrix&) const { c->drawImage(image.get(), x, y, &paint); }
332};
333struct DrawImageNine final : Op {
334 static const auto kType = Type::DrawImageNine;
335 DrawImageNine(sk_sp<const SkImage>&& image, const SkIRect& center, const SkRect& dst,
336 const SkPaint* paint)
337 : image(std::move(image)), center(center), dst(dst) {
338 if (paint) {
339 this->paint = *paint;
340 }
341 }
342 sk_sp<const SkImage> image;
343 SkIRect center;
344 SkRect dst;
345 SkPaint paint;
346 void draw(SkCanvas* c, const SkMatrix&) const {
347 c->drawImageNine(image.get(), center, dst, &paint);
348 }
349};
350struct DrawImageRect final : Op {
351 static const auto kType = Type::DrawImageRect;
352 DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst,
John Reck3b4510cd2018-09-27 17:39:45 -0700353 const SkPaint* paint, SkCanvas::SrcRectConstraint constraint,
354 BitmapPalette palette)
John Reckf3c724f2018-09-20 13:00:04 -0700355 : image(std::move(image)), dst(dst), constraint(constraint), palette(palette) {
Greg Kaiser5dda0032018-08-30 06:45:03 -0700356 this->src = src ? *src : SkRect::MakeIWH(this->image->width(), this->image->height());
John Reck8f45d4a2018-08-15 10:17:12 -0700357 if (paint) {
358 this->paint = *paint;
359 }
360 }
361 sk_sp<const SkImage> image;
362 SkRect src, dst;
363 SkPaint paint;
364 SkCanvas::SrcRectConstraint constraint;
John Reckf3c724f2018-09-20 13:00:04 -0700365 BitmapPalette palette;
John Reck8f45d4a2018-08-15 10:17:12 -0700366 void draw(SkCanvas* c, const SkMatrix&) const {
367 c->drawImageRect(image.get(), src, dst, &paint, constraint);
368 }
369};
370struct DrawImageLattice final : Op {
371 static const auto kType = Type::DrawImageLattice;
372 DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs, const SkIRect& src,
John Reck3b4510cd2018-09-27 17:39:45 -0700373 const SkRect& dst, const SkPaint* paint, BitmapPalette palette)
374 : image(std::move(image))
375 , xs(xs)
376 , ys(ys)
377 , fs(fs)
378 , src(src)
379 , dst(dst)
380 , palette(palette) {
John Reck8f45d4a2018-08-15 10:17:12 -0700381 if (paint) {
382 this->paint = *paint;
383 }
384 }
385 sk_sp<const SkImage> image;
386 int xs, ys, fs;
387 SkIRect src;
388 SkRect dst;
389 SkPaint paint;
John Reck3b4510cd2018-09-27 17:39:45 -0700390 BitmapPalette palette;
John Reck8f45d4a2018-08-15 10:17:12 -0700391 void draw(SkCanvas* c, const SkMatrix&) const {
392 auto xdivs = pod<int>(this, 0), ydivs = pod<int>(this, xs * sizeof(int));
393 auto colors = (0 == fs) ? nullptr : pod<SkColor>(this, (xs + ys) * sizeof(int));
394 auto flags =
395 (0 == fs) ? nullptr : pod<SkCanvas::Lattice::RectType>(
396 this, (xs + ys) * sizeof(int) + fs * sizeof(SkColor));
397 c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys, &src, colors}, dst, &paint);
398 }
399};
400
John Reck8f45d4a2018-08-15 10:17:12 -0700401struct DrawTextBlob final : Op {
402 static const auto kType = Type::DrawTextBlob;
403 DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
404 : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {}
405 sk_sp<const SkTextBlob> blob;
406 SkScalar x, y;
407 SkPaint paint;
408 void draw(SkCanvas* c, const SkMatrix&) const { c->drawTextBlob(blob.get(), x, y, paint); }
409};
410
411struct DrawPatch final : Op {
412 static const auto kType = Type::DrawPatch;
413 DrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texs[4],
414 SkBlendMode bmode, const SkPaint& paint)
415 : xfermode(bmode), paint(paint) {
416 copy_v(this->cubics, cubics, 12);
417 if (colors) {
418 copy_v(this->colors, colors, 4);
419 has_colors = true;
420 }
421 if (texs) {
422 copy_v(this->texs, texs, 4);
423 has_texs = true;
424 }
425 }
426 SkPoint cubics[12];
427 SkColor colors[4];
428 SkPoint texs[4];
429 SkBlendMode xfermode;
430 SkPaint paint;
431 bool has_colors = false;
432 bool has_texs = false;
433 void draw(SkCanvas* c, const SkMatrix&) const {
434 c->drawPatch(cubics, has_colors ? colors : nullptr, has_texs ? texs : nullptr, xfermode,
435 paint);
436 }
437};
438struct DrawPoints final : Op {
439 static const auto kType = Type::DrawPoints;
440 DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint)
441 : mode(mode), count(count), paint(paint) {}
442 SkCanvas::PointMode mode;
443 size_t count;
444 SkPaint paint;
445 void draw(SkCanvas* c, const SkMatrix&) const {
446 c->drawPoints(mode, count, pod<SkPoint>(this), paint);
447 }
448};
449struct DrawVertices final : Op {
450 static const auto kType = Type::DrawVertices;
451 DrawVertices(const SkVertices* v, int bc, SkBlendMode m, const SkPaint& p)
452 : vertices(sk_ref_sp(const_cast<SkVertices*>(v))), boneCount(bc), mode(m), paint(p) {}
453 sk_sp<SkVertices> vertices;
454 int boneCount;
455 SkBlendMode mode;
456 SkPaint paint;
457 void draw(SkCanvas* c, const SkMatrix&) const {
458 c->drawVertices(vertices, pod<SkVertices::Bone>(this), boneCount, mode, paint);
459 }
460};
461struct DrawAtlas final : Op {
462 static const auto kType = Type::DrawAtlas;
463 DrawAtlas(const SkImage* atlas, int count, SkBlendMode xfermode, const SkRect* cull,
464 const SkPaint* paint, bool has_colors)
465 : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_colors(has_colors) {
466 if (cull) {
467 this->cull = *cull;
468 }
469 if (paint) {
470 this->paint = *paint;
471 }
472 }
473 sk_sp<const SkImage> atlas;
474 int count;
475 SkBlendMode xfermode;
476 SkRect cull = kUnset;
477 SkPaint paint;
478 bool has_colors;
479 void draw(SkCanvas* c, const SkMatrix&) const {
480 auto xforms = pod<SkRSXform>(this, 0);
481 auto texs = pod<SkRect>(this, count * sizeof(SkRSXform));
482 auto colors = has_colors ? pod<SkColor>(this, count * (sizeof(SkRSXform) + sizeof(SkRect)))
483 : nullptr;
484 c->drawAtlas(atlas.get(), xforms, texs, colors, count, xfermode, maybe_unset(cull), &paint);
485 }
486};
487struct DrawShadowRec final : Op {
488 static const auto kType = Type::DrawShadowRec;
489 DrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) : fPath(path), fRec(rec) {}
490 SkPath fPath;
491 SkDrawShadowRec fRec;
492 void draw(SkCanvas* c, const SkMatrix&) const { c->private_draw_shadow_rec(fPath, fRec); }
493};
John Reck08ee8152018-09-20 16:27:46 -0700494
495struct DrawVectorDrawable final : Op {
496 static const auto kType = Type::DrawVectorDrawable;
497 DrawVectorDrawable(VectorDrawableRoot* tree)
498 : mRoot(tree)
499 , mBounds(tree->stagingProperties().getBounds())
500 , palette(tree->computePalette()) {
501 // Recording, so use staging properties
502 tree->getPaintFor(&paint, tree->stagingProperties());
503 }
504
John Reck3b4510cd2018-09-27 17:39:45 -0700505 void draw(SkCanvas* canvas, const SkMatrix&) const { mRoot->draw(canvas, mBounds, paint); }
John Reck08ee8152018-09-20 16:27:46 -0700506
507 sp<VectorDrawableRoot> mRoot;
508 SkRect mBounds;
509 SkPaint paint;
510 BitmapPalette palette;
511};
Stan Ilievff2c36b2019-08-19 10:48:31 -0400512struct DrawWebView final : Op {
513 static const auto kType = Type::DrawWebView;
514 DrawWebView(skiapipeline::FunctorDrawable* drawable) : drawable(sk_ref_sp(drawable)) {}
515 sk_sp<skiapipeline::FunctorDrawable> drawable;
516 // We can't invoke SkDrawable::draw directly, because VkFunctorDrawable expects
517 // SkDrawable::onSnapGpuDrawHandler callback instead of SkDrawable::onDraw.
518 // SkCanvas::drawDrawable/SkGpuDevice::drawDrawable has the logic to invoke
519 // onSnapGpuDrawHandler.
520 void draw(SkCanvas* c, const SkMatrix&) const { c->drawDrawable(drawable.get()); }
521};
John Reck8f45d4a2018-08-15 10:17:12 -0700522}
523
524template <typename T, typename... Args>
525void* DisplayListData::push(size_t pod, Args&&... args) {
526 size_t skip = SkAlignPtr(sizeof(T) + pod);
527 SkASSERT(skip < (1 << 24));
528 if (fUsed + skip > fReserved) {
529 static_assert(SkIsPow2(SKLITEDL_PAGE), "This math needs updating for non-pow2.");
530 // Next greater multiple of SKLITEDL_PAGE.
531 fReserved = (fUsed + skip + SKLITEDL_PAGE) & ~(SKLITEDL_PAGE - 1);
532 fBytes.realloc(fReserved);
533 }
534 SkASSERT(fUsed + skip <= fReserved);
535 auto op = (T*)(fBytes.get() + fUsed);
536 fUsed += skip;
537 new (op) T{std::forward<Args>(args)...};
538 op->type = (uint32_t)T::kType;
539 op->skip = skip;
540 return op + 1;
541}
542
543template <typename Fn, typename... Args>
544inline void DisplayListData::map(const Fn fns[], Args... args) const {
545 auto end = fBytes.get() + fUsed;
546 for (const uint8_t* ptr = fBytes.get(); ptr < end;) {
547 auto op = (const Op*)ptr;
548 auto type = op->type;
549 auto skip = op->skip;
550 if (auto fn = fns[type]) { // We replace no-op functions with nullptrs
551 fn(op, args...); // to avoid the overhead of a pointless call.
552 }
553 ptr += skip;
554 }
555}
556
557void DisplayListData::flush() {
558 this->push<Flush>(0);
559}
560
561void DisplayListData::save() {
562 this->push<Save>(0);
563}
564void DisplayListData::restore() {
565 this->push<Restore>(0);
566}
567void DisplayListData::saveLayer(const SkRect* bounds, const SkPaint* paint,
568 const SkImageFilter* backdrop, const SkImage* clipMask,
569 const SkMatrix* clipMatrix, SkCanvas::SaveLayerFlags flags) {
570 this->push<SaveLayer>(0, bounds, paint, backdrop, clipMask, clipMatrix, flags);
571}
572
Derek Sollenberger24fc9012018-12-07 14:12:12 -0500573void DisplayListData::saveBehind(const SkRect* subset) {
574 this->push<SaveBehind>(0, subset);
575}
576
Mike Reeda4973d82020-01-22 10:10:37 -0500577void DisplayListData::concat44(const SkScalar colMajor[16]) {
578 this->push<Concat44>(0, colMajor);
579}
John Reck8f45d4a2018-08-15 10:17:12 -0700580void DisplayListData::concat(const SkMatrix& matrix) {
581 this->push<Concat>(0, matrix);
582}
583void DisplayListData::setMatrix(const SkMatrix& matrix) {
584 this->push<SetMatrix>(0, matrix);
585}
Mike Reeda4973d82020-01-22 10:10:37 -0500586void DisplayListData::scale(SkScalar sx, SkScalar sy) {
587 this->push<Scale>(0, sx, sy);
588}
John Reck8f45d4a2018-08-15 10:17:12 -0700589void DisplayListData::translate(SkScalar dx, SkScalar dy) {
590 this->push<Translate>(0, dx, dy);
591}
592
593void DisplayListData::clipPath(const SkPath& path, SkClipOp op, bool aa) {
594 this->push<ClipPath>(0, path, op, aa);
595}
596void DisplayListData::clipRect(const SkRect& rect, SkClipOp op, bool aa) {
597 this->push<ClipRect>(0, rect, op, aa);
598}
599void DisplayListData::clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
600 this->push<ClipRRect>(0, rrect, op, aa);
601}
602void DisplayListData::clipRegion(const SkRegion& region, SkClipOp op) {
603 this->push<ClipRegion>(0, region, op);
604}
605
606void DisplayListData::drawPaint(const SkPaint& paint) {
607 this->push<DrawPaint>(0, paint);
608}
Derek Sollenbergerac33a482019-04-22 16:28:09 -0400609void DisplayListData::drawBehind(const SkPaint& paint) {
610 this->push<DrawBehind>(0, paint);
611}
John Reck8f45d4a2018-08-15 10:17:12 -0700612void DisplayListData::drawPath(const SkPath& path, const SkPaint& paint) {
613 this->push<DrawPath>(0, path, paint);
614}
615void DisplayListData::drawRect(const SkRect& rect, const SkPaint& paint) {
616 this->push<DrawRect>(0, rect, paint);
617}
618void DisplayListData::drawRegion(const SkRegion& region, const SkPaint& paint) {
619 this->push<DrawRegion>(0, region, paint);
620}
621void DisplayListData::drawOval(const SkRect& oval, const SkPaint& paint) {
622 this->push<DrawOval>(0, oval, paint);
623}
624void DisplayListData::drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
625 bool useCenter, const SkPaint& paint) {
626 this->push<DrawArc>(0, oval, startAngle, sweepAngle, useCenter, paint);
627}
628void DisplayListData::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
629 this->push<DrawRRect>(0, rrect, paint);
630}
631void DisplayListData::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
632 this->push<DrawDRRect>(0, outer, inner, paint);
633}
634
635void DisplayListData::drawAnnotation(const SkRect& rect, const char* key, SkData* value) {
636 size_t bytes = strlen(key) + 1;
637 void* pod = this->push<DrawAnnotation>(bytes, rect, value);
638 copy_v(pod, key, bytes);
639}
640void DisplayListData::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
641 this->push<DrawDrawable>(0, drawable, matrix);
642}
643void DisplayListData::drawPicture(const SkPicture* picture, const SkMatrix* matrix,
644 const SkPaint* paint) {
645 this->push<DrawPicture>(0, picture, matrix, paint);
646}
647void DisplayListData::drawImage(sk_sp<const SkImage> image, SkScalar x, SkScalar y,
John Reckf3c724f2018-09-20 13:00:04 -0700648 const SkPaint* paint, BitmapPalette palette) {
649 this->push<DrawImage>(0, std::move(image), x, y, paint, palette);
John Reck8f45d4a2018-08-15 10:17:12 -0700650}
651void DisplayListData::drawImageNine(sk_sp<const SkImage> image, const SkIRect& center,
652 const SkRect& dst, const SkPaint* paint) {
653 this->push<DrawImageNine>(0, std::move(image), center, dst, paint);
654}
655void DisplayListData::drawImageRect(sk_sp<const SkImage> image, const SkRect* src,
656 const SkRect& dst, const SkPaint* paint,
John Reckf3c724f2018-09-20 13:00:04 -0700657 SkCanvas::SrcRectConstraint constraint, BitmapPalette palette) {
658 this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint, palette);
John Reck8f45d4a2018-08-15 10:17:12 -0700659}
660void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanvas::Lattice& lattice,
John Reck3b4510cd2018-09-27 17:39:45 -0700661 const SkRect& dst, const SkPaint* paint,
662 BitmapPalette palette) {
John Reck8f45d4a2018-08-15 10:17:12 -0700663 int xs = lattice.fXCount, ys = lattice.fYCount;
664 int fs = lattice.fRectTypes ? (xs + 1) * (ys + 1) : 0;
665 size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::RectType) +
666 fs * sizeof(SkColor);
667 SkASSERT(lattice.fBounds);
668 void* pod = this->push<DrawImageLattice>(bytes, std::move(image), xs, ys, fs, *lattice.fBounds,
John Reck3b4510cd2018-09-27 17:39:45 -0700669 dst, paint, palette);
John Reck8f45d4a2018-08-15 10:17:12 -0700670 copy_v(pod, lattice.fXDivs, xs, lattice.fYDivs, ys, lattice.fColors, fs, lattice.fRectTypes,
671 fs);
672}
673
John Reck8f45d4a2018-08-15 10:17:12 -0700674void DisplayListData::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
675 const SkPaint& paint) {
676 this->push<DrawTextBlob>(0, blob, x, y, paint);
John Reckf3c724f2018-09-20 13:00:04 -0700677 mHasText = true;
John Reck8f45d4a2018-08-15 10:17:12 -0700678}
679
680void DisplayListData::drawPatch(const SkPoint points[12], const SkColor colors[4],
681 const SkPoint texs[4], SkBlendMode bmode, const SkPaint& paint) {
682 this->push<DrawPatch>(0, points, colors, texs, bmode, paint);
683}
684void DisplayListData::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint points[],
685 const SkPaint& paint) {
686 void* pod = this->push<DrawPoints>(count * sizeof(SkPoint), mode, count, paint);
687 copy_v(pod, points, count);
688}
689void DisplayListData::drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
690 int boneCount, SkBlendMode mode, const SkPaint& paint) {
691 void* pod = this->push<DrawVertices>(boneCount * sizeof(SkVertices::Bone), vertices, boneCount,
692 mode, paint);
693 copy_v(pod, bones, boneCount);
694}
695void DisplayListData::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const SkRect texs[],
696 const SkColor colors[], int count, SkBlendMode xfermode,
697 const SkRect* cull, const SkPaint* paint) {
698 size_t bytes = count * (sizeof(SkRSXform) + sizeof(SkRect));
699 if (colors) {
700 bytes += count * sizeof(SkColor);
701 }
702 void* pod =
703 this->push<DrawAtlas>(bytes, atlas, count, xfermode, cull, paint, colors != nullptr);
704 copy_v(pod, xforms, count, texs, count, colors, colors ? count : 0);
705}
706void DisplayListData::drawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
707 this->push<DrawShadowRec>(0, path, rec);
708}
John Reck08ee8152018-09-20 16:27:46 -0700709void DisplayListData::drawVectorDrawable(VectorDrawableRoot* tree) {
710 this->push<DrawVectorDrawable>(0, tree);
711}
Stan Ilievff2c36b2019-08-19 10:48:31 -0400712void DisplayListData::drawWebView(skiapipeline::FunctorDrawable* drawable) {
713 this->push<DrawWebView>(0, drawable);
714}
John Reck8f45d4a2018-08-15 10:17:12 -0700715
716typedef void (*draw_fn)(const void*, SkCanvas*, const SkMatrix&);
717typedef void (*void_fn)(const void*);
718typedef void (*color_transform_fn)(const void*, ColorTransform);
719
720// All ops implement draw().
721#define X(T) \
722 [](const void* op, SkCanvas* c, const SkMatrix& original) { \
723 ((const T*)op)->draw(c, original); \
724 },
725static const draw_fn draw_fns[] = {
726#include "DisplayListOps.in"
727};
728#undef X
729
730// Most state ops (matrix, clip, save, restore) have a trivial destructor.
731#define X(T) \
732 !std::is_trivially_destructible<T>::value ? [](const void* op) { ((const T*)op)->~T(); } \
733 : (void_fn) nullptr,
734
735static const void_fn dtor_fns[] = {
736#include "DisplayListOps.in"
737};
738#undef X
739
740void DisplayListData::draw(SkCanvas* canvas) const {
741 SkAutoCanvasRestore acr(canvas, false);
742 this->map(draw_fns, canvas, canvas->getTotalMatrix());
743}
744
745DisplayListData::~DisplayListData() {
746 this->reset();
747}
748
749void DisplayListData::reset() {
750 this->map(dtor_fns);
751
752 // Leave fBytes and fReserved alone.
753 fUsed = 0;
754}
755
756template <class T>
John Reckf3c724f2018-09-20 13:00:04 -0700757using has_paint_helper = decltype(std::declval<T>().paint);
758
759template <class T>
760constexpr bool has_paint = std::experimental::is_detected_v<has_paint_helper, T>;
761
762template <class T>
763using has_palette_helper = decltype(std::declval<T>().palette);
764
765template <class T>
766constexpr bool has_palette = std::experimental::is_detected_v<has_palette_helper, T>;
John Reck8f45d4a2018-08-15 10:17:12 -0700767
768template <class T>
769constexpr color_transform_fn colorTransformForOp() {
John Reck3b4510cd2018-09-27 17:39:45 -0700770 if
771 constexpr(has_paint<T> && has_palette<T>) {
772 // It's a bitmap
773 return [](const void* opRaw, ColorTransform transform) {
774 // TODO: We should be const. Or not. Or just use a different map
775 // Unclear, but this is the quick fix
776 const T* op = reinterpret_cast<const T*>(opRaw);
777 transformPaint(transform, const_cast<SkPaint*>(&(op->paint)), op->palette);
778 };
779 }
780 else if
781 constexpr(has_paint<T>) {
782 return [](const void* opRaw, ColorTransform transform) {
783 // TODO: We should be const. Or not. Or just use a different map
784 // Unclear, but this is the quick fix
785 const T* op = reinterpret_cast<const T*>(opRaw);
786 transformPaint(transform, const_cast<SkPaint*>(&(op->paint)));
787 };
788 }
789 else {
John Reck8f45d4a2018-08-15 10:17:12 -0700790 return nullptr;
791 }
792}
793
794#define X(T) colorTransformForOp<T>(),
795static const color_transform_fn color_transform_fns[] = {
796#include "DisplayListOps.in"
797};
798#undef X
799
800void DisplayListData::applyColorTransform(ColorTransform transform) {
801 this->map(color_transform_fns, transform);
802}
803
804RecordingCanvas::RecordingCanvas() : INHERITED(1, 1), fDL(nullptr) {}
805
806void RecordingCanvas::reset(DisplayListData* dl, const SkIRect& bounds) {
807 this->resetCanvas(bounds.right(), bounds.bottom());
808 fDL = dl;
Stan Ilievf09ee582018-11-06 17:35:50 -0500809 mClipMayBeComplex = false;
810 mSaveCount = mComplexSaveCount = 0;
John Reck8f45d4a2018-08-15 10:17:12 -0700811}
812
813sk_sp<SkSurface> RecordingCanvas::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) {
814 return nullptr;
815}
816
817void RecordingCanvas::onFlush() {
818 fDL->flush();
819}
820
821void RecordingCanvas::willSave() {
Stan Ilievf09ee582018-11-06 17:35:50 -0500822 mSaveCount++;
John Reck8f45d4a2018-08-15 10:17:12 -0700823 fDL->save();
824}
825SkCanvas::SaveLayerStrategy RecordingCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
826 fDL->saveLayer(rec.fBounds, rec.fPaint, rec.fBackdrop, rec.fClipMask, rec.fClipMatrix,
827 rec.fSaveLayerFlags);
828 return SkCanvas::kNoLayer_SaveLayerStrategy;
829}
830void RecordingCanvas::willRestore() {
Stan Ilievf09ee582018-11-06 17:35:50 -0500831 mSaveCount--;
832 if (mSaveCount < mComplexSaveCount) {
833 mClipMayBeComplex = false;
834 mComplexSaveCount = 0;
835 }
John Reck8f45d4a2018-08-15 10:17:12 -0700836 fDL->restore();
837}
838
Derek Sollenberger24fc9012018-12-07 14:12:12 -0500839bool RecordingCanvas::onDoSaveBehind(const SkRect* subset) {
840 fDL->saveBehind(subset);
841 return false;
842}
843
Mike Reeda4973d82020-01-22 10:10:37 -0500844void RecordingCanvas::didConcat44(const SkScalar colMajor[16]) {
845 fDL->concat44(colMajor);
846}
John Reck8f45d4a2018-08-15 10:17:12 -0700847void RecordingCanvas::didConcat(const SkMatrix& matrix) {
848 fDL->concat(matrix);
849}
850void RecordingCanvas::didSetMatrix(const SkMatrix& matrix) {
851 fDL->setMatrix(matrix);
852}
Mike Reeda4973d82020-01-22 10:10:37 -0500853void RecordingCanvas::didScale(SkScalar sx, SkScalar sy) {
854 fDL->scale(sx, sy);
855}
John Reck8f45d4a2018-08-15 10:17:12 -0700856void RecordingCanvas::didTranslate(SkScalar dx, SkScalar dy) {
857 fDL->translate(dx, dy);
858}
859
860void RecordingCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle style) {
861 fDL->clipRect(rect, op, style == kSoft_ClipEdgeStyle);
Stan Ilievf09ee582018-11-06 17:35:50 -0500862 if (!getTotalMatrix().isScaleTranslate()) {
863 setClipMayBeComplex();
864 }
John Reck8f45d4a2018-08-15 10:17:12 -0700865 this->INHERITED::onClipRect(rect, op, style);
866}
867void RecordingCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle style) {
Stan Ilievf09ee582018-11-06 17:35:50 -0500868 if (rrect.getType() > SkRRect::kRect_Type || !getTotalMatrix().isScaleTranslate()) {
869 setClipMayBeComplex();
870 }
John Reck8f45d4a2018-08-15 10:17:12 -0700871 fDL->clipRRect(rrect, op, style == kSoft_ClipEdgeStyle);
872 this->INHERITED::onClipRRect(rrect, op, style);
873}
874void RecordingCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle style) {
Stan Ilievf09ee582018-11-06 17:35:50 -0500875 setClipMayBeComplex();
John Reck8f45d4a2018-08-15 10:17:12 -0700876 fDL->clipPath(path, op, style == kSoft_ClipEdgeStyle);
877 this->INHERITED::onClipPath(path, op, style);
878}
879void RecordingCanvas::onClipRegion(const SkRegion& region, SkClipOp op) {
Stan Ilievf09ee582018-11-06 17:35:50 -0500880 if (region.isComplex() || !getTotalMatrix().isScaleTranslate()) {
881 setClipMayBeComplex();
882 }
John Reck8f45d4a2018-08-15 10:17:12 -0700883 fDL->clipRegion(region, op);
884 this->INHERITED::onClipRegion(region, op);
885}
886
887void RecordingCanvas::onDrawPaint(const SkPaint& paint) {
888 fDL->drawPaint(paint);
889}
Derek Sollenbergerac33a482019-04-22 16:28:09 -0400890void RecordingCanvas::onDrawBehind(const SkPaint& paint) {
891 fDL->drawBehind(paint);
892}
John Reck8f45d4a2018-08-15 10:17:12 -0700893void RecordingCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
894 fDL->drawPath(path, paint);
895}
896void RecordingCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
897 fDL->drawRect(rect, paint);
898}
899void RecordingCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
900 fDL->drawRegion(region, paint);
901}
902void RecordingCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
903 fDL->drawOval(oval, paint);
904}
905void RecordingCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
906 bool useCenter, const SkPaint& paint) {
907 fDL->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
908}
909void RecordingCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
910 fDL->drawRRect(rrect, paint);
911}
912void RecordingCanvas::onDrawDRRect(const SkRRect& out, const SkRRect& in, const SkPaint& paint) {
913 fDL->drawDRRect(out, in, paint);
914}
915
916void RecordingCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
917 fDL->drawDrawable(drawable, matrix);
918}
919void RecordingCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
920 const SkPaint* paint) {
921 fDL->drawPicture(picture, matrix, paint);
922}
923void RecordingCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* val) {
924 fDL->drawAnnotation(rect, key, val);
925}
926
John Reck8f45d4a2018-08-15 10:17:12 -0700927void RecordingCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
928 const SkPaint& paint) {
929 fDL->drawTextBlob(blob, x, y, paint);
930}
931
932void RecordingCanvas::onDrawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y,
933 const SkPaint* paint) {
John Reckf3c724f2018-09-20 13:00:04 -0700934 fDL->drawImage(SkImage::MakeFromBitmap(bm), x, y, paint, BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700935}
936void RecordingCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center, const SkRect& dst,
937 const SkPaint* paint) {
938 fDL->drawImageNine(SkImage::MakeFromBitmap(bm), center, dst, paint);
939}
940void RecordingCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst,
941 const SkPaint* paint, SrcRectConstraint constraint) {
John Reck3b4510cd2018-09-27 17:39:45 -0700942 fDL->drawImageRect(SkImage::MakeFromBitmap(bm), src, dst, paint, constraint,
943 BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700944}
945void RecordingCanvas::onDrawBitmapLattice(const SkBitmap& bm, const SkCanvas::Lattice& lattice,
946 const SkRect& dst, const SkPaint* paint) {
John Reck3b4510cd2018-09-27 17:39:45 -0700947 fDL->drawImageLattice(SkImage::MakeFromBitmap(bm), lattice, dst, paint, BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700948}
949
John Reckf3c724f2018-09-20 13:00:04 -0700950void RecordingCanvas::drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
951 const SkPaint* paint, BitmapPalette palette) {
952 fDL->drawImage(image, x, y, paint, palette);
953}
954
John Reck3b4510cd2018-09-27 17:39:45 -0700955void RecordingCanvas::drawImageRect(const sk_sp<SkImage>& image, const SkRect& src,
956 const SkRect& dst, const SkPaint* paint,
957 SrcRectConstraint constraint, BitmapPalette palette) {
John Reckf3c724f2018-09-20 13:00:04 -0700958 fDL->drawImageRect(image, &src, dst, paint, constraint, palette);
959}
960
John Reck3b4510cd2018-09-27 17:39:45 -0700961void RecordingCanvas::drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice,
962 const SkRect& dst, const SkPaint* paint,
963 BitmapPalette palette) {
964 if (!image || dst.isEmpty()) {
965 return;
966 }
967
968 SkIRect bounds;
969 Lattice latticePlusBounds = lattice;
970 if (!latticePlusBounds.fBounds) {
971 bounds = SkIRect::MakeWH(image->width(), image->height());
972 latticePlusBounds.fBounds = &bounds;
973 }
974
975 if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
976 fDL->drawImageLattice(image, latticePlusBounds, dst, paint, palette);
977 } else {
978 fDL->drawImageRect(image, nullptr, dst, paint, SrcRectConstraint::kFast_SrcRectConstraint,
979 palette);
980 }
981}
982
John Reck8f45d4a2018-08-15 10:17:12 -0700983void RecordingCanvas::onDrawImage(const SkImage* img, SkScalar x, SkScalar y,
984 const SkPaint* paint) {
John Reckf3c724f2018-09-20 13:00:04 -0700985 fDL->drawImage(sk_ref_sp(img), x, y, paint, BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700986}
987void RecordingCanvas::onDrawImageNine(const SkImage* img, const SkIRect& center, const SkRect& dst,
988 const SkPaint* paint) {
989 fDL->drawImageNine(sk_ref_sp(img), center, dst, paint);
990}
991void RecordingCanvas::onDrawImageRect(const SkImage* img, const SkRect* src, const SkRect& dst,
992 const SkPaint* paint, SrcRectConstraint constraint) {
John Reckf3c724f2018-09-20 13:00:04 -0700993 fDL->drawImageRect(sk_ref_sp(img), src, dst, paint, constraint, BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700994}
995void RecordingCanvas::onDrawImageLattice(const SkImage* img, const SkCanvas::Lattice& lattice,
996 const SkRect& dst, const SkPaint* paint) {
John Reck3b4510cd2018-09-27 17:39:45 -0700997 fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, paint, BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700998}
999
1000void RecordingCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
1001 const SkPoint texCoords[4], SkBlendMode bmode,
1002 const SkPaint& paint) {
1003 fDL->drawPatch(cubics, colors, texCoords, bmode, paint);
1004}
1005void RecordingCanvas::onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
1006 const SkPaint& paint) {
1007 fDL->drawPoints(mode, count, pts, paint);
1008}
1009void RecordingCanvas::onDrawVerticesObject(const SkVertices* vertices,
John Reck3b4510cd2018-09-27 17:39:45 -07001010 const SkVertices::Bone bones[], int boneCount,
1011 SkBlendMode mode, const SkPaint& paint) {
John Reck8f45d4a2018-08-15 10:17:12 -07001012 fDL->drawVertices(vertices, bones, boneCount, mode, paint);
1013}
1014void RecordingCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xforms[],
1015 const SkRect texs[], const SkColor colors[], int count,
1016 SkBlendMode bmode, const SkRect* cull, const SkPaint* paint) {
1017 fDL->drawAtlas(atlas, xforms, texs, colors, count, bmode, cull, paint);
1018}
1019void RecordingCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
1020 fDL->drawShadowRec(path, rec);
1021}
1022
John Reck08ee8152018-09-20 16:27:46 -07001023void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
1024 fDL->drawVectorDrawable(tree);
1025}
1026
Stan Ilievff2c36b2019-08-19 10:48:31 -04001027void RecordingCanvas::drawWebView(skiapipeline::FunctorDrawable* drawable) {
1028 fDL->drawWebView(drawable);
1029}
1030
Chris Blume7b8a8082018-11-30 15:51:58 -08001031} // namespace uirenderer
1032} // namespace android