diff options
author | mtklein <mtklein@chromium.org> | 2015-05-05 12:59:56 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-05 12:59:56 -0700 |
commit | d31c13d0441aecc8b2a4fa4f45fd5e59584cb3ea (patch) | |
tree | 9fcb7f63c559ed06dadd01268855b3603de6343d | |
parent | 14fe8fd3e53b5e988aac189a8bc3ed28904d85c8 (diff) |
DM: add a Via to simulate SP pictures.
Will use this to test the other CL that adds small SkPicture implementations.
Not quite sure why patch_primitive doesn't draw the same in 8888 and sp-8888, but everything else does, so I'm not going to let that hold me back for now.
BUG=skia:
Review URL: https://codereview.chromium.org/1126613005
-rw-r--r-- | dm/DM.cpp | 1 | ||||
-rw-r--r-- | dm/DMSrcSink.cpp | 67 | ||||
-rw-r--r-- | dm/DMSrcSink.h | 11 |
3 files changed, 79 insertions, 0 deletions
@@ -370,6 +370,7 @@ static Sink* create_via(const char* tag, Sink* wrapped) { VIA("serialize", ViaSerialization, wrapped); VIA("deferred", ViaDeferred, wrapped); VIA("2ndpic", ViaSecondPicture, wrapped); + VIA("sp", ViaSingletonPictures, 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 c5e039532b..4a3808ace5 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -20,6 +20,8 @@ #include "SkPictureData.h" #include "SkPictureRecorder.h" #include "SkRandom.h" +#include "SkRecordDraw.h" +#include "SkRecorder.h" #include "SkSVGCanvas.h" #include "SkScanlineDecoder.h" #include "SkStream.h" @@ -724,4 +726,69 @@ Error ViaSecondPicture::draw( }); } +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + +// This is like SkRecords::Draw, in that it plays back SkRecords ops into a Canvas. +// Unlike SkRecords::Draw, it builds a single-op sub-picture out of each Draw-type op. +// This is an only-slightly-exaggerated simluation of Blink's Slimming Paint pictures. +struct DrawsAsSingletonPictures { + SkCanvas* fCanvas; + + SK_CREATE_MEMBER_DETECTOR(paint); + + template <typename T> + void draw(const T& op, SkCanvas* canvas) { + // We must pass SkMatrix::I() as our initial matrix. + // By default SkRecords::Draw() uses the canvas' matrix as its initial matrix, + // which would have the funky effect of applying transforms over and over. + SkRecords::Draw(canvas, nullptr, nullptr, 0, &SkMatrix::I())(op); + } + + // Most things that have paints are Draw-type ops. Create sub-pictures for each. + template <typename T> + SK_WHEN(HasMember_paint<T>, void) operator()(const T& op) { + SkPictureRecorder rec; + this->draw(op, rec.beginRecording(SkRect::MakeLargest())); + SkAutoTUnref<SkPicture> pic(rec.endRecordingAsPicture()); + fCanvas->drawPicture(pic); + } + + // If you don't have a paint or are a SaveLayer, you're not a Draw-type op. + // We cannot make subpictures out of these because they affect state. Draw them directly. + template <typename T> + SK_WHEN(!HasMember_paint<T>, void) operator()(const T& op) { this->draw(op, fCanvas); } + void operator()(const SkRecords::SaveLayer& op) { this->draw(op, fCanvas); } +}; + +ViaSingletonPictures::ViaSingletonPictures(Sink* sink) : fSink(sink) {} + +// Record Src into a picture, then record it into a macro picture with a sub-picture for each draw. +// Then play back that macro picture into our wrapped sink. +Error ViaSingletonPictures::draw( + const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const { + auto size = src.size(); + return draw_to_canvas(fSink, bitmap, stream, log, size, [&](SkCanvas* canvas) -> Error { + // Use low-level (Skia-private) recording APIs so we can read the SkRecord. + SkRecord skr; + SkRecorder recorder(&skr, size.width(), size.height()); + Error err = src.draw(&recorder); + if (!err.isEmpty()) { + return err; + } + + // Record our macro-picture, with each draw op as its own sub-picture. + SkPictureRecorder macroRec; + SkCanvas* macroCanvas = macroRec.beginRecording(SkIntToScalar(size.width()), + SkIntToScalar(size.height())); + DrawsAsSingletonPictures drawsAsSingletonPictures = { macroCanvas }; + for (unsigned i = 0; i < skr.count(); i++) { + skr.visit<void>(i, drawsAsSingletonPictures); + } + SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); + + canvas->drawPicture(macroPic); + return ""; + }); +} + } // namespace DM diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index ea5572a7b9..0d612d0b93 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -295,6 +295,17 @@ private: SkAutoTDelete<Sink> fSink; }; +class ViaSingletonPictures : public Sink { +public: + explicit ViaSingletonPictures(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; +}; + } // namespace DM #endif//DMSrcSink_DEFINED |