18dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org/* 28dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org * Copyright 2014 Google Inc. 38dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org * 48dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 58dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org * found in the LICENSE file. 68dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org */ 78dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org 88dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "Test.h" 90a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org#include "RecordTestUtils.h" 108dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org 118dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecord.h" 128dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecordOpts.h" 138dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecorder.h" 148dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org#include "SkRecords.h" 15f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org#include "SkXfermode.h" 16f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 178dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.orgstatic const int W = 1920, H = 1080; 188dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org 19467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.orgDEF_TEST(RecordOpts_NoopDrawSaveRestore, r) { 20467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org SkRecord record; 21a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org SkRecorder recorder(&record, W, H); 22467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org 23467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org // The save and restore are pointless if there's only draw commands in the middle. 24467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org recorder.save(); 25467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org recorder.drawRect(SkRect::MakeWH(200, 200), SkPaint()); 26467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org recorder.drawRect(SkRect::MakeWH(300, 300), SkPaint()); 27467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org recorder.drawRect(SkRect::MakeWH(100, 100), SkPaint()); 28467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org recorder.restore(); 29467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org 30467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org record.replace<SkRecords::NoOp>(2); // NoOps should be allowed. 31467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org 32467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org SkRecordNoopSaveRestores(&record); 33467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org 34467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org assert_type<SkRecords::NoOp>(r, record, 0); 35467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org assert_type<SkRecords::DrawRect>(r, record, 1); 36467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org assert_type<SkRecords::NoOp>(r, record, 2); 37467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org assert_type<SkRecords::DrawRect>(r, record, 3); 38467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org assert_type<SkRecords::NoOp>(r, record, 4); 39467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org} 40467705adf05ba99bbd9ccdf6a40eb463484a6fbfcommit-bot@chromium.org 417066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.orgDEF_TEST(RecordOpts_SingleNoopSaveRestore, r) { 427066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org SkRecord record; 43a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org SkRecorder recorder(&record, W, H); 447066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org 457066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org recorder.save(); 467066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org recorder.clipRect(SkRect::MakeWH(200, 200)); 477066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org recorder.restore(); 487066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org 497066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org SkRecordNoopSaveRestores(&record); 507066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org for (unsigned i = 0; i < 3; i++) { 517066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org assert_type<SkRecords::NoOp>(r, record, i); 527066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org } 537066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org} 547066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org 558dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.orgDEF_TEST(RecordOpts_NoopSaveRestores, r) { 568dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org SkRecord record; 57a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org SkRecorder recorder(&record, W, H); 588dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org 598dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org // The second pass will clean up this pair after the first pass noops all the innards. 608dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org recorder.save(); 618dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org // A simple pointless pair of save/restore. 628dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org recorder.save(); 638dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org recorder.restore(); 648dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org 658dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org // As long as we don't draw in there, everything is a noop. 668dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org recorder.save(); 678dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org recorder.clipRect(SkRect::MakeWH(200, 200)); 688dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org recorder.clipRect(SkRect::MakeWH(100, 100)); 698dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org recorder.restore(); 708dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org recorder.restore(); 718dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org 728dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org SkRecordNoopSaveRestores(&record); 738dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org for (unsigned index = 0; index < 8; index++) { 747066bf3fbff7a54d3692414ec11ca419f3fd0ad5commit-bot@chromium.org assert_type<SkRecords::NoOp>(r, record, index); 758dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org } 768dac8b18eea8a729062440b85285d19fc890bb1acommit-bot@chromium.org} 77f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 7899d6a9ee8b3516de892d118c71aa5e6e5c865efdmtkleinDEF_TEST(RecordOpts_SaveSaveLayerRestoreRestore, r) { 7999d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein SkRecord record; 8099d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein SkRecorder recorder(&record, W, H); 8199d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein 8299d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein // A previous bug NoOp'd away the first 3 commands. 8399d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein recorder.save(); 8499d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein recorder.saveLayer(NULL, NULL); 8599d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein recorder.restore(); 8699d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein recorder.restore(); 8799d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein 8899d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein SkRecordNoopSaveRestores(&record); 8999d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein assert_type<SkRecords::Save> (r, record, 0); 9099d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein assert_type<SkRecords::SaveLayer>(r, record, 1); 9199d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein assert_type<SkRecords::Restore> (r, record, 2); 9299d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein assert_type<SkRecords::Restore> (r, record, 3); 9399d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein} 9499d6a9ee8b3516de892d118c71aa5e6e5c865efdmtklein 95f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.orgstatic void assert_savelayer_restore(skiatest::Reporter* r, 96f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org SkRecord* record, 97f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org unsigned i, 98f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org bool shouldBeNoOped) { 99f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org SkRecordNoopSaveLayerDrawRestores(record); 100f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org if (shouldBeNoOped) { 101f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org assert_type<SkRecords::NoOp>(r, *record, i); 102f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org assert_type<SkRecords::NoOp>(r, *record, i+2); 103f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org } else { 104f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org assert_type<SkRecords::SaveLayer>(r, *record, i); 105f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org assert_type<SkRecords::Restore>(r, *record, i+2); 106f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org } 107f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org} 108f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 109f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.orgDEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) { 110f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org SkRecord record; 111a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org SkRecorder recorder(&record, W, H); 112f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 113f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org SkRect bounds = SkRect::MakeWH(100, 200); 114f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org SkRect draw = SkRect::MakeWH(50, 60); 115f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 116f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org SkPaint goodLayerPaint, badLayerPaint, worseLayerPaint; 117f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org goodLayerPaint.setColor(0x03000000); // Only alpha. 118f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org badLayerPaint.setColor( 0x03040506); // Not only alpha. 119f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org worseLayerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode); // Any effect will do. 120f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 121f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org SkPaint goodDrawPaint, badDrawPaint; 122f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org goodDrawPaint.setColor(0xFF020202); // Opaque. 123f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org badDrawPaint.setColor( 0x0F020202); // Not opaque. 124f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 125f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org // No change: optimization can't handle bounds. 126f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.saveLayer(&bounds, NULL); 127f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.drawRect(draw, goodDrawPaint); 128f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.restore(); 129f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org assert_savelayer_restore(r, &record, 0, false); 130f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 131f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org // SaveLayer/Restore removed: no bounds + no paint = no point. 132f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.saveLayer(NULL, NULL); 133f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.drawRect(draw, goodDrawPaint); 134f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.restore(); 135f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org assert_savelayer_restore(r, &record, 3, true); 136f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 137f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org // TODO(mtklein): test case with null draw paint 138f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 139f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org // No change: layer paint isn't alpha-only. 140f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.saveLayer(NULL, &badLayerPaint); 141f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.drawRect(draw, goodDrawPaint); 142f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.restore(); 143f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org assert_savelayer_restore(r, &record, 6, false); 144f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 145f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org // No change: layer paint has an effect. 146f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.saveLayer(NULL, &worseLayerPaint); 147f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.drawRect(draw, goodDrawPaint); 148f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.restore(); 149f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org assert_savelayer_restore(r, &record, 9, false); 150f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 151f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org // No change: draw paint isn't opaque. 152f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.saveLayer(NULL, &goodLayerPaint); 153f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.drawRect(draw, badDrawPaint); 154f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.restore(); 155f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org assert_savelayer_restore(r, &record, 12, false); 156f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 157f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org // SaveLayer/Restore removed: we can fold in the alpha! 158f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.saveLayer(NULL, &goodLayerPaint); 159f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.drawRect(draw, goodDrawPaint); 160f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org recorder.restore(); 161f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org assert_savelayer_restore(r, &record, 15, true); 162f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org 163f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, record, 16); 164f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org REPORTER_ASSERT(r, drawRect != NULL); 165f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org REPORTER_ASSERT(r, drawRect->paint.getColor() == 0x03020202); 166f5bf3cf0257dc3d18932bde51f8eae33442e071fcommit-bot@chromium.org} 167