blob: 5735043074d72b096d7dde04365404f3c0f71d34 [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
12static void make_bm(SkBitmap* bm, int w, int h) {
commit-bot@chromium.orgfa9e5fa2014-02-13 22:00:04 +000013 bm->allocPixels(SkImageInfo::Make(w, h, kAlpha_8_SkColorType,
14 kPremul_SkAlphaType));
reed@google.coma513efb2013-09-17 20:14:52 +000015}
16
17static bool equal(const SkRasterClip& a, const SkRasterClip& b) {
18 if (a.isBW()) {
19 return b.isBW() && a.bwRgn() == b.bwRgn();
20 } else {
21 return a.isAA() && a.aaRgn() == b.aaRgn();
22 }
23}
24
robertphillips@google.com8c960bf2013-09-18 12:51:50 +000025static const struct {
26 SkISize fDevSize;
27 SkIRect fRCBounds;
28 SkIRect fRect;
29} gRec[] = {
30 { { 4000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 4000, 4000 } },
31 { { 10, 4000 }, { 0, 0, 10, 4000 }, { 0, 0, 4000, 4000 } },
32 // very large devce, small rect
33 { { 32000, 10 }, { 0, 0, 32000, 10 }, { 0, 0, 4000, 4000 } },
34 { { 10, 32000 }, { 0, 0, 10, 32000 }, { 0, 0, 4000, 4000 } },
35 // very large device, small clip
36 { { 32000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 32000, 32000 } },
37 { { 10, 32000 }, { 0, 0, 10, 4000 }, { 0, 0, 32000, 32000 } },
38};
39
reed@google.coma513efb2013-09-17 20:14:52 +000040static void test_simple(skiatest::Reporter* reporter) {
skia.committer@gmail.com2291e722013-09-18 07:01:33 +000041
reed@google.coma513efb2013-09-17 20:14:52 +000042 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
43 SkBitmap bitmap;
44 make_bm(&bitmap, gRec[i].fDevSize.width(), gRec[i].fDevSize.height());
skia.committer@gmail.com2291e722013-09-18 07:01:33 +000045
reed@google.coma513efb2013-09-17 20:14:52 +000046 SkRasterClip rc(gRec[i].fRCBounds);
skia.committer@gmail.com2291e722013-09-18 07:01:33 +000047
reed@google.coma513efb2013-09-17 20:14:52 +000048 for (int aa = 0; aa <= 1; ++aa) {
49 SkDeviceLooper looper(bitmap, rc, gRec[i].fRect, SkToBool(aa));
skia.committer@gmail.com2291e722013-09-18 07:01:33 +000050
reed@google.coma513efb2013-09-17 20:14:52 +000051 bool valid = looper.next();
52 REPORTER_ASSERT(reporter, valid);
53 if (valid) {
54 REPORTER_ASSERT(reporter, looper.getBitmap().width() == bitmap.width());
55 REPORTER_ASSERT(reporter, looper.getBitmap().height() == bitmap.height());
56 REPORTER_ASSERT(reporter, equal(looper.getRC(), rc));
skia.committer@gmail.com2291e722013-09-18 07:01:33 +000057
reed@google.coma513efb2013-09-17 20:14:52 +000058 REPORTER_ASSERT(reporter, !looper.next());
59 }
60 }
61 // test that a rect that doesn't intersect returns no loops
62 {
63 SkIRect r = rc.getBounds();
64 r.offset(r.width(), 0);
65 SkDeviceLooper looper(bitmap, rc, r, false);
66 REPORTER_ASSERT(reporter, !looper.next());
67 }
68 }
69}
70
71// mask-bits are interpreted as the areas where the clip is visible
72// [ 0x01 0x02 ]
73// [ 0x04 0x08 ]
74//
75static void make_rgn(SkRegion* rgn, int w, int h, unsigned mask) {
76 SkASSERT(SkAlign2(w));
77 SkASSERT(SkAlign2(h));
78 w >>= 1;
79 h >>= 1;
80 const SkIRect baseR = SkIRect::MakeWH(w, h);
81
82 int bit = 1;
83 for (int y = 0; y <= 1; ++y) {
84 for (int x = 0; x <= 1; ++x) {
85 if (mask & bit) {
86 SkIRect r = baseR;
87 r.offset(x * w, y * h);
88 rgn->op(r, SkRegion::kUnion_Op);
89 }
90 bit <<= 1;
91 }
92 }
93}
94
95static void test_complex(skiatest::Reporter* reporter) {
96 // choose size values that will result in 4 quadrants, given fAA setting
97 const int BW_SIZE = 17 * 1000;
98 const int AA_SIZE = 7 * 1000;
99
100 struct {
101 SkISize fSize;
102 bool fAA;
103 } const gRec[] = {
104 { { BW_SIZE, BW_SIZE }, false },
105 { { AA_SIZE, AA_SIZE }, true },
106 };
skia.committer@gmail.com2291e722013-09-18 07:01:33 +0000107
reed@google.coma513efb2013-09-17 20:14:52 +0000108 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
109 const int w = gRec[i].fSize.width();
110 const int h = gRec[i].fSize.height();
111
112 SkBitmap bitmap;
113 make_bm(&bitmap, w, h);
114
115 const SkIRect rect = SkIRect::MakeWH(w, h);
116
117 // mask-bits are interpreted as the areas where the clip is visible
118 // [ 0x01 0x02 ]
119 // [ 0x04 0x08 ]
120 //
121 for (int mask = 0; mask <= 15; ++mask) {
122 SkRegion rgn;
123 make_rgn(&rgn, w, h, mask);
124
125 SkRasterClip rc;
126 rc.op(rgn, SkRegion::kReplace_Op);
127
128 SkDeviceLooper looper(bitmap, rc, rect, gRec[i].fAA);
129 while (looper.next()) {
130 REPORTER_ASSERT(reporter, !looper.getRC().isEmpty());
131 }
132 }
133 }
134}
135
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000136DEF_TEST(DeviceLooper, reporter) {
reed@google.coma513efb2013-09-17 20:14:52 +0000137 test_simple(reporter);
138 test_complex(reporter);
139}