summaryrefslogtreecommitdiff
path: root/libs/hwui/RecordingCanvas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/RecordingCanvas.cpp')
-rw-r--r--libs/hwui/RecordingCanvas.cpp148
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