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
1105a429614ec3206f9d2b7c145cbda0b5a442b6d0Yuqian Li#include "SkBlurImageFilter.h"
12dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen#include "SkColorFilter.h"
138dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecord.h"
148dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecordOpts.h"
158dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecorder.h"
168dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecords.h"
17dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen#include "SkPictureRecorder.h"
18dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen#include "SkPictureImageFilter.h"
195a3c528f5661a0d5843ecab9567c40c96a9d881ereed#include "SkSurface.h"
20f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
218dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.orgstatic const int W = 1920, H = 1080;
228dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
232ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedDEF_TEST(RecordOpts_NoopDraw, r) {
24467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org    SkRecord record;
25a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
26467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
272ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.drawRect(SkRect::MakeWH(200, 200), SkPaint());
282ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.drawRect(SkRect::MakeWH(300, 300), SkPaint());
292ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.drawRect(SkRect::MakeWH(100, 100), SkPaint());
30467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    record.replace<SkRecords::NoOp>(1);  // NoOps should be allowed.
32467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
33467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org    SkRecordNoopSaveRestores(&record);
34467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 2 == count_instances_of_type<SkRecords::DrawRect>(record));
36467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org}
37467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
387066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.orgDEF_TEST(RecordOpts_SingleNoopSaveRestore, r) {
397066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    SkRecord record;
40a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
417066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org
427066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    recorder.save();
437066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org        recorder.clipRect(SkRect::MakeWH(200, 200));
447066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    recorder.restore();
457066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org
467066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    SkRecordNoopSaveRestores(&record);
47c6ad06acefa096716f8dabed5342f9b89dc43dfemtklein    for (int i = 0; i < 3; i++) {
487066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, record, i);
497066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    }
507066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org}
517066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org
528dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.orgDEF_TEST(RecordOpts_NoopSaveRestores, r) {
538dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    SkRecord record;
54a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
558dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
568dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    // The second pass will clean up this pair after the first pass noops all the innards.
578dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    recorder.save();
588dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        // A simple pointless pair of save/restore.
598dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.save();
608dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.restore();
618dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
628dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        // As long as we don't draw in there, everything is a noop.
638dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.save();
648dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org            recorder.clipRect(SkRect::MakeWH(200, 200));
658dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org            recorder.clipRect(SkRect::MakeWH(100, 100));
668dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.restore();
678dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    recorder.restore();
688dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
698dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    SkRecordNoopSaveRestores(&record);
70c6ad06acefa096716f8dabed5342f9b89dc43dfemtklein    for (int index = 0; index < record.count(); index++) {
717066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, record, index);
728dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    }
738dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org}
74f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
7599d6a9ee8b3516de892d118c71aa5e6e5c865efdmtkleinDEF_TEST(RecordOpts_SaveSaveLayerRestoreRestore, r) {
7699d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    SkRecord record;
7799d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    SkRecorder recorder(&record, W, H);
7899d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein
7999d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    // A previous bug NoOp'd away the first 3 commands.
8099d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    recorder.save();
8196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        recorder.saveLayer(nullptr, nullptr);
8299d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein        recorder.restore();
8399d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    recorder.restore();
8499d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein
8599d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    SkRecordNoopSaveRestores(&record);
862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    switch (record.count()) {
872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        case 4:
882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Save>     (r, record, 0);
892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::SaveLayer>(r, record, 1);
902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Restore>  (r, record, 2);
912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Restore>  (r, record, 3);
922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            break;
932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        case 2:
942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::SaveLayer>(r, record, 0);
952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Restore>  (r, record, 1);
962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            break;
972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        case 0:
982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            break;
992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        default:
1002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            REPORTER_ASSERT(r, false);
1012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    }
10299d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein}
10399d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein
10405a429614ec3206f9d2b7c145cbda0b5a442b6d0Yuqian Li#ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
105f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.orgstatic void assert_savelayer_restore(skiatest::Reporter* r,
106f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org                                     SkRecord* record,
107c6ad06acefa096716f8dabed5342f9b89dc43dfemtklein                                     int i,
108f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org                                     bool shouldBeNoOped) {
109f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRecordNoopSaveLayerDrawRestores(record);
110f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    if (shouldBeNoOped) {
111f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, *record, i);
112bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed        assert_type<SkRecords::NoOp>(r, *record, i+1);
113bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    } else {
114bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed        assert_type<SkRecords::SaveLayer>(r, *record, i);
115bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed        assert_type<SkRecords::Restore>(r, *record, i+1);
116bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    }
117bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed}
118bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed
119bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areedstatic void assert_savelayer_draw_restore(skiatest::Reporter* r,
120bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                          SkRecord* record,
121bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                          int i,
122bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                          bool shouldBeNoOped) {
123bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    SkRecordNoopSaveLayerDrawRestores(record);
124bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    if (shouldBeNoOped) {
125bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed        assert_type<SkRecords::NoOp>(r, *record, i);
126f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, *record, i+2);
127f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    } else {
128f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::SaveLayer>(r, *record, i);
129f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::Restore>(r, *record, i+2);
130f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    }
131f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org}
132f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
133f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.orgDEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) {
134f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRecord record;
135a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
136f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
137f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRect bounds = SkRect::MakeWH(100, 200);
138f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRect   draw = SkRect::MakeWH(50, 60);
139f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
140678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    SkPaint alphaOnlyLayerPaint, translucentLayerPaint, xfermodeLayerPaint;
141678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    alphaOnlyLayerPaint.setColor(0x03000000);  // Only alpha.
142678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    translucentLayerPaint.setColor(0x03040506);  // Not only alpha.
143374772bd61951f01bf84fe17bf53d8867681c9aereed    xfermodeLayerPaint.setBlendMode(SkBlendMode::kDstIn);  // Any effect will do.
144f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
145678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    SkPaint opaqueDrawPaint, translucentDrawPaint;
146678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    opaqueDrawPaint.setColor(0xFF020202);  // Opaque.
147678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    translucentDrawPaint.setColor(0x0F020202);  // Not opaque.
148f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
1490c278972d06882f21dda07e17d6e7457f590ea69mtklein    // SaveLayer/Restore removed: No paint = no point.
15096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    recorder.saveLayer(nullptr, nullptr);
151678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, opaqueDrawPaint);
152f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
153bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    assert_savelayer_draw_restore(r, &record, 0, true);
154f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
1550c278972d06882f21dda07e17d6e7457f590ea69mtklein    // Bounds don't matter.
15696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    recorder.saveLayer(&bounds, nullptr);
157678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, opaqueDrawPaint);
158f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
159bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    assert_savelayer_draw_restore(r, &record, 3, true);
160f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
161f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // TODO(mtklein): test case with null draw paint
162f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
163f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // No change: layer paint isn't alpha-only.
16496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    recorder.saveLayer(nullptr, &translucentLayerPaint);
165678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, opaqueDrawPaint);
166f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
167bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    assert_savelayer_draw_restore(r, &record, 6, false);
168f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
169f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // No change: layer paint has an effect.
17096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    recorder.saveLayer(nullptr, &xfermodeLayerPaint);
171678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, opaqueDrawPaint);
172f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
173bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    assert_savelayer_draw_restore(r, &record, 9, false);
174f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
175678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    // SaveLayer/Restore removed: we can fold in the alpha!
17696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    recorder.saveLayer(nullptr, &alphaOnlyLayerPaint);
177678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, translucentDrawPaint);
178f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
179bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    assert_savelayer_draw_restore(r, &record, 12, true);
180f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
181f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // SaveLayer/Restore removed: we can fold in the alpha!
18296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    recorder.saveLayer(nullptr, &alphaOnlyLayerPaint);
183678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, opaqueDrawPaint);
184f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
185bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    assert_savelayer_draw_restore(r, &record, 15, true);
186f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
187f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, record, 16);
18896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    REPORTER_ASSERT(r, drawRect != nullptr);
189f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    REPORTER_ASSERT(r, drawRect->paint.getColor() == 0x03020202);
190bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed
191bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    // saveLayer w/ backdrop should NOT go away
1926e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips    sk_sp<SkImageFilter> filter(SkBlurImageFilter::Make(3, 3, nullptr));
19353f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita    recorder.saveLayer({ nullptr, nullptr, filter.get(), nullptr, nullptr, 0});
194bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed        recorder.drawRect(draw, opaqueDrawPaint);
195bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    recorder.restore();
196bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed    assert_savelayer_draw_restore(r, &record, 18, false);
19753f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita
19853f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita    // saveLayer w/ clip mask should also NOT go away
19953f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita    {
20053f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita        sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(10, 10));
201b34ab04884f6219b93c1f143c83a1fc60fded40cMike Klein        recorder.saveLayer({ nullptr, nullptr, nullptr, surface->makeImageSnapshot().get(),
202b34ab04884f6219b93c1f143c83a1fc60fded40cMike Klein                             nullptr, 0});
20353f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita            recorder.drawRect(draw, opaqueDrawPaint);
20453f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita        recorder.restore();
20553f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita        assert_savelayer_draw_restore(r, &record, 21, false);
20653f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita    }
207f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org}
20805a429614ec3206f9d2b7c145cbda0b5a442b6d0Yuqian Li#endif
209dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
210dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunenstatic void assert_merge_svg_opacity_and_filter_layers(skiatest::Reporter* r,
211dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                                                       SkRecord* record,
212c6ad06acefa096716f8dabed5342f9b89dc43dfemtklein                                                       int i,
213dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                                                       bool shouldBeNoOped) {
214dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRecordMergeSvgOpacityAndFilterLayers(record);
215dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    if (shouldBeNoOped) {
216dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        assert_type<SkRecords::NoOp>(r, *record, i);
217dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        assert_type<SkRecords::NoOp>(r, *record, i + 6);
218dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    } else {
219dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        assert_type<SkRecords::SaveLayer>(r, *record, i);
220dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        assert_type<SkRecords::Restore>(r, *record, i + 6);
221dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    }
222dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen}
223dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
224dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunenDEF_TEST(RecordOpts_MergeSvgOpacityAndFilterLayers, r) {
225dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRecord record;
226dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRecorder recorder(&record, W, H);
227dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
228dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRect bounds = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(200));
229dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRect clip = SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(60));
230dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
231dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint alphaOnlyLayerPaint;
232dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    alphaOnlyLayerPaint.setColor(0x03000000);  // Only alpha.
233dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint translucentLayerPaint;
234dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    translucentLayerPaint.setColor(0x03040506);  // Not only alpha.
235dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint xfermodePaint;
236374772bd61951f01bf84fe17bf53d8867681c9aereed    xfermodePaint.setBlendMode(SkBlendMode::kDstIn);
237dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint colorFilterPaint;
238dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    colorFilterPaint.setColorFilter(
239374772bd61951f01bf84fe17bf53d8867681c9aereed        SkColorFilter::MakeModeFilter(SK_ColorLTGRAY, SkBlendMode::kSrcIn));
240dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
241dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint opaqueFilterLayerPaint;
242dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    opaqueFilterLayerPaint.setColor(0xFF020202);  // Opaque.
243dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint translucentFilterLayerPaint;
244dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    translucentFilterLayerPaint.setColor(0x0F020202);  // Not opaque.
245ca2622ba051829fed5f30facd74c5b41cd4b931creed    sk_sp<SkPicture> shape;
246dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    {
247dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPictureRecorder recorder;
248dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(100), SkIntToScalar(100));
249dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPaint shapePaint;
250dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        shapePaint.setColor(SK_ColorWHITE);
251dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        canvas->drawRect(SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(50)), shapePaint);
252ca2622ba051829fed5f30facd74c5b41cd4b931creed        shape = recorder.finishRecordingAsPicture();
253dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    }
2545ff17b13524eea03e4b672ee3b3a49b649dd09fbrobertphillips    translucentFilterLayerPaint.setImageFilter(SkPictureImageFilter::Make(shape));
255dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
256dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    int index = 0;
257dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
258dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    {
2596e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips        sk_sp<SkImageFilter> filter(SkBlurImageFilter::Make(3, 3, nullptr));
260bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed        // first (null) should be optimized, 2nd should not
261bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed        SkImageFilter* filters[] = { nullptr, filter.get() };
262bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed
263dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // Any combination of these should cause the pattern to be optimized.
26496fcdcc219d2a0d3579719b84b28bede76efba64halcanary        SkRect* firstBounds[] = { nullptr, &bounds };
26596fcdcc219d2a0d3579719b84b28bede76efba64halcanary        SkPaint* firstPaints[] = { nullptr, &alphaOnlyLayerPaint };
26696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        SkRect* secondBounds[] = { nullptr, &bounds };
267dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPaint* secondPaints[] = { &opaqueFilterLayerPaint, &translucentFilterLayerPaint };
268dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
269bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed        for (auto outerF : filters) {
270bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed            bool outerNoOped = !outerF;
271bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed            for (auto innerF : filters) {
272bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                for (size_t i = 0; i < SK_ARRAY_COUNT(firstBounds); ++ i) {
273bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                    for (size_t j = 0; j < SK_ARRAY_COUNT(firstPaints); ++j) {
274bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                        for (size_t k = 0; k < SK_ARRAY_COUNT(secondBounds); ++k) {
275bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                            for (size_t m = 0; m < SK_ARRAY_COUNT(secondPaints); ++m) {
276bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                bool innerNoOped = !secondBounds[k] && !secondPaints[m] && !innerF;
277bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed
27853f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita                                recorder.saveLayer({firstBounds[i], firstPaints[j], outerF,
27953f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita                                                    nullptr, nullptr, 0});
280bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                recorder.save();
281bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                recorder.clipRect(clip);
28253f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita                                recorder.saveLayer({secondBounds[k], secondPaints[m], innerF,
28353f77bd4fdd76525b66b7f26d1c5c550858120dfFlorin Malita                                                    nullptr, nullptr, 0});
284bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                recorder.restore();
285bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                recorder.restore();
286bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                recorder.restore();
287bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                assert_merge_svg_opacity_and_filter_layers(r, &record, index,
288bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                                                           outerNoOped);
289f3b16d01e36574d1a0ddf73975a5f72963727aa4Mike Klein                            #ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
290bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                assert_savelayer_restore(r, &record, index + 3, innerNoOped);
291f3b16d01e36574d1a0ddf73975a5f72963727aa4Mike Klein                            #endif
292bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                                index += 7;
293bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                            }
294bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed                        }
295dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                    }
296dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                }
297dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen            }
298dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        }
299dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    }
300dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
301dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    // These should cause the pattern to stay unoptimized:
302dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    struct {
303dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPaint* firstPaint;
304dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPaint* secondPaint;
305dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    } noChangeTests[] = {
30696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        // No change: nullptr filter layer paint not implemented.
30796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        { &alphaOnlyLayerPaint, nullptr },
308dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: layer paint is not alpha-only.
309dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &translucentLayerPaint, &opaqueFilterLayerPaint },
310dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: layer paint has an xfereffect.
311dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &xfermodePaint, &opaqueFilterLayerPaint },
312dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: filter layer paint has an xfereffect.
313dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &alphaOnlyLayerPaint, &xfermodePaint },
314dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: layer paint has a color filter.
315dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &colorFilterPaint, &opaqueFilterLayerPaint },
316dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: filter layer paint has a color filter (until the optimization accounts for
317dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // constant color draws that can filter the color).
318dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &alphaOnlyLayerPaint, &colorFilterPaint }
319dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    };
320dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
321dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    for (size_t i = 0; i < SK_ARRAY_COUNT(noChangeTests); ++i) {
32296fcdcc219d2a0d3579719b84b28bede76efba64halcanary        recorder.saveLayer(nullptr, noChangeTests[i].firstPaint);
323dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.save();
324dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.clipRect(clip);
32596fcdcc219d2a0d3579719b84b28bede76efba64halcanary        recorder.saveLayer(nullptr, noChangeTests[i].secondPaint);
326dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.restore();
327dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.restore();
328dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.restore();
329dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        assert_merge_svg_opacity_and_filter_layers(r, &record, index, false);
330dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        index += 7;
331dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    }
332dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
333dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    // Test the folded alpha value.
33496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    recorder.saveLayer(nullptr, &alphaOnlyLayerPaint);
335dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.save();
336dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.clipRect(clip);
33796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    recorder.saveLayer(nullptr, &opaqueFilterLayerPaint);
338dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.restore();
339dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.restore();
340dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.restore();
341dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    assert_merge_svg_opacity_and_filter_layers(r, &record, index, true);
342dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
343dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    const SkRecords::SaveLayer* saveLayer = assert_type<SkRecords::SaveLayer>(r, record, index + 3);
34496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    REPORTER_ASSERT(r, saveLayer != nullptr);
345dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    REPORTER_ASSERT(r, saveLayer->paint->getColor() == 0x03020202);
346dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
347dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    index += 7;
348dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
349dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    // Test that currently we do not fold alphas for patterns without the clip. This is just not
350dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    // implemented.
35196fcdcc219d2a0d3579719b84b28bede76efba64halcanary    recorder.saveLayer(nullptr, &alphaOnlyLayerPaint);
35296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    recorder.saveLayer(nullptr, &opaqueFilterLayerPaint);
353dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.restore();
354dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.restore();
355dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRecordMergeSvgOpacityAndFilterLayers(&record);
356dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    assert_type<SkRecords::SaveLayer>(r, record, index);
357dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    assert_type<SkRecords::SaveLayer>(r, record, index + 1);
358dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    assert_type<SkRecords::Restore>(r, record, index + 2);
359dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    assert_type<SkRecords::Restore>(r, record, index + 3);
360dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    index += 4;
361dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen}
3625a3c528f5661a0d5843ecab9567c40c96a9d881ereed
3635a3c528f5661a0d5843ecab9567c40c96a9d881ereedstatic void do_draw(SkCanvas* canvas, SkColor color, bool doLayer) {
3645a3c528f5661a0d5843ecab9567c40c96a9d881ereed    canvas->drawColor(SK_ColorWHITE);
3655a3c528f5661a0d5843ecab9567c40c96a9d881ereed
3665a3c528f5661a0d5843ecab9567c40c96a9d881ereed    SkPaint p;
3675a3c528f5661a0d5843ecab9567c40c96a9d881ereed    p.setColor(color);
3685a3c528f5661a0d5843ecab9567c40c96a9d881ereed
3695a3c528f5661a0d5843ecab9567c40c96a9d881ereed    if (doLayer) {
3705a3c528f5661a0d5843ecab9567c40c96a9d881ereed        canvas->saveLayer(nullptr, nullptr);
371374772bd61951f01bf84fe17bf53d8867681c9aereed        p.setBlendMode(SkBlendMode::kSrc);
3725a3c528f5661a0d5843ecab9567c40c96a9d881ereed        canvas->drawPaint(p);
3735a3c528f5661a0d5843ecab9567c40c96a9d881ereed        canvas->restore();
3745a3c528f5661a0d5843ecab9567c40c96a9d881ereed    } else {
3755a3c528f5661a0d5843ecab9567c40c96a9d881ereed        canvas->drawPaint(p);
3765a3c528f5661a0d5843ecab9567c40c96a9d881ereed    }
3775a3c528f5661a0d5843ecab9567c40c96a9d881ereed}
3785a3c528f5661a0d5843ecab9567c40c96a9d881ereed
3795a3c528f5661a0d5843ecab9567c40c96a9d881ereedstatic bool is_equal(SkSurface* a, SkSurface* b) {
3805a3c528f5661a0d5843ecab9567c40c96a9d881ereed    const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
3815a3c528f5661a0d5843ecab9567c40c96a9d881ereed    SkPMColor ca, cb;
3825a3c528f5661a0d5843ecab9567c40c96a9d881ereed    a->readPixels(info, &ca, sizeof(SkPMColor), 0, 0);
3835a3c528f5661a0d5843ecab9567c40c96a9d881ereed    b->readPixels(info, &cb, sizeof(SkPMColor), 0, 0);
3845a3c528f5661a0d5843ecab9567c40c96a9d881ereed    return ca == cb;
3855a3c528f5661a0d5843ecab9567c40c96a9d881ereed}
3865a3c528f5661a0d5843ecab9567c40c96a9d881ereed
3875a3c528f5661a0d5843ecab9567c40c96a9d881ereed// Test drawing w/ and w/o a simple layer (no bounds or paint), so see that drawing ops
3885a3c528f5661a0d5843ecab9567c40c96a9d881ereed// that *should* draw the same in fact do.
3895a3c528f5661a0d5843ecab9567c40c96a9d881ereed//
3905a3c528f5661a0d5843ecab9567c40c96a9d881ereed// Perform this test twice : once directly, and once via a picture
3915a3c528f5661a0d5843ecab9567c40c96a9d881ereed//
3925a3c528f5661a0d5843ecab9567c40c96a9d881ereedstatic void do_savelayer_srcmode(skiatest::Reporter* r, SkColor color) {
3935a3c528f5661a0d5843ecab9567c40c96a9d881ereed    for (int doPicture = 0; doPicture <= 1; ++doPicture) {
3945a3c528f5661a0d5843ecab9567c40c96a9d881ereed        sk_sp<SkSurface> surf0 = SkSurface::MakeRasterN32Premul(10, 10);
3955a3c528f5661a0d5843ecab9567c40c96a9d881ereed        sk_sp<SkSurface> surf1 = SkSurface::MakeRasterN32Premul(10, 10);
3965a3c528f5661a0d5843ecab9567c40c96a9d881ereed        SkCanvas* c0 = surf0->getCanvas();
3975a3c528f5661a0d5843ecab9567c40c96a9d881ereed        SkCanvas* c1 = surf1->getCanvas();
3985a3c528f5661a0d5843ecab9567c40c96a9d881ereed
3995a3c528f5661a0d5843ecab9567c40c96a9d881ereed        SkPictureRecorder rec0, rec1;
4005a3c528f5661a0d5843ecab9567c40c96a9d881ereed        if (doPicture) {
4015a3c528f5661a0d5843ecab9567c40c96a9d881ereed            c0 = rec0.beginRecording(10, 10);
4025a3c528f5661a0d5843ecab9567c40c96a9d881ereed            c1 = rec1.beginRecording(10, 10);
4035a3c528f5661a0d5843ecab9567c40c96a9d881ereed        }
4045a3c528f5661a0d5843ecab9567c40c96a9d881ereed
4055a3c528f5661a0d5843ecab9567c40c96a9d881ereed        do_draw(c0, color, false);
4065a3c528f5661a0d5843ecab9567c40c96a9d881ereed        do_draw(c1, color, true);
4075a3c528f5661a0d5843ecab9567c40c96a9d881ereed
4085a3c528f5661a0d5843ecab9567c40c96a9d881ereed        if (doPicture) {
4095a3c528f5661a0d5843ecab9567c40c96a9d881ereed            surf0->getCanvas()->drawPicture(rec0.finishRecordingAsPicture());
4105a3c528f5661a0d5843ecab9567c40c96a9d881ereed            surf1->getCanvas()->drawPicture(rec1.finishRecordingAsPicture());
4115a3c528f5661a0d5843ecab9567c40c96a9d881ereed        }
4125a3c528f5661a0d5843ecab9567c40c96a9d881ereed
4135a3c528f5661a0d5843ecab9567c40c96a9d881ereed        // we replicate the assert so we can see which line is reported if there is a failure
4145a3c528f5661a0d5843ecab9567c40c96a9d881ereed        if (doPicture) {
4155a3c528f5661a0d5843ecab9567c40c96a9d881ereed            REPORTER_ASSERT(r, is_equal(surf0.get(), surf1.get()));
4165a3c528f5661a0d5843ecab9567c40c96a9d881ereed        } else {
4175a3c528f5661a0d5843ecab9567c40c96a9d881ereed            REPORTER_ASSERT(r, is_equal(surf0.get(), surf1.get()));
4185a3c528f5661a0d5843ecab9567c40c96a9d881ereed        }
4195a3c528f5661a0d5843ecab9567c40c96a9d881ereed    }
4205a3c528f5661a0d5843ecab9567c40c96a9d881ereed}
4215a3c528f5661a0d5843ecab9567c40c96a9d881ereed
4225a3c528f5661a0d5843ecab9567c40c96a9d881ereedDEF_TEST(savelayer_srcmode_opaque, r) {
4235a3c528f5661a0d5843ecab9567c40c96a9d881ereed    do_savelayer_srcmode(r, SK_ColorRED);
4245a3c528f5661a0d5843ecab9567c40c96a9d881ereed}
4255a3c528f5661a0d5843ecab9567c40c96a9d881ereed
4265a3c528f5661a0d5843ecab9567c40c96a9d881ereedDEF_TEST(savelayer_srcmode_alpha, r) {
4275a3c528f5661a0d5843ecab9567c40c96a9d881ereed    do_savelayer_srcmode(r, 0x80FF0000);
4285a3c528f5661a0d5843ecab9567c40c96a9d881ereed}
4295a3c528f5661a0d5843ecab9567c40c96a9d881ereed
430