SkLiteDL: closing in
authormtklein <mtklein@chromium.org>
Sun, 7 Aug 2016 03:31:30 +0000 (20:31 -0700)
committerCommit bot <commit-bot@chromium.org>
Sun, 7 Aug 2016 03:31:31 +0000 (20:31 -0700)
 - optimizeFor(GrContext*)
 - images
 - basic text

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2224753002

Review-Url: https://codereview.chromium.org/2224753002

src/core/SkLiteDL.cpp
src/core/SkLiteDL.h
src/core/SkLiteRecorder.cpp

index 283f4e6..e3a4c0a 100644 (file)
 #include "SkLiteDL.h"
 #include "SkMutex.h"
 #include "SkSpinlock.h"
+#include "SkTextBlob.h"
+
+// memcpy_v(dst, src0,bytes0, src1,bytes1, ...) 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);
+    memcpy_v(SkTAddOffset<void>(dst, bytes), std::forward<Rest>(rest)...);
+}
+
+// Convert images and image-based shaders to textures.
+static void optimize_for(GrContext* ctx, SkPaint* paint, sk_sp<const SkImage>* image = nullptr) {
+    SkMatrix matrix;
+    SkShader::TileMode xy[2];
+    if (auto shader = paint->getShader())
+    if (auto image  = shader->isAImage(&matrix, xy)) {  // TODO: compose shaders, etc.
+        paint->setShader(image->makeTextureImage(ctx)->makeShader(xy[0], xy[1], &matrix));
+    }
+
+    if (image) {
+        *image = (*image)->makeTextureImage(ctx);
+    }
+}
 
 namespace {
     struct Op {
         virtual ~Op() {}
         virtual void draw(SkCanvas*) = 0;
+        virtual void optimizeFor(GrContext*) {}
 
         size_t skip;
     };
@@ -36,6 +61,7 @@ namespace {
         void draw(SkCanvas* c) override {
             c->saveLayer({ &bounds, &paint, backdrop.get(), flags });
         }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
     };
 
     struct Concat final : Op {
@@ -81,30 +107,35 @@ namespace {
         DrawPaint(const SkPaint& paint) : paint(paint) {}
         SkPaint paint;
         void draw(SkCanvas* c) override { c->drawPaint(paint); }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
     };
     struct DrawPath final : Op {
         DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(paint) {}
         SkPath  path;
         SkPaint paint;
         void draw(SkCanvas* c) override { c->drawPath(path, paint); }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
     };
     struct DrawRect final : Op {
         DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(paint) {}
         SkRect  rect;
         SkPaint paint;
         void draw(SkCanvas* c) override { c->drawRect(rect, paint); }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
     };
     struct DrawOval final : Op {
         DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(paint) {}
         SkRect  oval;
         SkPaint paint;
         void draw(SkCanvas* c) override { c->drawOval(oval, paint); }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
     };
     struct DrawRRect final : Op {
         DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), paint(paint) {}
         SkRRect rrect;
         SkPaint paint;
         void draw(SkCanvas* c) override { c->drawRRect(rrect, paint); }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
     };
     struct DrawDRRect final : Op {
         DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
@@ -112,24 +143,108 @@ namespace {
         SkRRect outer, inner;
         SkPaint paint;
         void draw(SkCanvas* c) override { c->drawDRRect(outer, inner, paint); }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
     };
 
-    template <typename T, typename... Args>
-    static void* push(SkTDArray<uint8_t>* bytes, size_t pod, Args&&... args) {
-        size_t skip = SkAlignPtr(sizeof(T) + pod);
-        auto op = (T*)bytes->append(skip);
-        new (op) T{ std::forward<Args>(args)... };
-        op->skip = skip;
-        return op+1;
-    }
+    struct DrawImage final : Op {
+        DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint)
+            : image(image), x(x), y(y) {
+            if (paint) { this->paint = *paint; }
+        }
+        sk_sp<const SkImage> image;
+        SkScalar x,y;
+        SkPaint paint;
+        void draw(SkCanvas* c) override { c->drawImage(image.get(), x,y, &paint); }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &image); }
+    };
+    struct DrawImageNine final : Op {
+        DrawImageNine(sk_sp<const SkImage>&& image,
+                      const SkIRect& center, const SkRect& dst, const SkPaint* paint)
+            : image(image), center(center), dst(dst) {
+            if (paint) { this->paint = *paint; }
+        }
+        sk_sp<const SkImage> image;
+        SkIRect center;
+        SkRect  dst;
+        SkPaint paint;
+        void draw(SkCanvas* c) override { c->drawImageNine(image.get(), center, dst, &paint); }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &image); }
+    };
+    struct DrawImageRect final : Op {
+        DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst,
+                      const SkPaint* paint, SkCanvas::SrcRectConstraint constraint)
+            : image(image), dst(dst), constraint(constraint) {
+            this->src = src ? *src : SkRect::MakeIWH(image->width(), image->height());
+            if (paint) { this->paint = *paint; }
+        }
+        sk_sp<const SkImage> image;
+        SkRect src, dst;
+        SkPaint paint;
+        SkCanvas::SrcRectConstraint constraint;
+        void draw(SkCanvas* c) override {
+            c->drawImageRect(image.get(), src, dst, &paint, constraint);
+        }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint, &image); }
+    };
 
