aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/DeviceLooperTest.cpp
blob: c8eb3c7b7587c724c4993c4d8ae21ea683ac2e67 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkAutoPixmapStorage.h"
#include "SkDeviceLooper.h"
#include "SkRasterClip.h"
#include "Test.h"

static void make_pm(SkAutoPixmapStorage* pixmap, int w, int h) {
    pixmap->alloc(SkImageInfo::Make(w, h, kAlpha_8_SkColorType, kPremul_SkAlphaType));
}

static bool equal(const SkRasterClip& a, const SkRasterClip& b) {
    if (a.isBW()) {
        return b.isBW() && a.bwRgn() == b.bwRgn();
    } else {
        return a.isAA() && a.aaRgn() == b.aaRgn();
    }
}

static const struct {
    SkISize fDevSize;
    SkIRect fRCBounds;
    SkIRect fRect;
} gRec[] = {
    { { 4000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 4000, 4000 } },
    { { 10, 4000 }, { 0, 0, 10, 4000 }, { 0, 0, 4000, 4000 } },
    // very large devce, small rect
    { { 32000, 10 }, { 0, 0, 32000, 10 }, { 0, 0, 4000, 4000 } },
    { { 10, 32000 }, { 0, 0, 10, 32000 }, { 0, 0, 4000, 4000 } },
    // very large device, small clip
    { { 32000, 10 }, { 0, 0, 4000, 10 }, { 0, 0, 32000, 32000 } },
    { { 10, 32000 }, { 0, 0, 10, 4000 }, { 0, 0, 32000, 32000 } },
};

static void test_simple(skiatest::Reporter* reporter) {

    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
        SkAutoPixmapStorage pmap;
        make_pm(&pmap, gRec[i].fDevSize.width(), gRec[i].fDevSize.height());

        SkRasterClip rc(gRec[i].fRCBounds);

        for (int aa = 0; aa <= 1; ++aa) {
            SkDeviceLooper looper(pmap, rc, gRec[i].fRect, SkToBool(aa));

            bool valid = looper.next();
            REPORTER_ASSERT(reporter, valid);
            if (valid) {
                REPORTER_ASSERT(reporter, looper.getPixmap().width() == pmap.width());
                REPORTER_ASSERT(reporter, looper.getPixmap().height() == pmap.height());
                REPORTER_ASSERT(reporter, equal(looper.getRC(), rc));

                REPORTER_ASSERT(reporter, !looper.next());
            }
        }
        // test that a rect that doesn't intersect returns no loops
        {
            SkIRect r = rc.getBounds();
            r.offset(r.width(), 0);
            SkDeviceLooper looper(pmap, rc, r, false);
            REPORTER_ASSERT(reporter, !looper.next());
        }
    }
}

// mask-bits are interpreted as the areas where the clip is visible
//  [ 0x01  0x02 ]
//  [ 0x04  0x08 ]
//
static void make_rgn(SkRegion* rgn, int w, int h, unsigned mask) {
    SkASSERT(SkAlign2(w));
    SkASSERT(SkAlign2(h));
    w >>= 1;
    h >>= 1;
    const SkIRect baseR = SkIRect::MakeWH(w, h);

    int bit = 1;
    for (int y = 0; y <= 1; ++y) {
        for (int x = 0; x <= 1; ++x) {
            if (mask & bit) {
                SkIRect r = baseR;
                r.offset(x * w, y * h);
                rgn->op(r, SkRegion::kUnion_Op);
            }
            bit <<= 1;
        }
    }
}

static void test_complex(skiatest::Reporter* reporter) {
    // choose size values that will result in 4 quadrants, given fAA setting
    const int BW_SIZE = 17 * 1000;
    const int AA_SIZE = 7 * 1000;

    struct {
        SkISize fSize;
        bool    fAA;
    } const gRec[] = {
        { { BW_SIZE, BW_SIZE }, false },
        { {  AA_SIZE, AA_SIZE }, true },
    };

    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
        const int w = gRec[i].fSize.width();
        const int h = gRec[i].fSize.height();

        SkAutoPixmapStorage pmap;
        make_pm(&pmap, w, h);

        const SkIRect rect = SkIRect::MakeWH(w, h);

        // mask-bits are interpreted as the areas where the clip is visible
        //  [ 0x01  0x02 ]
        //  [ 0x04  0x08 ]
        //
        for (int mask = 0; mask <= 15; ++mask) {
            SkRegion rgn;
            make_rgn(&rgn, w, h, mask);

            SkRasterClip rc;
            rc.op(rgn, SkRegion::kReplace_Op);

            SkDeviceLooper looper(pmap, rc, rect, gRec[i].fAA);
            while (looper.next()) {
                REPORTER_ASSERT(reporter, !looper.getRC().isEmpty());
            }
        }
    }
}

DEF_TEST(DeviceLooper, reporter) {
    test_simple(reporter);
    test_complex(reporter);
}