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