RecordOptsTest.cpp revision 2ff1fcede1e9525285c5de1f35fb2dcb0fab32bd
18dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org/*
28dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org * Copyright 2014 Google Inc.
38dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org *
48dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
58dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org * found in the LICENSE file.
68dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org */
78dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
88dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "Test.h"
90a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org#include "RecordTestUtils.h"
108dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
118dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecord.h"
128dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecordOpts.h"
138dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecorder.h"
148dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecords.h"
15f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org#include "SkXfermode.h"
16f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
178dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.orgstatic const int W = 1920, H = 1080;
188dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedDEF_TEST(RecordOpts_NoopDraw, r) {
20467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org    SkRecord record;
21a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
22467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
232ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.drawRect(SkRect::MakeWH(200, 200), SkPaint());
242ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.drawRect(SkRect::MakeWH(300, 300), SkPaint());
252ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.drawRect(SkRect::MakeWH(100, 100), SkPaint());
26467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
272ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    record.replace<SkRecords::NoOp>(1);  // NoOps should be allowed.
28467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
29467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org    SkRecordNoopSaveRestores(&record);
30467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 2 == count_instances_of_type<SkRecords::DrawRect>(record));
32467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org}
33467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
347066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.orgDEF_TEST(RecordOpts_SingleNoopSaveRestore, r) {
357066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    SkRecord record;
36a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
377066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org
387066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    recorder.save();
397066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org        recorder.clipRect(SkRect::MakeWH(200, 200));
407066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    recorder.restore();
417066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org
427066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    SkRecordNoopSaveRestores(&record);
437066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    for (unsigned i = 0; i < 3; i++) {
447066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, record, i);
457066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    }
467066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org}
477066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org
488dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.orgDEF_TEST(RecordOpts_NoopSaveRestores, r) {
498dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    SkRecord record;
50a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
518dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
528dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    // The second pass will clean up this pair after the first pass noops all the innards.
538dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    recorder.save();
548dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        // A simple pointless pair of save/restore.
558dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.save();
568dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.restore();
578dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
588dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        // As long as we don't draw in there, everything is a noop.
598dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.save();
608dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org            recorder.clipRect(SkRect::MakeWH(200, 200));
618dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org            recorder.clipRect(SkRect::MakeWH(100, 100));
628dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.restore();
638dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    recorder.restore();
648dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
658dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    SkRecordNoopSaveRestores(&record);
662ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    for (unsigned index = 0; index < record.count(); index++) {
677066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, record, index);
688dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    }
698dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org}
70f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
7199d6a9ee8b3516de892d118c71aa5e6e5c865efdmtkleinDEF_TEST(RecordOpts_SaveSaveLayerRestoreRestore, r) {
7299d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    SkRecord record;
7399d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    SkRecorder recorder(&record, W, H);
7499d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein
7599d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    // A previous bug NoOp'd away the first 3 commands.
7699d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    recorder.save();
7799d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein        recorder.saveLayer(NULL, NULL);
7899d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein        recorder.restore();
7999d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    recorder.restore();
8099d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein
8199d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    SkRecordNoopSaveRestores(&record);
822ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    switch (record.count()) {
832ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        case 4:
842ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Save>     (r, record, 0);
852ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::SaveLayer>(r, record, 1);
862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Restore>  (r, record, 2);
872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Restore>  (r, record, 3);
882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            break;
892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        case 2:
902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::SaveLayer>(r, record, 0);
912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Restore>  (r, record, 1);
922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            break;
932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        case 0:
942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            break;
952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        default:
962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            REPORTER_ASSERT(r, false);
972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    }
9899d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein}
9999d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein
100f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.orgstatic void assert_savelayer_restore(skiatest::Reporter* r,
101f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org                                     SkRecord* record,
102f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org                                     unsigned i,
103f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org                                     bool shouldBeNoOped) {
104f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRecordNoopSaveLayerDrawRestores(record);
105f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    if (shouldBeNoOped) {
106f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, *record, i);
107f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, *record, i+2);
108f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    } else {
109f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::SaveLayer>(r, *record, i);
110f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::Restore>(r, *record, i+2);
111f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    }
112f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org}
113f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
114f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.orgDEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) {
115f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRecord record;
116a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
117f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
118f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRect bounds = SkRect::MakeWH(100, 200);
119f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRect   draw = SkRect::MakeWH(50, 60);
120f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
121f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkPaint goodLayerPaint, badLayerPaint, worseLayerPaint;
122f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    goodLayerPaint.setColor(0x03000000);  // Only alpha.
123f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    badLayerPaint.setColor( 0x03040506);  // Not only alpha.
124f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    worseLayerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);  // Any effect will do.
125f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
126f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkPaint goodDrawPaint, badDrawPaint;
127f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    goodDrawPaint.setColor(0xFF020202);  // Opaque.
128f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    badDrawPaint.setColor( 0x0F020202);  // Not opaque.
129f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
130f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // No change: optimization can't handle bounds.
131f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.saveLayer(&bounds, NULL);
132f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        recorder.drawRect(draw, goodDrawPaint);
133f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
134f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    assert_savelayer_restore(r, &record, 0, false);
135f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
136f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // SaveLayer/Restore removed: no bounds + no paint = no point.
137f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.saveLayer(NULL, NULL);
138f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        recorder.drawRect(draw, goodDrawPaint);
139f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
140f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    assert_savelayer_restore(r, &record, 3, true);
141f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
142f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // TODO(mtklein): test case with null draw paint
143f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
144f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // No change: layer paint isn't alpha-only.
145f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.saveLayer(NULL, &badLayerPaint);
146f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        recorder.drawRect(draw, goodDrawPaint);
147f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
148f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    assert_savelayer_restore(r, &record, 6, false);
149f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
150f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // No change: layer paint has an effect.
151f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.saveLayer(NULL, &worseLayerPaint);
152f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        recorder.drawRect(draw, goodDrawPaint);
153f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
154f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    assert_savelayer_restore(r, &record, 9, false);
155f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
156f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // No change: draw paint isn't opaque.
157f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.saveLayer(NULL, &goodLayerPaint);
158f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        recorder.drawRect(draw, badDrawPaint);
159f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
160f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    assert_savelayer_restore(r, &record, 12, false);
161f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
162f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // SaveLayer/Restore removed: we can fold in the alpha!
163f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.saveLayer(NULL, &goodLayerPaint);
164f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        recorder.drawRect(draw, goodDrawPaint);
165f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
166f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    assert_savelayer_restore(r, &record, 15, true);
167f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
168f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, record, 16);
169f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    REPORTER_ASSERT(r, drawRect != NULL);
170f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    REPORTER_ASSERT(r, drawRect->paint.getColor() == 0x03020202);
171f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org}
172