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 "Test.h"
      9 #include "TestClassDef.h"
     10 #include "SkDeviceLooper.h"
     11 #include "SkRasterClip.h"
     12 
     13 static void make_bm(SkBitmap* bm, int w, int h) {
     14     bm->setConfig(SkBitmap::kA8_Config, w, h);
     15     bm->allocPixels();
     16 }
     17 
     18 static 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 
     26 static 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 
     41 static void test_simple(skiatest::Reporter* reporter) {
     42 
     43     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());
     46 
     47         SkRasterClip rc(gRec[i].fRCBounds);
     48 
     49         for (int aa = 0; aa <= 1; ++aa) {
     50             SkDeviceLooper looper(bitmap, rc, gRec[i].fRect, SkToBool(aa));
     51 
     52             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));
     58 
     59                 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 //
     76 static 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 
     96 static 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     };
    108 
    109     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 
    137 DEF_TEST(DeviceLooper, reporter) {
    138     test_simple(reporter);
    139     test_complex(reporter);
    140 }
    141