diff options
Diffstat (limited to 'libs/hwui/RecordingCanvas.cpp')
-rw-r--r-- | libs/hwui/RecordingCanvas.cpp | 148 |
1 files changed, 123 insertions, 25 deletions
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index 3eaff03db369..f928de9b92a6 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -16,11 +16,14 @@ #include "RecordingCanvas.h" +#include "VectorDrawable.h" + #include "SkCanvas.h" #include "SkData.h" #include "SkDrawShadowInfo.h" #include "SkImage.h" #include "SkImageFilter.h" +#include "SkLatticeIter.h" #include "SkMath.h" #include "SkPicture.h" #include "SkRSXform.h" @@ -278,8 +281,9 @@ struct DrawPicture final : Op { struct DrawImage final : Op { static const auto kType = Type::DrawImage; - DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint) - : image(std::move(image)), x(x), y(y) { + DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint, + BitmapPalette palette) + : image(std::move(image)), x(x), y(y), palette(palette) { if (paint) { this->paint = *paint; } @@ -287,6 +291,7 @@ struct DrawImage final : Op { sk_sp<const SkImage> image; SkScalar x, y; SkPaint paint; + BitmapPalette palette; void draw(SkCanvas* c, const SkMatrix&) const { c->drawImage(image.get(), x, y, &paint); } }; struct DrawImageNine final : Op { @@ -309,8 +314,9 @@ struct DrawImageNine final : Op { struct DrawImageRect final : Op { static const auto kType = Type::DrawImageRect; DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst, - const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) - : image(std::move(image)), dst(dst), constraint(constraint) { + const SkPaint* paint, SkCanvas::SrcRectConstraint constraint, + BitmapPalette palette) + : image(std::move(image)), dst(dst), constraint(constraint), palette(palette) { this->src = src ? *src : SkRect::MakeIWH(this->image->width(), this->image->height()); if (paint) { this->paint = *paint; @@ -320,6 +326,7 @@ struct DrawImageRect final : Op { SkRect src, dst; SkPaint paint; SkCanvas::SrcRectConstraint constraint; + BitmapPalette palette; void draw(SkCanvas* c, const SkMatrix&) const { c->drawImageRect(image.get(), src, dst, &paint, constraint); } @@ -327,8 +334,14 @@ struct DrawImageRect final : Op { struct DrawImageLattice final : Op { static const auto kType = Type::DrawImageLattice; DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs, const SkIRect& src, - const SkRect& dst, const SkPaint* paint) - : image(std::move(image)), xs(xs), ys(ys), fs(fs), src(src), dst(dst) { + const SkRect& dst, const SkPaint* paint, BitmapPalette palette) + : image(std::move(image)) + , xs(xs) + , ys(ys) + , fs(fs) + , src(src) + , dst(dst) + , palette(palette) { if (paint) { this->paint = *paint; } @@ -338,6 +351,7 @@ struct DrawImageLattice final : Op { SkIRect src; SkRect dst; SkPaint paint; + BitmapPalette palette; void draw(SkCanvas* c, const SkMatrix&) const { auto xdivs = pod<int>(this, 0), ydivs = pod<int>(this, xs * sizeof(int)); auto colors = (0 == fs) ? nullptr : pod<SkColor>(this, (xs + ys) * sizeof(int)); @@ -496,6 +510,24 @@ struct DrawShadowRec final : Op { SkDrawShadowRec fRec; void draw(SkCanvas* c, const SkMatrix&) const { c->private_draw_shadow_rec(fPath, fRec); } }; + +struct DrawVectorDrawable final : Op { + static const auto kType = Type::DrawVectorDrawable; + DrawVectorDrawable(VectorDrawableRoot* tree) + : mRoot(tree) + , mBounds(tree->stagingProperties().getBounds()) + , palette(tree->computePalette()) { + // Recording, so use staging properties + tree->getPaintFor(&paint, tree->stagingProperties()); + } + + void draw(SkCanvas* canvas, const SkMatrix&) const { mRoot->draw(canvas, mBounds, paint); } + + sp<VectorDrawableRoot> mRoot; + SkRect mBounds; + SkPaint paint; + BitmapPalette palette; +}; } template <typename T, typename... Args> @@ -609,8 +641,8 @@ void DisplayListData::drawPicture(const SkPicture* picture, const SkMatrix* matr this->push<DrawPicture>(0, picture, matrix, paint); } void DisplayListData::drawImage(sk_sp<const SkImage> image, SkScalar x, SkScalar y, - const SkPaint* paint) { - this->push<DrawImage>(0, std::move(image), x, y, paint); + const SkPaint* paint, BitmapPalette palette) { + this->push<DrawImage>(0, std::move(image), x, y, paint, palette); } void DisplayListData::drawImageNine(sk_sp<const SkImage> image, const SkIRect& center, const SkRect& dst, const SkPaint* paint) { @@ -618,18 +650,19 @@ void DisplayListData::drawImageNine(sk_sp<const SkImage> image, const SkIRect& c } void DisplayListData::drawImageRect(sk_sp<const SkImage> image, const SkRect* src, const SkRect& dst, const SkPaint* paint, - SkCanvas::SrcRectConstraint constraint) { - this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint); + SkCanvas::SrcRectConstraint constraint, BitmapPalette palette) { + this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint, palette); } void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanvas::Lattice& lattice, - const SkRect& dst, const SkPaint* paint) { + const SkRect& dst, const SkPaint* paint, + BitmapPalette palette) { int xs = lattice.fXCount, ys = lattice.fYCount; int fs = lattice.fRectTypes ? (xs + 1) * (ys + 1) : 0; size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::RectType) + fs * sizeof(SkColor); SkASSERT(lattice.fBounds); void* pod = this->push<DrawImageLattice>(bytes, std::move(image), xs, ys, fs, *lattice.fBounds, - dst, paint); + dst, paint, palette); copy_v(pod, lattice.fXDivs, xs, lattice.fYDivs, ys, lattice.fColors, fs, lattice.fRectTypes, fs); } @@ -638,28 +671,33 @@ void DisplayListData::drawText(const void* text, size_t bytes, SkScalar x, SkSca const SkPaint& paint) { void* pod = this->push<DrawText>(bytes, bytes, x, y, paint); copy_v(pod, (const char*)text, bytes); + mHasText = true; } void DisplayListData::drawPosText(const void* text, size_t bytes, const SkPoint pos[], const SkPaint& paint) { int n = paint.countText(text, bytes); void* pod = this->push<DrawPosText>(n * sizeof(SkPoint) + bytes, bytes, paint, n); copy_v(pod, pos, n, (const char*)text, bytes); + mHasText = true; } void DisplayListData::drawPosTextH(const void* text, size_t bytes, const SkScalar xs[], SkScalar y, const SkPaint& paint) { int n = paint.countText(text, bytes); void* pod = this->push<DrawPosTextH>(n * sizeof(SkScalar) + bytes, bytes, y, paint, n); copy_v(pod, xs, n, (const char*)text, bytes); + mHasText = true; } void DisplayListData::drawTextRSXform(const void* text, size_t bytes, const SkRSXform xforms[], const SkRect* cull, const SkPaint& paint) { int n = paint.countText(text, bytes); void* pod = this->push<DrawTextRSXform>(bytes + n * sizeof(SkRSXform), bytes, n, cull, paint); copy_v(pod, xforms, n, (const char*)text, bytes); + mHasText = true; } void DisplayListData::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) { this->push<DrawTextBlob>(0, blob, x, y, paint); + mHasText = true; } void DisplayListData::drawPatch(const SkPoint points[12], const SkColor colors[4], @@ -691,6 +729,9 @@ void DisplayListData::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], void DisplayListData::drawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) { this->push<DrawShadowRec>(0, path, rec); } +void DisplayListData::drawVectorDrawable(VectorDrawableRoot* tree) { + this->push<DrawVectorDrawable>(0, tree); +} typedef void (*draw_fn)(const void*, SkCanvas*, const SkMatrix&); typedef void (*void_fn)(const void*); @@ -733,17 +774,36 @@ void DisplayListData::reset() { } template <class T> -using has_paint_t = decltype(std::declval<T>().paint); +using has_paint_helper = decltype(std::declval<T>().paint); + +template <class T> +constexpr bool has_paint = std::experimental::is_detected_v<has_paint_helper, T>; + +template <class T> +using has_palette_helper = decltype(std::declval<T>().palette); + +template <class T> +constexpr bool has_palette = std::experimental::is_detected_v<has_palette_helper, T>; template <class T> constexpr color_transform_fn colorTransformForOp() { if - constexpr(std::experimental::is_detected_v<has_paint_t, T>) { - return [](const void* op, ColorTransform transform) { + constexpr(has_paint<T> && has_palette<T>) { + // It's a bitmap + return [](const void* opRaw, ColorTransform transform) { + // TODO: We should be const. Or not. Or just use a different map + // Unclear, but this is the quick fix + const T* op = reinterpret_cast<const T*>(opRaw); + transformPaint(transform, const_cast<SkPaint*>(&(op->paint)), op->palette); + }; + } + else if + constexpr(has_paint<T>) { + return [](const void* opRaw, ColorTransform transform) { // TODO: We should be const. Or not. Or just use a different map // Unclear, but this is the quick fix - transformPaint(transform, - const_cast<SkPaint*>(&(reinterpret_cast<const T*>(op)->paint))); + const T* op = reinterpret_cast<const T*>(opRaw); + transformPaint(transform, const_cast<SkPaint*>(&(op->paint))); }; } else { @@ -875,7 +935,7 @@ void RecordingCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScala void RecordingCanvas::onDrawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y, const SkPaint* paint) { - fDL->drawImage(SkImage::MakeFromBitmap(bm), x, y, paint); + fDL->drawImage(SkImage::MakeFromBitmap(bm), x, y, paint, BitmapPalette::Unknown); } void RecordingCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center, const SkRect& dst, const SkPaint* paint) { @@ -883,16 +943,50 @@ void RecordingCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center } void RecordingCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) { - fDL->drawImageRect(SkImage::MakeFromBitmap(bm), src, dst, paint, constraint); + fDL->drawImageRect(SkImage::MakeFromBitmap(bm), src, dst, paint, constraint, + BitmapPalette::Unknown); } void RecordingCanvas::onDrawBitmapLattice(const SkBitmap& bm, const SkCanvas::Lattice& lattice, const SkRect& dst, const SkPaint* paint) { - fDL->drawImageLattice(SkImage::MakeFromBitmap(bm), lattice, dst, paint); + fDL->drawImageLattice(SkImage::MakeFromBitmap(bm), lattice, dst, paint, BitmapPalette::Unknown); +} + +void RecordingCanvas::drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y, + const SkPaint* paint, BitmapPalette palette) { + fDL->drawImage(image, x, y, paint, palette); +} + +void RecordingCanvas::drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, + const SkRect& dst, const SkPaint* paint, + SrcRectConstraint constraint, BitmapPalette palette) { + fDL->drawImageRect(image, &src, dst, paint, constraint, palette); +} + +void RecordingCanvas::drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice, + const SkRect& dst, const SkPaint* paint, + BitmapPalette palette) { + if (!image || dst.isEmpty()) { + return; + } + + SkIRect bounds; + Lattice latticePlusBounds = lattice; + if (!latticePlusBounds.fBounds) { + bounds = SkIRect::MakeWH(image->width(), image->height()); + latticePlusBounds.fBounds = &bounds; + } + + if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) { + fDL->drawImageLattice(image, latticePlusBounds, dst, paint, palette); + } else { + fDL->drawImageRect(image, nullptr, dst, paint, SrcRectConstraint::kFast_SrcRectConstraint, + palette); + } } void RecordingCanvas::onDrawImage(const SkImage* img, SkScalar x, SkScalar y, const SkPaint* paint) { - fDL->drawImage(sk_ref_sp(img), x, y, paint); + fDL->drawImage(sk_ref_sp(img), x, y, paint, BitmapPalette::Unknown); } void RecordingCanvas::onDrawImageNine(const SkImage* img, const SkIRect& center, const SkRect& dst, const SkPaint* paint) { @@ -900,11 +994,11 @@ void RecordingCanvas::onDrawImageNine(const SkImage* img, const SkIRect& center, } void RecordingCanvas::onDrawImageRect(const SkImage* img, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) { - fDL->drawImageRect(sk_ref_sp(img), src, dst, paint, constraint); + fDL->drawImageRect(sk_ref_sp(img), src, dst, paint, constraint, BitmapPalette::Unknown); } void RecordingCanvas::onDrawImageLattice(const SkImage* img, const SkCanvas::Lattice& lattice, const SkRect& dst, const SkPaint* paint) { - fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, paint); + fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, paint, BitmapPalette::Unknown); } void RecordingCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], @@ -917,8 +1011,8 @@ void RecordingCanvas::onDrawPoints(SkCanvas::PointMode mode, size_t count, const fDL->drawPoints(mode, count, pts, paint); } void RecordingCanvas::onDrawVerticesObject(const SkVertices* vertices, - const SkVertices::Bone bones[], int boneCount, - SkBlendMode mode, const SkPaint& paint) { + const SkVertices::Bone bones[], int boneCount, + SkBlendMode mode, const SkPaint& paint) { fDL->drawVertices(vertices, bones, boneCount, mode, paint); } void RecordingCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xforms[], @@ -930,5 +1024,9 @@ void RecordingCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& fDL->drawShadowRec(path, rec); } +void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) { + fDL->drawVectorDrawable(tree); +} + }; // namespace uirenderer }; // namespace android |