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
11dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen#include "SkColorFilter.h"
128dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecord.h"
138dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecordOpts.h"
148dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecorder.h"
158dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecords.h"
16f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org#include "SkXfermode.h"
17dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen#include "SkPictureRecorder.h"
18dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen#include "SkPictureImageFilter.h"
19f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
208dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.orgstatic const int W = 1920, H = 1080;
218dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
222ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedDEF_TEST(RecordOpts_NoopDraw, r) {
23467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org    SkRecord record;
24a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
25467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
262ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.drawRect(SkRect::MakeWH(200, 200), SkPaint());
272ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.drawRect(SkRect::MakeWH(300, 300), SkPaint());
282ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    recorder.drawRect(SkRect::MakeWH(100, 100), SkPaint());
29467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
302ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    record.replace<SkRecords::NoOp>(1);  // NoOps should be allowed.
31467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
32467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org    SkRecordNoopSaveRestores(&record);
33467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    REPORTER_ASSERT(r, 2 == count_instances_of_type<SkRecords::DrawRect>(record));
35467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org}
36467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org
377066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.orgDEF_TEST(RecordOpts_SingleNoopSaveRestore, r) {
387066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    SkRecord record;
39a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
407066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org
417066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    recorder.save();
427066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org        recorder.clipRect(SkRect::MakeWH(200, 200));
437066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    recorder.restore();
447066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org
457066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    SkRecordNoopSaveRestores(&record);
467066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    for (unsigned i = 0; i < 3; i++) {
477066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, record, i);
487066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org    }
497066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org}
507066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org
518dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.orgDEF_TEST(RecordOpts_NoopSaveRestores, r) {
528dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    SkRecord record;
53a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
548dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
558dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    // The second pass will clean up this pair after the first pass noops all the innards.
568dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    recorder.save();
578dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        // A simple pointless pair of save/restore.
588dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.save();
598dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.restore();
608dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
618dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        // As long as we don't draw in there, everything is a noop.
628dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.save();
638dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org            recorder.clipRect(SkRect::MakeWH(200, 200));
648dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org            recorder.clipRect(SkRect::MakeWH(100, 100));
658dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org        recorder.restore();
668dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    recorder.restore();
678dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org
688dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    SkRecordNoopSaveRestores(&record);
692ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    for (unsigned index = 0; index < record.count(); index++) {
707066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, record, index);
718dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org    }
728dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org}
73f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
7499d6a9ee8b3516de892d118c71aa5e6e5c865efdmtkleinDEF_TEST(RecordOpts_SaveSaveLayerRestoreRestore, r) {
7599d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    SkRecord record;
7699d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    SkRecorder recorder(&record, W, H);
7799d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein
7899d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    // A previous bug NoOp'd away the first 3 commands.
7999d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    recorder.save();
8099d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein        recorder.saveLayer(NULL, NULL);
8199d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein        recorder.restore();
8299d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    recorder.restore();
8399d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein
8499d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein    SkRecordNoopSaveRestores(&record);
852ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    switch (record.count()) {
862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        case 4:
872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Save>     (r, record, 0);
882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::SaveLayer>(r, record, 1);
892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Restore>  (r, record, 2);
902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Restore>  (r, record, 3);
912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            break;
922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        case 2:
932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::SaveLayer>(r, record, 0);
942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            assert_type<SkRecords::Restore>  (r, record, 1);
952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            break;
962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        case 0:
972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            break;
982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed        default:
992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed            REPORTER_ASSERT(r, false);
1002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed    }
10199d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein}
10299d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein
103f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.orgstatic void assert_savelayer_restore(skiatest::Reporter* r,
104f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org                                     SkRecord* record,
105f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org                                     unsigned i,
106f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org                                     bool shouldBeNoOped) {
107f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRecordNoopSaveLayerDrawRestores(record);
108f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    if (shouldBeNoOped) {
109f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, *record, i);
110f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::NoOp>(r, *record, i+2);
111f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    } else {
112f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::SaveLayer>(r, *record, i);
113f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org        assert_type<SkRecords::Restore>(r, *record, i+2);
114f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    }
115f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org}
116f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
117f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.orgDEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) {
118f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRecord record;
119a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org    SkRecorder recorder(&record, W, H);
120f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
121f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRect bounds = SkRect::MakeWH(100, 200);
122f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    SkRect   draw = SkRect::MakeWH(50, 60);
123f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
124678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    SkPaint alphaOnlyLayerPaint, translucentLayerPaint, xfermodeLayerPaint;
125678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    alphaOnlyLayerPaint.setColor(0x03000000);  // Only alpha.
126678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    translucentLayerPaint.setColor(0x03040506);  // Not only alpha.
127678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    xfermodeLayerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);  // Any effect will do.
128f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
129678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    SkPaint opaqueDrawPaint, translucentDrawPaint;
130678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    opaqueDrawPaint.setColor(0xFF020202);  // Opaque.
131678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    translucentDrawPaint.setColor(0x0F020202);  // Not opaque.
132f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
1330c278972d06882f21dda07e17d6e7457f590ea69mtklein    // SaveLayer/Restore removed: No paint = no point.
1340c278972d06882f21dda07e17d6e7457f590ea69mtklein    recorder.saveLayer(NULL, NULL);
135678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, opaqueDrawPaint);
136f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
1370c278972d06882f21dda07e17d6e7457f590ea69mtklein    assert_savelayer_restore(r, &record, 0, true);
138f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
1390c278972d06882f21dda07e17d6e7457f590ea69mtklein    // Bounds don't matter.
1400c278972d06882f21dda07e17d6e7457f590ea69mtklein    recorder.saveLayer(&bounds, NULL);
141678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, opaqueDrawPaint);
142f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
143f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    assert_savelayer_restore(r, &record, 3, true);
144f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
145f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // TODO(mtklein): test case with null draw paint
146f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
147f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // No change: layer paint isn't alpha-only.
148678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    recorder.saveLayer(NULL, &translucentLayerPaint);
149678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, opaqueDrawPaint);
150f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
151f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    assert_savelayer_restore(r, &record, 6, false);
152f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
153f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // No change: layer paint has an effect.
154678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    recorder.saveLayer(NULL, &xfermodeLayerPaint);
155678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, opaqueDrawPaint);
156f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
157f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    assert_savelayer_restore(r, &record, 9, false);
158f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
159678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    // SaveLayer/Restore removed: we can fold in the alpha!
160678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    recorder.saveLayer(NULL, &alphaOnlyLayerPaint);
161678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, translucentDrawPaint);
162f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
163678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    assert_savelayer_restore(r, &record, 12, true);
164f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
165f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    // SaveLayer/Restore removed: we can fold in the alpha!
166678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen    recorder.saveLayer(NULL, &alphaOnlyLayerPaint);
167678c1b019ac98bc7d94841132c8105a77490bc64kkinnunen        recorder.drawRect(draw, opaqueDrawPaint);
168f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    recorder.restore();
169f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    assert_savelayer_restore(r, &record, 15, true);
170f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org
171f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, record, 16);
172f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    REPORTER_ASSERT(r, drawRect != NULL);
173f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org    REPORTER_ASSERT(r, drawRect->paint.getColor() == 0x03020202);
174f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org}
175dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
176dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunenstatic void assert_merge_svg_opacity_and_filter_layers(skiatest::Reporter* r,
177dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                                                       SkRecord* record,
178dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                                                       unsigned i,
179dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                                                       bool shouldBeNoOped) {
180dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRecordMergeSvgOpacityAndFilterLayers(record);
181dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    if (shouldBeNoOped) {
182dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        assert_type<SkRecords::NoOp>(r, *record, i);
183dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        assert_type<SkRecords::NoOp>(r, *record, i + 6);
184dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    } else {
185dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        assert_type<SkRecords::SaveLayer>(r, *record, i);
186dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        assert_type<SkRecords::Restore>(r, *record, i + 6);
187dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    }
188dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen}
189dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
190dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunenDEF_TEST(RecordOpts_MergeSvgOpacityAndFilterLayers, r) {
191dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRecord record;
192dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRecorder recorder(&record, W, H);
193dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
194dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRect bounds = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(200));
195dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRect clip = SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(60));
196dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
197dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint alphaOnlyLayerPaint;
198dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    alphaOnlyLayerPaint.setColor(0x03000000);  // Only alpha.
199dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint translucentLayerPaint;
200dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    translucentLayerPaint.setColor(0x03040506);  // Not only alpha.
201dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint xfermodePaint;
202dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    xfermodePaint.setXfermodeMode(SkXfermode::kDstIn_Mode);
203dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint colorFilterPaint;
204dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    colorFilterPaint.setColorFilter(
205dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkColorFilter::CreateModeFilter(SK_ColorLTGRAY, SkXfermode::kSrcIn_Mode))->unref();
206dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
207dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint opaqueFilterLayerPaint;
208dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    opaqueFilterLayerPaint.setColor(0xFF020202);  // Opaque.
209dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkPaint translucentFilterLayerPaint;
210dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    translucentFilterLayerPaint.setColor(0x0F020202);  // Not opaque.
211dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkAutoTUnref<SkPicture> shape;
212dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    {
213dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPictureRecorder recorder;
214dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(100), SkIntToScalar(100));
215dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPaint shapePaint;
216dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        shapePaint.setColor(SK_ColorWHITE);
217dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        canvas->drawRect(SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(50)), shapePaint);
218dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        shape.reset(recorder.endRecordingAsPicture());
219dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    }
220dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    translucentFilterLayerPaint.setImageFilter(SkPictureImageFilter::Create(shape))->unref();
221dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
222dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    int index = 0;
223dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
224dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    {
225dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // Any combination of these should cause the pattern to be optimized.
226dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkRect* firstBounds[] = { NULL, &bounds };
227dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPaint* firstPaints[] = { NULL, &alphaOnlyLayerPaint };
228dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkRect* secondBounds[] = { NULL, &bounds };
229dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPaint* secondPaints[] = { &opaqueFilterLayerPaint, &translucentFilterLayerPaint };
230dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
231dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        for (size_t i = 0; i < SK_ARRAY_COUNT(firstBounds); ++ i) {
232dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen            for (size_t j = 0; j < SK_ARRAY_COUNT(firstPaints); ++j) {
233dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                for (size_t k = 0; k < SK_ARRAY_COUNT(secondBounds); ++k) {
234dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                    for (size_t m = 0; m < SK_ARRAY_COUNT(secondPaints); ++m) {
235dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                        recorder.saveLayer(firstBounds[i], firstPaints[j]);
236dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                        recorder.save();
237dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                        recorder.clipRect(clip);
238dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                        recorder.saveLayer(secondBounds[k], secondPaints[m]);
239dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                        recorder.restore();
240dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                        recorder.restore();
241dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                        recorder.restore();
242dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                        assert_merge_svg_opacity_and_filter_layers(r, &record, index, true);
243dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                        index += 7;
244dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                    }
245dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen                }
246dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen            }
247dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        }
248dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    }
249dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
250dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    // These should cause the pattern to stay unoptimized:
251dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    struct {
252dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPaint* firstPaint;
253dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        SkPaint* secondPaint;
254dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    } noChangeTests[] = {
255dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: NULL filter layer paint not implemented.
256dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &alphaOnlyLayerPaint, NULL },
257dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: layer paint is not alpha-only.
258dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &translucentLayerPaint, &opaqueFilterLayerPaint },
259dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: layer paint has an xfereffect.
260dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &xfermodePaint, &opaqueFilterLayerPaint },
261dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: filter layer paint has an xfereffect.
262dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &alphaOnlyLayerPaint, &xfermodePaint },
263dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: layer paint has a color filter.
264dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &colorFilterPaint, &opaqueFilterLayerPaint },
265dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // No change: filter layer paint has a color filter (until the optimization accounts for
266dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        // constant color draws that can filter the color).
267dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        { &alphaOnlyLayerPaint, &colorFilterPaint }
268dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    };
269dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
270dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    for (size_t i = 0; i < SK_ARRAY_COUNT(noChangeTests); ++i) {
271dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.saveLayer(NULL, noChangeTests[i].firstPaint);
272dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.save();
273dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.clipRect(clip);
274dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.saveLayer(NULL, noChangeTests[i].secondPaint);
275dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.restore();
276dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.restore();
277dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        recorder.restore();
278dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        assert_merge_svg_opacity_and_filter_layers(r, &record, index, false);
279dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen        index += 7;
280dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    }
281dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
282dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    // Test the folded alpha value.
283dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.saveLayer(NULL, &alphaOnlyLayerPaint);
284dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.save();
285dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.clipRect(clip);
286dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.saveLayer(NULL, &opaqueFilterLayerPaint);
287dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.restore();
288dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.restore();
289dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.restore();
290dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    assert_merge_svg_opacity_and_filter_layers(r, &record, index, true);
291dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
292dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    const SkRecords::SaveLayer* saveLayer = assert_type<SkRecords::SaveLayer>(r, record, index + 3);
293dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    REPORTER_ASSERT(r, saveLayer != NULL);
294dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    REPORTER_ASSERT(r, saveLayer->paint->getColor() == 0x03020202);
295dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
296dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    index += 7;
297dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen
298dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    // Test that currently we do not fold alphas for patterns without the clip. This is just not
299dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    // implemented.
300dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.saveLayer(NULL, &alphaOnlyLayerPaint);
301dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.saveLayer(NULL, &opaqueFilterLayerPaint);
302dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.restore();
303dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    recorder.restore();
304dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    SkRecordMergeSvgOpacityAndFilterLayers(&record);
305dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    assert_type<SkRecords::SaveLayer>(r, record, index);
306dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    assert_type<SkRecords::SaveLayer>(r, record, index + 1);
307dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    assert_type<SkRecords::Restore>(r, record, index + 2);
308dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    assert_type<SkRecords::Restore>(r, record, index + 3);
309dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen    index += 4;
310dc0f408a961b6ce4e7631e06031bbfe1d8d7bceckkinnunen}
311