-    template <typename Fn>
-    static void map(SkTDArray<uint8_t>* bytes, Fn&& fn) {
-        for (uint8_t* ptr = bytes->begin(); ptr < bytes->end(); ) {
-            auto op = (Op*)ptr;
-            fn(op);
-            ptr += op->skip;
+    struct DrawText final : Op {
+        DrawText(size_t bytes, SkScalar x, SkScalar y, const SkPaint& paint)
+            : bytes(bytes), x(x), y(y), paint(paint) {}
+        size_t bytes;
+        SkScalar x,y;
+        SkPaint paint;
+        void draw(SkCanvas* c) override { c->drawText(this+1, bytes, x,y, paint); }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
+    };
+    struct DrawPosText final : Op {
+        DrawPosText(size_t bytes, const SkPaint& paint)
+            : bytes(bytes), paint(paint) {}
+        size_t bytes;
+        SkPaint paint;
+        void draw(SkCanvas* c) override {
+            auto pos = SkTAddOffset<SkPoint>(this+1, bytes);
+            c->drawPosText(this+1, bytes, pos, 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;
+        SkScalar y;
+        SkPaint paint;
+        void draw(SkCanvas* c) override {
+            auto xs = SkTAddOffset<SkScalar>(this+1, bytes);
+            c->drawPosTextH(this+1, bytes, xs, y, paint);
+        }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
+    };
+    struct DrawTextBlob final : Op {
+        DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
+            : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {}
+        sk_sp<const SkTextBlob> blob;
+        SkScalar x,y;
+        SkPaint paint;
+        void draw(SkCanvas* c) override { c->drawTextBlob(blob.get(), x,y, paint); }
+        void optimizeFor(GrContext* ctx) override { optimize_for(ctx, &paint); }
+    };
+}
+
+template <typename T, typename... Args>
+static void* push(SkTDArray<uint8_t>* bytes, size_t pod, Args&&... args) {
+    size_t skip = SkAlignPtr(sizeof(T) + pod);
+    auto op = (T*)bytes->append(skip);
+    new (op) T{ std::forward<Args>(args)... };
+    op->skip = skip;
+    return op+1;
+}
+
+template <typename Fn>
+static void map(SkTDArray<uint8_t>* bytes, Fn&& fn) {
+    for (uint8_t* ptr = bytes->begin(); ptr < bytes->end(); ) {
+        auto op = (Op*)ptr;
+        fn(op);
+        ptr += op->skip;
     }
 }
 
@@ -175,10 +290,60 @@ void SkLiteDL::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPa
     push<DrawDRRect>(&fBytes, 0, outer, inner, paint);
 }
 
+void SkLiteDL::drawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y, const SkPaint* paint) {
+    push<DrawImage>(&fBytes, 0, SkImage::MakeFromBitmap(bm), x,y, paint);
+}
+void SkLiteDL::drawBitmapNine(const SkBitmap& bm, const SkIRect& center,
+                              const SkRect& dst, const SkPaint* paint) {
+    push<DrawImageNine>(&fBytes, 0, SkImage::MakeFromBitmap(bm), center, dst, paint);
+}
+void SkLiteDL::drawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst,
+                              const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) {
+    push<DrawImageRect>(&fBytes, 0, SkImage::MakeFromBitmap(bm), src, dst, paint, constraint);
+}
+
+void SkLiteDL::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) {
+    push<DrawImage>(&fBytes, 0, sk_ref_sp(image), x,y, paint);
+}
+void SkLiteDL::drawImageNine(const SkImage* image, const SkIRect& center,
+                             const SkRect& dst, const SkPaint* paint) {
+    push<DrawImageNine>(&fBytes, 0, sk_ref_sp(image), center, dst, paint);
+}
+void SkLiteDL::drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
+                             const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) {
+    push<DrawImageRect>(&fBytes, 0, sk_ref_sp(image), src, dst, paint, constraint);
+}
+
+void SkLiteDL::drawText(const void* text, size_t bytes,
+                        SkScalar x, SkScalar y, const SkPaint& paint) {
+    void* pod = push<DrawText>(&fBytes, bytes, bytes, x, y, paint);
+    memcpy_v(pod, text,bytes);
+}
+void SkLiteDL::drawPosText(const void* text, size_t bytes,
+                           const SkPoint pos[], const SkPaint& paint) {
+    int n = paint.countText(text, bytes);
+    void* pod = push<DrawPosText>(&fBytes, bytes+n*sizeof(SkPoint), bytes, paint);
+    memcpy_v(pod, text,bytes, pos,n*sizeof(SkPoint));
+}
+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);
+    memcpy_v(pod, text,bytes, xs,n*sizeof(SkScalar));
+}
+void SkLiteDL::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) {
+    push<DrawTextBlob>(&fBytes, 0, blob, x,y, paint);
+}
+
+
 void SkLiteDL::onDraw(SkCanvas* canvas) {
     map(&fBytes, [canvas](Op* op) { op->draw(canvas); });
 }
 
