diff options
author | mtklein <mtklein@chromium.org> | 2016-01-08 10:19:35 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-08 10:19:35 -0800 |
commit | 4a34ecbe352114bd8403b134eb72f6e63bec0b11 (patch) | |
tree | 1bf70e4fb1aaf0f446dba104220c678b26a00011 /dm | |
parent | de8dc7e9201a14759076ea4090bdf8a54791817b (diff) |
DM: more invariants
- add ViaPicture
- run ViaPicture on most bots
- run ViaSecondPicture (tests SkPictureRecorder reuse) and ViaTwice (tests caching) on some bots
- extend ViaSerialization reference checking to ViaPicture, ViaSecondPicture,
ViaSingletonPictures, and ViaTwice
- suppress current reference check failures with --blacklist
I'm open to following up on changing how those suppressions work.
Passing --nocheck turns off these invariant checks, letting us debug failures with normal image diff tools.
CQ_EXTRA_TRYBOTS=client.skia:Test-Win8-MSVC-ShuttleB-CPU-AVX2-x86_64-Release-Trybot
BUG=skia:4769
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1569823006
Review URL: https://codereview.chromium.org/1569823006
Diffstat (limited to 'dm')
-rw-r--r-- | dm/DM.cpp | 1 | ||||
-rw-r--r-- | dm/DMSrcSink.cpp | 74 | ||||
-rw-r--r-- | dm/DMSrcSink.h | 6 |
3 files changed, 59 insertions, 22 deletions
@@ -624,6 +624,7 @@ static Sink* create_via(const SkString& tag, Sink* wrapped) { #define VIA(t, via, ...) if (tag.equals(t)) { return new via(__VA_ARGS__); } VIA("twice", ViaTwice, wrapped); VIA("serialize", ViaSerialization, wrapped); + VIA("pic", ViaPicture, wrapped); VIA("2ndpic", ViaSecondPicture, wrapped); VIA("sp", ViaSingletonPictures, wrapped); VIA("tiles", ViaTiles, 256, 256, nullptr, wrapped); diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index aca86968c9..c9bdcf6706 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -1004,6 +1004,36 @@ static Error draw_to_canvas(Sink* sink, SkBitmap* bitmap, SkWStream* stream, SkS /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +DEFINE_bool(check, true, "If true, have most Via- modes fail if they affect the output."); + +// Is *bitmap identical to what you get drawing src into sink? +static Error check_against_reference(const SkBitmap* bitmap, const Src& src, Sink* sink) { + // We can only check raster outputs. + // (Non-raster outputs like .pdf, .skp, .svg may differ but still draw identically.) + if (FLAGS_check && bitmap) { + SkBitmap reference; + SkString log; + Error err = sink->draw(src, &reference, nullptr, &log); + // If we can draw into this Sink via some pipeline, we should be able to draw directly. + SkASSERT(err.isEmpty()); + if (!err.isEmpty()) { + return err; + } + // The dimensions are a property of the Src only, and so should be identical. + SkASSERT(reference.getSize() == bitmap->getSize()); + if (reference.getSize() != bitmap->getSize()) { + return "Dimensions don't match reference"; + } + // All SkBitmaps in DM are pre-locked and tight, so this comparison is easy. + if (0 != memcmp(reference.getPixels(), bitmap->getPixels(), reference.getSize())) { + return "Pixels don't match reference"; + } + } + return ""; +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + static SkISize auto_compute_translate(SkMatrix* matrix, int srcW, int srcH) { SkRect bounds = SkRect::MakeIWH(srcW, srcH); matrix->mapRect(&bounds); @@ -1073,15 +1103,6 @@ Error ViaRemote::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStr Error ViaSerialization::draw( const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const { - // Draw the Src directly as a reference. - SkBitmap reference; - if (bitmap) { - Error err = fSink->draw(src, &reference, nullptr, log); - if (!err.isEmpty()) { - return err; - } - } - // Record our Src into a picture. auto size = src.size(); SkPictureRecorder recorder; @@ -1100,16 +1121,7 @@ Error ViaSerialization::draw( return draw_to_canvas(fSink, bitmap, stream, log, size, [&](SkCanvas* canvas) { canvas->drawPicture(deserialized); - // Check against the reference if we have one. - if (bitmap) { - if (reference.getSize() != bitmap->getSize()) { - return "Serialized and direct have different dimensions."; - } - if (0 != memcmp(reference.getPixels(), bitmap->getPixels(), reference.getSize())) { - return "Serialized and direct have different pixels."; - } - } - return ""; + return check_against_reference(bitmap, src, fSink); }); } @@ -1169,6 +1181,24 @@ Error ViaTiles::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStri /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +Error ViaPicture::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 { + SkPictureRecorder recorder; + SkAutoTUnref<SkPicture> pic; + Error err = src.draw(recorder.beginRecording(SkIntToScalar(size.width()), + SkIntToScalar(size.height()))); + if (!err.isEmpty()) { + return err; + } + pic.reset(recorder.endRecordingAsPicture()); + canvas->drawPicture(pic); + return check_against_reference(bitmap, src, fSink); + }); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Draw the Src into two pictures, then draw the second picture into the wrapped Sink. // This tests that any shortcuts we may take while recording that second picture are legal. Error ViaSecondPicture::draw( @@ -1186,7 +1216,7 @@ Error ViaSecondPicture::draw( pic.reset(recorder.endRecordingAsPicture()); } canvas->drawPicture(pic); - return ""; + return check_against_reference(bitmap, src, fSink); }); } @@ -1203,7 +1233,7 @@ Error ViaTwice::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStri return err; } } - return ""; + return check_against_reference(bitmap, src, fSink); }); } @@ -1273,7 +1303,7 @@ Error ViaSingletonPictures::draw( SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); canvas->drawPicture(macroPic); - return ""; + return check_against_reference(bitmap, src, fSink); }); } diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index 4251808d6d..6645807286 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -329,6 +329,12 @@ public: Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; }; +class ViaPicture : public Via { +public: + explicit ViaPicture(Sink* sink) : Via(sink) {} + Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; +}; + class ViaTiles : public Via { public: ViaTiles(int w, int h, SkBBHFactory*, Sink*); |