Fix a bug in Save-Restore no-op optimization.

We optimize
    Save
        SaveLayer
        Restore
    Restore
into
    NoOp
        NoOp
        NoOp
    Restore

I'm considering skipping the call to SkRecordOptimize again just to eliminate
this extra variable from landing SkRecord.  Thoughts?

BUG=skia:
R=robertphillips@google.com, mtklein@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/560163002
This commit is contained in:
mtklein 2014-09-10 16:08:27 -07:00 committed by Commit bot
parent f91c47d91d
commit 99d6a9ee8b
3 changed files with 24 additions and 1 deletions

View File

@ -55,8 +55,10 @@ struct SaveOnlyDrawsRestoreNooper {
// Turns logical no-op Save-[non-drawing command]*-Restore patterns into actual no-ops.
struct SaveNoDrawsRestoreNooper {
// Star matches greedily, so we also have to exclude Save and Restore.
// Nested SaveLayers need to be excluded, or we'll match their Restore!
typedef Pattern3<Is<Save>,
Star<Not<Or3<Is<Save>,
Star<Not<Or4<Is<Save>,
Is<SaveLayer>,
Is<Restore>,
IsDraw> > >,
Is<Restore> >

View File

@ -85,6 +85,10 @@ struct Or {
template <typename A, typename B, typename C>
struct Or3 : Or<A, Or<B, C> > {};
// Matches if any of A, B, C or D does. Stores nothing.
template <typename A, typename B, typename C, typename D>
struct Or4 : Or<A, Or<B, Or<C, D> > > {};
// Star is a special matcher that greedily matches Matcher 0 or more times. Stores nothing.
template <typename Matcher>
struct Star {

View File

@ -99,6 +99,23 @@ DEF_TEST(RecordOpts_NoopSaveRestores, r) {
}
}
DEF_TEST(RecordOpts_SaveSaveLayerRestoreRestore, r) {
SkRecord record;
SkRecorder recorder(&record, W, H);
// A previous bug NoOp'd away the first 3 commands.
recorder.save();
recorder.saveLayer(NULL, NULL);
recorder.restore();
recorder.restore();
SkRecordNoopSaveRestores(&record);
assert_type<SkRecords::Save> (r, record, 0);
assert_type<SkRecords::SaveLayer>(r, record, 1);
assert_type<SkRecords::Restore> (r, record, 2);
assert_type<SkRecords::Restore> (r, record, 3);
}
static void assert_savelayer_restore(skiatest::Reporter* r,
SkRecord* record,
unsigned i,