180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
7910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "Test.h"
9910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#include "TestClassDef.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBitmap.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkCanvas.h"
120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkData.h"
13910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#include "SkDiscardableMemoryPool.h"
14910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#include "SkImageGenerator.h"
150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkPaint.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkShader.h"
170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkSurface.h"
18d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "SkRandom.h"
19d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "SkMatrixUtils.h"
20d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
21910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergernamespace {
220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// A BitmapFactory that always fails when asked to return pixels.
23910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerclass FailureImageGenerator : public SkImageGenerator {
24910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenbergerpublic:
25910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    FailureImageGenerator() { }
26910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    virtual ~FailureImageGenerator() { }
27910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    virtual bool getInfo(SkImageInfo* info) {
28910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        info->fWidth = 100;
29910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        info->fHeight = 100;
30910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        info->fColorType = kPMColor_SkColorType;
310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        info->fAlphaType = kPremul_SkAlphaType;
32910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        return true;
330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
34910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    virtual bool getPixels(const SkImageInfo& info,
35910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                           void* pixels,
36910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                           size_t rowBytes) SK_OVERRIDE {
37910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        // this will deliberately return false if they are asking us
38910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        // to decode into pixels.
39910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        return false;
40910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    }
41910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger};
42910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger}  // namespace
430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// crbug.com/295895
450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger// Crashing in skia when a pixelref fails in lockPixels
460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger//
470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic void test_faulty_pixelref(skiatest::Reporter* reporter) {
480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // need a cache, but don't expect to use it, so the budget is not critical
49910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    SkAutoTUnref<SkDiscardableMemoryPool> pool(SkNEW_ARGS(SkDiscardableMemoryPool,
50910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                                                          (10 * 1000, NULL)));
510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkBitmap bm;
52910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    bool installSuccess = SkInstallDiscardablePixelRef(SkNEW(FailureImageGenerator), &bm, pool);
53910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    REPORTER_ASSERT(reporter, installSuccess);
540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // now our bitmap has a pixelref, but we know it will fail to lock
550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(200, 200));
570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkCanvas* canvas = surface->getCanvas();
580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const SkPaint::FilterLevel levels[] = {
600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkPaint::kNone_FilterLevel,
610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkPaint::kLow_FilterLevel,
620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkPaint::kMedium_FilterLevel,
630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkPaint::kHigh_FilterLevel,
640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    };
650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkPaint paint;
670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    canvas->scale(2, 2);    // need a scale, otherwise we may ignore filtering
680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    for (size_t i = 0; i < SK_ARRAY_COUNT(levels); ++i) {
690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        paint.setFilterLevel(levels[i]);
700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        canvas->drawBitmap(bm, 0, 0, &paint);
710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic void rand_matrix(SkMatrix* mat, SkRandom& rand, unsigned mask) {
77d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat->setIdentity();
78d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (mask & SkMatrix::kTranslate_Mask) {
79d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        mat->postTranslate(rand.nextSScalar1(), rand.nextSScalar1());
80d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
81d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (mask & SkMatrix::kScale_Mask) {
82d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        mat->postScale(rand.nextSScalar1(), rand.nextSScalar1());
83d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
84d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (mask & SkMatrix::kAffine_Mask) {
85d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        mat->postRotate(rand.nextSScalar1() * 360);
86d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
87d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (mask & SkMatrix::kPerspective_Mask) {
88d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        mat->setPerspX(rand.nextSScalar1());
89d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        mat->setPerspY(rand.nextSScalar1());
90d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
91d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
92d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic void rand_size(SkISize* size, SkRandom& rand) {
94d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    size->set(rand.nextU() & 0xFFFF, rand.nextU() & 0xFFFF);
95d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
96d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
97d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic bool treat_as_sprite(const SkMatrix& mat, const SkISize& size,
98d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                            unsigned bits) {
99d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    return SkTreatAsSprite(mat, size.width(), size.height(), bits);
100d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
101d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
102d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic void test_treatAsSprite(skiatest::Reporter* reporter) {
103d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const unsigned bilerBits = kSkSubPixelBitsForBilerp;
104d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
105d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    SkMatrix mat;
106d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    SkISize  size;
1070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkRandom rand;
108d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
109d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // assert: translate-only no-filter can always be treated as sprite
110d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    for (int i = 0; i < 1000; ++i) {
111d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        rand_matrix(&mat, rand, SkMatrix::kTranslate_Mask);
112d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        for (int j = 0; j < 1000; ++j) {
113d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            rand_size(&size, rand);
114d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, 0));
115d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        }
116d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
117d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
118d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // assert: rotate/perspect is never treated as sprite
119d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    for (int i = 0; i < 1000; ++i) {
120d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        rand_matrix(&mat, rand, SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask);
121d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        for (int j = 0; j < 1000; ++j) {
122d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            rand_size(&size, rand);
123d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, 0));
124d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
125d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        }
126d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
127d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
128d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    size.set(500, 600);
129d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
130910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    const SkScalar tooMuchSubpixel = 100.1f;
131d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setTranslate(tooMuchSubpixel, 0);
132d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
133d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setTranslate(0, tooMuchSubpixel);
134d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
135d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
136910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    const SkScalar tinySubPixel = 100.02f;
137d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setTranslate(tinySubPixel, 0);
138d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits));
139d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setTranslate(0, tinySubPixel);
140d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits));
141d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
142d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar twoThirds = SK_Scalar1 * 2 / 3;
143d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar bigScale = SkScalarDiv(size.width() + twoThirds, size.width());
144d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setScale(bigScale, bigScale);
145d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, false));
146d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
147d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
148d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar oneThird = SK_Scalar1 / 3;
149d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar smallScale = SkScalarDiv(size.width() + oneThird, size.width());
150d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setScale(smallScale, smallScale);
151d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false));
152d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits));
153d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
154d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar oneFortyth = SK_Scalar1 / 40;
155d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    const SkScalar tinyScale = SkScalarDiv(size.width() + oneFortyth, size.width());
156d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    mat.setScale(tinyScale, tinyScale);
157d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false));
158d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits));
159d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void assert_ifDrawnTo(skiatest::Reporter* reporter,
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             const SkBitmap& bm, bool shouldBeDrawn) {
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int y = 0; y < bm.height(); ++y) {
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int x = 0; x < bm.width(); ++x) {
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (shouldBeDrawn) {
16658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                if (SK_ColorTRANSPARENT == *bm.getAddr32(x, y)) {
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    REPORTER_ASSERT(reporter, false);
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    return;
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else {
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // should not be drawn
17258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                if (SK_ColorTRANSPARENT != *bm.getAddr32(x, y)) {
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    REPORTER_ASSERT(reporter, false);
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    return;
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_wacky_bitmapshader(skiatest::Reporter* reporter,
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    int width, int height, bool shouldBeDrawn) {
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap dev;
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dev.setConfig(SkBitmap::kARGB_8888_Config, 0x56F, 0x4f6);
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dev.allocPixels();
186363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    dev.eraseColor(SK_ColorTRANSPARENT);  // necessary, so we know if we draw to it
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix matrix;
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkCanvas c(dev);
191910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    matrix.setAll(-119.34097f,
192910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                  -43.436558f,
193910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                  93489.945f,
194910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                  43.436558f,
195910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                  -119.34097f,
196910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                  123.98426f,
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  0, 0, SK_Scalar1);
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    c.concat(matrix);
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap bm;
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.setConfig(SkBitmap::kARGB_8888_Config, width, height);
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.allocPixels();
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.eraseColor(SK_ColorRED);
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                               SkShader::kRepeat_TileMode);
207910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    matrix.setAll(0.0078740157f,
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  0,
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  SkIntToScalar(249),
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  0,
211910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                  0.0078740157f,
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  SkIntToScalar(239),
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                  0, 0, SK_Scalar1);
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    s->setLocalMatrix(matrix);
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setShader(s)->unref();
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect r = SkRect::MakeXYWH(681, 239, 695, 253);
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    c.drawRect(r, paint);
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    assert_ifDrawnTo(reporter, dev, shouldBeDrawn);
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  Original bug was asserting that the matrix-proc had generated a (Y) value
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  that was out of range. This led (in the release build) to the sampler-proc
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  reading memory out-of-bounds of the original bitmap.
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  We were numerically overflowing our 16bit coordinates that we communicate
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  between these two procs. The fixes was in two parts:
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  1. Just don't draw bitmaps larger than 64K-1 in width or height, since we
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *     can't represent those coordinates in our transport format (yet).
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  2. Perform an unsigned shift during the calculation, so we don't get
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *     sign-extension bleed when packing the two values (X,Y) into our 32bit
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *     slot.
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  This tests exercises the original setup, plus 3 more to ensure that we can,
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  in fact, handle bitmaps at 64K-1 (assuming we don't exceed the total
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  memory allocation limit).
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void test_giantrepeat_crbug118018(skiatest::Reporter* reporter) {
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const struct {
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int fWidth;
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int fHeight;
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool fExpectedToDraw;
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } gTests[] = {
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { 0x1b294, 0x7f,  false },   // crbug 118018 (width exceeds 64K)
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { 0xFFFF, 0x7f,    true },   // should draw, test max width
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { 0x7f, 0xFFFF,    true },   // should draw, test max height
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        { 0xFFFF, 0xFFFF, false },   // allocation fails (too much RAM)
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); ++i) {
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        test_wacky_bitmapshader(reporter,
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                gTests[i].fWidth, gTests[i].fHeight,
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                gTests[i].fExpectedToDraw);
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
266096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerstatic void test_nan_antihair() {
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap bm;
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.setConfig(SkBitmap::kARGB_8888_Config, 20, 20);
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm.allocPixels();
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkCanvas canvas(bm);
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPath path;
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    path.moveTo(0, 0);
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    path.lineTo(10, SK_ScalarNaN);
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPaint paint;
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setAntiAlias(true);
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    paint.setStyle(SkPaint::kStroke_Style);
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // before our fix to SkScan_Antihair.cpp to check for integral NaN (0x800...)
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // this would trigger an assert/crash.
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // see rev. 3558
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawPath(path, paint);
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool check_for_all_zeros(const SkBitmap& bm) {
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoLockPixels alp(bm);
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t count = bm.width() * bm.bytesPerPixel();
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int y = 0; y < bm.height(); y++) {
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint8_t* ptr = reinterpret_cast<const uint8_t*>(bm.getAddr(0, y));
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (size_t i = 0; i < count; i++) {
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (ptr[i]) {
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int gWidth = 256;
30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int gHeight = 256;
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void create(SkBitmap* bm, SkBitmap::Config config, SkColor color) {
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm->setConfig(config, gWidth, gHeight);
30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm->allocPixels();
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bm->eraseColor(color);
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
312910f694aefb0b671dd8522a9afe9b6be645701c1Derek SollenbergerDEF_TEST(DrawBitmapRect, reporter) {
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBitmap src, dst;
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    create(&src, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    create(&dst, SkBitmap::kARGB_8888_Config, 0);
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkCanvas canvas(dst);
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkIRect srcR = { gWidth, 0, gWidth + 16, 16 };
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect  dstR = { 0, 0, SkIntToScalar(16), SkIntToScalar(16) };
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas.drawBitmapRect(src, &srcR, dstR, NULL);
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // ensure that we draw nothing if srcR does not intersect the bitmap
32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    REPORTER_ASSERT(reporter, check_for_all_zeros(dst));
32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
328096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    test_nan_antihair();
32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    test_giantrepeat_crbug118018(reporter);
330d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
331d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    test_treatAsSprite(reporter);
3320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    test_faulty_pixelref(reporter);
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
334