+void SkLiteDL::optimizeFor(GrContext* ctx) {
+    map(&fBytes, [ctx](Op* op) { op->optimizeFor(ctx); });
+}
+
 SkRect SkLiteDL::onGetBounds() {
     return fBounds;
 }
index 3dc8779..cbefdf5 100644 (file)
 #include "SkRect.h"
 #include "SkTDArray.h"
 
+class GrContext;
+
 class SkLiteDL final : public SkDrawable {
 public:
     static sk_sp<SkLiteDL> New(SkRect);
 
+    void optimizeFor(GrContext*);
+
     void save();
     void saveLayer(const SkRect*, const SkPaint*, const SkImageFilter*, uint32_t);
     void restore();
@@ -45,21 +49,24 @@ public:
     void drawPicture        (const SkPicture*, const SkMatrix*, const SkPaint*) {/*TODO*/}
     void drawShadowedPicture(const SkPicture*, const SkMatrix*, const SkPaint*) {/*TODO*/}
 
-    void drawText       (const void*, size_t, SkScalar, SkScalar, const SkPaint&) {/*TODO*/}
-    void drawPosText    (const void*, size_t, const SkPoint[], const SkPaint&) {/*TODO*/}
-    void drawPosTextH   (const void*, size_t, const SkScalar[], SkScalar, const SkPaint&) {/*TODO*/}
+    void drawText       (const void*, size_t, SkScalar, SkScalar, const SkPaint&);
+    void drawPosText    (const void*, size_t, const SkPoint[], const SkPaint&);
+    void drawPosTextH   (const void*, size_t, const SkScalar[], SkScalar, const SkPaint&);
     void drawTextOnPath (const void*, size_t, const SkPath&, const SkMatrix*, const SkPaint&) {/*TODO*/}
     void drawTextRSXForm(const void*, size_t, const SkRSXform[], const SkRect*, const SkPaint&) {/*TODO*/}
-    void drawTextBlob   (const SkTextBlob*, SkScalar,SkScalar, const SkPaint&) {/*TODO*/}
-
-    void drawBitmap    (const SkBitmap&, SkScalar,SkScalar,     const SkPaint*) {/*TODO*/}
-    void drawBitmapNine(const SkBitmap&, SkIRect, const SkRect&,       const SkPaint*) {/*TODO*/}
-    void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*, bool) {/*TODO*/}
-
-    void drawImage       (const SkImage*, SkScalar,SkScalar,     const SkPaint*) {/*TODO*/}
-    void drawImageNine   (const SkImage*, SkIRect, const SkRect&,       const SkPaint*) {/*TODO*/}
-    void drawImageRect   (const SkImage*, const SkRect*, const SkRect&, const SkPaint*, bool) {/*TODO*/}
-    void drawImageLattice(const SkImage*, SkCanvas::Lattice, const SkRect&, const SkPaint*) {/*TODO*/}
+    void drawTextBlob   (const SkTextBlob*, SkScalar,SkScalar, const SkPaint&);
+
+    void drawBitmap    (const SkBitmap&, SkScalar, SkScalar,            const SkPaint*);
+    void drawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect&, const SkPaint*);
+    void drawBitmapRect(const SkBitmap&, const SkRect*,  const SkRect&, const SkPaint*,
+                        SkCanvas::SrcRectConstraint);
+
+    void drawImage    (const SkImage*, SkScalar,SkScalar,             const SkPaint*);
+    void drawImageNine(const SkImage*, const SkIRect&, const SkRect&, const SkPaint*);
+    void drawImageRect(const SkImage*, const SkRect*, const SkRect&,  const SkPaint*,
+                       SkCanvas::SrcRectConstraint);
+    void drawImageLattice(const SkImage*, const SkCanvas::Lattice&, const SkRect&, const SkPaint*)
+        {/*TODO*/}
 
     void drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4],
                    SkXfermode*, const SkPaint&) {/*TODO*/}
