diff options
-rw-r--r-- | dm/DM.cpp | 1 | ||||
-rw-r--r-- | dm/DMSrcSink.cpp | 36 | ||||
-rw-r--r-- | dm/DMSrcSink.h | 11 |
3 files changed, 48 insertions, 0 deletions
@@ -368,6 +368,7 @@ static Sink* create_via(const char* tag, Sink* wrapped) { #define VIA(t, via, ...) if (0 == strcmp(t, tag)) { return new via(__VA_ARGS__); } VIA("pipe", ViaPipe, wrapped); VIA("serialize", ViaSerialization, wrapped); + VIA("deferred", ViaDeferred, wrapped); VIA("2ndpic", ViaSecondPicture, wrapped); VIA("tiles", ViaTiles, 256, 256, NULL, wrapped); VIA("tiles_rt", ViaTiles, 256, 256, new SkRTreeFactory, wrapped); diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 9811f9e426..b33ba14b66 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -10,6 +10,7 @@ #include "SkCommonFlags.h" #include "SkCodec.h" #include "SkData.h" +#include "SkDeferredCanvas.h" #include "SkDocument.h" #include "SkError.h" #include "SkImageGenerator.h" @@ -590,6 +591,41 @@ Error ViaPipe::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStrin } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + +ViaDeferred::ViaDeferred(Sink* sink) : fSink(sink) {} + +Error ViaDeferred::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const { + // We turn ourselves into another Src that draws our argument into a deferred canvas, + // via a surface created by the original canvas. We then draw a snapped image from that + // surface back into the original canvas. + struct ProxySrc : public Src { + const Src& fSrc; + ProxySrc(const Src& src) : fSrc(src) {} + + Error draw(SkCanvas* canvas) const override { + SkAutoTUnref<SkSurface> surface(canvas->newSurface(canvas->imageInfo())); + if (!surface.get()) { + return "can't make surface for deferred canvas"; + } + SkAutoTDelete<SkDeferredCanvas> defcan(SkDeferredCanvas::Create(surface)); + Error err = fSrc.draw(defcan); + if (!err.isEmpty()) { + return err; + } + SkAutoTUnref<SkImage> image(defcan->newImageSnapshot()); + if (!image) { + return "failed to create deferred image snapshot"; + } + canvas->drawImage(image, 0, 0, NULL); + return ""; + } + SkISize size() const override { return fSrc.size(); } + Name name() const override { sk_throw(); return ""; } // No one should be calling this. + } proxy(src); + return fSink->draw(proxy, bitmap, stream, log); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ ViaSerialization::ViaSerialization(Sink* sink) : fSink(sink) {} diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index 0807cb6644..ea5572a7b9 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -249,6 +249,17 @@ private: SkAutoTDelete<Sink> fSink; }; +class ViaDeferred : public Sink { +public: + explicit ViaDeferred(Sink*); + + Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; + int enclave() const override { return fSink->enclave(); } + const char* fileExtension() const override { return fSink->fileExtension(); } +private: + SkAutoTDelete<Sink> fSink; +}; + class ViaSerialization : public Sink { public: explicit ViaSerialization(Sink*); |