blob: 85947665839a70d3bcfef9c66afcfc54febf594d [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
John Reck08ee8152018-09-20 16:27:46 -070019#include "VectorDrawable.h"
20
Derek Sollenberger24fc9012018-12-07 14:12:12 -050021#include "SkAndroidFrameworkUtils.h"
John Reck8f45d4a2018-08-15 10:17:12 -070022#include "SkCanvas.h"
23#include "SkData.h"
24#include "SkDrawShadowInfo.h"
25#include "SkImage.h"
26#include "SkImageFilter.h"
John Reck3b4510cd2018-09-27 17:39:45 -070027#include "SkLatticeIter.h"
John Reck8f45d4a2018-08-15 10:17:12 -070028#include "SkMath.h"
29#include "SkPicture.h"
30#include "SkRSXform.h"
31#include "SkRegion.h"
32#include "SkTextBlob.h"
33#include "SkVertices.h"
34
35#include <experimental/type_traits>
36
37namespace android {
38namespace uirenderer {
39
40#ifndef SKLITEDL_PAGE
41#define SKLITEDL_PAGE 4096
42#endif
43
44// A stand-in for an optional SkRect which was not set, e.g. bounds for a saveLayer().
45static const SkRect kUnset = {SK_ScalarInfinity, 0, 0, 0};
46static const SkRect* maybe_unset(const SkRect& r) {
47 return r.left() == SK_ScalarInfinity ? nullptr : &r;
48}
49
50// copy_v(dst, src,n, src,n, ...) copies an arbitrary number of typed srcs into dst.
51static void copy_v(void* dst) {}
52
53template <typename S, typename... Rest>
54static void copy_v(void* dst, const S* src, int n, Rest&&... rest) {
55 SkASSERTF(((uintptr_t)dst & (alignof(S) - 1)) == 0,
56 "Expected %p to be aligned for at least %zu bytes.", dst, alignof(S));
57 sk_careful_memcpy(dst, src, n * sizeof(S));
58 copy_v(SkTAddOffset<void>(dst, n * sizeof(S)), std::forward<Rest>(rest)...);
59}
60
61// Helper for getting back at arrays which have been copy_v'd together after an Op.
62template <typename D, typename T>
63static const D* pod(const T* op, size_t offset = 0) {
64 return SkTAddOffset<const D>(op + 1, offset);
65}
66
67namespace {
68
69#define X(T) T,
70enum class Type : uint8_t {
71#include "DisplayListOps.in"
72};
73#undef X
74
75struct Op {
76 uint32_t type : 8;
77 uint32_t skip : 24;
78};
79static_assert(sizeof(Op) == 4, "");
80
81struct Flush final : Op {
82 static const auto kType = Type::Flush;
83 void draw(SkCanvas* c, const SkMatrix&) const { c->flush(); }
84};
85
86struct Save final : Op {
87 static const auto kType = Type::Save;
88 void draw(SkCanvas* c, const SkMatrix&) const { c->save(); }
89};
90struct Restore final : Op {
91 static const auto kType = Type::Restore;
92 void draw(SkCanvas* c, const SkMatrix&) const { c->restore(); }
93};
94struct SaveLayer final : Op {
95 static const auto kType = Type::SaveLayer;
96 SaveLayer(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
97 const SkImage* clipMask, const SkMatrix* clipMatrix, SkCanvas::SaveLayerFlags flags) {
98 if (bounds) {
99 this->bounds = *bounds;
100 }
101 if (paint) {
102 this->paint = *paint;
103 }
104 this->backdrop = sk_ref_sp(backdrop);
105 this->clipMask = sk_ref_sp(clipMask);
106 this->clipMatrix = clipMatrix ? *clipMatrix : SkMatrix::I();
107 this->flags = flags;
108 }
109 SkRect bounds = kUnset;
110 SkPaint paint;
111 sk_sp<const SkImageFilter> backdrop;
112 sk_sp<const SkImage> clipMask;
113 SkMatrix clipMatrix;
114 SkCanvas::SaveLayerFlags flags;
115 void draw(SkCanvas* c, const SkMatrix&) const {
116 c->saveLayer({maybe_unset(bounds), &paint, backdrop.get(), clipMask.get(),
117 clipMatrix.isIdentity() ? nullptr : &clipMatrix, flags});
118 }
119};
Derek Sollenberger24fc9012018-12-07 14:12:12 -0500120struct SaveBehind final : Op {
121 static const auto kType = Type::SaveBehind;
122 SaveBehind(const SkRect* subset) {
123 if (subset) { this->subset = *subset; }
124 }
125 SkRect subset = kUnset;
126 void draw(SkCanvas* c, const SkMatrix&) const {
127 SkAndroidFrameworkUtils::SaveBehind(c, &subset);
128 }
129};
John Reck8f45d4a2018-08-15 10:17:12 -0700130
131struct Concat final : Op {
132 static const auto kType = Type::Concat;
133 Concat(const SkMatrix& matrix) : matrix(matrix) {}
134 SkMatrix matrix;
135 void draw(SkCanvas* c, const SkMatrix&) const { c->concat(matrix); }
136};
137struct SetMatrix final : Op {
138 static const auto kType = Type::SetMatrix;
139 SetMatrix(const SkMatrix& matrix) : matrix(matrix) {}
140 SkMatrix matrix;
141 void draw(SkCanvas* c, const SkMatrix& original) const {
142 c->setMatrix(SkMatrix::Concat(original, matrix));
143 }
144};
145struct Translate final : Op {
146 static const auto kType = Type::Translate;
147 Translate(SkScalar dx, SkScalar dy) : dx(dx), dy(dy) {}
148 SkScalar dx, dy;
149 void draw(SkCanvas* c, const SkMatrix&) const { c->translate(dx, dy); }
150};
151
152struct ClipPath final : Op {
153 static const auto kType = Type::ClipPath;
154 ClipPath(const SkPath& path, SkClipOp op, bool aa) : path(path), op(op), aa(aa) {}
155 SkPath path;
156 SkClipOp op;
157 bool aa;
158 void draw(SkCanvas* c, const SkMatrix&) const { c->clipPath(path, op, aa); }
159};
160struct ClipRect final : Op {
161 static const auto kType = Type::ClipRect;
162 ClipRect(const SkRect& rect, SkClipOp op, bool aa) : rect(rect), op(op), aa(aa) {}
163 SkRect rect;
164 SkClipOp op;
165 bool aa;
166 void draw(SkCanvas* c, const SkMatrix&) const { c->clipRect(rect, op, aa); }
167};
168struct ClipRRect final : Op {
169 static const auto kType = Type::ClipRRect;
170 ClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) : rrect(rrect), op(op), aa(aa) {}
171 SkRRect rrect;
172 SkClipOp op;
173 bool aa;
174 void draw(SkCanvas* c, const SkMatrix&) const { c->clipRRect(rrect, op, aa); }
175};
176struct ClipRegion final : Op {
177 static const auto kType = Type::ClipRegion;
178 ClipRegion(const SkRegion& region, SkClipOp op) : region(region), op(op) {}
179 SkRegion region;
180 SkClipOp op;
181 void draw(SkCanvas* c, const SkMatrix&) const { c->clipRegion(region, op); }
182};
183
184struct DrawPaint final : Op {
185 static const auto kType = Type::DrawPaint;
186 DrawPaint(const SkPaint& paint) : paint(paint) {}
187 SkPaint paint;
188 void draw(SkCanvas* c, const SkMatrix&) const { c->drawPaint(paint); }
189};
190struct DrawPath final : Op {
191 static const auto kType = Type::DrawPath;
192 DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(paint) {}
193 SkPath path;
194 SkPaint paint;
195 void draw(SkCanvas* c, const SkMatrix&) const { c->drawPath(path, paint); }
196};
197struct DrawRect final : Op {
198 static const auto kType = Type::DrawRect;
199 DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(paint) {}
200 SkRect rect;
201 SkPaint paint;
202 void draw(SkCanvas* c, const SkMatrix&) const { c->drawRect(rect, paint); }
203};
204struct DrawRegion final : Op {
205 static const auto kType = Type::DrawRegion;
206 DrawRegion(const SkRegion& region, const SkPaint& paint) : region(region), paint(paint) {}
207 SkRegion region;
208 SkPaint paint;
209 void draw(SkCanvas* c, const SkMatrix&) const { c->drawRegion(region, paint); }
210};
211struct DrawOval final : Op {
212 static const auto kType = Type::DrawOval;
213 DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(paint) {}
214 SkRect oval;
215 SkPaint paint;
216 void draw(SkCanvas* c, const SkMatrix&) const { c->drawOval(oval, paint); }
217};
218struct DrawArc final : Op {
219 static const auto kType = Type::DrawArc;
220 DrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
221 const SkPaint& paint)
222 : oval(oval)
223 , startAngle(startAngle)
224 , sweepAngle(sweepAngle)
225 , useCenter(useCenter)
226 , paint(paint) {}
227 SkRect oval;
228 SkScalar startAngle;
229 SkScalar sweepAngle;
230 bool useCenter;
231 SkPaint paint;
232 void draw(SkCanvas* c, const SkMatrix&) const {
233 c->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
234 }
235};
236struct DrawRRect final : Op {
237 static const auto kType = Type::DrawRRect;
238 DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), paint(paint) {}
239 SkRRect rrect;
240 SkPaint paint;
241 void draw(SkCanvas* c, const SkMatrix&) const { c->drawRRect(rrect, paint); }
242};
243struct DrawDRRect final : Op {
244 static const auto kType = Type::DrawDRRect;
245 DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
246 : outer(outer), inner(inner), paint(paint) {}
247 SkRRect outer, inner;
248 SkPaint paint;
249 void draw(SkCanvas* c, const SkMatrix&) const { c->drawDRRect(outer, inner, paint); }
250};
251
252struct DrawAnnotation final : Op {
253 static const auto kType = Type::DrawAnnotation;
254 DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk_ref_sp(value)) {}
255 SkRect rect;
256 sk_sp<SkData> value;
257 void draw(SkCanvas* c, const SkMatrix&) const {
258 c->drawAnnotation(rect, pod<char>(this), value.get());
259 }
260};
261struct DrawDrawable final : Op {
262 static const auto kType = Type::DrawDrawable;
263 DrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) : drawable(sk_ref_sp(drawable)) {
264 if (matrix) {
265 this->matrix = *matrix;
266 }
267 }
268 sk_sp<SkDrawable> drawable;
269 SkMatrix matrix = SkMatrix::I();
270 void draw(SkCanvas* c, const SkMatrix&) const { c->drawDrawable(drawable.get(), &matrix); }
271};
272struct DrawPicture final : Op {
273 static const auto kType = Type::DrawPicture;
274 DrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
275 : picture(sk_ref_sp(picture)) {
276 if (matrix) {
277 this->matrix = *matrix;
278 }
279 if (paint) {
280 this->paint = *paint;
281 has_paint = true;
282 }
283 }
284 sk_sp<const SkPicture> picture;
285 SkMatrix matrix = SkMatrix::I();
286 SkPaint paint;
287 bool has_paint = false; // TODO: why is a default paint not the same?
288 void draw(SkCanvas* c, const SkMatrix&) const {
289 c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr);
290 }
291};
292
293struct DrawImage final : Op {
294 static const auto kType = Type::DrawImage;
John Reck3b4510cd2018-09-27 17:39:45 -0700295 DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint,
296 BitmapPalette palette)
John Reckf3c724f2018-09-20 13:00:04 -0700297 : image(std::move(image)), x(x), y(y), palette(palette) {
John Reck8f45d4a2018-08-15 10:17:12 -0700298 if (paint) {
299 this->paint = *paint;
300 }
301 }
302 sk_sp<const SkImage> image;
303 SkScalar x, y;
304 SkPaint paint;
John Reckf3c724f2018-09-20 13:00:04 -0700305 BitmapPalette palette;
John Reck8f45d4a2018-08-15 10:17:12 -0700306 void draw(SkCanvas* c, const SkMatrix&) const { c->drawImage(image.get(), x, y, &paint); }
307};
308struct DrawImageNine final : Op {
309 static const auto kType = Type::DrawImageNine;
310 DrawImageNine(sk_sp<const SkImage>&& image, const SkIRect& center, const SkRect& dst,
311 const SkPaint* paint)
312 : image(std::move(image)), center(center), dst(dst) {
313 if (paint) {
314 this->paint = *paint;
315 }
316 }
317 sk_sp<const SkImage> image;
318 SkIRect center;
319 SkRect dst;
320 SkPaint paint;
321 void draw(SkCanvas* c, const SkMatrix&) const {
322 c->drawImageNine(image.get(), center, dst, &paint);
323 }
324};
325struct DrawImageRect final : Op {
326 static const auto kType = Type::DrawImageRect;
327 DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst,
John Reck3b4510cd2018-09-27 17:39:45 -0700328 const SkPaint* paint, SkCanvas::SrcRectConstraint constraint,
329 BitmapPalette palette)
John Reckf3c724f2018-09-20 13:00:04 -0700330 : image(std::move(image)), dst(dst), constraint(constraint), palette(palette) {
Greg Kaiser5dda0032018-08-30 06:45:03 -0700331 this->src = src ? *src : SkRect::MakeIWH(this->image->width(), this->image->height());
John Reck8f45d4a2018-08-15 10:17:12 -0700332 if (paint) {
333 this->paint = *paint;
334 }
335 }
336 sk_sp<const SkImage> image;
337 SkRect src, dst;
338 SkPaint paint;
339 SkCanvas::SrcRectConstraint constraint;
John Reckf3c724f2018-09-20 13:00:04 -0700340 BitmapPalette palette;
John Reck8f45d4a2018-08-15 10:17:12 -0700341 void draw(SkCanvas* c, const SkMatrix&) const {
342 c->drawImageRect(image.get(), src, dst, &paint, constraint);
343 }
344};
345struct DrawImageLattice final : Op {
346 static const auto kType = Type::DrawImageLattice;
347 DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs, const SkIRect& src,
John Reck3b4510cd2018-09-27 17:39:45 -0700348 const SkRect& dst, const SkPaint* paint, BitmapPalette palette)
349 : image(std::move(image))
350 , xs(xs)
351 , ys(ys)
352 , fs(fs)
353 , src(src)
354 , dst(dst)
355 , palette(palette) {
John Reck8f45d4a2018-08-15 10:17:12 -0700356 if (paint) {
357 this->paint = *paint;
358 }
359 }
360 sk_sp<const SkImage> image;
361 int xs, ys, fs;
362 SkIRect src;
363 SkRect dst;
364 SkPaint paint;
John Reck3b4510cd2018-09-27 17:39:45 -0700365 BitmapPalette palette;
John Reck8f45d4a2018-08-15 10:17:12 -0700366 void draw(SkCanvas* c, const SkMatrix&) const {
367 auto xdivs = pod<int>(this, 0), ydivs = pod<int>(this, xs * sizeof(int));
368 auto colors = (0 == fs) ? nullptr : pod<SkColor>(this, (xs + ys) * sizeof(int));
369 auto flags =
370 (0 == fs) ? nullptr : pod<SkCanvas::Lattice::RectType>(
371 this, (xs + ys) * sizeof(int) + fs * sizeof(SkColor));
372 c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys, &src, colors}, dst, &paint);
373 }
374};
375
John Reck8f45d4a2018-08-15 10:17:12 -0700376struct DrawTextBlob final : Op {
377 static const auto kType = Type::DrawTextBlob;
378 DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
379 : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {}
380 sk_sp<const SkTextBlob> blob;
381 SkScalar x, y;
382 SkPaint paint;
383 void draw(SkCanvas* c, const SkMatrix&) const { c->drawTextBlob(blob.get(), x, y, paint); }
384};
385
386struct DrawPatch final : Op {
387 static const auto kType = Type::DrawPatch;
388 DrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texs[4],
389 SkBlendMode bmode, const SkPaint& paint)
390 : xfermode(bmode), paint(paint) {
391 copy_v(this->cubics, cubics, 12);
392 if (colors) {
393 copy_v(this->colors, colors, 4);
394 has_colors = true;
395 }
396 if (texs) {
397 copy_v(this->texs, texs, 4);
398 has_texs = true;
399 }
400 }
401 SkPoint cubics[12];
402 SkColor colors[4];
403 SkPoint texs[4];
404 SkBlendMode xfermode;
405 SkPaint paint;
406 bool has_colors = false;
407 bool has_texs = false;
408 void draw(SkCanvas* c, const SkMatrix&) const {
409 c->drawPatch(cubics, has_colors ? colors : nullptr, has_texs ? texs : nullptr, xfermode,
410 paint);
411 }
412};
413struct DrawPoints final : Op {
414 static const auto kType = Type::DrawPoints;
415 DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint)
416 : mode(mode), count(count), paint(paint) {}
417 SkCanvas::PointMode mode;
418 size_t count;
419 SkPaint paint;
420 void draw(SkCanvas* c, const SkMatrix&) const {
421 c->drawPoints(mode, count, pod<SkPoint>(this), paint);
422 }
423};
424struct DrawVertices final : Op {
425 static const auto kType = Type::DrawVertices;
426 DrawVertices(const SkVertices* v, int bc, SkBlendMode m, const SkPaint& p)
427 : vertices(sk_ref_sp(const_cast<SkVertices*>(v))), boneCount(bc), mode(m), paint(p) {}
428 sk_sp<SkVertices> vertices;
429 int boneCount;
430 SkBlendMode mode;
431 SkPaint paint;
432 void draw(SkCanvas* c, const SkMatrix&) const {
433 c->drawVertices(vertices, pod<SkVertices::Bone>(this), boneCount, mode, paint);
434 }
435};
436struct DrawAtlas final : Op {
437 static const auto kType = Type::DrawAtlas;
438 DrawAtlas(const SkImage* atlas, int count, SkBlendMode xfermode, const SkRect* cull,
439 const SkPaint* paint, bool has_colors)
440 : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_colors(has_colors) {
441 if (cull) {
442 this->cull = *cull;
443 }
444 if (paint) {
445 this->paint = *paint;
446 }
447 }
448 sk_sp<const SkImage> atlas;
449 int count;
450 SkBlendMode xfermode;
451 SkRect cull = kUnset;
452 SkPaint paint;
453 bool has_colors;
454 void draw(SkCanvas* c, const SkMatrix&) const {
455 auto xforms = pod<SkRSXform>(this, 0);
456 auto texs = pod<SkRect>(this, count * sizeof(SkRSXform));
457 auto colors = has_colors ? pod<SkColor>(this, count * (sizeof(SkRSXform) + sizeof(SkRect)))
458 : nullptr;
459 c->drawAtlas(atlas.get(), xforms, texs, colors, count, xfermode, maybe_unset(cull), &paint);
460 }
461};
462struct DrawShadowRec final : Op {
463 static const auto kType = Type::DrawShadowRec;
464 DrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) : fPath(path), fRec(rec) {}
465 SkPath fPath;
466 SkDrawShadowRec fRec;
467 void draw(SkCanvas* c, const SkMatrix&) const { c->private_draw_shadow_rec(fPath, fRec); }
468};
John Reck08ee8152018-09-20 16:27:46 -0700469
470struct DrawVectorDrawable final : Op {
471 static const auto kType = Type::DrawVectorDrawable;
472 DrawVectorDrawable(VectorDrawableRoot* tree)
473 : mRoot(tree)
474 , mBounds(tree->stagingProperties().getBounds())
475 , palette(tree->computePalette()) {
476 // Recording, so use staging properties
477 tree->getPaintFor(&paint, tree->stagingProperties());
478 }
479
John Reck3b4510cd2018-09-27 17:39:45 -0700480 void draw(SkCanvas* canvas, const SkMatrix&) const { mRoot->draw(canvas, mBounds, paint); }
John Reck08ee8152018-09-20 16:27:46 -0700481
482 sp<VectorDrawableRoot> mRoot;
483 SkRect mBounds;
484 SkPaint paint;
485 BitmapPalette palette;
486};
John Reck8f45d4a2018-08-15 10:17:12 -0700487}
488
489template <typename T, typename... Args>
490void* DisplayListData::push(size_t pod, Args&&... args) {
491 size_t skip = SkAlignPtr(sizeof(T) + pod);
492 SkASSERT(skip < (1 << 24));
493 if (fUsed + skip > fReserved) {
494 static_assert(SkIsPow2(SKLITEDL_PAGE), "This math needs updating for non-pow2.");
495 // Next greater multiple of SKLITEDL_PAGE.
496 fReserved = (fUsed + skip + SKLITEDL_PAGE) & ~(SKLITEDL_PAGE - 1);
497 fBytes.realloc(fReserved);
498 }
499 SkASSERT(fUsed + skip <= fReserved);
500 auto op = (T*)(fBytes.get() + fUsed);
501 fUsed += skip;
502 new (op) T{std::forward<Args>(args)...};
503 op->type = (uint32_t)T::kType;
504 op->skip = skip;
505 return op + 1;
506}
507
508template <typename Fn, typename... Args>
509inline void DisplayListData::map(const Fn fns[], Args... args) const {
510 auto end = fBytes.get() + fUsed;
511 for (const uint8_t* ptr = fBytes.get(); ptr < end;) {
512 auto op = (const Op*)ptr;
513 auto type = op->type;
514 auto skip = op->skip;
515 if (auto fn = fns[type]) { // We replace no-op functions with nullptrs
516 fn(op, args...); // to avoid the overhead of a pointless call.
517 }
518 ptr += skip;
519 }
520}
521
522void DisplayListData::flush() {
523 this->push<Flush>(0);
524}
525
526void DisplayListData::save() {
527 this->push<Save>(0);
528}
529void DisplayListData::restore() {
530 this->push<Restore>(0);
531}
532void DisplayListData::saveLayer(const SkRect* bounds, const SkPaint* paint,
533 const SkImageFilter* backdrop, const SkImage* clipMask,
534 const SkMatrix* clipMatrix, SkCanvas::SaveLayerFlags flags) {
535 this->push<SaveLayer>(0, bounds, paint, backdrop, clipMask, clipMatrix, flags);
536}
537
Derek Sollenberger24fc9012018-12-07 14:12:12 -0500538void DisplayListData::saveBehind(const SkRect* subset) {
539 this->push<SaveBehind>(0, subset);
540}
541
John Reck8f45d4a2018-08-15 10:17:12 -0700542void DisplayListData::concat(const SkMatrix& matrix) {
543 this->push<Concat>(0, matrix);
544}
545void DisplayListData::setMatrix(const SkMatrix& matrix) {
546 this->push<SetMatrix>(0, matrix);
547}
548void DisplayListData::translate(SkScalar dx, SkScalar dy) {
549 this->push<Translate>(0, dx, dy);
550}
551
552void DisplayListData::clipPath(const SkPath& path, SkClipOp op, bool aa) {
553 this->push<ClipPath>(0, path, op, aa);
554}
555void DisplayListData::clipRect(const SkRect& rect, SkClipOp op, bool aa) {
556 this->push<ClipRect>(0, rect, op, aa);
557}
558void DisplayListData::clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
559 this->push<ClipRRect>(0, rrect, op, aa);
560}
561void DisplayListData::clipRegion(const SkRegion& region, SkClipOp op) {
562 this->push<ClipRegion>(0, region, op);
563}
564
565void DisplayListData::drawPaint(const SkPaint& paint) {
566 this->push<DrawPaint>(0, paint);
567}
568void DisplayListData::drawPath(const SkPath& path, const SkPaint& paint) {
569 this->push<DrawPath>(0, path, paint);
570}
571void DisplayListData::drawRect(const SkRect& rect, const SkPaint& paint) {
572 this->push<DrawRect>(0, rect, paint);
573}
574void DisplayListData::drawRegion(const SkRegion& region, const SkPaint& paint) {
575 this->push<DrawRegion>(0, region, paint);
576}
577void DisplayListData::drawOval(const SkRect& oval, const SkPaint& paint) {
578 this->push<DrawOval>(0, oval, paint);
579}
580void DisplayListData::drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
581 bool useCenter, const SkPaint& paint) {
582 this->push<DrawArc>(0, oval, startAngle, sweepAngle, useCenter, paint);
583}
584void DisplayListData::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
585 this->push<DrawRRect>(0, rrect, paint);
586}
587void DisplayListData::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
588 this->push<DrawDRRect>(0, outer, inner, paint);
589}
590
591void DisplayListData::drawAnnotation(const SkRect& rect, const char* key, SkData* value) {
592 size_t bytes = strlen(key) + 1;
593 void* pod = this->push<DrawAnnotation>(bytes, rect, value);
594 copy_v(pod, key, bytes);
595}
596void DisplayListData::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
597 this->push<DrawDrawable>(0, drawable, matrix);
598}
599void DisplayListData::drawPicture(const SkPicture* picture, const SkMatrix* matrix,
600 const SkPaint* paint) {
601 this->push<DrawPicture>(0, picture, matrix, paint);
602}
603void DisplayListData::drawImage(sk_sp<const SkImage> image, SkScalar x, SkScalar y,
John Reckf3c724f2018-09-20 13:00:04 -0700604 const SkPaint* paint, BitmapPalette palette) {
605 this->push<DrawImage>(0, std::move(image), x, y, paint, palette);
John Reck8f45d4a2018-08-15 10:17:12 -0700606}
607void DisplayListData::drawImageNine(sk_sp<const SkImage> image, const SkIRect& center,
608 const SkRect& dst, const SkPaint* paint) {
609 this->push<DrawImageNine>(0, std::move(image), center, dst, paint);
610}
611void DisplayListData::drawImageRect(sk_sp<const SkImage> image, const SkRect* src,
612 const SkRect& dst, const SkPaint* paint,
John Reckf3c724f2018-09-20 13:00:04 -0700613 SkCanvas::SrcRectConstraint constraint, BitmapPalette palette) {
614 this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint, palette);
John Reck8f45d4a2018-08-15 10:17:12 -0700615}
616void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanvas::Lattice& lattice,
John Reck3b4510cd2018-09-27 17:39:45 -0700617 const SkRect& dst, const SkPaint* paint,
618 BitmapPalette palette) {
John Reck8f45d4a2018-08-15 10:17:12 -0700619 int xs = lattice.fXCount, ys = lattice.fYCount;
620 int fs = lattice.fRectTypes ? (xs + 1) * (ys + 1) : 0;
621 size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::RectType) +
622 fs * sizeof(SkColor);
623 SkASSERT(lattice.fBounds);
624 void* pod = this->push<DrawImageLattice>(bytes, std::move(image), xs, ys, fs, *lattice.fBounds,
John Reck3b4510cd2018-09-27 17:39:45 -0700625 dst, paint, palette);
John Reck8f45d4a2018-08-15 10:17:12 -0700626 copy_v(pod, lattice.fXDivs, xs, lattice.fYDivs, ys, lattice.fColors, fs, lattice.fRectTypes,
627 fs);
628}
629
John Reck8f45d4a2018-08-15 10:17:12 -0700630void DisplayListData::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
631 const SkPaint& paint) {
632 this->push<DrawTextBlob>(0, blob, x, y, paint);
John Reckf3c724f2018-09-20 13:00:04 -0700633 mHasText = true;
John Reck8f45d4a2018-08-15 10:17:12 -0700634}
635
636void DisplayListData::drawPatch(const SkPoint points[12], const SkColor colors[4],
637 const SkPoint texs[4], SkBlendMode bmode, const SkPaint& paint) {
638 this->push<DrawPatch>(0, points, colors, texs, bmode, paint);
639}
640void DisplayListData::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint points[],
641 const SkPaint& paint) {
642 void* pod = this->push<DrawPoints>(count * sizeof(SkPoint), mode, count, paint);
643 copy_v(pod, points, count);
644}
645void DisplayListData::drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
646 int boneCount, SkBlendMode mode, const SkPaint& paint) {
647 void* pod = this->push<DrawVertices>(boneCount * sizeof(SkVertices::Bone), vertices, boneCount,
648 mode, paint);
649 copy_v(pod, bones, boneCount);
650}
651void DisplayListData::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const SkRect texs[],
652 const SkColor colors[], int count, SkBlendMode xfermode,
653 const SkRect* cull, const SkPaint* paint) {
654 size_t bytes = count * (sizeof(SkRSXform) + sizeof(SkRect));
655 if (colors) {
656 bytes += count * sizeof(SkColor);
657 }
658 void* pod =
659 this->push<DrawAtlas>(bytes, atlas, count, xfermode, cull, paint, colors != nullptr);
660 copy_v(pod, xforms, count, texs, count, colors, colors ? count : 0);
661}
662void DisplayListData::drawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
663 this->push<DrawShadowRec>(0, path, rec);
664}
John Reck08ee8152018-09-20 16:27:46 -0700665void DisplayListData::drawVectorDrawable(VectorDrawableRoot* tree) {
666 this->push<DrawVectorDrawable>(0, tree);
667}
John Reck8f45d4a2018-08-15 10:17:12 -0700668
669typedef void (*draw_fn)(const void*, SkCanvas*, const SkMatrix&);
670typedef void (*void_fn)(const void*);
671typedef void (*color_transform_fn)(const void*, ColorTransform);
672
673// All ops implement draw().
674#define X(T) \
675 [](const void* op, SkCanvas* c, const SkMatrix& original) { \
676 ((const T*)op)->draw(c, original); \
677 },
678static const draw_fn draw_fns[] = {
679#include "DisplayListOps.in"
680};
681#undef X
682
683// Most state ops (matrix, clip, save, restore) have a trivial destructor.
684#define X(T) \
685 !std::is_trivially_destructible<T>::value ? [](const void* op) { ((const T*)op)->~T(); } \
686 : (void_fn) nullptr,
687
688static const void_fn dtor_fns[] = {
689#include "DisplayListOps.in"
690};
691#undef X
692
693void DisplayListData::draw(SkCanvas* canvas) const {
694 SkAutoCanvasRestore acr(canvas, false);
695 this->map(draw_fns, canvas, canvas->getTotalMatrix());
696}
697
698DisplayListData::~DisplayListData() {
699 this->reset();
700}
701
702void DisplayListData::reset() {
703 this->map(dtor_fns);
704
705 // Leave fBytes and fReserved alone.
706 fUsed = 0;
707}
708
709template <class T>
John Reckf3c724f2018-09-20 13:00:04 -0700710using has_paint_helper = decltype(std::declval<T>().paint);
711
712template <class T>
713constexpr bool has_paint = std::experimental::is_detected_v<has_paint_helper, T>;
714
715template <class T>
716using has_palette_helper = decltype(std::declval<T>().palette);
717
718template <class T>
719constexpr bool has_palette = std::experimental::is_detected_v<has_palette_helper, T>;
John Reck8f45d4a2018-08-15 10:17:12 -0700720
721template <class T>
722constexpr color_transform_fn colorTransformForOp() {
John Reck3b4510cd2018-09-27 17:39:45 -0700723 if
724 constexpr(has_paint<T> && has_palette<T>) {
725 // It's a bitmap
726 return [](const void* opRaw, ColorTransform transform) {
727 // TODO: We should be const. Or not. Or just use a different map
728 // Unclear, but this is the quick fix
729 const T* op = reinterpret_cast<const T*>(opRaw);
730 transformPaint(transform, const_cast<SkPaint*>(&(op->paint)), op->palette);
731 };
732 }
733 else if
734 constexpr(has_paint<T>) {
735 return [](const void* opRaw, ColorTransform transform) {
736 // TODO: We should be const. Or not. Or just use a different map
737 // Unclear, but this is the quick fix
738 const T* op = reinterpret_cast<const T*>(opRaw);
739 transformPaint(transform, const_cast<SkPaint*>(&(op->paint)));
740 };
741 }
742 else {
John Reck8f45d4a2018-08-15 10:17:12 -0700743 return nullptr;
744 }
745}
746
747#define X(T) colorTransformForOp<T>(),
748static const color_transform_fn color_transform_fns[] = {
749#include "DisplayListOps.in"
750};
751#undef X
752
753void DisplayListData::applyColorTransform(ColorTransform transform) {
754 this->map(color_transform_fns, transform);
755}
756
757RecordingCanvas::RecordingCanvas() : INHERITED(1, 1), fDL(nullptr) {}
758
759void RecordingCanvas::reset(DisplayListData* dl, const SkIRect& bounds) {
760 this->resetCanvas(bounds.right(), bounds.bottom());
761 fDL = dl;
Stan Ilievf09ee582018-11-06 17:35:50 -0500762 mClipMayBeComplex = false;
763 mSaveCount = mComplexSaveCount = 0;
John Reck8f45d4a2018-08-15 10:17:12 -0700764}
765
766sk_sp<SkSurface> RecordingCanvas::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) {
767 return nullptr;
768}
769
770void RecordingCanvas::onFlush() {
771 fDL->flush();
772}
773
774void RecordingCanvas::willSave() {
Stan Ilievf09ee582018-11-06 17:35:50 -0500775 mSaveCount++;
John Reck8f45d4a2018-08-15 10:17:12 -0700776 fDL->save();
777}
778SkCanvas::SaveLayerStrategy RecordingCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
779 fDL->saveLayer(rec.fBounds, rec.fPaint, rec.fBackdrop, rec.fClipMask, rec.fClipMatrix,
780 rec.fSaveLayerFlags);
781 return SkCanvas::kNoLayer_SaveLayerStrategy;
782}
783void RecordingCanvas::willRestore() {
Stan Ilievf09ee582018-11-06 17:35:50 -0500784 mSaveCount--;
785 if (mSaveCount < mComplexSaveCount) {
786 mClipMayBeComplex = false;
787 mComplexSaveCount = 0;
788 }
John Reck8f45d4a2018-08-15 10:17:12 -0700789 fDL->restore();
790}
791
Derek Sollenberger24fc9012018-12-07 14:12:12 -0500792bool RecordingCanvas::onDoSaveBehind(const SkRect* subset) {
793 fDL->saveBehind(subset);
794 return false;
795}
796
John Reck8f45d4a2018-08-15 10:17:12 -0700797void RecordingCanvas::didConcat(const SkMatrix& matrix) {
798 fDL->concat(matrix);
799}
800void RecordingCanvas::didSetMatrix(const SkMatrix& matrix) {
801 fDL->setMatrix(matrix);
802}
803void RecordingCanvas::didTranslate(SkScalar dx, SkScalar dy) {
804 fDL->translate(dx, dy);
805}
806
807void RecordingCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle style) {
808 fDL->clipRect(rect, op, style == kSoft_ClipEdgeStyle);
Stan Ilievf09ee582018-11-06 17:35:50 -0500809 if (!getTotalMatrix().isScaleTranslate()) {
810 setClipMayBeComplex();
811 }
John Reck8f45d4a2018-08-15 10:17:12 -0700812 this->INHERITED::onClipRect(rect, op, style);
813}
814void RecordingCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle style) {
Stan Ilievf09ee582018-11-06 17:35:50 -0500815 if (rrect.getType() > SkRRect::kRect_Type || !getTotalMatrix().isScaleTranslate()) {
816 setClipMayBeComplex();
817 }
John Reck8f45d4a2018-08-15 10:17:12 -0700818 fDL->clipRRect(rrect, op, style == kSoft_ClipEdgeStyle);
819 this->INHERITED::onClipRRect(rrect, op, style);
820}
821void RecordingCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle style) {
Stan Ilievf09ee582018-11-06 17:35:50 -0500822 setClipMayBeComplex();
John Reck8f45d4a2018-08-15 10:17:12 -0700823 fDL->clipPath(path, op, style == kSoft_ClipEdgeStyle);
824 this->INHERITED::onClipPath(path, op, style);
825}
826void RecordingCanvas::onClipRegion(const SkRegion& region, SkClipOp op) {
Stan Ilievf09ee582018-11-06 17:35:50 -0500827 if (region.isComplex() || !getTotalMatrix().isScaleTranslate()) {
828 setClipMayBeComplex();
829 }
John Reck8f45d4a2018-08-15 10:17:12 -0700830 fDL->clipRegion(region, op);
831 this->INHERITED::onClipRegion(region, op);
832}
833
834void RecordingCanvas::onDrawPaint(const SkPaint& paint) {
835 fDL->drawPaint(paint);
836}
837void RecordingCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
838 fDL->drawPath(path, paint);
839}
840void RecordingCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
841 fDL->drawRect(rect, paint);
842}
843void RecordingCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
844 fDL->drawRegion(region, paint);
845}
846void RecordingCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
847 fDL->drawOval(oval, paint);
848}
849void RecordingCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
850 bool useCenter, const SkPaint& paint) {
851 fDL->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
852}
853void RecordingCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
854 fDL->drawRRect(rrect, paint);
855}
856void RecordingCanvas::onDrawDRRect(const SkRRect& out, const SkRRect& in, const SkPaint& paint) {
857 fDL->drawDRRect(out, in, paint);
858}
859
860void RecordingCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
861 fDL->drawDrawable(drawable, matrix);
862}
863void RecordingCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
864 const SkPaint* paint) {
865 fDL->drawPicture(picture, matrix, paint);
866}
867void RecordingCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* val) {
868 fDL->drawAnnotation(rect, key, val);
869}
870
John Reck8f45d4a2018-08-15 10:17:12 -0700871void RecordingCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
872 const SkPaint& paint) {
873 fDL->drawTextBlob(blob, x, y, paint);
874}
875
876void RecordingCanvas::onDrawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y,
877 const SkPaint* paint) {
John Reckf3c724f2018-09-20 13:00:04 -0700878 fDL->drawImage(SkImage::MakeFromBitmap(bm), x, y, paint, BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700879}
880void RecordingCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center, const SkRect& dst,
881 const SkPaint* paint) {
882 fDL->drawImageNine(SkImage::MakeFromBitmap(bm), center, dst, paint);
883}
884void RecordingCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst,
885 const SkPaint* paint, SrcRectConstraint constraint) {
John Reck3b4510cd2018-09-27 17:39:45 -0700886 fDL->drawImageRect(SkImage::MakeFromBitmap(bm), src, dst, paint, constraint,
887 BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700888}
889void RecordingCanvas::onDrawBitmapLattice(const SkBitmap& bm, const SkCanvas::Lattice& lattice,
890 const SkRect& dst, const SkPaint* paint) {
John Reck3b4510cd2018-09-27 17:39:45 -0700891 fDL->drawImageLattice(SkImage::MakeFromBitmap(bm), lattice, dst, paint, BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700892}
893
John Reckf3c724f2018-09-20 13:00:04 -0700894void RecordingCanvas::drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
895 const SkPaint* paint, BitmapPalette palette) {
896 fDL->drawImage(image, x, y, paint, palette);
897}
898
John Reck3b4510cd2018-09-27 17:39:45 -0700899void RecordingCanvas::drawImageRect(const sk_sp<SkImage>& image, const SkRect& src,
900 const SkRect& dst, const SkPaint* paint,
901 SrcRectConstraint constraint, BitmapPalette palette) {
John Reckf3c724f2018-09-20 13:00:04 -0700902 fDL->drawImageRect(image, &src, dst, paint, constraint, palette);
903}
904
John Reck3b4510cd2018-09-27 17:39:45 -0700905void RecordingCanvas::drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice,
906 const SkRect& dst, const SkPaint* paint,
907 BitmapPalette palette) {
908 if (!image || dst.isEmpty()) {
909 return;
910 }
911
912 SkIRect bounds;
913 Lattice latticePlusBounds = lattice;
914 if (!latticePlusBounds.fBounds) {
915 bounds = SkIRect::MakeWH(image->width(), image->height());
916 latticePlusBounds.fBounds = &bounds;
917 }
918
919 if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
920 fDL->drawImageLattice(image, latticePlusBounds, dst, paint, palette);
921 } else {
922 fDL->drawImageRect(image, nullptr, dst, paint, SrcRectConstraint::kFast_SrcRectConstraint,
923 palette);
924 }
925}
926
John Reck8f45d4a2018-08-15 10:17:12 -0700927void RecordingCanvas::onDrawImage(const SkImage* img, SkScalar x, SkScalar y,
928 const SkPaint* paint) {
John Reckf3c724f2018-09-20 13:00:04 -0700929 fDL->drawImage(sk_ref_sp(img), x, y, paint, BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700930}
931void RecordingCanvas::onDrawImageNine(const SkImage* img, const SkIRect& center, const SkRect& dst,
932 const SkPaint* paint) {
933 fDL->drawImageNine(sk_ref_sp(img), center, dst, paint);
934}
935void RecordingCanvas::onDrawImageRect(const SkImage* img, const SkRect* src, const SkRect& dst,
936 const SkPaint* paint, SrcRectConstraint constraint) {
John Reckf3c724f2018-09-20 13:00:04 -0700937 fDL->drawImageRect(sk_ref_sp(img), src, dst, paint, constraint, BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700938}
939void RecordingCanvas::onDrawImageLattice(const SkImage* img, const SkCanvas::Lattice& lattice,
940 const SkRect& dst, const SkPaint* paint) {
John Reck3b4510cd2018-09-27 17:39:45 -0700941 fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, paint, BitmapPalette::Unknown);
John Reck8f45d4a2018-08-15 10:17:12 -0700942}
943
944void RecordingCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
945 const SkPoint texCoords[4], SkBlendMode bmode,
946 const SkPaint& paint) {
947 fDL->drawPatch(cubics, colors, texCoords, bmode, paint);
948}
949void RecordingCanvas::onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
950 const SkPaint& paint) {
951 fDL->drawPoints(mode, count, pts, paint);
952}
953void RecordingCanvas::onDrawVerticesObject(const SkVertices* vertices,
John Reck3b4510cd2018-09-27 17:39:45 -0700954 const SkVertices::Bone bones[], int boneCount,
955 SkBlendMode mode, const SkPaint& paint) {
John Reck8f45d4a2018-08-15 10:17:12 -0700956 fDL->drawVertices(vertices, bones, boneCount, mode, paint);
957}
958void RecordingCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xforms[],
959 const SkRect texs[], const SkColor colors[], int count,
960 SkBlendMode bmode, const SkRect* cull, const SkPaint* paint) {
961 fDL->drawAtlas(atlas, xforms, texs, colors, count, bmode, cull, paint);
962}
963void RecordingCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
964 fDL->drawShadowRec(path, rec);
965}
966
John Reck08ee8152018-09-20 16:27:46 -0700967void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
968 fDL->drawVectorDrawable(tree);
969}
970
Chris Blume7b8a8082018-11-30 15:51:58 -0800971} // namespace uirenderer
972} // namespace android