RecordOptsTest.cpp revision 0a98d870448f66ea0df7c37a47b38cf2d3b734e5
18dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/*
28dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor * Copyright 2014 Google Inc.
38dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor *
48dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor * Use of this source code is governed by a BSD-style license that can be
58dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor * found in the LICENSE file.
68dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor */
78dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
88dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "Test.h"
98dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "RecordTestUtils.h"
108dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
118dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "SkRecord.h"
122d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "SkRecordOpts.h"
13e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "SkRecorder.h"
14f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "SkRecords.h"
157cd088e519d7e6caa4c4c12db52e0e4ae35d25c2John McCall#include "SkXfermode.h"
16aba43bb13b3aa3e81990989375fba3a902bfe1c2Douglas Gregor
178dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregorstatic const int W = 1920, H = 1080;
188dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
198dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDEF_TEST(RecordOpts_Culling, r) {
200c01d18094100db92d38daa923c95661512db203John McCall    SkRecord record;
218dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
22a88cfbfac9bbcbb9858f048d6d73a48711d8e93dDouglas Gregor
2321ef0fa27b0783ec0bc6aa5b524feb2ec840f952John McCall    recorder.drawRect(SkRect::MakeWH(1000, 10000), SkPaint());
2483ddad3ab513f5d73698cf9fbeb4ed3f011bc3b9Douglas Gregor
258dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    recorder.pushCull(SkRect::MakeWH(100, 100));
268dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        recorder.drawRect(SkRect::MakeWH(10, 10), SkPaint());
278dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        recorder.drawRect(SkRect::MakeWH(30, 30), SkPaint());
288dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        recorder.pushCull(SkRect::MakeWH(5, 5));
2985b4521e34dcd4a0a4a1f0819e1123128e5a3125Benjamin Kramer            recorder.drawRect(SkRect::MakeWH(1, 1), SkPaint());
30b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner        recorder.popCull();
318dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    recorder.popCull();
328dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
33d6350aefb1396b299e199c7f1fe51bb40c12e75eDouglas Gregor    SkRecordAnnotateCullingPairs(&record);
341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
358dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    REPORTER_ASSERT(r, 6 == assert_type<SkRecords::PairedPushCull>(r, record, 1)->skip);
368dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    REPORTER_ASSERT(r, 2 == assert_type<SkRecords::PairedPushCull>(r, record, 4)->skip);
37d6350aefb1396b299e199c7f1fe51bb40c12e75eDouglas Gregor}
387e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
391eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpDEF_TEST(RecordOpts_NoopCulls, r) {
40390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    SkRecord record;
41390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
429a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt
434f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor    // All should be nooped.
444f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor    recorder.pushCull(SkRect::MakeWH(200, 200));
453dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall        recorder.pushCull(SkRect::MakeWH(100, 100));
468dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        recorder.popCull();
473d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor    recorder.popCull();
486206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara
498dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // Kept for now.  We could peel off a layer of culling.
508dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    recorder.pushCull(SkRect::MakeWH(5, 5));
518dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        recorder.pushCull(SkRect::MakeWH(5, 5));
526477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor            recorder.drawRect(SkRect::MakeWH(1, 1), SkPaint());
5302cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall        recorder.popCull();
54a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor    recorder.popCull();
55a735b206fdb5c15767a45289e1ffb3b568f70f2bDouglas Gregor
56d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor    SkRecordNoopCulls(&record);
57d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor
58d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    for (unsigned i = 0; i < 4; i++) {
59615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor        assert_type<SkRecords::NoOp>(r, record, i);
6003b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor    }
61bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor    assert_type<SkRecords::PushCull>(r, record, 4);
626477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor    assert_type<SkRecords::PushCull>(r, record, 5);
63e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    assert_type<SkRecords::DrawRect>(r, record, 6);
647974c3b7062f85bb7c0ada34526cdefe1d30f89bDouglas Gregor    assert_type<SkRecords::PopCull>(r, record, 7);
657974c3b7062f85bb7c0ada34526cdefe1d30f89bDouglas Gregor    assert_type<SkRecords::PopCull>(r, record, 8);
66d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor}
67e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
6833642df30088f2ddb0b22c609523ab8df9dff595Douglas Gregorstatic void draw_pos_text(SkCanvas* canvas, const char* text, bool constantY) {
699106ef78f8fcc9df1a60c7a5b64c7d967194207eDouglas Gregor    const size_t len = strlen(text);
7048c32a7e7c977f317dc1dc19524c2f54d29c7270Douglas Gregor    SkAutoTMalloc<SkPoint> pos(len);
71ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    for (size_t i = 0; i < len; i++) {
72ed97649e9574b9d854fa4d6109c9333ae0993554John McCall        pos[i].fX = (SkScalar)i;
737ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall        pos[i].fY = constantY ? SK_Scalar1 : (SkScalar)i;
747ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall    }
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    canvas->drawPosText(text, len, pos, SkPaint());
768dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
7748c32a7e7c977f317dc1dc19524c2f54d29c7270Douglas Gregor
7848c32a7e7c977f317dc1dc19524c2f54d29c7270Douglas GregorDEF_TEST(RecordOpts_StrengthReduction, r) {
7948c32a7e7c977f317dc1dc19524c2f54d29c7270Douglas Gregor    SkRecord record;
8048c32a7e7c977f317dc1dc19524c2f54d29c7270Douglas Gregor    SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
8148c32a7e7c977f317dc1dc19524c2f54d29c7270Douglas Gregor
8248c32a7e7c977f317dc1dc19524c2f54d29c7270Douglas Gregor    // We can convert a drawPosText into a drawPosTextH when all the Ys are the same.
8348c32a7e7c977f317dc1dc19524c2f54d29c7270Douglas Gregor    draw_pos_text(&recorder, "This will be reduced to drawPosTextH.", true);
848dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    draw_pos_text(&recorder, "This cannot be reduced to drawPosTextH.", false);
858dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
865545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    SkRecordReduceDrawPosTextStrength(&record);
875545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
8821ef0fa27b0783ec0bc6aa5b524feb2ec840f952John McCall    assert_type<SkRecords::DrawPosTextH>(r, record, 0);
895545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    assert_type<SkRecords::DrawPosText>(r, record, 1);
90e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor}
915545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
92e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCallDEF_TEST(RecordOpts_TextBounding, r) {
93e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    SkRecord record;
94ce3ff2bd3a3386dbc209d3cba4b8769173b274c1John McCall    SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
95b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall
96b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    // First, get a drawPosTextH.  Here's a handy way.  Its text size will be the default (12).
97b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    draw_pos_text(&recorder, "This will be reduced to drawPosTextH.", true);
98b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    SkRecordReduceDrawPosTextStrength(&record);
99b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall
100ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    const SkRecords::DrawPosTextH* original =
101ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor        assert_type<SkRecords::DrawPosTextH>(r, record, 0);
102ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
103ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    // This should wrap the original DrawPosTextH with minY and maxY.
1048dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    SkRecordBoundDrawPosTextH(&record);
1058dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1068dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    const SkRecords::BoundedDrawPosTextH* bounded =
107b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall        assert_type<SkRecords::BoundedDrawPosTextH>(r, record, 0);
108b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall
109b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    const SkPaint defaults;
110b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    REPORTER_ASSERT(r, bounded->base == original);
111b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    REPORTER_ASSERT(r, bounded->minY <= SK_Scalar1 - defaults.getTextSize());
112b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    REPORTER_ASSERT(r, bounded->maxY >= SK_Scalar1 + defaults.getTextSize());
113b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall}
114b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall
115b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCallDEF_TEST(RecordOpts_NoopDrawSaveRestore, r) {
116b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    SkRecord record;
117b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
118b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall
119b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    // The save and restore are pointless if there's only draw commands in the middle.
120b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    recorder.save();
121b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall        recorder.drawRect(SkRect::MakeWH(200, 200), SkPaint());
122b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall        recorder.drawRect(SkRect::MakeWH(300, 300), SkPaint());
123b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall        recorder.drawRect(SkRect::MakeWH(100, 100), SkPaint());
124b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    recorder.restore();
125b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall
126b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    record.replace<SkRecords::NoOp>(2);  // NoOps should be allowed.
127b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall
128b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    SkRecordNoopSaveRestores(&record);
129b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall
130b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    assert_type<SkRecords::NoOp>(r, record, 0);
131b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    assert_type<SkRecords::DrawRect>(r, record, 1);
132b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    assert_type<SkRecords::NoOp>(r, record, 2);
133b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    assert_type<SkRecords::DrawRect>(r, record, 3);
134b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    assert_type<SkRecords::NoOp>(r, record, 4);
135b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall}
136b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall
137b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCallDEF_TEST(RecordOpts_SingleNoopSaveRestore, r) {
138b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall    SkRecord record;
1394ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
1401d8d1ccd36888f1120b3a1df9e76f35dc2edb81dJohn McCall
1411d8d1ccd36888f1120b3a1df9e76f35dc2edb81dJohn McCall    recorder.save();
142cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        recorder.clipRect(SkRect::MakeWH(200, 200));
143cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    recorder.restore();
144cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
1454ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    SkRecordNoopSaveRestores(&record);
1464ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    for (unsigned i = 0; i < 3; i++) {
147cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        assert_type<SkRecords::NoOp>(r, record, i);
1484ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    }
1491d8d1ccd36888f1120b3a1df9e76f35dc2edb81dJohn McCall}
150f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall
1514ced79f0971592e6e7122037de69ee9ae534ce72Chandler CarruthDEF_TEST(RecordOpts_NoopSaveRestores, r) {
152cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    SkRecord record;
15360d7b3a319d84d688752be3870615ac0f111fb16John McCall    SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
154cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
155cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    // The second pass will clean up this pair after the first pass noops all the innards.
156cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt    recorder.save();
157cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        // A simple pointless pair of save/restore.
158cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        recorder.save();
159cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        recorder.restore();
160cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt
161cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        // As long as we don't draw in there, everything is a noop.
162cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        recorder.save();
163cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            recorder.clipRect(SkRect::MakeWH(200, 200));
164cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt            recorder.clipRect(SkRect::MakeWH(100, 100));
165cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt        recorder.restore();
1664ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    recorder.restore();
1674ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth
1684ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    SkRecordNoopSaveRestores(&record);
1694ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth    for (unsigned index = 0; index < 8; index++) {
170d8fe2d56fb5463c9d109e8c6dab2e98b06bee186Anders Carlsson        assert_type<SkRecords::NoOp>(r, record, index);
1711d8d1ccd36888f1120b3a1df9e76f35dc2edb81dJohn McCall    }
172d8fe2d56fb5463c9d109e8c6dab2e98b06bee186Anders Carlsson}
173d8fe2d56fb5463c9d109e8c6dab2e98b06bee186Anders Carlsson
174d8fe2d56fb5463c9d109e8c6dab2e98b06bee186Anders Carlssonstatic void assert_savelayer_restore(skiatest::Reporter* r,
175d8fe2d56fb5463c9d109e8c6dab2e98b06bee186Anders Carlsson                                     SkRecord* record,
1764f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor                                     unsigned i,
1774f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor                                     bool shouldBeNoOped) {
1784f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor    SkRecordNoopSaveLayerDrawRestores(record);
1794f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor    if (shouldBeNoOped) {
1804f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor        assert_type<SkRecords::NoOp>(r, *record, i);
1814f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor        assert_type<SkRecords::NoOp>(r, *record, i+2);
1824f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor    } else {
1834f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor        assert_type<SkRecords::SaveLayer>(r, *record, i);
1844f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor        assert_type<SkRecords::Restore>(r, *record, i+2);
1854f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor    }
1864f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor}
1874f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor
1883dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCallDEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) {
1893dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    SkRecord record;
1903dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
1913dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall
1923dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    SkRect bounds = SkRect::MakeWH(100, 200);
1933dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    SkRect   draw = SkRect::MakeWH(50, 60);
1943dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall
1953dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    SkPaint goodLayerPaint, badLayerPaint, worseLayerPaint;
1963dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    goodLayerPaint.setColor(0x03000000);  // Only alpha.
1973dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    badLayerPaint.setColor( 0x03040506);  // Not only alpha.
1983dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    worseLayerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);  // Any effect will do.
1993dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall
2003dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    SkPaint goodDrawPaint, badDrawPaint;
2013dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    goodDrawPaint.setColor(0xFF020202);  // Opaque.
2023dbd3d5c04cd5abd7dfd83b15f51d7c610a3c512John McCall    badDrawPaint.setColor( 0x0F020202);  // Not opaque.
2038dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2048dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // No change: optimization can't handle bounds.
205a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    recorder.saveLayer(&bounds, NULL);
206836adf6771d5170d936599dfcce21687e37e9bbfDouglas Gregor        recorder.drawRect(draw, goodDrawPaint);
207836adf6771d5170d936599dfcce21687e37e9bbfDouglas Gregor    recorder.restore();
208ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    assert_savelayer_restore(r, &record, 0, false);
209ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall
210ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    // SaveLayer/Restore removed: no bounds + no paint = no point.
2118dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    recorder.saveLayer(NULL, NULL);
212a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall        recorder.drawRect(draw, goodDrawPaint);
2138dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    recorder.restore();
214b4eeaff1595b7d0a8fbc2b3c8bec7dc63f48b7fdDouglas Gregor    assert_savelayer_restore(r, &record, 3, true);
215b4eeaff1595b7d0a8fbc2b3c8bec7dc63f48b7fdDouglas Gregor
2168dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // TODO(mtklein): test case with null draw paint
2171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2188dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // No change: layer paint isn't alpha-only.
2198dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    recorder.saveLayer(NULL, &badLayerPaint);
2208dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        recorder.drawRect(draw, goodDrawPaint);
221ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall    recorder.restore();
2228dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    assert_savelayer_restore(r, &record, 6, false);
2238dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2248dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // No change: layer paint has an effect.
225d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor    recorder.saveLayer(NULL, &worseLayerPaint);
226d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor        recorder.drawRect(draw, goodDrawPaint);
227d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor    recorder.restore();
228d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor    assert_savelayer_restore(r, &record, 9, false);
229d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor
230d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor    // No change: draw paint isn't opaque.
231d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor    recorder.saveLayer(NULL, &goodLayerPaint);
232d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor        recorder.drawRect(draw, badDrawPaint);
233d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor    recorder.restore();
2345126fd0dd92c4ec211c837ee78d5ce59c68dcbd5John McCall    assert_savelayer_restore(r, &record, 12, false);
2357c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor
2367c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor    // SaveLayer/Restore removed: we can fold in the alpha!
2375126fd0dd92c4ec211c837ee78d5ce59c68dcbd5John McCall    recorder.saveLayer(NULL, &goodLayerPaint);
2385126fd0dd92c4ec211c837ee78d5ce59c68dcbd5John McCall        recorder.drawRect(draw, goodDrawPaint);
2395126fd0dd92c4ec211c837ee78d5ce59c68dcbd5John McCall    recorder.restore();
2401d8d1ccd36888f1120b3a1df9e76f35dc2edb81dJohn McCall    assert_savelayer_restore(r, &record, 15, true);
241d57a38ee02c285d69d05fed6df0d7406b2517888Douglas Gregor
24246460a68f6508775e98c19b4bb8454bb471aac24John McCall    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, record, 16);
24317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    REPORTER_ASSERT(r, drawRect != NULL);
2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    REPORTER_ASSERT(r, drawRect->paint.getColor() == 0x03020202);
2458dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
2468dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor