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