blob: 1a51b5898038e7cb6e3cd1dfd58040188c0c4f91 [file] [log] [blame]
reed@google.coma513efb2013-09-17 20:14:52 +00001/*
2 * Copyright 2013 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
reed@google.coma513efb2013-09-17 20:14:52 +00008#include "SkDeviceLooper.h"
9#include "SkRasterClip.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000010#include "Test.h"
reed@google.coma513efb2013-09-17 20:14:52 +000011
reed41e010c2015-06-09 12:16:53 -070012static void make_pm(SkAutoPixmapStorage* pixmap, int w, int h) {
13 pixmap->alloc(SkImageInfo::Make(w, h, kAlpha_8_SkColorType, kPremul_SkAlphaType));
reed@google.coma513efb2013-09-17 20:14:52 +000014}
15
16static bool equal(const SkRasterClip& a, const SkRasterClip& b) {
17 if (a.isBW()) {
18 return b.isBW() && a.bwRgn() == b.bwRgn();
19 } else {
20 return a.isAA() && a.aaRgn() == b.aaRgn();
21 }
22}
23
robertphillips@google.com8c960bf2013-09-18 12:51:50 +000024static const struct {
25 SkISize fDevSize;
26 SkIRect fRCBounds;
27 SkIRect fRect;
28} gRec[] = {
29 { { 4000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 4000, 4000 } },
30 { { 10, 4000 }, { 0, 0, 10, 4000 }, { 0, 0, 4000, 4000 } },
31 // very large devce, small rect
32 { { 32000, 10 }, { 0, 0, 32000, 10 }, { 0, 0, 4000, 4000 } },
33 { { 10, 32000 }, { 0, 0, 10, 32000 }, { 0, 0, 4000, 4000 } },
34 // very large device, small clip
35 { { 32000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 32000, 32000 } },
36 { { 10, 32000 }, { 0, 0, 10, 4000 }, { 0, 0, 32000, 32000 } },
37};
38
reed@google.coma513efb2013-09-17 20:14:52 +000039static void test_simple(skiatest::Reporter* reporter) {
skia.committer@gmail.com2291e722013-09-18 07:01:33 +000040
reed@google.coma513efb2013-09-17 20:14:52 +000041 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
reed41e010c2015-06-09 12:16:53 -070042 SkAutoPixmapStorage pmap;
43 make_pm(&pmap, gRec[i].fDevSize.width(), gRec[i].fDevSize.height());
skia.committer@gmail.com2291e722013-09-18 07:01:33 +000044
reed@google.coma513efb2013-09-17 20:14:52 +000045 SkRasterClip rc(gRec[i].fRCBounds);
skia.committer@gmail.com2291e722013-09-18 07:01:33 +000046
reed@google.coma513efb2013-09-17 20:14:52 +000047 for (int aa = 0; aa <= 1; ++aa) {
reed41e010c2015-06-09 12:16:53 -070048 SkDeviceLooper looper(pmap, rc, gRec[i].fRect, SkToBool(aa));
skia.committer@gmail.com2291e722013-09-18 07:01:33 +000049
reed@google.coma513efb2013-09-17 20:14:52 +000050 bool valid = looper.next();
51 REPORTER_ASSERT(reporter, valid);
52 if (valid) {
reed41e010c2015-06-09 12:16:53 -070053 REPORTER_ASSERT(reporter, looper.getPixmap().width() == pmap.width());
54 REPORTER_ASSERT(reporter, looper.getPixmap().height() == pmap.height());
reed@google.coma513efb2013-09-17 20:14:52 +000055 REPORTER_ASSERT(reporter, equal(looper.getRC(), rc));
skia.committer@gmail.com2291e722013-09-18 07:01:33 +000056
reed@google.coma513efb2013-09-17 20:14:52 +000057 REPORTER_ASSERT(reporter, !looper.next());
58 }
59 }
60 // test that a rect that doesn't intersect returns no loops
61 {
62 SkIRect r = rc.getBounds();
63 r.offset(r.width(), 0);
reed41e010c2015-06-09 12:16:53 -070064 SkDeviceLooper looper(pmap, rc, r, false);
reed@google.coma513efb2013-09-17 20:14:52 +000065 REPORTER_ASSERT(reporter, !looper.next());
66 }
67 }
68}
69
70// mask-bits are interpreted as the areas where the clip is visible
71// [ 0x01 0x02 ]
72// [ 0x04 0x08 ]
73//
74static void make_rgn(SkRegion* rgn, int w, int h, unsigned mask) {
75 SkASSERT(SkAlign2(w));
76 SkASSERT(SkAlign2(h));
77 w >>= 1;
78 h >>= 1;
79 const SkIRect baseR = SkIRect::MakeWH(w, h);
80
81 int bit = 1;
82 for (int y = 0; y <= 1; ++y) {
83 for (int x = 0; x <= 1; ++x) {
84 if (mask & bit) {
85 SkIRect r = baseR;
86 r.offset(x * w, y * h);
87 rgn->op(r, SkRegion::kUnion_Op);
88 }
89 bit <<= 1;
90 }
91 }
92}
93
94static void test_complex(skiatest::Reporter* reporter) {
95 // choose size values that will result in 4 quadrants, given fAA setting
96 const int BW_SIZE = 17 * 1000;
97 const int AA_SIZE = 7 * 1000;
98
99 struct {
100 SkISize fSize;
101 bool fAA;
102 } const gRec[] = {
103 { { BW_SIZE, BW_SIZE }, false },
104 { { AA_SIZE, AA_SIZE }, true },
105 };
skia.committer@gmail.com2291e722013-09-18 07:01:33 +0000106
reed@google.coma513efb2013-09-17 20:14:52 +0000107 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
108 const int w = gRec[i].fSize.width();
109 const int h = gRec[i].fSize.height();
110
reed41e010c2015-06-09 12:16:53 -0700111 SkAutoPixmapStorage pmap;
112 make_pm(&pmap, w, h);
reed@google.coma513efb2013-09-17 20:14:52 +0000113
114 const SkIRect rect = SkIRect::MakeWH(w, h);
115
116 // mask-bits are interpreted as the areas where the clip is visible
117 // [ 0x01 0x02 ]
118 // [ 0x04 0x08 ]
119 //
120 for (int mask = 0; mask <= 15; ++mask) {
121 SkRegion rgn;
122 make_rgn(&rgn, w, h, mask);
123
124 SkRasterClip rc;
125 rc.op(rgn, SkRegion::kReplace_Op);
126
reed41e010c2015-06-09 12:16:53 -0700127 SkDeviceLooper looper(pmap, rc, rect, gRec[i].fAA);
reed@google.coma513efb2013-09-17 20:14:52 +0000128 while (looper.next()) {
129 REPORTER_ASSERT(reporter, !looper.getRC().isEmpty());
130 }
131 }
132 }
133}
134
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000135DEF_TEST(DeviceLooper, reporter) {
reed@google.coma513efb2013-09-17 20:14:52 +0000136 test_simple(reporter);
137 test_complex(reporter);
138}