SkLiteDL, very nearly the rest
fix saveLayer bounds
all the misc calls
a bit of refactoring
just drawVertices and drawPatch to go, plus some todos and likely bug fixes
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2226563002
Review-Url: https://codereview.chromium.org/2226563002
diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp
index e3a4c0a..77b1704 100644
--- a/src/core/SkLiteDL.cpp
+++ b/src/core/SkLiteDL.cpp
@@ -6,21 +6,39 @@
*/
#include "SkCanvas.h"
+#include "SkData.h"
#include "SkImageFilter.h"
#include "SkLiteDL.h"
+#include "SkPicture.h"
#include "SkMutex.h"
+#include "SkRSXform.h"
#include "SkSpinlock.h"
#include "SkTextBlob.h"
-// memcpy_v(dst, src0,bytes0, src1,bytes1, ...) copies an arbitrary number of srcs into dst.
+// TODO: make sure DrawPosText and DrawPosTextH positions are aligned
+// (move the text after the positions).
+
+// A stand-in for an optional SkRect which was not set, e.g. bounds for a saveLayer().
+static const SkRect kUnset = {SK_ScalarInfinity, 0,0,0};
+static const SkRect* maybe_unset(const SkRect& r) {
+ return r.left() == SK_ScalarInfinity ? nullptr : &r;
+}
+
+// memcpy_v(dst, src,bytes, src,bytes, ...) copies an arbitrary number of srcs into dst.
static void memcpy_v(void* dst) {}
template <typename... Rest>
static void memcpy_v(void* dst, const void* src, size_t bytes, Rest&&... rest) {
- memcpy(dst, src, bytes);
+ sk_careful_memcpy(dst, src, bytes);
memcpy_v(SkTAddOffset<void>(dst, bytes), std::forward<Rest>(rest)...);
}
+// Helper for getting back at arrays which have been memcpy_v'd together after an Op.
+template <typename D, typename T>
+static D* pod(T* op, size_t offset = 0) {
+ return SkTAddOffset<D>(op+1, offset);
+}
+
// Convert images and image-based shaders to textures.
static void optimize_for(GrContext* ctx, SkPaint* paint, sk_sp<const SkImage>* image = nullptr) {
SkMatrix matrix;
@@ -48,18 +66,18 @@
struct Restore final : Op { void draw(SkCanvas* c) override { c->restore(); } };
struct SaveLayer final : Op {
SaveLayer(const SkRect* bounds, const SkPaint* paint,
- const SkImageFilter* backdrop, uint32_t flags) {
+ const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags) {
if (bounds) { this->bounds = *bounds; }
if (paint) { this->paint = *paint; }
this->backdrop = sk_ref_sp(backdrop);
this->flags = flags;
}
- SkRect bounds = {SK_ScalarMin,SK_ScalarMin, SK_ScalarMax,SK_ScalarMax};
+ SkRect bounds = kUnset;
SkPaint paint;
sk_sp<const SkImageFilter> backdrop;
- uint32_t flags;
+ SkCanvas::SaveLayerFlags flags;
void draw(SkCanvas* c) override {
- c->saveLayer({ &bounds, &paint, backdrop.get(), flags });
+ c->saveLayer({ maybe_unset(bounds), &paint, backdrop.get(), flags });
}
void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
};
@@ -74,6 +92,15 @@
SkMatrix matrix;
void draw(SkCanvas* c) override { c->setMatrix(matrix); }
};
+ struct TranslateZ final : Op {
+ TranslateZ(SkScalar dz) : dz(dz) {}
+ SkScalar dz;
+ void draw(SkCanvas* c) override {
+ #ifdef SK_EXPERIMENTAL_SHADOWING
+ c->translateZ(dz);
+ #endif
+ }
+ };
struct ClipPath final : Op {
ClipPath(const SkPath& path, SkRegion::Op op, bool aa) : path(path), op(op), aa(aa) {}
@@ -146,6 +173,49 @@
void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
};
+ struct DrawAnnotation final : Op {
+ DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk_ref_sp(value)) {}
+ SkRect rect;
+ sk_sp<SkData> value;
+ void draw(SkCanvas* c) override { c->drawAnnotation(rect, pod<char>(this), value.get()); }
+ };
+ struct DrawDrawable final : Op {
+ DrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) : drawable(sk_ref_sp(drawable)) {
+ if (matrix) { this->matrix = *matrix; }
+ }
+ sk_sp<SkDrawable> drawable;
+ SkMatrix matrix = SkMatrix::I();
+ void draw(SkCanvas* c) override { c->drawDrawable(drawable.get(), &matrix); }
+ };
+ struct DrawPicture final : Op {
+ DrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
+ : picture(sk_ref_sp(picture)) {
+ if (matrix) { this->matrix = *matrix; }
+ if (paint) { this->paint = *paint; }
+ }
+ sk_sp<const SkPicture> picture;
+ SkMatrix matrix = SkMatrix::I();
+ SkPaint paint;
+ void draw(SkCanvas* c) override { c->drawPicture(picture.get(), &matrix, &paint); }
+ void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
+ };
+ struct DrawShadowedPicture final : Op {
+ DrawShadowedPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
+ : picture(sk_ref_sp(picture)) {
+ if (matrix) { this->matrix = *matrix; }
+ if (paint) { this->paint = *paint; }
+ }
+ sk_sp<const SkPicture> picture;
+ SkMatrix matrix = SkMatrix::I();
+ SkPaint paint;
+ void draw(SkCanvas* c) override {
+ #ifdef SK_EXPERIMENTAL_SHADOWING
+ c->drawShadowedPicture(picture.get(), &matrix, &paint);
+ #endif
+ }
+ void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
+ };
+
struct DrawImage final : Op {
DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint)
: image(image), x(x), y(y) {
@@ -186,6 +256,23 @@
}
void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &image); }
};
+ struct DrawImageLattice final : Op {
+ DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys,
+ const SkRect& dst, const SkPaint* paint)
+ : image(image), xs(xs), ys(ys), dst(dst) {
+ if (paint) { this->paint = *paint; }
+ }
+ sk_sp<const SkImage> image;
+ int xs, ys;
+ SkRect dst;
+ SkPaint paint;
+ void draw(SkCanvas* c) override {
+ auto xdivs = pod<int>(this, 0),
+ ydivs = pod<int>(this, xs*sizeof(int));
+ c->drawImageLattice(image.get(), {xdivs, xs, ydivs, ys}, dst, &paint);
+ }
+ void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &image); }
+ };
struct DrawText final : Op {
DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint)
@@ -193,7 +280,7 @@
size_t bytes;
SkScalar x,y;
SkPaint paint;
- void draw(SkCanvas* c) override { c->drawText(this+1, bytes, x,y, paint); }
+ void draw(SkCanvas* c) override { c->drawText(pod<void>(this), bytes, x,y, paint); }
void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
};
struct DrawPosText final : Op {
@@ -202,20 +289,47 @@
size_t bytes;
SkPaint paint;
void draw(SkCanvas* c) override {
- auto pos = SkTAddOffset<SkPoint>(this+1, bytes);
- c->drawPosText(this+1, bytes, pos, paint);
+ c->drawPosText(pod<void>(this), bytes, pod<SkPoint>(this, bytes), paint);
}
void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
};
struct DrawPosTextH final : Op {
DrawPosTextH(size_t bytes, SkScalar y, const SkPaint& paint)
: bytes(bytes), y(y), paint(paint) {}
- size_t bytes;
+ size_t bytes;
SkScalar y;
+ SkPaint paint;
+ void draw(SkCanvas* c) override {
+ c->drawPosTextH(pod<void>(this), bytes, pod<SkScalar>(this, bytes), y, paint);
+ }
+ void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
+ };
+ struct DrawTextOnPath final : Op {
+ DrawTextOnPath(size_t bytes, const SkPath& path,
+ const SkMatrix* matrix, const SkPaint& paint)
+ : bytes(bytes), path(path), paint(paint) {
+ if (matrix) { this->matrix = *matrix; }
+ }
+ size_t bytes;
+ SkPath path;
+ SkMatrix matrix = SkMatrix::I();
+ SkPaint paint;
+ void draw(SkCanvas* c) override {
+ c->drawTextOnPath(pod<void>(this), bytes, path, &matrix, paint);
+ }
+ void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
+ };
+ struct DrawTextRSXform final : Op {
+ DrawTextRSXform(size_t bytes, const SkRect* cull, const SkPaint& paint)
+ : bytes(bytes), paint(paint) {
+ if (cull) { this->cull = *cull; }
+ }
+ size_t bytes;
+ SkRect cull = kUnset;
SkPaint paint;
void draw(SkCanvas* c) override {
- auto xs = SkTAddOffset<SkScalar>(this+1, bytes);
- c->drawPosTextH(this+1, bytes, xs, y, paint);
+ c->drawTextRSXform(pod<void>(this), bytes, pod<SkRSXform>(this, bytes),
+ maybe_unset(cull), paint);
}
void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
};
@@ -228,6 +342,40 @@
void draw(SkCanvas* c) override { c->drawTextBlob(blob.get(), x,y, paint); }
void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
};
+
+ struct DrawPoints final : Op {
+ DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint)
+ : mode(mode), count(count), paint(paint) {}
+ SkCanvas::PointMode mode;
+ size_t count;
+ SkPaint paint;
+ void draw(SkCanvas* c) override { c->drawPoints(mode, count, pod<SkPoint>(this), paint); }
+ void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
+ };
+ struct DrawAtlas final : Op {
+ DrawAtlas(const SkImage* atlas, int count, SkXfermode::Mode xfermode,
+ const SkRect* cull, const SkPaint* paint, bool has_colors)
+ : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_colors(has_colors) {
+ if (cull) { this->cull = *cull; }
+ if (paint) { this->paint = *paint; }
+ }
+ sk_sp<const SkImage> atlas;
+ int count;
+ SkXfermode::Mode xfermode;
+ SkRect cull = kUnset;
+ SkPaint paint;
+ bool has_colors;
+ void draw(SkCanvas* c) override {
+ auto xforms = pod<SkRSXform>(this, 0);
+ auto texs = pod<SkRect>(this, count*sizeof(SkRSXform));
+ auto colors = has_colors
+ ? pod<SkColor>(this, count*(sizeof(SkRSXform) + sizeof(SkRect)))
+ : nullptr;
+ c->drawAtlas(atlas.get(), xforms, texs, colors, count, xfermode,
+ maybe_unset(cull), &paint);
+ }
+ void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &atlas); }
+ };
}
template <typename T, typename... Args>
@@ -251,12 +399,13 @@
void SkLiteDL:: save() { push <Save>(&fBytes, 0); }
void SkLiteDL::restore() { push<Restore>(&fBytes, 0); }
void SkLiteDL::saveLayer(const SkRect* bounds, const SkPaint* paint,
- const SkImageFilter* backdrop, uint32_t flags) {
+ const SkImageFilter* backdrop, SkCanvas::SaveLayerFlags flags) {
push<SaveLayer>(&fBytes, 0, bounds, paint, backdrop, flags);
}
void SkLiteDL:: concat(const SkMatrix& matrix) { push <Concat>(&fBytes, 0, matrix); }
void SkLiteDL::setMatrix(const SkMatrix& matrix) { push<SetMatrix>(&fBytes, 0, matrix); }
+void SkLiteDL::translateZ(SkScalar dz) { push<TranslateZ>(&fBytes, 0, dz); }
void SkLiteDL::clipPath(const SkPath& path, SkRegion::Op op, bool aa) {
push<ClipPath>(&fBytes, 0, path, op, aa);
@@ -290,6 +439,23 @@
push<DrawDRRect>(&fBytes, 0, outer, inner, paint);
}
+void SkLiteDL::drawAnnotation(const SkRect& rect, const char* key, SkData* value) {
+ size_t bytes = strlen(key)+1;
+ void* pod = push<DrawAnnotation>(&fBytes, bytes, rect, value);
+ memcpy_v(pod, key,bytes);
+}
+void SkLiteDL::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
+ push<DrawDrawable>(&fBytes, 0, drawable, matrix);
+}
+void SkLiteDL::drawPicture(const SkPicture* picture,
+ const SkMatrix* matrix, const SkPaint* paint) {
+ push<DrawPicture>(&fBytes, 0, picture, matrix, paint);
+}
+void SkLiteDL::drawShadowedPicture(const SkPicture* picture,
+ const SkMatrix* matrix, const SkPaint* paint) {
+ push<DrawShadowedPicture>(&fBytes, 0, picture, matrix, paint);
+}
+
void SkLiteDL::drawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y, const SkPaint* paint) {
push<DrawImage>(&fBytes, 0, SkImage::MakeFromBitmap(bm), x,y, paint);
}
@@ -313,6 +479,14 @@
const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) {
push<DrawImageRect>(&fBytes, 0, sk_ref_sp(image), src, dst, paint, constraint);
}
+void SkLiteDL::drawImageLattice(const SkImage* image, const SkCanvas::Lattice& lattice,
+ const SkRect& dst, const SkPaint* paint) {
+ int xs = lattice.fXCount, ys = lattice.fYCount;
+ size_t bytes = (xs + ys) * sizeof(int);
+ void* pod = push<DrawImageLattice>(&fBytes, bytes, sk_ref_sp(image), xs, ys, dst, paint);
+ memcpy_v(pod, lattice.fXDivs,xs*sizeof(int),
+ lattice.fYDivs,ys*sizeof(int));
+}
void SkLiteDL::drawText(const void* text, size_t bytes,
SkScalar x, SkScalar y, const SkPaint& paint) {
@@ -328,13 +502,43 @@
void SkLiteDL::drawPosTextH(const void* text, size_t bytes,
const SkScalar xs[], SkScalar y, const SkPaint& paint) {
int n = paint.countText(text, bytes);
- void* pod = push<DrawPosTextH>(&fBytes, bytes + n*sizeof(SkScalar), bytes, y, paint);
+ void* pod = push<DrawPosTextH>(&fBytes, bytes+n*sizeof(SkScalar), bytes, y, paint);
memcpy_v(pod, text,bytes, xs,n*sizeof(SkScalar));
}
+void SkLiteDL::drawTextOnPath(const void* text, size_t bytes,
+ const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
+ void* pod = push<DrawTextOnPath>(&fBytes, bytes, bytes, path, matrix, paint);
+ memcpy_v(pod, text,bytes);
+}
+void SkLiteDL::drawTextRSXform(const void* text, size_t bytes,
+ const SkRSXform xforms[], const SkRect* cull, const SkPaint& paint) {
+ int n = paint.countText(text, bytes);
+ void* pod = push<DrawTextRSXform>(&fBytes, bytes+n*sizeof(SkRSXform), bytes, cull, paint);
+ memcpy_v(pod, text,bytes, xforms,n*sizeof(SkRSXform));
+}
void SkLiteDL::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) {
push<DrawTextBlob>(&fBytes, 0, blob, x,y, paint);
}
+void SkLiteDL::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint points[],
+ const SkPaint& paint) {
+ void* pod = push<DrawPoints>(&fBytes, count*sizeof(SkPoint), mode, count, paint);
+ memcpy_v(pod, points,count*sizeof(SkPoint));
+}
+void SkLiteDL::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const SkRect texs[],
+ const SkColor colors[], int count, SkXfermode::Mode xfermode,
+ const SkRect* cull, const SkPaint* paint) {
+ size_t bytes = count*(sizeof(SkRSXform) + sizeof(SkRect));
+ if (colors) {
+ bytes += count*sizeof(SkColor);
+ }
+ void* pod = push<DrawAtlas>(&fBytes, bytes,
+ atlas, count, xfermode, cull, paint, colors != nullptr);
+ memcpy_v(pod, xforms, count*sizeof(SkRSXform),
+ texs, count*sizeof(SkRect),
+ colors, colors ? count*sizeof(SkColor) : 0);
+}
+
void SkLiteDL::onDraw(SkCanvas* canvas) {
map(&fBytes, [canvas](Op* op) { op->draw(canvas); });