index 00441fd..b712ca6 100644 (file)
@@ -124,7 +124,7 @@ void SkLiteRecorder::onDrawBitmapNine(const SkBitmap& bm,
 void SkLiteRecorder::onDrawBitmapRect(const SkBitmap& bm,
                                       const SkRect* src, const SkRect& dst,
                                       const SkPaint* paint, SrcRectConstraint constraint) {
-    fDL->drawBitmapRect(bm, src, dst, paint, constraint == kStrict_SrcRectConstraint);
+    fDL->drawBitmapRect(bm, src, dst, paint, constraint);
 }
 
 void SkLiteRecorder::onDrawImage(const SkImage* img,
@@ -140,7 +140,7 @@ void SkLiteRecorder::onDrawImageNine(const SkImage* img,
 void SkLiteRecorder::onDrawImageRect(const SkImage* img,
                                       const SkRect* src, const SkRect& dst,
                                       const SkPaint* paint, SrcRectConstraint constraint) {
-    fDL->drawImageRect(img, src, dst, paint, constraint == kStrict_SrcRectConstraint);
+    fDL->drawImageRect(img, src, dst, paint, constraint);
 }
 void SkLiteRecorder::onDrawImageLattice(const SkImage* img,
                                         const SkCanvas::Lattice& lattice, const SkRect& dst,