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