180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "Test.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBitmap.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkCanvas.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkShader.h"
12d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "SkRandom.h"
13d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "SkMatrixUtils.h"
14d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
15096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerstatic void rand_matrix(SkMatrix* mat, SkMWCRandom& rand, unsigned mask) {
16d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat->setIdentity();
17d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (mask & SkMatrix::kTranslate_Mask) {
18d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        mat->postTranslate(rand.nextSScalar1(), rand.nextSScalar1());
19d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
20d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (mask & SkMatrix::kScale_Mask) {
21d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        mat->postScale(rand.nextSScalar1(), rand.nextSScalar1());
22d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
23d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (mask & SkMatrix::kAffine_Mask) {
24d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        mat->postRotate(rand.nextSScalar1() * 360);
25d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
26d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (mask & SkMatrix::kPerspective_Mask) {
27d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        mat->setPerspX(rand.nextSScalar1());
28d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        mat->setPerspY(rand.nextSScalar1());
29d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
30d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
31d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
32096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerstatic void rand_size(SkISize* size, SkMWCRandom& rand) {
33d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    size->set(rand.nextU() & 0xFFFF, rand.nextU() & 0xFFFF);
34d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
35d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
36d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic bool treat_as_sprite(const SkMatrix& mat, const SkISize& size,
37d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                            unsigned bits) {
38d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    return SkTreatAsSprite(mat, size.width(), size.height(), bits);
39d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
40d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
41d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic void test_treatAsSprite(skiatest::Reporter* reporter) {
42d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const unsigned bilerBits = kSkSubPixelBitsForBilerp;
43d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
44d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    SkMatrix mat;
45d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    SkISize  size;
46096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkMWCRandom rand;
47d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
48d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // assert: translate-only no-filter can always be treated as sprite
49d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    for (int i = 0; i < 1000; ++i) {
50d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        rand_matrix(&mat, rand, SkMatrix::kTranslate_Mask);
51d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        for (int j = 0; j < 1000; ++j) {
52d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            rand_size(&size, rand);
53d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, 0));
54d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        }
55d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
56d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
57d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // assert: rotate/perspect is never treated as sprite
58d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    for (int i = 0; i < 1000; ++i) {
59d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        rand_matrix(&mat, rand, SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask);
60d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        for (int j = 0; j < 1000; ++j) {
61d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            rand_size(&size, rand);
62d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, 0));
63d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
64d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        }
65d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
66d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
67d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    size.set(500, 600);
68d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
69d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar tooMuchSubpixel = SkFloatToScalar(100.1f);
70d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setTranslate(tooMuchSubpixel, 0);
71d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
72d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setTranslate(0, tooMuchSubpixel);
73d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
74d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
75d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar tinySubPixel = SkFloatToScalar(100.02f);
76d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setTranslate(tinySubPixel, 0);
77d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits));
78d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setTranslate(0, tinySubPixel);
79d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits));
80d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
81d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar twoThirds = SK_Scalar1 * 2 / 3;
82d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar bigScale = SkScalarDiv(size.width() + twoThirds, size.width());
83d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setScale(bigScale, bigScale);
84d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, false));
85d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
86d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
87d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar oneThird = SK_Scalar1 / 3;
88d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar smallScale = SkScalarDiv(size.width() + oneThird, size.width());
89d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setScale(smallScale, smallScale);
90d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false));
91d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
92d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
93d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar oneFortyth = SK_Scalar1 / 40;
94d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar tinyScale = SkScalarDiv(size.width() + oneFortyth, size.width());
95d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setScale(tinyScale, tinyScale);
96d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false));
97d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits));
98d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void assert_ifDrawnTo(skiatest::Reporter* reporter,
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             const SkBitmap& bm, bool shouldBeDrawn) {
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int y = 0; y < bm.height(); ++y) {
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int x = 0; x < bm.width(); ++x) {
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (shouldBeDrawn) {
10558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                if (SK_ColorTRANSPARENT == *bm.getAddr32(x, y)) {
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    REPORTER_ASSERT(reporter, false);
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    return;
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else {
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // should not be drawn
11158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                if (SK_ColorTRANSPARENT != *bm.getAddr32(x, y)) {
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    REPORTER_ASSERT(reporter, false);
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    return;
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_wacky_bitmapshader(skiatest::Reporter* reporter,
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    int width, int height, bool shouldBeDrawn) {
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap dev;
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dev.setConfig(SkBitmap::kARGB_8888_Config, 0x56F, 0x4f6);
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dev.allocPixels();
125363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    dev.eraseColor(SK_ColorTRANSPARENT);  // necessary, so we know if we draw to it
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix matrix;
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkCanvas c(dev);
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix.setAll(SkFloatToScalar(-119.34097f),
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  SkFloatToScalar(-43.436558f),
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  SkFloatToScalar(93489.945f),
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  SkFloatToScalar(43.436558f),
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  SkFloatToScalar(-119.34097f),
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  SkFloatToScalar(123.98426f),
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  0, 0, SK_Scalar1);
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    c.concat(matrix);
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap bm;
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.setConfig(SkBitmap::kARGB_8888_Config, width, height);
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.allocPixels();
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.eraseColor(SK_ColorRED);
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                               SkShader::kRepeat_TileMode);
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix.setAll(SkFloatToScalar(0.0078740157f),
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  0,
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  SkIntToScalar(249),
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  0,
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  SkFloatToScalar(0.0078740157f),
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  SkIntToScalar(239),
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  0, 0, SK_Scalar1);
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    s->setLocalMatrix(matrix);
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setShader(s)->unref();
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect r = SkRect::MakeXYWH(681, 239, 695, 253);
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    c.drawRect(r, paint);
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    assert_ifDrawnTo(reporter, dev, shouldBeDrawn);
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  Original bug was asserting that the matrix-proc had generated a (Y) value
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  that was out of range. This led (in the release build) to the sampler-proc
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  reading memory out-of-bounds of the original bitmap.
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  We were numerically overflowing our 16bit coordinates that we communicate
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  between these two procs. The fixes was in two parts:
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  1. Just don't draw bitmaps larger than 64K-1 in width or height, since we
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *     can't represent those coordinates in our transport format (yet).
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  2. Perform an unsigned shift during the calculation, so we don't get
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *     sign-extension bleed when packing the two values (X,Y) into our 32bit
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *     slot.
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  This tests exercises the original setup, plus 3 more to ensure that we can,
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  in fact, handle bitmaps at 64K-1 (assuming we don't exceed the total
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  memory allocation limit).
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_giantrepeat_crbug118018(skiatest::Reporter* reporter) {
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const struct {
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int fWidth;
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int fHeight;
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool fExpectedToDraw;
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } gTests[] = {
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { 0x1b294, 0x7f,  false },   // crbug 118018 (width exceeds 64K)
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { 0xFFFF, 0x7f,    true },   // should draw, test max width
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { 0x7f, 0xFFFF,    true },   // should draw, test max height
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { 0xFFFF, 0xFFFF, false },   // allocation fails (too much RAM)
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); ++i) {
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        test_wacky_bitmapshader(reporter,
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                gTests[i].fWidth, gTests[i].fHeight,
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                gTests[i].fExpectedToDraw);
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
205096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerstatic void test_nan_antihair() {
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap bm;
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.setConfig(SkBitmap::kARGB_8888_Config, 20, 20);
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.allocPixels();
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkCanvas canvas(bm);
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPath path;
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    path.moveTo(0, 0);
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    path.lineTo(10, SK_ScalarNaN);
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setAntiAlias(true);
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setStyle(SkPaint::kStroke_Style);
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // before our fix to SkScan_Antihair.cpp to check for integral NaN (0x800...)
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // this would trigger an assert/crash.
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // see rev. 3558
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawPath(path, paint);
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool check_for_all_zeros(const SkBitmap& bm) {
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoLockPixels alp(bm);
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t count = bm.width() * bm.bytesPerPixel();
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int y = 0; y < bm.height(); y++) {
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint8_t* ptr = reinterpret_cast<const uint8_t*>(bm.getAddr(0, y));
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (size_t i = 0; i < count; i++) {
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (ptr[i]) {
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int gWidth = 256;
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int gHeight = 256;
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void create(SkBitmap* bm, SkBitmap::Config config, SkColor color) {
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm->setConfig(config, gWidth, gHeight);
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm->allocPixels();
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm->eraseColor(color);
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void TestDrawBitmapRect(skiatest::Reporter* reporter) {
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap src, dst;
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    create(&src, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    create(&dst, SkBitmap::kARGB_8888_Config, 0);
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkCanvas canvas(dst);
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkIRect srcR = { gWidth, 0, gWidth + 16, 16 };
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect  dstR = { 0, 0, SkIntToScalar(16), SkIntToScalar(16) };
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawBitmapRect(src, &srcR, dstR, NULL);
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // ensure that we draw nothing if srcR does not intersect the bitmap
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, check_for_all_zeros(dst));
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
267096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    test_nan_antihair();
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    test_giantrepeat_crbug118018(reporter);
269d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
270d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    test_treatAsSprite(reporter);
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "TestClassDef.h"
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruDEFINE_TESTCLASS("DrawBitmapRect", TestDrawBitmapRectClass, TestDrawBitmapRect)
275