aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/PictureOverheadBench.cpp45
-rw-r--r--dm/DM.cpp1
-rw-r--r--dm/DMSrcSink.cpp22
-rw-r--r--dm/DMSrcSink.h6
-rw-r--r--gyp/core.gypi2
-rw-r--r--include/core/SkCanvas.h1
-rw-r--r--include/core/SkRefCnt.h7
-rw-r--r--src/core/SkLiteDL.cpp150
-rw-r--r--src/core/SkLiteDL.h86
-rw-r--r--src/core/SkLiteRecorder.cpp188
-rw-r--r--src/core/SkLiteRecorder.h85
-rw-r--r--tests/SkLiteDLTest.cpp64
12 files changed, 643 insertions, 14 deletions
diff --git a/bench/PictureOverheadBench.cpp b/bench/PictureOverheadBench.cpp
index fc72f8623a..3bd9fb0bd9 100644
--- a/bench/PictureOverheadBench.cpp
+++ b/bench/PictureOverheadBench.cpp
@@ -10,26 +10,53 @@
#include "Benchmark.h"
#include "SkCanvas.h"
+#include "SkLiteDL.h"
+#include "SkLiteRecorder.h"
#include "SkPictureRecorder.h"
-template <bool kDraw>
+template <int kDraws, bool kLite>
struct PictureOverheadBench : public Benchmark {
- const char* onGetName() override {
- return kDraw ? "picture_overhead_draw" : "picture_overhead_nodraw";
+ PictureOverheadBench() {
+ fName.appendf("picture_overhead_%d%s\n", kDraws, kLite ? "_lite" : "");
}
+ const char* onGetName() override { return fName.c_str(); }
bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
void onDraw(int loops, SkCanvas*) override {
+ SkLiteRecorder lite;
SkPictureRecorder rec;
for (int i = 0; i < loops; i++) {
- rec.beginRecording(SkRect::MakeWH(2000,3000));
- if (kDraw) {
- rec.getRecordingCanvas()->drawRect(SkRect::MakeXYWH(10, 10, 1000, 1000), SkPaint());
+ SkRect bounds{0,0, 2000,3000};
+
+ sk_sp<SkLiteDL> liteDL;
+ SkCanvas* canvas;
+ if (kLite) {
+ liteDL = SkLiteDL::New(bounds);
+ lite.reset(liteDL.get());
+ canvas = &lite;
+ } else {
+ rec.beginRecording(bounds);
+ canvas = rec.getRecordingCanvas();
+ }
+
+ for (int i = 0; i < kDraws; i++) {
+ canvas->drawRect({10,10, 1000, 1000}, SkPaint{});
+ }
+
+ if (!kLite) {
+ (void)rec.finishRecordingAsPicture();
}
- (void)rec.finishRecordingAsPicture();
}
}
+
+ SkString fName;
};
-DEF_BENCH(return (new PictureOverheadBench<false>);)
-DEF_BENCH(return (new PictureOverheadBench< true>);)
+DEF_BENCH(return (new PictureOverheadBench<0, false>);)
+DEF_BENCH(return (new PictureOverheadBench<1, false>);)
+DEF_BENCH(return (new PictureOverheadBench<2, false>);)
+DEF_BENCH(return (new PictureOverheadBench<10,false>);)
+DEF_BENCH(return (new PictureOverheadBench<0, true>);)
+DEF_BENCH(return (new PictureOverheadBench<1, true>);)
+DEF_BENCH(return (new PictureOverheadBench<2, true>);)
+DEF_BENCH(return (new PictureOverheadBench<10, true>);)
diff --git a/dm/DM.cpp b/dm/DM.cpp
index bf80c863ba..5dd8a6f63e 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -879,6 +879,7 @@ static Sink* create_sink(const SkCommandLineConfig* config) {
static Sink* create_via(const SkString& tag, Sink* wrapped) {
#define VIA(t, via, ...) if (tag.equals(t)) { return new via(__VA_ARGS__); }
+ VIA("lite", ViaLite, wrapped);
VIA("twice", ViaTwice, wrapped);
VIA("serialize", ViaSerialization, wrapped);
VIA("pic", ViaPicture, wrapped);
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 2e9e565c86..52e1dd9ef3 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -21,6 +21,8 @@
#include "SkImageGenerator.h"
#include "SkImageGeneratorCG.h"
#include "SkImageGeneratorWIC.h"
+#include "SkLiteDL.h"
+#include "SkLiteRecorder.h"
#include "SkMallocPixelRef.h"
#include "SkMultiPictureDraw.h"
#include "SkNullCanvas.h"
@@ -1609,4 +1611,24 @@ Error ViaSingletonPictures::draw(
});
}
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+Error ViaLite::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const {
+ auto size = src.size();
+ SkRect bounds = {0,0, (SkScalar)size.width(), (SkScalar)size.height()};
+ return draw_to_canvas(fSink, bitmap, stream, log, size, [&](SkCanvas* canvas) -> Error {
+ sk_sp<SkLiteDL> dl = SkLiteDL::New(bounds);
+
+ SkLiteRecorder rec;
+ rec.reset(dl.get());
+
+ Error err = src.draw(&rec);
+ if (!err.isEmpty()) {
+ return err;
+ }
+ dl->draw(canvas);
+ return ""; //check_against_reference(bitmap, src, fSink);
+ });
+}
+
} // namespace DM
diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h
index a54ddb8d7f..086becb6f6 100644
--- a/dm/DMSrcSink.h
+++ b/dm/DMSrcSink.h
@@ -446,6 +446,12 @@ public:
Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
};
+class ViaLite : public Via {
+public:
+ explicit ViaLite(Sink* sink) : Via(sink) {}
+ Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override;
+};
+
} // namespace DM
#endif//DMSrcSink_DEFINED
diff --git a/gyp/core.gypi b/gyp/core.gypi
index 6b1d9f4eb5..306c90f5bc 100644
--- a/gyp/core.gypi
+++ b/gyp/core.gypi
@@ -161,6 +161,8 @@
'<(skia_src_path)/core/SkLinearBitmapPipeline_tile.h',
'<(skia_src_path)/core/SkLinearBitmapPipeline_sample.h',
'<(skia_src_path)/core/SkLineClipper.cpp',
+ '<(skia_src_path)/core/SkLiteDL.cpp',
+ '<(skia_src_path)/core/SkLiteRecorder.cpp',
'<(skia_src_path)/core/SkLocalMatrixImageFilter.cpp',
'<(skia_src_path)/core/SkLocalMatrixImageFilter.h',
'<(skia_src_path)/core/SkLocalMatrixShader.cpp',
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index c3f8599db4..26e3c8e3c5 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -1578,6 +1578,7 @@ private:
friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip
friend class SkSurface_Raster; // needs getDevice()
friend class SkRecorder; // InitFlags
+ friend class SkLiteRecorder; // InitFlags
friend class SkNoSaveLayerCanvas; // InitFlags
friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h
index 3227e68740..82a3c9e000 100644
--- a/include/core/SkRefCnt.h
+++ b/include/core/SkRefCnt.h
@@ -101,15 +101,12 @@ public:
protected:
/**
* Allow subclasses to call this if they've overridden internal_dispose
- * so they can reset fRefCnt before the destructor is called. Should only
- * be called right before calling through to inherited internal_dispose()
- * or before calling the destructor.
+ * so they can reset fRefCnt before the destructor is called or if they
+ * choose not to call the destructor (e.g. using a free list).
*/
void internal_dispose_restore_refcnt_to_1() const {
-#ifdef SK_DEBUG
SkASSERT(0 == getRefCnt());
fRefCnt.store(1, std::memory_order_relaxed);
-#endif
}
private:
diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp
new file mode 100644
index 0000000000..90f62c28f5
--- /dev/null
+++ b/src/core/SkLiteDL.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkCanvas.h"
+#include "SkLiteDL.h"
+#include "SkMutex.h"
+#include "SkSpinlock.h"
+
+namespace {
+ struct Op {
+ virtual ~Op() {}
+ virtual void draw(SkCanvas*) = 0;
+
+ size_t skip;
+ };
+
+ struct Save final : Op { void draw(SkCanvas* c) override { c-> save(); } };
+ struct Restore final : Op { void draw(SkCanvas* c) override { c->restore(); } };
+
+ struct Concat final : Op {
+ Concat(const SkMatrix& matrix) : matrix(matrix) {}
+ SkMatrix matrix;
+ void draw(SkCanvas* c) override { c->concat(matrix); }
+ };
+ struct SetMatrix final : Op {
+ SetMatrix(const SkMatrix& matrix) : matrix(matrix) {}
+ SkMatrix matrix;
+ void draw(SkCanvas* c) override { c->setMatrix(matrix); }
+ };
+
+ struct ClipRect final : Op {
+ ClipRect(const SkRect& rect, SkRegion::Op op, bool aa) : rect(rect), op(op), aa(aa) {}
+ SkRect rect;
+ SkRegion::Op op;
+ bool aa;
+ void draw(SkCanvas* c) override { c->clipRect(rect, op, aa); }
+ };
+
+ 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); }
+ };
+
+ 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); }
+ };
+
+ 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;
+ }
+ }
+}
+
+void SkLiteDL:: save() { push <Save>(&fBytes, 0); }
+void SkLiteDL::restore() { push<Restore>(&fBytes, 0); }
+
+void SkLiteDL:: concat(const SkMatrix& matrix) { push <Concat>(&fBytes, 0, matrix); }
+void SkLiteDL::setMatrix(const SkMatrix& matrix) { push<SetMatrix>(&fBytes, 0, matrix); }
+
+void SkLiteDL::clipRect(const SkRect& rect, SkRegion::Op op, bool aa) {
+ push<ClipRect>(&fBytes, 0, rect, op, aa);
+}
+
+void SkLiteDL::drawRect(const SkRect& rect, const SkPaint& paint) {
+ push<DrawRect>(&fBytes, 0, rect, paint);
+}
+void SkLiteDL::drawPath(const SkPath& path, const SkPaint& paint) {
+ push<DrawPath>(&fBytes, 0, path, paint);
+}
+
+void SkLiteDL::onDraw(SkCanvas* canvas) {
+ map(&fBytes, [canvas](Op* op) { op->draw(canvas); });
+}
+
+SkRect SkLiteDL::onGetBounds() {
+ return fBounds;
+}
+
+SkLiteDL:: SkLiteDL() {}
+SkLiteDL::~SkLiteDL() {}
+
+static const int kFreeStackByteLimit = 128*1024;
+static const int kFreeStackCountLimit = 8;
+
+static SkSpinlock gFreeStackLock;
+static SkLiteDL* gFreeStack = nullptr;
+static int gFreeStackCount = 0;
+
+sk_sp<SkLiteDL> SkLiteDL::New(SkRect bounds) {
+ sk_sp<SkLiteDL> dl;
+ {
+ SkAutoMutexAcquire lock(gFreeStackLock);
+ if (gFreeStack) {
+ dl.reset(gFreeStack); // Adopts the ref the stack's been holding.
+ gFreeStack = gFreeStack->fNext;
+ gFreeStackCount--;
+ }
+ }
+
+ if (!dl) {
+ dl.reset(new SkLiteDL);
+ }
+
+ dl->fBounds = bounds;
+ return dl;
+}
+
+void SkLiteDL::internal_dispose() const {
+ // Whether we delete this or leave it on the free stack,
+ // we want its refcnt at 1.
+ this->internal_dispose_restore_refcnt_to_1();
+
+ auto self = const_cast<SkLiteDL*>(this);
+ map(&self->fBytes, [](Op* op) { op->~Op(); });
+
+ if (self->fBytes.reserved() < kFreeStackByteLimit) {
+ self->fBytes.rewind();
+ SkAutoMutexAcquire lock(gFreeStackLock);
+ if (gFreeStackCount < kFreeStackCountLimit) {
+ self->fNext = gFreeStack;
+ gFreeStack = self;
+ gFreeStackCount++;
+ return;
+ }
+ }
+
+ delete this;
+}
diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h
new file mode 100644
index 0000000000..88c959f88d
--- /dev/null
+++ b/src/core/SkLiteDL.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkLiteDL_DEFINED
+#define SkLiteDL_DEFINED
+
+#include "SkCanvas.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkDrawable.h"
+#include "SkRect.h"
+#include "SkTDArray.h"
+
+class SkLiteDL final : public SkDrawable {
+public:
+ static sk_sp<SkLiteDL> New(SkRect);
+
+ void save();
+ void saveLayer(const SkRect*, const SkPaint*, const SkImageFilter*, uint32_t) {/*TODO*/}
+ void restore();
+
+ void concat (const SkMatrix&);
+ void setMatrix (const SkMatrix&);
+ void translateZ(SkScalar) {/*TODO*/}
+
+ void clipPath (const SkPath&, SkRegion::Op, bool aa) {/*TODO*/}
+ void clipRRect (const SkRRect&, SkRegion::Op, bool aa) {/*TODO*/}
+ void clipRect (const SkRect&, SkRegion::Op, bool aa);
+ void clipRegion(const SkRegion&, SkRegion::Op) {/*TODO*/}
+
+
+ void drawPaint (const SkPaint&) {/*TODO*/}
+ void drawPath (const SkPath&, const SkPaint&);
+ void drawRect (const SkRect&, const SkPaint&);
+ void drawOval (const SkRect&, const SkPaint&) {/*TODO*/}
+ void drawRRect (const SkRRect&, const SkPaint&) {/*TODO*/}
+ void drawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) {/*TODO*/}
+
+ void drawAnnotation (const SkRect&, const char*, SkData*) {/*TODO*/}
+ void drawDrawable (SkDrawable*, const SkMatrix*) {/*TODO*/}
+ 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 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 drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4],
+ SkXfermode*, const SkPaint&) {/*TODO*/}
+ void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&) {/*TODO*/}
+ void drawVertices(SkCanvas::VertexMode, int, const SkPoint[], const SkPoint[], const SkColor[],
+ SkXfermode*, const uint16_t[], int, const SkPaint&) {/*TODO*/}
+ void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
+ SkXfermode::Mode, const SkRect*, const SkPaint*) {/*TODO*/}
+
+private:
+ SkLiteDL();
+ ~SkLiteDL();
+
+ void internal_dispose() const override;
+
+ SkRect onGetBounds() override;
+ void onDraw(SkCanvas*) override;
+
+ SkLiteDL* fNext;
+ SkRect fBounds;
+ SkTDArray<uint8_t> fBytes;
+};
+
+#endif//SkLiteDL_DEFINED
diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp
new file mode 100644
index 0000000000..00441fdf84
--- /dev/null
+++ b/src/core/SkLiteRecorder.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkLiteDL.h"
+#include "SkLiteRecorder.h"
+#include "SkSurface.h"
+
+SkLiteRecorder::SkLiteRecorder()
+ : SkCanvas({0,0,1,1}, SkCanvas::kConservativeRasterClip_InitFlag)
+ , fDL(nullptr) {}
+
+void SkLiteRecorder::reset(SkLiteDL* dl) {
+ this->resetForNextPicture(dl->getBounds().roundOut());
+ fDL = dl;
+}
+
+sk_sp<SkSurface> SkLiteRecorder::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) {
+ return nullptr;
+}
+
+void SkLiteRecorder::willSave() { fDL->save(); }
+SkCanvas::SaveLayerStrategy SkLiteRecorder::getSaveLayerStrategy(const SaveLayerRec& rec) {
+ fDL->saveLayer(rec.fBounds, rec.fPaint, rec.fBackdrop, rec.fSaveLayerFlags);
+ return SkCanvas::kNoLayer_SaveLayerStrategy;
+}
+void SkLiteRecorder::willRestore() { fDL->restore(); }
+
+void SkLiteRecorder::didConcat (const SkMatrix& matrix) { fDL-> concat(matrix); }
+void SkLiteRecorder::didSetMatrix(const SkMatrix& matrix) { fDL->setMatrix(matrix); }
+
+void SkLiteRecorder::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle style) {
+ fDL->clipRect(rect, op, style==kSoft_ClipEdgeStyle);
+ SkCanvas::onClipRect(rect, op, style);
+}
+void SkLiteRecorder::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle style) {
+ fDL->clipRRect(rrect, op, style==kSoft_ClipEdgeStyle);
+ SkCanvas::onClipRRect(rrect, op, style);
+}
+void SkLiteRecorder::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle style) {
+ fDL->clipPath(path, op, style==kSoft_ClipEdgeStyle);
+ SkCanvas::onClipPath(path, op, style);
+}
+void SkLiteRecorder::onClipRegion(const SkRegion& region, SkRegion::Op op) {
+ fDL->clipRegion(region, op);
+ SkCanvas::onClipRegion(region, op);
+}
+
+void SkLiteRecorder::onDrawPaint(const SkPaint& paint) {
+ fDL->drawPaint(paint);
+}
+void SkLiteRecorder::onDrawPath(const SkPath& path, const SkPaint& paint) {
+ fDL->drawPath(path, paint);
+}
+void SkLiteRecorder::onDrawRect(const SkRect& rect, const SkPaint& paint) {
+ fDL->drawRect(rect, paint);
+}
+void SkLiteRecorder::onDrawOval(const SkRect& oval, const SkPaint& paint) {
+ fDL->drawOval(oval, paint);
+}
+void SkLiteRecorder::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
+ fDL->drawRRect(rrect, paint);
+}
+void SkLiteRecorder::onDrawDRRect(const SkRRect& out, const SkRRect& in, const SkPaint& paint) {
+ fDL->drawDRRect(out, in, paint);
+}
+
+void SkLiteRecorder::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
+ fDL->drawDrawable(drawable, matrix);
+}
+void SkLiteRecorder::onDrawPicture(const SkPicture* picture,
+ const SkMatrix* matrix,
+ const SkPaint* paint) {
+ fDL->drawPicture(picture, matrix, paint);
+}
+void SkLiteRecorder::onDrawAnnotation(const SkRect& rect, const char key[], SkData* val) {
+ fDL->drawAnnotation(rect, key, val);
+}
+
+void SkLiteRecorder::onDrawText(const void* text, size_t bytes,
+ SkScalar x, SkScalar y,
+ const SkPaint& paint) {
+ fDL->drawText(text, bytes, x, y, paint);
+}
+void SkLiteRecorder::onDrawPosText(const void* text, size_t bytes,
+ const SkPoint pos[],
+ const SkPaint& paint) {
+ fDL->drawPosText(text, bytes, pos, paint);
+}
+void SkLiteRecorder::onDrawPosTextH(const void* text, size_t bytes,
+ const SkScalar xs[], SkScalar y,
+ const SkPaint& paint) {
+ fDL->drawPosTextH(text, bytes, xs, y, paint);
+}
+void SkLiteRecorder::onDrawTextOnPath(const void* text, size_t bytes,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint) {
+ fDL->drawTextOnPath(text, bytes, path, matrix, paint);
+}
+void SkLiteRecorder::onDrawTextRSXform(const void* text, size_t bytes,
+ const SkRSXform xform[], const SkRect* cull,
+ const SkPaint& paint) {
+ fDL->drawTextRSXForm(text, bytes, xform, cull, paint);
+}
+void SkLiteRecorder::onDrawTextBlob(const SkTextBlob* blob,
+ SkScalar x, SkScalar y,
+ const SkPaint& paint) {
+ fDL->drawTextBlob(blob, x,y, paint);
+}
+
+void SkLiteRecorder::onDrawBitmap(const SkBitmap& bm,
+ SkScalar x, SkScalar y,
+ const SkPaint* paint) {
+ fDL->drawBitmap(bm, x,y, paint);
+}
+void SkLiteRecorder::onDrawBitmapNine(const SkBitmap& bm,
+ const SkIRect& center, const SkRect& dst,
+ const SkPaint* paint) {
+ fDL->drawBitmapNine(bm, center, dst, paint);
+}
+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);
+}
+
+void SkLiteRecorder::onDrawImage(const SkImage* img,
+ SkScalar x, SkScalar y,
+ const SkPaint* paint) {
+ fDL->drawImage(img, x,y, paint);
+}
+void SkLiteRecorder::onDrawImageNine(const SkImage* img,
+ const SkIRect& center, const SkRect& dst,
+ const SkPaint* paint) {
+ fDL->drawImageNine(img, center, dst, paint);
+}
+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);
+}
+void SkLiteRecorder::onDrawImageLattice(const SkImage* img,
+ const SkCanvas::Lattice& lattice, const SkRect& dst,
+ const SkPaint* paint) {
+ fDL->drawImageLattice(img, lattice, dst, paint);
+}
+
+
+void SkLiteRecorder::onDrawPatch(const SkPoint cubics[12],
+ const SkColor colors[4], const SkPoint texCoords[4],
+ SkXfermode* xfermode, const SkPaint& paint) {
+ fDL->drawPatch(cubics, colors, texCoords, xfermode, paint);
+}
+void SkLiteRecorder::onDrawPoints(SkCanvas::PointMode mode,
+ size_t count, const SkPoint pts[],
+ const SkPaint& paint) {
+ fDL->drawPoints(mode, count, pts, paint);
+}
+void SkLiteRecorder::onDrawVertices(SkCanvas::VertexMode mode,
+ int count, const SkPoint vertices[],
+ const SkPoint texs[], const SkColor colors[],
+ SkXfermode* xfermode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) {
+ fDL->drawVertices(mode, count, vertices, texs, colors, xfermode, indices, indexCount, paint);
+}
+void SkLiteRecorder::onDrawAtlas(const SkImage* atlas,
+ const SkRSXform xforms[],
+ const SkRect texs[],
+ const SkColor colors[],
+ int count,
+ SkXfermode::Mode xfermode,
+ const SkRect* cull,
+ const SkPaint* paint) {
+ fDL->drawAtlas(atlas, xforms, texs, colors, count, xfermode, cull, paint);
+}
+
+void SkLiteRecorder::didTranslateZ(SkScalar dz) {
+ fDL->translateZ(dz);
+}
+void SkLiteRecorder::onDrawShadowedPicture(const SkPicture* picture,
+ const SkMatrix* matrix,
+ const SkPaint* paint) {
+ fDL->drawShadowedPicture(picture, matrix, paint);
+}
diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h
new file mode 100644
index 0000000000..1a38c02fb0
--- /dev/null
+++ b/src/core/SkLiteRecorder.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkLiteRecorder_DEFINED
+#define SkLiteRecorder_DEFINED
+
+#include "SkCanvas.h"
+
+class SkLiteDL;
+
+class SkLiteRecorder final : public SkCanvas {
+public:
+ SkLiteRecorder();
+ void reset(SkLiteDL*);
+
+ sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
+
+ void willSave() override;
+ SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
+ void willRestore() override;
+
+ void didConcat(const SkMatrix&) override;
+ void didSetMatrix(const SkMatrix&) override;
+
+ void onClipRect (const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
+ void onClipRRect (const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
+ void onClipPath (const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
+ void onClipRegion(const SkRegion&, SkRegion::Op) override;
+
+ void onDrawPaint (const SkPaint&) override;
+ void onDrawPath (const SkPath&, const SkPaint&) override;
+ void onDrawRect (const SkRect&, const SkPaint&) override;
+ void onDrawOval (const SkRect&, const SkPaint&) override;
+ void onDrawRRect (const SkRRect&, const SkPaint&) override;
+ void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
+
+ void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
+ void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
+ void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
+
+ void onDrawText (const void*, size_t, SkScalar x, SkScalar y, const SkPaint&) override;
+ void onDrawPosText (const void*, size_t, const SkPoint[], const SkPaint&) override;
+ void onDrawPosTextH (const void*, size_t, const SkScalar[], SkScalar, const SkPaint&) override;
+ void onDrawTextOnPath(const void*, size_t,
+ const SkPath&, const SkMatrix*, const SkPaint&) override;
+ void onDrawTextRSXform(const void*, size_t,
+ const SkRSXform[], const SkRect*, const SkPaint&) override;
+ void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override;
+
+ void onDrawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint*) override;
+ void onDrawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect&, const SkPaint*) override;
+ void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
+ SrcRectConstraint) override;
+
+ void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
+ void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&, const SkPaint*) override;
+ void onDrawImageNine(const SkImage*, const SkIRect&, const SkRect&, const SkPaint*) override;
+ void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
+ SrcRectConstraint) override;
+
+ void onDrawPatch(const SkPoint[12], const SkColor[4],
+ const SkPoint[4], SkXfermode*, const SkPaint&) override;
+ void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
+ void onDrawVertices(VertexMode, int, const SkPoint[], const SkPoint[], const SkColor[],
+ SkXfermode*, const uint16_t[], int, const SkPaint&) override;
+ void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
+ int, SkXfermode::Mode, const SkRect*, const SkPaint*) override;
+
+#ifdef SK_EXPERIMENTAL_SHADOWING
+ void didTranslateZ(SkScalar) override;
+ void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
+#else
+ void didTranslateZ(SkScalar);
+ void onDrawShadowedPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
+#endif
+
+private:
+ SkLiteDL* fDL;
+};
+
+#endif//SkLiteRecorder_DEFINED
diff --git a/tests/SkLiteDLTest.cpp b/tests/SkLiteDLTest.cpp
new file mode 100644
index 0000000000..cb6ba98708
--- /dev/null
+++ b/tests/SkLiteDLTest.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Test.h"
+#include "SkLiteDL.h"
+#include "SkLiteRecorder.h"
+
+#if 0 // This test doesn't make sense when run in a threaded environment. It tests global state.
+DEF_TEST(SkLiteDL_freelisting, r) {
+ // TODO: byte and count limit tests
+ sk_sp<SkLiteDL> sp1 = SkLiteDL::New({1,1,10,10}),
+ sp2 = SkLiteDL::New({2,2,20,20});
+
+ SkLiteDL* p1 = sp1.get();
+ SkLiteDL* p2 = sp2.get();
+ REPORTER_ASSERT(r, p1 != p2);
+ REPORTER_ASSERT(r, p1->getBounds().left() == 1);
+ REPORTER_ASSERT(r, p2->getBounds().left() == 2);
+
+ sp2.reset();
+
+ sk_sp<SkLiteDL> sp3 = SkLiteDL::New({3,3,30,30});
+ SkLiteDL* p3 = sp3.get();
+ REPORTER_ASSERT(r, p1 != p3);
+ REPORTER_ASSERT(r, p2 == p3);
+ REPORTER_ASSERT(r, p1->getBounds().left() == 1);
+ REPORTER_ASSERT(r, p3->getBounds().left() == 3);
+
+ sp3.reset();
+ sp1.reset();
+
+ sk_sp<SkLiteDL> sp4 = SkLiteDL::New({4,4,40,40});
+ SkLiteDL* p4 = sp4.get();
+ REPORTER_ASSERT(r, p4 == p1); // Checks that we operate in stack order. Nice, not essential.
+ REPORTER_ASSERT(r, p4->getBounds().left() == 4);
+}
+#endif
+
+DEF_TEST(SkLiteDL_basics, r) {
+ sk_sp<SkLiteDL> p { SkLiteDL::New({2,2,3,3}) };
+
+ p->save();
+ p->clipRect(SkRect{2,3,4,5}, SkRegion::kIntersect_Op, true);
+ p->drawRect(SkRect{0,0,9,9}, SkPaint{});
+ p->restore();
+}
+
+DEF_TEST(SkLiteRecorder, r) {
+ sk_sp<SkLiteDL> p { SkLiteDL::New({2,2,3,3}) };
+
+ SkLiteRecorder rec;
+ SkCanvas* c = &rec;
+
+ rec.reset(p.get());
+
+ c->save();
+ c->clipRect(SkRect{2,3,4,5}, SkRegion::kIntersect_Op, true);
+ c->drawRect(SkRect{0,0,9,9}, SkPaint{});
+ c->restore();
+}