diff options
-rw-r--r-- | bench/PictureOverheadBench.cpp | 45 | ||||
-rw-r--r-- | dm/DM.cpp | 1 | ||||
-rw-r--r-- | dm/DMSrcSink.cpp | 22 | ||||
-rw-r--r-- | dm/DMSrcSink.h | 6 | ||||
-rw-r--r-- | gyp/core.gypi | 2 | ||||
-rw-r--r-- | include/core/SkCanvas.h | 1 | ||||
-rw-r--r-- | include/core/SkRefCnt.h | 7 | ||||
-rw-r--r-- | src/core/SkLiteDL.cpp | 150 | ||||
-rw-r--r-- | src/core/SkLiteDL.h | 86 | ||||
-rw-r--r-- | src/core/SkLiteRecorder.cpp | 188 | ||||
-rw-r--r-- | src/core/SkLiteRecorder.h | 85 | ||||
-rw-r--r-- | tests/SkLiteDLTest.cpp | 64 |
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>);) @@ -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(); +} |