Home | History | Annotate | Download | only in tests
      1 /*
      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 "SkAutoPixmapStorage.h"
      9 #include "SkDeviceLooper.h"
     10 #include "SkRasterClip.h"
     11 #include "Test.h"
     12 
     13 static void make_pm(SkAutoPixmapStorage* pixmap, int w, int h) {
     14     pixmap->alloc(SkImageInfo::Make(w, h, kAlpha_8_SkColorType, kPremul_SkAlphaType));
     15 }
     16 
     17 static 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 
     25 static 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 
     40 static void test_simple(skiatest::Reporter* reporter) {
     41 
     42     for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
     43         SkAutoPixmapStorage pmap;
     44         make_pm(&pmap, gRec[i].fDevSize.width(), gRec[i].fDevSize.height());
     45 
     46         SkRasterClip rc(gRec[i].fRCBounds);
     47 
     48         for (int aa = 0; aa <= 1; ++aa) {
     49             SkDeviceLooper looper(pmap, rc, gRec[i].fRect, SkToBool(aa));
     50 
     51             bool valid = looper.next();
     52             REPORTER_ASSERT(reporter, valid);
     53             if (valid) {
     54                 REPORTER_ASSERT(reporter, looper.getPixmap().width() == pmap.width());
     55                 REPORTER_ASSERT(reporter, looper.getPixmap().height() == pmap.height());
     56                 REPORTER_ASSERT(reporter, equal(looper.getRC(), rc));
     57 
     58                 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(pmap, 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 //
     75 static 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 
     95 static 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     };
    107 
    108     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         SkAutoPixmapStorage pmap;
    113         make_pm(&pmap, 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(pmap, rc, rect, gRec[i].fAA);
    129             while (looper.next()) {
    130                 REPORTER_ASSERT(reporter, !looper.getRC().isEmpty());
    131             }
    132         }
    133     }
    134 }
    135 
    136 DEF_TEST(DeviceLooper, reporter) {
    137     test_simple(reporter);
    138     test_complex(reporter);
    139 }
    140