blob: eaeb737af3cee4c979b29f9313455080da72e298 [file] [log] [blame]
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +00001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Test.h"
commit-bot@chromium.org0a98d872014-05-19 15:15:24 +00009#include "RecordTestUtils.h"
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000010
11#include "SkRecord.h"
12#include "SkRecordOpts.h"
13#include "SkRecorder.h"
14#include "SkRecords.h"
commit-bot@chromium.orgf5bf3cf2014-05-07 14:47:44 +000015#include "SkXfermode.h"
16
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000017static const int W = 1920, H = 1080;
18
reed2ff1fce2014-12-11 07:07:37 -080019DEF_TEST(RecordOpts_NoopDraw, r) {
commit-bot@chromium.org467705a2014-05-07 17:17:48 +000020 SkRecord record;
commit-bot@chromium.orga0950412014-05-29 16:52:40 +000021 SkRecorder recorder(&record, W, H);
commit-bot@chromium.org467705a2014-05-07 17:17:48 +000022
reed2ff1fce2014-12-11 07:07:37 -080023 recorder.drawRect(SkRect::MakeWH(200, 200), SkPaint());
24 recorder.drawRect(SkRect::MakeWH(300, 300), SkPaint());
25 recorder.drawRect(SkRect::MakeWH(100, 100), SkPaint());
commit-bot@chromium.org467705a2014-05-07 17:17:48 +000026
reed2ff1fce2014-12-11 07:07:37 -080027 record.replace<SkRecords::NoOp>(1); // NoOps should be allowed.
commit-bot@chromium.org467705a2014-05-07 17:17:48 +000028
29 SkRecordNoopSaveRestores(&record);
30
reed2ff1fce2014-12-11 07:07:37 -080031 REPORTER_ASSERT(r, 2 == count_instances_of_type<SkRecords::DrawRect>(record));
commit-bot@chromium.org467705a2014-05-07 17:17:48 +000032}
33
commit-bot@chromium.org7066bf32014-05-05 17:09:05 +000034DEF_TEST(RecordOpts_SingleNoopSaveRestore, r) {
35 SkRecord record;
commit-bot@chromium.orga0950412014-05-29 16:52:40 +000036 SkRecorder recorder(&record, W, H);
commit-bot@chromium.org7066bf32014-05-05 17:09:05 +000037
38 recorder.save();
39 recorder.clipRect(SkRect::MakeWH(200, 200));
40 recorder.restore();
41
42 SkRecordNoopSaveRestores(&record);
43 for (unsigned i = 0; i < 3; i++) {
44 assert_type<SkRecords::NoOp>(r, record, i);
45 }
46}
47
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000048DEF_TEST(RecordOpts_NoopSaveRestores, r) {
49 SkRecord record;
commit-bot@chromium.orga0950412014-05-29 16:52:40 +000050 SkRecorder recorder(&record, W, H);
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000051
52 // The second pass will clean up this pair after the first pass noops all the innards.
53 recorder.save();
54 // A simple pointless pair of save/restore.
55 recorder.save();
56 recorder.restore();
57
58 // As long as we don't draw in there, everything is a noop.
59 recorder.save();
60 recorder.clipRect(SkRect::MakeWH(200, 200));
61 recorder.clipRect(SkRect::MakeWH(100, 100));
62 recorder.restore();
63 recorder.restore();
64
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000065 SkRecordNoopSaveRestores(&record);
reed2ff1fce2014-12-11 07:07:37 -080066 for (unsigned index = 0; index < record.count(); index++) {
commit-bot@chromium.org7066bf32014-05-05 17:09:05 +000067 assert_type<SkRecords::NoOp>(r, record, index);
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000068 }
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000069}
commit-bot@chromium.orgf5bf3cf2014-05-07 14:47:44 +000070
mtklein99d6a9e2014-09-10 16:08:27 -070071DEF_TEST(RecordOpts_SaveSaveLayerRestoreRestore, r) {
72 SkRecord record;
73 SkRecorder recorder(&record, W, H);
74
75 // A previous bug NoOp'd away the first 3 commands.
76 recorder.save();
77 recorder.saveLayer(NULL, NULL);
78 recorder.restore();
79 recorder.restore();
80
81 SkRecordNoopSaveRestores(&record);
reed2ff1fce2014-12-11 07:07:37 -080082 switch (record.count()) {
83 case 4:
84 assert_type<SkRecords::Save> (r, record, 0);
85 assert_type<SkRecords::SaveLayer>(r, record, 1);
86 assert_type<SkRecords::Restore> (r, record, 2);
87 assert_type<SkRecords::Restore> (r, record, 3);
88 break;
89 case 2:
90 assert_type<SkRecords::SaveLayer>(r, record, 0);
91 assert_type<SkRecords::Restore> (r, record, 1);
92 break;
93 case 0:
94 break;
95 default:
96 REPORTER_ASSERT(r, false);
97 }
mtklein99d6a9e2014-09-10 16:08:27 -070098}
99
commit-bot@chromium.orgf5bf3cf2014-05-07 14:47:44 +0000100static void assert_savelayer_restore(skiatest::Reporter* r,
101 SkRecord* record,
102 unsigned i,
103 bool shouldBeNoOped) {
104 SkRecordNoopSaveLayerDrawRestores(record);
105 if (shouldBeNoOped) {
106 assert_type<SkRecords::NoOp>(r, *record, i);
107 assert_type<SkRecords::NoOp>(r, *record, i+2);
108 } else {
109 assert_type<SkRecords::SaveLayer>(r, *record, i);
110 assert_type<SkRecords::Restore>(r, *record, i+2);
111 }
112}
113
114DEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) {
115 SkRecord record;
commit-bot@chromium.orga0950412014-05-29 16:52:40 +0000116 SkRecorder recorder(&record, W, H);
commit-bot@chromium.orgf5bf3cf2014-05-07 14:47:44 +0000117
118 SkRect bounds = SkRect::MakeWH(100, 200);
119 SkRect draw = SkRect::MakeWH(50, 60);
120
121 SkPaint goodLayerPaint, badLayerPaint, worseLayerPaint;
122 goodLayerPaint.setColor(0x03000000); // Only alpha.
123 badLayerPaint.setColor( 0x03040506); // Not only alpha.
124 worseLayerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode); // Any effect will do.
125
126 SkPaint goodDrawPaint, badDrawPaint;
127 goodDrawPaint.setColor(0xFF020202); // Opaque.
128 badDrawPaint.setColor( 0x0F020202); // Not opaque.
129
mtklein0c278972015-01-15 08:08:10 -0800130 // SaveLayer/Restore removed: No paint = no point.
131 recorder.saveLayer(NULL, NULL);
commit-bot@chromium.orgf5bf3cf2014-05-07 14:47:44 +0000132 recorder.drawRect(draw, goodDrawPaint);
133 recorder.restore();
mtklein0c278972015-01-15 08:08:10 -0800134 assert_savelayer_restore(r, &record, 0, true);
commit-bot@chromium.orgf5bf3cf2014-05-07 14:47:44 +0000135
mtklein0c278972015-01-15 08:08:10 -0800136 // Bounds don't matter.
137 recorder.saveLayer(&bounds, NULL);
commit-bot@chromium.orgf5bf3cf2014-05-07 14:47:44 +0000138 recorder.drawRect(draw, goodDrawPaint);
139 recorder.restore();
140 assert_savelayer_restore(r, &record, 3, true);
141
142 // TODO(mtklein): test case with null draw paint
143
144 // No change: layer paint isn't alpha-only.
145 recorder.saveLayer(NULL, &badLayerPaint);
146 recorder.drawRect(draw, goodDrawPaint);
147 recorder.restore();
148 assert_savelayer_restore(r, &record, 6, false);
149
150 // No change: layer paint has an effect.
151 recorder.saveLayer(NULL, &worseLayerPaint);
152 recorder.drawRect(draw, goodDrawPaint);
153 recorder.restore();
154 assert_savelayer_restore(r, &record, 9, false);
155
156 // No change: draw paint isn't opaque.
157 recorder.saveLayer(NULL, &goodLayerPaint);
158 recorder.drawRect(draw, badDrawPaint);
159 recorder.restore();
160 assert_savelayer_restore(r, &record, 12, false);
161
162 // SaveLayer/Restore removed: we can fold in the alpha!
163 recorder.saveLayer(NULL, &goodLayerPaint);
164 recorder.drawRect(draw, goodDrawPaint);
165 recorder.restore();
166 assert_savelayer_restore(r, &record, 15, true);
167
168 const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, record, 16);
169 REPORTER_ASSERT(r, drawRect != NULL);
170 REPORTER_ASSERT(r, drawRect->paint.getColor() == 0x03020202);
171}