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