Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2015 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 "GrStrokeInfo.h"
      9 #include "GrTestUtils.h"
     10 #include "SkMatrix.h"
     11 #include "SkPathEffect.h"
     12 #include "SkPath.h"
     13 #include "SkRRect.h"
     14 
     15 #ifdef GR_TEST_UTILS
     16 
     17 static const SkMatrix& test_matrix(SkRandom* random, bool includePerspective) {
     18     static SkMatrix gMatrices[5];
     19     static const int kPerspectiveCount = 1;
     20     static bool gOnce;
     21     if (!gOnce) {
     22         gOnce = true;
     23         gMatrices[0].reset();
     24         gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
     25         gMatrices[2].setRotate(SkIntToScalar(17));
     26         gMatrices[3].setRotate(SkIntToScalar(185));
     27         gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
     28         gMatrices[3].postScale(SkIntToScalar(2), SK_ScalarHalf);
     29 
     30         // Perspective matrices
     31         gMatrices[4].setRotate(SkIntToScalar(215));
     32         gMatrices[4].set(SkMatrix::kMPersp0, 0.00013f);
     33         gMatrices[4].set(SkMatrix::kMPersp1, -0.000039f);
     34     }
     35 
     36     uint32_t count = static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices));
     37     if (includePerspective) {
     38         return gMatrices[random->nextULessThan(count)];
     39     } else {
     40         return gMatrices[random->nextULessThan(count - kPerspectiveCount)];
     41     }
     42 }
     43 
     44 namespace GrTest {
     45 const SkMatrix& TestMatrix(SkRandom* random) { return test_matrix(random, true); }
     46 
     47 const SkMatrix& TestMatrixPreservesRightAngles(SkRandom* random) {
     48     static SkMatrix gMatrices[5];
     49     static bool gOnce;
     50     if (!gOnce) {
     51         gOnce = true;
     52         // identity
     53         gMatrices[0].reset();
     54         // translation
     55         gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
     56         // scale
     57         gMatrices[2].setScale(SkIntToScalar(17), SkIntToScalar(17));
     58         // scale + translation
     59         gMatrices[3].setScale(SkIntToScalar(-17), SkIntToScalar(-17));
     60         gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
     61         // orthogonal basis vectors
     62         gMatrices[4].reset();
     63         gMatrices[4].setScale(SkIntToScalar(-1), SkIntToScalar(-1));
     64         gMatrices[4].setRotate(47);
     65 
     66         for (size_t i = 0; i < SK_ARRAY_COUNT(gMatrices); i++) {
     67             SkASSERT(gMatrices[i].preservesRightAngles());
     68         }
     69     }
     70     return gMatrices[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices)))];
     71 }
     72 
     73 const SkMatrix& TestMatrixRectStaysRect(SkRandom* random) {
     74     static SkMatrix gMatrices[6];
     75     static bool gOnce;
     76     if (!gOnce) {
     77         gOnce = true;
     78         // identity
     79         gMatrices[0].reset();
     80         // translation
     81         gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
     82         // scale
     83         gMatrices[2].setScale(SkIntToScalar(17), SkIntToScalar(17));
     84         // scale + translation
     85         gMatrices[3].setScale(SkIntToScalar(-17), SkIntToScalar(-17));
     86         gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
     87         // reflection
     88         gMatrices[4].setScale(SkIntToScalar(-1), SkIntToScalar(-1));
     89         // 90 degress rotation
     90         gMatrices[5].setRotate(90);
     91 
     92         for (size_t i = 0; i < SK_ARRAY_COUNT(gMatrices); i++) {
     93             SkASSERT(gMatrices[i].rectStaysRect());
     94         }
     95     }
     96     return gMatrices[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices)))];
     97 }
     98 
     99 const SkMatrix& TestMatrixInvertible(SkRandom* random) { return test_matrix(random, false); }
    100 
    101 const SkRect& TestRect(SkRandom* random) {
    102     static SkRect gRects[7];
    103     static bool gOnce;
    104     if (!gOnce) {
    105         gOnce = true;
    106         gRects[0] = SkRect::MakeWH(1.f, 1.f);
    107         gRects[1] = SkRect::MakeWH(1.0f, 256.0f);
    108         gRects[2] = SkRect::MakeWH(256.0f, 1.0f);
    109         gRects[3] = SkRect::MakeLargest();
    110         gRects[4] = SkRect::MakeLTRB(-65535.0f, -65535.0f, 65535.0f, 65535.0f);
    111         gRects[5] = SkRect::MakeLTRB(-10.0f, -10.0f, 10.0f, 10.0f);
    112     }
    113     return gRects[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRects)))];
    114 }
    115 
    116 // Just some simple rects for code which expects its input very sanitized
    117 const SkRect& TestSquare(SkRandom* random) {
    118     static SkRect gRects[2];
    119     static bool gOnce;
    120     if (!gOnce) {
    121         gOnce = true;
    122         gRects[0] = SkRect::MakeWH(128.f, 128.f);
    123         gRects[1] = SkRect::MakeWH(256.0f, 256.0f);
    124     }
    125     return gRects[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRects)))];
    126 }
    127 
    128 const SkRRect& TestRRectSimple(SkRandom* random) {
    129     static SkRRect gRRect[2];
    130     static bool gOnce;
    131     if (!gOnce) {
    132         gOnce = true;
    133         SkRect rectangle = SkRect::MakeWH(10.f, 20.f);
    134         // true round rect with circular corners
    135         gRRect[0].setRectXY(rectangle, 1.f, 1.f);
    136         // true round rect with elliptical corners
    137         gRRect[1].setRectXY(rectangle, 2.0f, 1.0f);
    138 
    139         for (size_t i = 0; i < SK_ARRAY_COUNT(gRRect); i++) {
    140             SkASSERT(gRRect[i].isSimple());
    141         }
    142     }
    143     return gRRect[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRRect)))];
    144 }
    145 
    146 const SkPath& TestPath(SkRandom* random) {
    147     static SkPath gPath[7];
    148     static bool gOnce;
    149     if (!gOnce) {
    150         gOnce = true;
    151         // line
    152         gPath[0].moveTo(0.f, 0.f);
    153         gPath[0].lineTo(10.f, 10.f);
    154         // quad
    155         gPath[1].moveTo(0.f, 0.f);
    156         gPath[1].quadTo(10.f, 10.f, 20.f, 20.f);
    157         // conic
    158         gPath[2].moveTo(0.f, 0.f);
    159         gPath[2].conicTo(10.f, 10.f, 20.f, 20.f, 1.f);
    160         // cubic
    161         gPath[3].moveTo(0.f, 0.f);
    162         gPath[3].cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f);
    163         // all three
    164         gPath[4].moveTo(0.f, 0.f);
    165         gPath[4].lineTo(10.f, 10.f);
    166         gPath[4].quadTo(10.f, 10.f, 20.f, 20.f);
    167         gPath[4].conicTo(10.f, 10.f, 20.f, 20.f, 1.f);
    168         gPath[4].cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f);
    169         // convex
    170         gPath[5].moveTo(0.0f, 0.0f);
    171         gPath[5].lineTo(10.0f, 0.0f);
    172         gPath[5].lineTo(10.0f, 10.0f);
    173         gPath[5].lineTo(0.0f, 10.0f);
    174         gPath[5].close();
    175         // concave
    176         gPath[6].moveTo(0.0f, 0.0f);
    177         gPath[6].lineTo(5.0f, 5.0f);
    178         gPath[6].lineTo(10.0f, 0.0f);
    179         gPath[6].lineTo(10.0f, 10.0f);
    180         gPath[6].lineTo(0.0f, 10.0f);
    181         gPath[6].close();
    182     }
    183 
    184     return gPath[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gPath)))];
    185 }
    186 
    187 const SkPath& TestPathConvex(SkRandom* random) {
    188     static SkPath gPath[3];
    189     static bool gOnce;
    190     if (!gOnce) {
    191         gOnce = true;
    192         // narrow rect
    193         gPath[0].moveTo(-1.5f, -50.0f);
    194         gPath[0].lineTo(-1.5f, -50.0f);
    195         gPath[0].lineTo( 1.5f, -50.0f);
    196         gPath[0].lineTo( 1.5f,  50.0f);
    197         gPath[0].lineTo(-1.5f,  50.0f);
    198         // degenerate
    199         gPath[1].moveTo(-0.025f, -0.025f);
    200         gPath[1].lineTo(-0.025f, -0.025f);
    201         gPath[1].lineTo( 0.025f, -0.025f);
    202         gPath[1].lineTo( 0.025f,  0.025f);
    203         gPath[1].lineTo(-0.025f,  0.025f);
    204         // clipped triangle
    205         gPath[2].moveTo(-10.0f, -50.0f);
    206         gPath[2].lineTo(-10.0f, -50.0f);
    207         gPath[2].lineTo( 10.0f, -50.0f);
    208         gPath[2].lineTo( 50.0f,  31.0f);
    209         gPath[2].lineTo( 40.0f,  50.0f);
    210         gPath[2].lineTo(-40.0f,  50.0f);
    211         gPath[2].lineTo(-50.0f,  31.0f);
    212 
    213         for (size_t i = 0; i < SK_ARRAY_COUNT(gPath); i++) {
    214             SkASSERT(SkPath::kConvex_Convexity == gPath[i].getConvexity());
    215         }
    216     }
    217 
    218     return gPath[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gPath)))];
    219 }
    220 
    221 static void randomize_stroke_rec(SkStrokeRec* rec, SkRandom* random) {
    222     bool strokeAndFill = random->nextBool();
    223     SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f;
    224     rec->setStrokeStyle(strokeWidth, strokeAndFill);
    225 
    226     SkPaint::Cap cap = SkPaint::Cap(random->nextULessThan(SkPaint::kCapCount));
    227     SkPaint::Join join = SkPaint::Join(random->nextULessThan(SkPaint::kJoinCount));
    228     SkScalar miterLimit = random->nextRangeScalar(1.f, 5.f);
    229     rec->setStrokeParams(cap, join, miterLimit);
    230 }
    231 
    232 SkStrokeRec TestStrokeRec(SkRandom* random) {
    233     SkStrokeRec::InitStyle style =
    234             SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1));
    235     SkStrokeRec rec(style);
    236     randomize_stroke_rec(&rec, random);
    237     return rec;
    238 }
    239 
    240 GrStrokeInfo TestStrokeInfo(SkRandom* random) {
    241     SkStrokeRec::InitStyle style =
    242             SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1));
    243     GrStrokeInfo strokeInfo(style);
    244     randomize_stroke_rec(&strokeInfo, random);
    245     SkPathEffect::DashInfo dashInfo;
    246     dashInfo.fCount = random->nextRangeU(1, 50) * 2;
    247     dashInfo.fIntervals = new SkScalar[dashInfo.fCount];
    248     SkScalar sum = 0;
    249     for (int i = 0; i < dashInfo.fCount; i++) {
    250         dashInfo.fIntervals[i] = random->nextRangeScalar(SkDoubleToScalar(0.01),
    251                                                          SkDoubleToScalar(10.0));
    252         sum += dashInfo.fIntervals[i];
    253     }
    254     dashInfo.fPhase = random->nextRangeScalar(0, sum);
    255     strokeInfo.setDashInfo(dashInfo);
    256     delete[] dashInfo.fIntervals;
    257     return strokeInfo;
    258 }
    259 
    260 };
    261 
    262 #endif
    263