Home | History | Annotate | Download | only in tests
      1 
      2 /*
      3  * Copyright 2013 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #include "SkBitmap.h"
     10 #include "SkBitmapDevice.h"
     11 #include "SkBlurImageFilter.h"
     12 #include "SkCanvas.h"
     13 #include "SkColorFilterImageFilter.h"
     14 #include "SkColorMatrixFilter.h"
     15 #include "SkComposeImageFilter.h"
     16 #include "SkDisplacementMapEffect.h"
     17 #include "SkDropShadowImageFilter.h"
     18 #include "SkFlattenableSerialization.h"
     19 #include "SkGradientShader.h"
     20 #include "SkImage.h"
     21 #include "SkImageSource.h"
     22 #include "SkLightingImageFilter.h"
     23 #include "SkMatrixConvolutionImageFilter.h"
     24 #include "SkMergeImageFilter.h"
     25 #include "SkMorphologyImageFilter.h"
     26 #include "SkOffsetImageFilter.h"
     27 #include "SkPaintImageFilter.h"
     28 #include "SkPerlinNoiseShader.h"
     29 #include "SkPicture.h"
     30 #include "SkPictureImageFilter.h"
     31 #include "SkPictureRecorder.h"
     32 #include "SkPoint3.h"
     33 #include "SkReadBuffer.h"
     34 #include "SkRect.h"
     35 #include "SkSurface.h"
     36 #include "SkTableColorFilter.h"
     37 #include "SkTileImageFilter.h"
     38 #include "SkXfermodeImageFilter.h"
     39 #include "Test.h"
     40 
     41 #if SK_SUPPORT_GPU
     42 #include "GrContext.h"
     43 #include "SkGpuDevice.h"
     44 #endif
     45 
     46 static const int kBitmapSize = 4;
     47 
     48 namespace {
     49 
     50 class MatrixTestImageFilter : public SkImageFilter {
     51 public:
     52     MatrixTestImageFilter(skiatest::Reporter* reporter, const SkMatrix& expectedMatrix)
     53       : SkImageFilter(0, nullptr), fReporter(reporter), fExpectedMatrix(expectedMatrix) {
     54     }
     55 
     56     bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context& ctx,
     57                                  SkBitmap* result, SkIPoint* offset) const override {
     58         REPORTER_ASSERT(fReporter, ctx.ctm() == fExpectedMatrix);
     59         return true;
     60     }
     61 
     62     SK_TO_STRING_OVERRIDE()
     63     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(MatrixTestImageFilter)
     64 
     65 protected:
     66     void flatten(SkWriteBuffer& buffer) const override {
     67         this->INHERITED::flatten(buffer);
     68         buffer.writeFunctionPtr(fReporter);
     69         buffer.writeMatrix(fExpectedMatrix);
     70     }
     71 
     72 private:
     73     skiatest::Reporter* fReporter;
     74     SkMatrix fExpectedMatrix;
     75 
     76     typedef SkImageFilter INHERITED;
     77 };
     78 
     79 }
     80 
     81 SkFlattenable* MatrixTestImageFilter::CreateProc(SkReadBuffer& buffer) {
     82     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
     83     skiatest::Reporter* reporter = (skiatest::Reporter*)buffer.readFunctionPtr();
     84     SkMatrix matrix;
     85     buffer.readMatrix(&matrix);
     86     return new MatrixTestImageFilter(reporter, matrix);
     87 }
     88 
     89 #ifndef SK_IGNORE_TO_STRING
     90 void MatrixTestImageFilter::toString(SkString* str) const {
     91     str->appendf("MatrixTestImageFilter: (");
     92     str->append(")");
     93 }
     94 #endif
     95 
     96 static SkImage* make_small_image() {
     97     SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(kBitmapSize, kBitmapSize));
     98     SkCanvas* canvas = surface->getCanvas();
     99     canvas->clear(0x00000000);
    100     SkPaint darkPaint;
    101     darkPaint.setColor(0xFF804020);
    102     SkPaint lightPaint;
    103     lightPaint.setColor(0xFF244484);
    104     const int i = kBitmapSize / 4;
    105     for (int y = 0; y < kBitmapSize; y += i) {
    106         for (int x = 0; x < kBitmapSize; x += i) {
    107             canvas->save();
    108             canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
    109             canvas->drawRect(SkRect::MakeXYWH(0, 0,
    110                                              SkIntToScalar(i),
    111                                              SkIntToScalar(i)), darkPaint);
    112             canvas->drawRect(SkRect::MakeXYWH(SkIntToScalar(i),
    113                                              0,
    114                                              SkIntToScalar(i),
    115                                              SkIntToScalar(i)), lightPaint);
    116             canvas->drawRect(SkRect::MakeXYWH(0,
    117                                              SkIntToScalar(i),
    118                                              SkIntToScalar(i),
    119                                              SkIntToScalar(i)), lightPaint);
    120             canvas->drawRect(SkRect::MakeXYWH(SkIntToScalar(i),
    121                                              SkIntToScalar(i),
    122                                              SkIntToScalar(i),
    123                                              SkIntToScalar(i)), darkPaint);
    124             canvas->restore();
    125         }
    126     }
    127 
    128     return surface->newImageSnapshot();
    129 }
    130 
    131 static SkImageFilter* make_scale(float amount, SkImageFilter* input = nullptr) {
    132     SkScalar s = amount;
    133     SkScalar matrix[20] = { s, 0, 0, 0, 0,
    134                             0, s, 0, 0, 0,
    135                             0, 0, s, 0, 0,
    136                             0, 0, 0, s, 0 };
    137     SkAutoTUnref<SkColorFilter> filter(SkColorMatrixFilter::Create(matrix));
    138     return SkColorFilterImageFilter::Create(filter, input);
    139 }
    140 
    141 static SkImageFilter* make_grayscale(SkImageFilter* input, const SkImageFilter::CropRect* cropRect) {
    142     SkScalar matrix[20];
    143     memset(matrix, 0, 20 * sizeof(SkScalar));
    144     matrix[0] = matrix[5] = matrix[10] = 0.2126f;
    145     matrix[1] = matrix[6] = matrix[11] = 0.7152f;
    146     matrix[2] = matrix[7] = matrix[12] = 0.0722f;
    147     matrix[18] = 1.0f;
    148     SkAutoTUnref<SkColorFilter> filter(SkColorMatrixFilter::Create(matrix));
    149     return SkColorFilterImageFilter::Create(filter, input, cropRect);
    150 }
    151 
    152 static SkImageFilter* make_blue(SkImageFilter* input, const SkImageFilter::CropRect* cropRect) {
    153     SkAutoTUnref<SkColorFilter> filter(SkColorFilter::CreateModeFilter(SK_ColorBLUE,
    154                                                                        SkXfermode::kSrcIn_Mode));
    155     return SkColorFilterImageFilter::Create(filter, input, cropRect);
    156 }
    157 
    158 DEF_TEST(ImageFilter, reporter) {
    159     {
    160         // Check that two non-clipping color-matrice-filters concatenate into a single filter.
    161         SkAutoTUnref<SkImageFilter> halfBrightness(make_scale(0.5f));
    162         SkAutoTUnref<SkImageFilter> quarterBrightness(make_scale(0.5f, halfBrightness));
    163         REPORTER_ASSERT(reporter, nullptr == quarterBrightness->getInput(0));
    164         SkColorFilter* cf;
    165         REPORTER_ASSERT(reporter, quarterBrightness->asColorFilter(&cf));
    166         REPORTER_ASSERT(reporter, cf->asColorMatrix(nullptr));
    167         cf->unref();
    168     }
    169 
    170     {
    171         // Check that a clipping color-matrice-filter followed by a color-matrice-filters
    172         // concatenates into a single filter, but not a matrixfilter (due to clamping).
    173         SkAutoTUnref<SkImageFilter> doubleBrightness(make_scale(2.0f));
    174         SkAutoTUnref<SkImageFilter> halfBrightness(make_scale(0.5f, doubleBrightness));
    175         REPORTER_ASSERT(reporter, nullptr == halfBrightness->getInput(0));
    176         SkColorFilter* cf;
    177         REPORTER_ASSERT(reporter, halfBrightness->asColorFilter(&cf));
    178         REPORTER_ASSERT(reporter, !cf->asColorMatrix(nullptr));
    179         cf->unref();
    180     }
    181 
    182     {
    183         // Check that a color filter image filter without a crop rect can be
    184         // expressed as a color filter.
    185         SkAutoTUnref<SkImageFilter> gray(make_grayscale(nullptr, nullptr));
    186         REPORTER_ASSERT(reporter, true == gray->asColorFilter(nullptr));
    187     }
    188 
    189     {
    190         // Check that a colorfilterimage filter without a crop rect but with an input
    191         // that is another colorfilterimage can be expressed as a colorfilter (composed).
    192         SkAutoTUnref<SkImageFilter> mode(make_blue(nullptr, nullptr));
    193         SkAutoTUnref<SkImageFilter> gray(make_grayscale(mode, nullptr));
    194         REPORTER_ASSERT(reporter, true == gray->asColorFilter(nullptr));
    195     }
    196 
    197     {
    198         // Test that if we exceed the limit of what ComposeColorFilter can combine, we still
    199         // can build the DAG and won't assert if we call asColorFilter.
    200         SkAutoTUnref<SkImageFilter> filter(make_blue(nullptr, nullptr));
    201         const int kWayTooManyForComposeColorFilter = 100;
    202         for (int i = 0; i < kWayTooManyForComposeColorFilter; ++i) {
    203             filter.reset(make_blue(filter, nullptr));
    204             // the first few of these will succeed, but after we hit the internal limit,
    205             // it will then return false.
    206             (void)filter->asColorFilter(nullptr);
    207         }
    208     }
    209 
    210     {
    211         // Check that a color filter image filter with a crop rect cannot
    212         // be expressed as a color filter.
    213         SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(0, 0, 100, 100));
    214         SkAutoTUnref<SkImageFilter> grayWithCrop(make_grayscale(nullptr, &cropRect));
    215         REPORTER_ASSERT(reporter, false == grayWithCrop->asColorFilter(nullptr));
    216     }
    217 
    218     {
    219         // Check that two non-commutative matrices are concatenated in
    220         // the correct order.
    221         SkScalar blueToRedMatrix[20] = { 0 };
    222         blueToRedMatrix[2] = blueToRedMatrix[18] = SK_Scalar1;
    223         SkScalar redToGreenMatrix[20] = { 0 };
    224         redToGreenMatrix[5] = redToGreenMatrix[18] = SK_Scalar1;
    225         SkAutoTUnref<SkColorFilter> blueToRed(SkColorMatrixFilter::Create(blueToRedMatrix));
    226         SkAutoTUnref<SkImageFilter> filter1(SkColorFilterImageFilter::Create(blueToRed.get()));
    227         SkAutoTUnref<SkColorFilter> redToGreen(SkColorMatrixFilter::Create(redToGreenMatrix));
    228         SkAutoTUnref<SkImageFilter> filter2(SkColorFilterImageFilter::Create(redToGreen.get(), filter1.get()));
    229 
    230         SkBitmap result;
    231         result.allocN32Pixels(kBitmapSize, kBitmapSize);
    232 
    233         SkPaint paint;
    234         paint.setColor(SK_ColorBLUE);
    235         paint.setImageFilter(filter2.get());
    236         SkCanvas canvas(result);
    237         canvas.clear(0x0);
    238         SkRect rect = SkRect::Make(SkIRect::MakeWH(kBitmapSize, kBitmapSize));
    239         canvas.drawRect(rect, paint);
    240         uint32_t pixel = *result.getAddr32(0, 0);
    241         // The result here should be green, since we have effectively shifted blue to green.
    242         REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
    243     }
    244 
    245     {
    246         // Tests pass by not asserting
    247         SkAutoTUnref<SkImage> image(make_small_image());
    248         SkBitmap result;
    249         result.allocN32Pixels(kBitmapSize, kBitmapSize);
    250 
    251         {
    252             // This tests for :
    253             // 1 ) location at (0,0,1)
    254             SkPoint3 location = SkPoint3::Make(0, 0, SK_Scalar1);
    255             // 2 ) location and target at same value
    256             SkPoint3 target = SkPoint3::Make(location.fX, location.fY, location.fZ);
    257             // 3 ) large negative specular exponent value
    258             SkScalar specularExponent = -1000;
    259 
    260             SkAutoTUnref<SkImageFilter> bmSrc(SkImageSource::Create(image));
    261             SkPaint paint;
    262             paint.setImageFilter(SkLightingImageFilter::CreateSpotLitSpecular(
    263                     location, target, specularExponent, 180,
    264                     0xFFFFFFFF, SK_Scalar1, SK_Scalar1, SK_Scalar1,
    265                     bmSrc))->unref();
    266             SkCanvas canvas(result);
    267             SkRect r = SkRect::MakeWH(SkIntToScalar(kBitmapSize),
    268                                       SkIntToScalar(kBitmapSize));
    269             canvas.drawRect(r, paint);
    270         }
    271     }
    272 }
    273 
    274 static void test_crop_rects(SkImageFilter::Proxy* proxy, skiatest::Reporter* reporter) {
    275     // Check that all filters offset to their absolute crop rect,
    276     // unaffected by the input crop rect.
    277     // Tests pass by not asserting.
    278     SkBitmap bitmap;
    279     bitmap.allocN32Pixels(100, 100);
    280     bitmap.eraseARGB(0, 0, 0, 0);
    281 
    282     SkImageFilter::CropRect inputCropRect(SkRect::MakeXYWH(8, 13, 80, 80));
    283     SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(20, 30, 60, 60));
    284     SkAutoTUnref<SkImageFilter> input(make_grayscale(nullptr, &inputCropRect));
    285 
    286     SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED, SkXfermode::kSrcIn_Mode));
    287     SkPoint3 location = SkPoint3::Make(0, 0, SK_Scalar1);
    288     SkScalar kernel[9] = {
    289         SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
    290         SkIntToScalar( 1), SkIntToScalar(-7), SkIntToScalar( 1),
    291         SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
    292     };
    293     SkISize kernelSize = SkISize::Make(3, 3);
    294     SkScalar gain = SK_Scalar1, bias = 0;
    295 
    296     SkImageFilter* filters[] = {
    297         SkColorFilterImageFilter::Create(cf.get(), input.get(), &cropRect),
    298         SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType,
    299                                         SkDisplacementMapEffect::kB_ChannelSelectorType,
    300                                         40.0f, input.get(), input.get(), &cropRect),
    301         SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
    302         SkDropShadowImageFilter::Create(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1,
    303             SK_ColorGREEN, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
    304             input.get(), &cropRect),
    305         SkLightingImageFilter::CreatePointLitDiffuse(location, SK_ColorGREEN, 0, 0, input.get(), &cropRect),
    306         SkLightingImageFilter::CreatePointLitSpecular(location, SK_ColorGREEN, 0, 0, 0, input.get(), &cropRect),
    307         SkMatrixConvolutionImageFilter::Create(kernelSize, kernel, gain, bias, SkIPoint::Make(1, 1), SkMatrixConvolutionImageFilter::kRepeat_TileMode, false, input.get(), &cropRect),
    308         SkMergeImageFilter::Create(input.get(), input.get(), SkXfermode::kSrcOver_Mode, &cropRect),
    309         SkOffsetImageFilter::Create(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
    310         SkOffsetImageFilter::Create(SK_Scalar1, SK_Scalar1, input.get(), &cropRect),
    311         SkDilateImageFilter::Create(3, 2, input.get(), &cropRect),
    312         SkErodeImageFilter::Create(2, 3, input.get(), &cropRect),
    313         SkTileImageFilter::Create(inputCropRect.rect(), cropRect.rect(), input.get()),
    314         SkXfermodeImageFilter::Create(SkXfermode::Create(SkXfermode::kSrcOver_Mode), input.get(), input.get(), &cropRect),
    315     };
    316 
    317     for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
    318         SkImageFilter* filter = filters[i];
    319         SkBitmap result;
    320         SkIPoint offset;
    321         SkString str;
    322         str.printf("filter %d", static_cast<int>(i));
    323         SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr);
    324         REPORTER_ASSERT_MESSAGE(reporter,
    325                                 filter->filterImageDeprecated(proxy, bitmap, ctx,
    326                                                               &result, &offset),
    327                                 str.c_str());
    328         REPORTER_ASSERT_MESSAGE(reporter, offset.fX == 20 && offset.fY == 30, str.c_str());
    329     }
    330 
    331     for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
    332         SkSafeUnref(filters[i]);
    333     }
    334 }
    335 
    336 static SkBitmap make_gradient_circle(int width, int height) {
    337     SkBitmap bitmap;
    338     SkScalar x = SkIntToScalar(width / 2);
    339     SkScalar y = SkIntToScalar(height / 2);
    340     SkScalar radius = SkMinScalar(x, y) * 0.8f;
    341     bitmap.allocN32Pixels(width, height);
    342     SkCanvas canvas(bitmap);
    343     canvas.clear(0x00000000);
    344     SkColor colors[2];
    345     colors[0] = SK_ColorWHITE;
    346     colors[1] = SK_ColorBLACK;
    347     SkAutoTUnref<SkShader> shader(
    348         SkGradientShader::CreateRadial(SkPoint::Make(x, y), radius, colors, nullptr, 2,
    349                                        SkShader::kClamp_TileMode)
    350     );
    351     SkPaint paint;
    352     paint.setShader(shader);
    353     canvas.drawCircle(x, y, radius, paint);
    354     return bitmap;
    355 }
    356 
    357 static void test_negative_blur_sigma(SkImageFilter::Proxy* proxy, skiatest::Reporter* reporter) {
    358     // Check that SkBlurImageFilter will accept a negative sigma, either in
    359     // the given arguments or after CTM application.
    360     const int width = 32, height = 32;
    361     const SkScalar five = SkIntToScalar(5);
    362 
    363     SkAutoTUnref<SkImageFilter> positiveFilter(SkBlurImageFilter::Create(five, five));
    364     SkAutoTUnref<SkImageFilter> negativeFilter(SkBlurImageFilter::Create(-five, five));
    365 
    366     SkBitmap gradient = make_gradient_circle(width, height);
    367     SkBitmap positiveResult1, negativeResult1;
    368     SkBitmap positiveResult2, negativeResult2;
    369     SkIPoint offset;
    370     SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(32, 32), nullptr);
    371     REPORTER_ASSERT(reporter,
    372                     positiveFilter->filterImageDeprecated(proxy, gradient, ctx,
    373                                                           &positiveResult1, &offset));
    374     REPORTER_ASSERT(reporter,
    375                     negativeFilter->filterImageDeprecated(proxy, gradient, ctx,
    376                                                           &negativeResult1, &offset));
    377     SkMatrix negativeScale;
    378     negativeScale.setScale(-SK_Scalar1, SK_Scalar1);
    379     SkImageFilter::Context negativeCTX(negativeScale, SkIRect::MakeWH(32, 32), nullptr);
    380     REPORTER_ASSERT(reporter,
    381                     positiveFilter->filterImageDeprecated(proxy, gradient, negativeCTX,
    382                                                           &negativeResult2, &offset));
    383     REPORTER_ASSERT(reporter,
    384                     negativeFilter->filterImageDeprecated(proxy, gradient, negativeCTX,
    385                                                           &positiveResult2, &offset));
    386     SkAutoLockPixels lockP1(positiveResult1);
    387     SkAutoLockPixels lockP2(positiveResult2);
    388     SkAutoLockPixels lockN1(negativeResult1);
    389     SkAutoLockPixels lockN2(negativeResult2);
    390     for (int y = 0; y < height; y++) {
    391         int diffs = memcmp(positiveResult1.getAddr32(0, y), negativeResult1.getAddr32(0, y), positiveResult1.rowBytes());
    392         REPORTER_ASSERT(reporter, !diffs);
    393         if (diffs) {
    394             break;
    395         }
    396         diffs = memcmp(positiveResult1.getAddr32(0, y), negativeResult2.getAddr32(0, y), positiveResult1.rowBytes());
    397         REPORTER_ASSERT(reporter, !diffs);
    398         if (diffs) {
    399             break;
    400         }
    401         diffs = memcmp(positiveResult1.getAddr32(0, y), positiveResult2.getAddr32(0, y), positiveResult1.rowBytes());
    402         REPORTER_ASSERT(reporter, !diffs);
    403         if (diffs) {
    404             break;
    405         }
    406     }
    407 }
    408 
    409 DEF_TEST(TestNegativeBlurSigma, reporter) {
    410     const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
    411     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
    412 
    413     SkAutoTUnref<SkBaseDevice> device(SkBitmapDevice::Create(info, props));
    414     SkImageFilter::DeviceProxy proxy(device);
    415 
    416     test_negative_blur_sigma(&proxy, reporter);
    417 }
    418 
    419 DEF_TEST(ImageFilterDrawTiled, reporter) {
    420     // Check that all filters when drawn tiled (with subsequent clip rects) exactly
    421     // match the same filters drawn with a single full-canvas bitmap draw.
    422     // Tests pass by not asserting.
    423 
    424     SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED, SkXfermode::kSrcIn_Mode));
    425     SkPoint3 location = SkPoint3::Make(0, 0, SK_Scalar1);
    426     SkScalar kernel[9] = {
    427         SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
    428         SkIntToScalar( 1), SkIntToScalar(-7), SkIntToScalar( 1),
    429         SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
    430     };
    431     const SkISize kernelSize = SkISize::Make(3, 3);
    432     const SkScalar gain = SK_Scalar1, bias = 0;
    433     const SkScalar five = SkIntToScalar(5);
    434 
    435     SkAutoTUnref<SkImage> gradientImage(SkImage::NewFromBitmap(make_gradient_circle(64, 64)));
    436     SkAutoTUnref<SkImageFilter> gradientSource(SkImageSource::Create(gradientImage));
    437     SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(five, five));
    438     SkMatrix matrix;
    439 
    440     matrix.setTranslate(SK_Scalar1, SK_Scalar1);
    441     matrix.postRotate(SkIntToScalar(45), SK_Scalar1, SK_Scalar1);
    442 
    443     SkRTreeFactory factory;
    444     SkPictureRecorder recorder;
    445     SkCanvas* recordingCanvas = recorder.beginRecording(64, 64, &factory, 0);
    446 
    447     SkPaint greenPaint;
    448     greenPaint.setColor(SK_ColorGREEN);
    449     recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeXYWH(10, 10, 30, 20)), greenPaint);
    450     SkAutoTUnref<SkPicture> picture(recorder.endRecording());
    451     SkAutoTUnref<SkImageFilter> pictureFilter(SkPictureImageFilter::Create(picture.get()));
    452     SkAutoTUnref<SkShader> shader(SkPerlinNoiseShader::CreateTurbulence(SK_Scalar1, SK_Scalar1, 1, 0));
    453     SkPaint noisePaint;
    454     noisePaint.setShader(shader);
    455 
    456     SkAutoTUnref<SkImageFilter> paintFilter(SkPaintImageFilter::Create(noisePaint));
    457 
    458     SkImageFilter::CropRect leftSideCropRect(SkRect::MakeXYWH(0, 0, 32, 64));
    459     SkAutoTUnref<SkImageFilter> paintFilterLeft(SkPaintImageFilter::Create(greenPaint, &leftSideCropRect));
    460     SkImageFilter::CropRect rightSideCropRect(SkRect::MakeXYWH(32, 0, 32, 64));
    461     SkAutoTUnref<SkImageFilter> paintFilterRight(SkPaintImageFilter::Create(greenPaint, &rightSideCropRect));
    462 
    463     struct {
    464         const char*    fName;
    465         SkImageFilter* fFilter;
    466     } filters[] = {
    467         { "color filter", SkColorFilterImageFilter::Create(cf.get()) },
    468         { "displacement map", SkDisplacementMapEffect::Create(
    469               SkDisplacementMapEffect::kR_ChannelSelectorType,
    470               SkDisplacementMapEffect::kB_ChannelSelectorType,
    471               20.0f, gradientSource.get()) },
    472         { "blur", SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1) },
    473         { "drop shadow", SkDropShadowImageFilter::Create(
    474               SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN,
    475               SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode) },
    476         { "diffuse lighting", SkLightingImageFilter::CreatePointLitDiffuse(
    477               location, SK_ColorGREEN, 0, 0) },
    478         { "specular lighting",
    479               SkLightingImageFilter::CreatePointLitSpecular(location, SK_ColorGREEN, 0, 0, 0) },
    480         { "matrix convolution",
    481               SkMatrixConvolutionImageFilter::Create(
    482                   kernelSize, kernel, gain, bias, SkIPoint::Make(1, 1),
    483                   SkMatrixConvolutionImageFilter::kRepeat_TileMode, false) },
    484         { "merge", SkMergeImageFilter::Create(nullptr, nullptr, SkXfermode::kSrcOver_Mode) },
    485         { "merge with disjoint inputs", SkMergeImageFilter::Create(
    486               paintFilterLeft, paintFilterRight, SkXfermode::kSrcOver_Mode) },
    487         { "offset", SkOffsetImageFilter::Create(SK_Scalar1, SK_Scalar1) },
    488         { "dilate", SkDilateImageFilter::Create(3, 2) },
    489         { "erode", SkErodeImageFilter::Create(2, 3) },
    490         { "tile", SkTileImageFilter::Create(SkRect::MakeXYWH(0, 0, 50, 50),
    491                                             SkRect::MakeXYWH(0, 0, 100, 100), nullptr) },
    492         { "matrix", SkImageFilter::CreateMatrixFilter(matrix, kLow_SkFilterQuality) },
    493         { "blur and offset", SkOffsetImageFilter::Create(five, five, blur.get()) },
    494         { "picture and blur", SkBlurImageFilter::Create(five, five, pictureFilter.get()) },
    495         { "paint and blur", SkBlurImageFilter::Create(five, five, paintFilter.get()) },
    496     };
    497 
    498     SkBitmap untiledResult, tiledResult;
    499     const int width = 64, height = 64;
    500     untiledResult.allocN32Pixels(width, height);
    501     tiledResult.allocN32Pixels(width, height);
    502     SkCanvas tiledCanvas(tiledResult);
    503     SkCanvas untiledCanvas(untiledResult);
    504     int tileSize = 8;
    505 
    506     for (int scale = 1; scale <= 2; ++scale) {
    507         for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
    508             tiledCanvas.clear(0);
    509             untiledCanvas.clear(0);
    510             SkPaint paint;
    511             paint.setImageFilter(filters[i].fFilter);
    512             paint.setTextSize(SkIntToScalar(height));
    513             paint.setColor(SK_ColorWHITE);
    514             SkString str;
    515             const char* text = "ABC";
    516             SkScalar ypos = SkIntToScalar(height);
    517             untiledCanvas.save();
    518             untiledCanvas.scale(SkIntToScalar(scale), SkIntToScalar(scale));
    519             untiledCanvas.drawText(text, strlen(text), 0, ypos, paint);
    520             untiledCanvas.restore();
    521             for (int y = 0; y < height; y += tileSize) {
    522                 for (int x = 0; x < width; x += tileSize) {
    523                     tiledCanvas.save();
    524                     tiledCanvas.clipRect(SkRect::Make(SkIRect::MakeXYWH(x, y, tileSize, tileSize)));
    525                     tiledCanvas.scale(SkIntToScalar(scale), SkIntToScalar(scale));
    526                     tiledCanvas.drawText(text, strlen(text), 0, ypos, paint);
    527                     tiledCanvas.restore();
    528                 }
    529             }
    530             untiledCanvas.flush();
    531             tiledCanvas.flush();
    532             for (int y = 0; y < height; y++) {
    533                 int diffs = memcmp(untiledResult.getAddr32(0, y), tiledResult.getAddr32(0, y), untiledResult.rowBytes());
    534                 REPORTER_ASSERT_MESSAGE(reporter, !diffs, filters[i].fName);
    535                 if (diffs) {
    536                     break;
    537                 }
    538             }
    539         }
    540     }
    541 
    542     for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) {
    543         SkSafeUnref(filters[i].fFilter);
    544     }
    545 }
    546 
    547 static void draw_saveLayer_picture(int width, int height, int tileSize,
    548                                    SkBBHFactory* factory, SkBitmap* result) {
    549 
    550     SkMatrix matrix;
    551     matrix.setTranslate(SkIntToScalar(50), 0);
    552 
    553     SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorWHITE, SkXfermode::kSrc_Mode));
    554     SkAutoTUnref<SkImageFilter> cfif(SkColorFilterImageFilter::Create(cf.get()));
    555     SkAutoTUnref<SkImageFilter> imageFilter(SkImageFilter::CreateMatrixFilter(matrix, kNone_SkFilterQuality, cfif.get()));
    556 
    557     SkPaint paint;
    558     paint.setImageFilter(imageFilter.get());
    559     SkPictureRecorder recorder;
    560     SkRect bounds = SkRect::Make(SkIRect::MakeXYWH(0, 0, 50, 50));
    561     SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(width),
    562                                                         SkIntToScalar(height),
    563                                                         factory, 0);
    564     recordingCanvas->translate(-55, 0);
    565     recordingCanvas->saveLayer(&bounds, &paint);
    566     recordingCanvas->restore();
    567     SkAutoTUnref<SkPicture> picture1(recorder.endRecording());
    568 
    569     result->allocN32Pixels(width, height);
    570     SkCanvas canvas(*result);
    571     canvas.clear(0);
    572     canvas.clipRect(SkRect::Make(SkIRect::MakeWH(tileSize, tileSize)));
    573     canvas.drawPicture(picture1.get());
    574 }
    575 
    576 DEF_TEST(ImageFilterDrawMatrixBBH, reporter) {
    577     // Check that matrix filter when drawn tiled with BBH exactly
    578     // matches the same thing drawn without BBH.
    579     // Tests pass by not asserting.
    580 
    581     const int width = 200, height = 200;
    582     const int tileSize = 100;
    583     SkBitmap result1, result2;
    584     SkRTreeFactory factory;
    585 
    586     draw_saveLayer_picture(width, height, tileSize, &factory, &result1);
    587     draw_saveLayer_picture(width, height, tileSize, nullptr, &result2);
    588 
    589     for (int y = 0; y < height; y++) {
    590         int diffs = memcmp(result1.getAddr32(0, y), result2.getAddr32(0, y), result1.rowBytes());
    591         REPORTER_ASSERT(reporter, !diffs);
    592         if (diffs) {
    593             break;
    594         }
    595     }
    596 }
    597 
    598 static SkImageFilter* makeBlur(SkImageFilter* input = nullptr) {
    599     return SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1, input);
    600 }
    601 
    602 static SkImageFilter* makeDropShadow(SkImageFilter* input = nullptr) {
    603     return SkDropShadowImageFilter::Create(
    604         SkIntToScalar(100), SkIntToScalar(100),
    605         SkIntToScalar(10), SkIntToScalar(10),
    606         SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
    607         input, nullptr);
    608 }
    609 
    610 DEF_TEST(ImageFilterBlurThenShadowBounds, reporter) {
    611     SkAutoTUnref<SkImageFilter> filter1(makeBlur());
    612     SkAutoTUnref<SkImageFilter> filter2(makeDropShadow(filter1.get()));
    613 
    614     SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100);
    615     SkIRect expectedBounds = SkIRect::MakeXYWH(-133, -133, 236, 236);
    616     filter2->filterBounds(bounds, SkMatrix::I(), &bounds);
    617 
    618     REPORTER_ASSERT(reporter, bounds == expectedBounds);
    619 }
    620 
    621 DEF_TEST(ImageFilterShadowThenBlurBounds, reporter) {
    622     SkAutoTUnref<SkImageFilter> filter1(makeDropShadow());
    623     SkAutoTUnref<SkImageFilter> filter2(makeBlur(filter1.get()));
    624 
    625     SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100);
    626     SkIRect expectedBounds = SkIRect::MakeXYWH(-133, -133, 236, 236);
    627     filter2->filterBounds(bounds, SkMatrix::I(), &bounds);
    628 
    629     REPORTER_ASSERT(reporter, bounds == expectedBounds);
    630 }
    631 
    632 DEF_TEST(ImageFilterDilateThenBlurBounds, reporter) {
    633     SkAutoTUnref<SkImageFilter> filter1(SkDilateImageFilter::Create(2, 2));
    634     SkAutoTUnref<SkImageFilter> filter2(makeDropShadow(filter1.get()));
    635 
    636     SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100);
    637     SkIRect expectedBounds = SkIRect::MakeXYWH(-132, -132, 234, 234);
    638     filter2->filterBounds(bounds, SkMatrix::I(), &bounds);
    639 
    640     REPORTER_ASSERT(reporter, bounds == expectedBounds);
    641 }
    642 
    643 DEF_TEST(ImageFilterComposedBlurFastBounds, reporter) {
    644     SkAutoTUnref<SkImageFilter> filter1(makeBlur());
    645     SkAutoTUnref<SkImageFilter> filter2(makeBlur());
    646     SkAutoTUnref<SkImageFilter> composedFilter(SkComposeImageFilter::Create(filter1.get(), filter2.get()));
    647 
    648     SkRect boundsSrc = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
    649     SkRect expectedBounds = SkRect::MakeXYWH(
    650         SkIntToScalar(-6), SkIntToScalar(-6), SkIntToScalar(112), SkIntToScalar(112));
    651     SkRect boundsDst = SkRect::MakeEmpty();
    652     composedFilter->computeFastBounds(boundsSrc, &boundsDst);
    653 
    654     REPORTER_ASSERT(reporter, boundsDst == expectedBounds);
    655 }
    656 
    657 DEF_TEST(ImageFilterMergeResultSize, reporter) {
    658     SkBitmap greenBM;
    659     greenBM.allocN32Pixels(20, 20);
    660     greenBM.eraseColor(SK_ColorGREEN);
    661     SkAutoTUnref<SkImage> greenImage(SkImage::NewFromBitmap(greenBM));
    662     SkAutoTUnref<SkImageFilter> source(SkImageSource::Create(greenImage.get()));
    663     SkAutoTUnref<SkImageFilter> merge(SkMergeImageFilter::Create(source.get(), source.get()));
    664 
    665     SkBitmap bitmap;
    666     bitmap.allocN32Pixels(1, 1);
    667     bitmap.eraseColor(0);
    668     const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
    669     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
    670     SkAutoTUnref<SkBaseDevice> device(SkBitmapDevice::Create(info, props));
    671     SkImageFilter::DeviceProxy proxy(device);
    672     SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(0, 0, 100, 100), nullptr);
    673     SkBitmap result;
    674     SkIPoint offset;
    675     REPORTER_ASSERT(reporter, merge->filterImageDeprecated(&proxy, bitmap, ctx, &result, &offset));
    676     REPORTER_ASSERT(reporter, result.width() == 20 && result.height() == 20);
    677 }
    678 
    679 static void draw_blurred_rect(SkCanvas* canvas) {
    680     SkAutoTUnref<SkImageFilter> filter(SkBlurImageFilter::Create(SkIntToScalar(8), 0));
    681     SkPaint filterPaint;
    682     filterPaint.setColor(SK_ColorWHITE);
    683     filterPaint.setImageFilter(filter);
    684     canvas->saveLayer(nullptr, &filterPaint);
    685     SkPaint whitePaint;
    686     whitePaint.setColor(SK_ColorWHITE);
    687     canvas->drawRect(SkRect::Make(SkIRect::MakeWH(4, 4)), whitePaint);
    688     canvas->restore();
    689 }
    690 
    691 static void draw_picture_clipped(SkCanvas* canvas, const SkRect& clipRect, const SkPicture* picture) {
    692     canvas->save();
    693     canvas->clipRect(clipRect);
    694     canvas->drawPicture(picture);
    695     canvas->restore();
    696 }
    697 
    698 DEF_TEST(ImageFilterDrawTiledBlurRTree, reporter) {
    699     // Check that the blur filter when recorded with RTree acceleration,
    700     // and drawn tiled (with subsequent clip rects) exactly
    701     // matches the same filter drawn with without RTree acceleration.
    702     // This tests that the "bleed" from the blur into the otherwise-blank
    703     // tiles is correctly rendered.
    704     // Tests pass by not asserting.
    705 
    706     int width = 16, height = 8;
    707     SkBitmap result1, result2;
    708     result1.allocN32Pixels(width, height);
    709     result2.allocN32Pixels(width, height);
    710     SkCanvas canvas1(result1);
    711     SkCanvas canvas2(result2);
    712     int tileSize = 8;
    713 
    714     canvas1.clear(0);
    715     canvas2.clear(0);
    716 
    717     SkRTreeFactory factory;
    718 
    719     SkPictureRecorder recorder1, recorder2;
    720     // The only difference between these two pictures is that one has RTree aceleration.
    721     SkCanvas* recordingCanvas1 = recorder1.beginRecording(SkIntToScalar(width),
    722                                                           SkIntToScalar(height),
    723                                                           nullptr, 0);
    724     SkCanvas* recordingCanvas2 = recorder2.beginRecording(SkIntToScalar(width),
    725                                                           SkIntToScalar(height),
    726                                                           &factory, 0);
    727     draw_blurred_rect(recordingCanvas1);
    728     draw_blurred_rect(recordingCanvas2);
    729     SkAutoTUnref<SkPicture> picture1(recorder1.endRecording());
    730     SkAutoTUnref<SkPicture> picture2(recorder2.endRecording());
    731     for (int y = 0; y < height; y += tileSize) {
    732         for (int x = 0; x < width; x += tileSize) {
    733             SkRect tileRect = SkRect::Make(SkIRect::MakeXYWH(x, y, tileSize, tileSize));
    734             draw_picture_clipped(&canvas1, tileRect, picture1);
    735             draw_picture_clipped(&canvas2, tileRect, picture2);
    736         }
    737     }
    738     for (int y = 0; y < height; y++) {
    739         int diffs = memcmp(result1.getAddr32(0, y), result2.getAddr32(0, y), result1.rowBytes());
    740         REPORTER_ASSERT(reporter, !diffs);
    741         if (diffs) {
    742             break;
    743         }
    744     }
    745 }
    746 
    747 DEF_TEST(ImageFilterMatrixConvolution, reporter) {
    748     // Check that a 1x3 filter does not cause a spurious assert.
    749     SkScalar kernel[3] = {
    750         SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1),
    751     };
    752     SkISize kernelSize = SkISize::Make(1, 3);
    753     SkScalar gain = SK_Scalar1, bias = 0;
    754     SkIPoint kernelOffset = SkIPoint::Make(0, 0);
    755 
    756     SkAutoTUnref<SkImageFilter> filter(
    757         SkMatrixConvolutionImageFilter::Create(
    758             kernelSize, kernel, gain, bias, kernelOffset,
    759             SkMatrixConvolutionImageFilter::kRepeat_TileMode, false));
    760 
    761     SkBitmap result;
    762     int width = 16, height = 16;
    763     result.allocN32Pixels(width, height);
    764     SkCanvas canvas(result);
    765     canvas.clear(0);
    766 
    767     SkPaint paint;
    768     paint.setImageFilter(filter);
    769     SkRect rect = SkRect::Make(SkIRect::MakeWH(width, height));
    770     canvas.drawRect(rect, paint);
    771 }
    772 
    773 DEF_TEST(ImageFilterMatrixConvolutionBorder, reporter) {
    774     // Check that a filter with borders outside the target bounds
    775     // does not crash.
    776     SkScalar kernel[3] = {
    777         0, 0, 0,
    778     };
    779     SkISize kernelSize = SkISize::Make(3, 1);
    780     SkScalar gain = SK_Scalar1, bias = 0;
    781     SkIPoint kernelOffset = SkIPoint::Make(2, 0);
    782 
    783     SkAutoTUnref<SkImageFilter> filter(
    784         SkMatrixConvolutionImageFilter::Create(
    785             kernelSize, kernel, gain, bias, kernelOffset,
    786             SkMatrixConvolutionImageFilter::kClamp_TileMode, true));
    787 
    788     SkBitmap result;
    789 
    790     int width = 10, height = 10;
    791     result.allocN32Pixels(width, height);
    792     SkCanvas canvas(result);
    793     canvas.clear(0);
    794 
    795     SkPaint filterPaint;
    796     filterPaint.setImageFilter(filter);
    797     SkRect bounds = SkRect::MakeWH(1, 10);
    798     SkRect rect = SkRect::Make(SkIRect::MakeWH(width, height));
    799     SkPaint rectPaint;
    800     canvas.saveLayer(&bounds, &filterPaint);
    801     canvas.drawRect(rect, rectPaint);
    802     canvas.restore();
    803 }
    804 
    805 DEF_TEST(ImageFilterCropRect, reporter) {
    806     const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
    807     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
    808 
    809     SkAutoTUnref<SkBaseDevice> device(SkBitmapDevice::Create(info, props));
    810     SkImageFilter::DeviceProxy proxy(device);
    811 
    812     test_crop_rects(&proxy, reporter);
    813 }
    814 
    815 DEF_TEST(ImageFilterMatrix, reporter) {
    816     SkBitmap temp;
    817     temp.allocN32Pixels(100, 100);
    818     SkCanvas canvas(temp);
    819     canvas.scale(SkIntToScalar(2), SkIntToScalar(2));
    820 
    821     SkMatrix expectedMatrix = canvas.getTotalMatrix();
    822 
    823     SkRTreeFactory factory;
    824     SkPictureRecorder recorder;
    825     SkCanvas* recordingCanvas = recorder.beginRecording(100, 100, &factory, 0);
    826 
    827     SkPaint paint;
    828     SkAutoTUnref<MatrixTestImageFilter> imageFilter(
    829         new MatrixTestImageFilter(reporter, expectedMatrix));
    830     paint.setImageFilter(imageFilter.get());
    831     recordingCanvas->saveLayer(nullptr, &paint);
    832     SkPaint solidPaint;
    833     solidPaint.setColor(0xFFFFFFFF);
    834     recordingCanvas->save();
    835     recordingCanvas->scale(SkIntToScalar(10), SkIntToScalar(10));
    836     recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(100, 100)), solidPaint);
    837     recordingCanvas->restore(); // scale
    838     recordingCanvas->restore(); // saveLayer
    839     SkAutoTUnref<SkPicture> picture(recorder.endRecording());
    840 
    841     canvas.drawPicture(picture);
    842 }
    843 
    844 DEF_TEST(ImageFilterCrossProcessPictureImageFilter, reporter) {
    845     SkRTreeFactory factory;
    846     SkPictureRecorder recorder;
    847     SkCanvas* recordingCanvas = recorder.beginRecording(1, 1, &factory, 0);
    848 
    849     // Create an SkPicture which simply draws a green 1x1 rectangle.
    850     SkPaint greenPaint;
    851     greenPaint.setColor(SK_ColorGREEN);
    852     recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), greenPaint);
    853     SkAutoTUnref<SkPicture> picture(recorder.endRecording());
    854 
    855     // Wrap that SkPicture in an SkPictureImageFilter.
    856     SkAutoTUnref<SkImageFilter> imageFilter(
    857         SkPictureImageFilter::Create(picture.get()));
    858 
    859     // Check that SkPictureImageFilter successfully serializes its contained
    860     // SkPicture when not in cross-process mode.
    861     SkPaint paint;
    862     paint.setImageFilter(imageFilter.get());
    863     SkPictureRecorder outerRecorder;
    864     SkCanvas* outerCanvas = outerRecorder.beginRecording(1, 1, &factory, 0);
    865     SkPaint redPaintWithFilter;
    866     redPaintWithFilter.setColor(SK_ColorRED);
    867     redPaintWithFilter.setImageFilter(imageFilter.get());
    868     outerCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), redPaintWithFilter);
    869     SkAutoTUnref<SkPicture> outerPicture(outerRecorder.endRecording());
    870 
    871     SkBitmap bitmap;
    872     bitmap.allocN32Pixels(1, 1);
    873     SkCanvas canvas(bitmap);
    874 
    875     // The result here should be green, since the filter replaces the primitive's red interior.
    876     canvas.clear(0x0);
    877     canvas.drawPicture(outerPicture);
    878     uint32_t pixel = *bitmap.getAddr32(0, 0);
    879     REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
    880 
    881     // Check that, for now, SkPictureImageFilter does not serialize or
    882     // deserialize its contained picture when the filter is serialized
    883     // cross-process. Do this by "laundering" it through SkValidatingReadBuffer.
    884     SkAutoTUnref<SkData> data(SkValidatingSerializeFlattenable(imageFilter.get()));
    885     SkAutoTUnref<SkFlattenable> flattenable(SkValidatingDeserializeFlattenable(
    886         data->data(), data->size(), SkImageFilter::GetFlattenableType()));
    887     SkImageFilter* unflattenedFilter = static_cast<SkImageFilter*>(flattenable.get());
    888 
    889     redPaintWithFilter.setImageFilter(unflattenedFilter);
    890     SkPictureRecorder crossProcessRecorder;
    891     SkCanvas* crossProcessCanvas = crossProcessRecorder.beginRecording(1, 1, &factory, 0);
    892     crossProcessCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), redPaintWithFilter);
    893     SkAutoTUnref<SkPicture> crossProcessPicture(crossProcessRecorder.endRecording());
    894 
    895     canvas.clear(0x0);
    896     canvas.drawPicture(crossProcessPicture);
    897     pixel = *bitmap.getAddr32(0, 0);
    898     // If the security precautions are enabled, the result here should not be green, since the
    899     // filter draws nothing.
    900     REPORTER_ASSERT(reporter, SkPicture::PictureIOSecurityPrecautionsEnabled()
    901         ? pixel != SK_ColorGREEN : pixel == SK_ColorGREEN);
    902 }
    903 
    904 DEF_TEST(ImageFilterClippedPictureImageFilter, reporter) {
    905     SkRTreeFactory factory;
    906     SkPictureRecorder recorder;
    907     SkCanvas* recordingCanvas = recorder.beginRecording(1, 1, &factory, 0);
    908 
    909     // Create an SkPicture which simply draws a green 1x1 rectangle.
    910     SkPaint greenPaint;
    911     greenPaint.setColor(SK_ColorGREEN);
    912     recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), greenPaint);
    913     SkAutoTUnref<SkPicture> picture(recorder.endRecording());
    914 
    915     SkAutoTUnref<SkImageFilter> imageFilter(SkPictureImageFilter::Create(picture.get()));
    916 
    917     SkBitmap result;
    918     SkIPoint offset;
    919     SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(1, 1, 1, 1), nullptr);
    920     SkBitmap bitmap;
    921     bitmap.allocN32Pixels(2, 2);
    922     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
    923     SkBitmapDevice device(bitmap, props);
    924     SkImageFilter::DeviceProxy proxy(&device);
    925     REPORTER_ASSERT(reporter,
    926                     !imageFilter->filterImageDeprecated(&proxy, bitmap, ctx, &result, &offset));
    927 }
    928 
    929 DEF_TEST(ImageFilterEmptySaveLayer, reporter) {
    930     // Even when there's an empty saveLayer()/restore(), ensure that an image
    931     // filter or color filter which affects transparent black still draws.
    932 
    933     SkBitmap bitmap;
    934     bitmap.allocN32Pixels(10, 10);
    935     SkCanvas canvas(bitmap);
    936 
    937     SkRTreeFactory factory;
    938     SkPictureRecorder recorder;
    939 
    940     SkAutoTUnref<SkColorFilter> green(
    941         SkColorFilter::CreateModeFilter(SK_ColorGREEN, SkXfermode::kSrc_Mode));
    942     SkAutoTUnref<SkImageFilter> imageFilter(
    943         SkColorFilterImageFilter::Create(green.get()));
    944     SkPaint imageFilterPaint;
    945     imageFilterPaint.setImageFilter(imageFilter.get());
    946     SkPaint colorFilterPaint;
    947     colorFilterPaint.setColorFilter(green.get());
    948 
    949     SkRect bounds = SkRect::MakeWH(10, 10);
    950 
    951     SkCanvas* recordingCanvas = recorder.beginRecording(10, 10, &factory, 0);
    952     recordingCanvas->saveLayer(&bounds, &imageFilterPaint);
    953     recordingCanvas->restore();
    954     SkAutoTUnref<SkPicture> picture(recorder.endRecording());
    955 
    956     canvas.clear(0);
    957     canvas.drawPicture(picture);
    958     uint32_t pixel = *bitmap.getAddr32(0, 0);
    959     REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
    960 
    961     recordingCanvas = recorder.beginRecording(10, 10, &factory, 0);
    962     recordingCanvas->saveLayer(nullptr, &imageFilterPaint);
    963     recordingCanvas->restore();
    964     SkAutoTUnref<SkPicture> picture2(recorder.endRecording());
    965 
    966     canvas.clear(0);
    967     canvas.drawPicture(picture2);
    968     pixel = *bitmap.getAddr32(0, 0);
    969     REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
    970 
    971     recordingCanvas = recorder.beginRecording(10, 10, &factory, 0);
    972     recordingCanvas->saveLayer(&bounds, &colorFilterPaint);
    973     recordingCanvas->restore();
    974     SkAutoTUnref<SkPicture> picture3(recorder.endRecording());
    975 
    976     canvas.clear(0);
    977     canvas.drawPicture(picture3);
    978     pixel = *bitmap.getAddr32(0, 0);
    979     REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
    980 }
    981 
    982 static void test_huge_blur(SkCanvas* canvas, skiatest::Reporter* reporter) {
    983     SkBitmap bitmap;
    984     bitmap.allocN32Pixels(100, 100);
    985     bitmap.eraseARGB(0, 0, 0, 0);
    986 
    987     // Check that a blur with an insane radius does not crash or assert.
    988     SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(SkIntToScalar(1<<30), SkIntToScalar(1<<30)));
    989 
    990     SkPaint paint;
    991     paint.setImageFilter(blur);
    992     canvas->drawBitmap(bitmap, 0, 0, &paint);
    993 }
    994 
    995 DEF_TEST(HugeBlurImageFilter, reporter) {
    996     SkBitmap temp;
    997     temp.allocN32Pixels(100, 100);
    998     SkCanvas canvas(temp);
    999     test_huge_blur(&canvas, reporter);
   1000 }
   1001 
   1002 DEF_TEST(MatrixConvolutionSanityTest, reporter) {
   1003     SkScalar kernel[1] = { 0 };
   1004     SkScalar gain = SK_Scalar1, bias = 0;
   1005     SkIPoint kernelOffset = SkIPoint::Make(1, 1);
   1006 
   1007     // Check that an enormous (non-allocatable) kernel gives a nullptr filter.
   1008     SkAutoTUnref<SkImageFilter> conv(SkMatrixConvolutionImageFilter::Create(
   1009         SkISize::Make(1<<30, 1<<30),
   1010         kernel,
   1011         gain,
   1012         bias,
   1013         kernelOffset,
   1014         SkMatrixConvolutionImageFilter::kRepeat_TileMode,
   1015         false));
   1016 
   1017     REPORTER_ASSERT(reporter, nullptr == conv.get());
   1018 
   1019     // Check that a nullptr kernel gives a nullptr filter.
   1020     conv.reset(SkMatrixConvolutionImageFilter::Create(
   1021         SkISize::Make(1, 1),
   1022         nullptr,
   1023         gain,
   1024         bias,
   1025         kernelOffset,
   1026         SkMatrixConvolutionImageFilter::kRepeat_TileMode,
   1027         false));
   1028 
   1029     REPORTER_ASSERT(reporter, nullptr == conv.get());
   1030 
   1031     // Check that a kernel width < 1 gives a nullptr filter.
   1032     conv.reset(SkMatrixConvolutionImageFilter::Create(
   1033         SkISize::Make(0, 1),
   1034         kernel,
   1035         gain,
   1036         bias,
   1037         kernelOffset,
   1038         SkMatrixConvolutionImageFilter::kRepeat_TileMode,
   1039         false));
   1040 
   1041     REPORTER_ASSERT(reporter, nullptr == conv.get());
   1042 
   1043     // Check that kernel height < 1 gives a nullptr filter.
   1044     conv.reset(SkMatrixConvolutionImageFilter::Create(
   1045         SkISize::Make(1, -1),
   1046         kernel,
   1047         gain,
   1048         bias,
   1049         kernelOffset,
   1050         SkMatrixConvolutionImageFilter::kRepeat_TileMode,
   1051         false));
   1052 
   1053     REPORTER_ASSERT(reporter, nullptr == conv.get());
   1054 }
   1055 
   1056 static void test_xfermode_cropped_input(SkCanvas* canvas, skiatest::Reporter* reporter) {
   1057     canvas->clear(0);
   1058 
   1059     SkBitmap bitmap;
   1060     bitmap.allocN32Pixels(1, 1);
   1061     bitmap.eraseARGB(255, 255, 255, 255);
   1062 
   1063     SkAutoTUnref<SkColorFilter> green(
   1064         SkColorFilter::CreateModeFilter(SK_ColorGREEN, SkXfermode::kSrcIn_Mode));
   1065     SkAutoTUnref<SkImageFilter> greenFilter(SkColorFilterImageFilter::Create(green.get()));
   1066     SkImageFilter::CropRect cropRect(SkRect::MakeEmpty());
   1067     SkAutoTUnref<SkImageFilter> croppedOut(
   1068         SkColorFilterImageFilter::Create(green.get(), nullptr, &cropRect));
   1069 
   1070     // Check that an xfermode image filter whose input has been cropped out still draws the other
   1071     // input. Also check that drawing with both inputs cropped out doesn't cause a GPU warning.
   1072     SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrcOver_Mode);
   1073     SkAutoTUnref<SkImageFilter> xfermodeNoFg(
   1074         SkXfermodeImageFilter::Create(mode, greenFilter, croppedOut));
   1075     SkAutoTUnref<SkImageFilter> xfermodeNoBg(
   1076         SkXfermodeImageFilter::Create(mode, croppedOut, greenFilter));
   1077     SkAutoTUnref<SkImageFilter> xfermodeNoFgNoBg(
   1078         SkXfermodeImageFilter::Create(mode, croppedOut, croppedOut));
   1079 
   1080     SkPaint paint;
   1081     paint.setImageFilter(xfermodeNoFg);
   1082     canvas->drawBitmap(bitmap, 0, 0, &paint);   // drawSprite
   1083 
   1084     uint32_t pixel;
   1085     SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType);
   1086     canvas->readPixels(info, &pixel, 4, 0, 0);
   1087     REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
   1088 
   1089     paint.setImageFilter(xfermodeNoBg);
   1090     canvas->drawBitmap(bitmap, 0, 0, &paint);   // drawSprite
   1091     canvas->readPixels(info, &pixel, 4, 0, 0);
   1092     REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
   1093 
   1094     paint.setImageFilter(xfermodeNoFgNoBg);
   1095     canvas->drawBitmap(bitmap, 0, 0, &paint);   // drawSprite
   1096     canvas->readPixels(info, &pixel, 4, 0, 0);
   1097     REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
   1098 }
   1099 
   1100 DEF_TEST(ImageFilterNestedSaveLayer, reporter) {
   1101     SkBitmap temp;
   1102     temp.allocN32Pixels(50, 50);
   1103     SkCanvas canvas(temp);
   1104     canvas.clear(0x0);
   1105 
   1106     SkBitmap bitmap;
   1107     bitmap.allocN32Pixels(10, 10);
   1108     bitmap.eraseColor(SK_ColorGREEN);
   1109 
   1110     SkMatrix matrix;
   1111     matrix.setScale(SkIntToScalar(2), SkIntToScalar(2));
   1112     matrix.postTranslate(SkIntToScalar(-20), SkIntToScalar(-20));
   1113     SkAutoTUnref<SkImageFilter> matrixFilter(
   1114         SkImageFilter::CreateMatrixFilter(matrix, kLow_SkFilterQuality));
   1115 
   1116     // Test that saveLayer() with a filter nested inside another saveLayer() applies the
   1117     // correct offset to the filter matrix.
   1118     SkRect bounds1 = SkRect::MakeXYWH(10, 10, 30, 30);
   1119     canvas.saveLayer(&bounds1, nullptr);
   1120     SkPaint filterPaint;
   1121     filterPaint.setImageFilter(matrixFilter);
   1122     SkRect bounds2 = SkRect::MakeXYWH(20, 20, 10, 10);
   1123     canvas.saveLayer(&bounds2, &filterPaint);
   1124     SkPaint greenPaint;
   1125     greenPaint.setColor(SK_ColorGREEN);
   1126     canvas.drawRect(bounds2, greenPaint);
   1127     canvas.restore();
   1128     canvas.restore();
   1129     SkPaint strokePaint;
   1130     strokePaint.setStyle(SkPaint::kStroke_Style);
   1131     strokePaint.setColor(SK_ColorRED);
   1132 
   1133     SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType);
   1134     uint32_t pixel;
   1135     canvas.readPixels(info, &pixel, 4, 25, 25);
   1136     REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
   1137 
   1138     // Test that drawSprite() with a filter nested inside a saveLayer() applies the
   1139     // correct offset to the filter matrix.
   1140     canvas.clear(0x0);
   1141     canvas.readPixels(info, &pixel, 4, 25, 25);
   1142     canvas.saveLayer(&bounds1, nullptr);
   1143     canvas.drawBitmap(bitmap, 20, 20, &filterPaint);    // drawSprite
   1144     canvas.restore();
   1145 
   1146     canvas.readPixels(info, &pixel, 4, 25, 25);
   1147     REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
   1148 }
   1149 
   1150 DEF_TEST(XfermodeImageFilterCroppedInput, reporter) {
   1151     SkBitmap temp;
   1152     temp.allocN32Pixels(100, 100);
   1153     SkCanvas canvas(temp);
   1154     test_xfermode_cropped_input(&canvas, reporter);
   1155 }
   1156 
   1157 DEF_TEST(ComposedImageFilterOffset, reporter) {
   1158     SkBitmap bitmap;
   1159     bitmap.allocN32Pixels(100, 100);
   1160     bitmap.eraseARGB(0, 0, 0, 0);
   1161     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
   1162     SkBitmapDevice device(bitmap, props);
   1163     SkImageFilter::DeviceProxy proxy(&device);
   1164 
   1165     SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(1, 0, 20, 20));
   1166     SkAutoTUnref<SkImageFilter> offsetFilter(SkOffsetImageFilter::Create(0, 0, nullptr, &cropRect));
   1167     SkAutoTUnref<SkImageFilter> blurFilter(SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1,
   1168                                                                      nullptr, &cropRect));
   1169     SkAutoTUnref<SkImageFilter> composedFilter(SkComposeImageFilter::Create(blurFilter,
   1170                                                                             offsetFilter.get()));
   1171     SkBitmap result;
   1172     SkIPoint offset;
   1173     SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr);
   1174     REPORTER_ASSERT(reporter,
   1175                     composedFilter->filterImageDeprecated(&proxy, bitmap, ctx, &result, &offset));
   1176     REPORTER_ASSERT(reporter, offset.fX == 1 && offset.fY == 0);
   1177 }
   1178 
   1179 DEF_TEST(PartialCropRect, reporter) {
   1180     SkBitmap bitmap;
   1181     bitmap.allocN32Pixels(100, 100);
   1182     bitmap.eraseARGB(0, 0, 0, 0);
   1183     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
   1184     SkBitmapDevice device(bitmap, props);
   1185     SkImageFilter::DeviceProxy proxy(&device);
   1186 
   1187     SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(100, 0, 20, 30),
   1188         SkImageFilter::CropRect::kHasWidth_CropEdge | SkImageFilter::CropRect::kHasHeight_CropEdge);
   1189     SkAutoTUnref<SkImageFilter> filter(make_grayscale(nullptr, &cropRect));
   1190     SkBitmap result;
   1191     SkIPoint offset;
   1192     SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr);
   1193     REPORTER_ASSERT(reporter,
   1194                     filter->filterImageDeprecated(&proxy, bitmap, ctx, &result, &offset));
   1195     REPORTER_ASSERT(reporter, offset.fX == 0);
   1196     REPORTER_ASSERT(reporter, offset.fY == 0);
   1197     REPORTER_ASSERT(reporter, result.width() == 20);
   1198     REPORTER_ASSERT(reporter, result.height() == 30);
   1199 }
   1200 
   1201 DEF_TEST(ImageFilterCanComputeFastBounds, reporter) {
   1202 
   1203     SkPoint3 location = SkPoint3::Make(0, 0, SK_Scalar1);
   1204     SkAutoTUnref<SkImageFilter> lighting(SkLightingImageFilter::CreatePointLitDiffuse(
   1205           location, SK_ColorGREEN, 0, 0));
   1206     REPORTER_ASSERT(reporter, !lighting->canComputeFastBounds());
   1207 
   1208     SkAutoTUnref<SkImageFilter> gray(make_grayscale(nullptr, nullptr));
   1209     REPORTER_ASSERT(reporter, gray->canComputeFastBounds());
   1210     {
   1211         SkColorFilter* grayCF;
   1212         REPORTER_ASSERT(reporter, gray->asAColorFilter(&grayCF));
   1213         REPORTER_ASSERT(reporter, !grayCF->affectsTransparentBlack());
   1214         grayCF->unref();
   1215     }
   1216     REPORTER_ASSERT(reporter, gray->canComputeFastBounds());
   1217 
   1218     SkAutoTUnref<SkImageFilter> grayBlur(SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1, gray.get()));
   1219     REPORTER_ASSERT(reporter, grayBlur->canComputeFastBounds());
   1220 
   1221     SkScalar greenMatrix[20] = { 0, 0, 0, 0, 0,
   1222                                  0, 0, 0, 0, 1,
   1223                                  0, 0, 0, 0, 0,
   1224                                  0, 0, 0, 0, 1 };
   1225     SkAutoTUnref<SkColorFilter> greenCF(SkColorMatrixFilter::Create(greenMatrix));
   1226     SkAutoTUnref<SkImageFilter> green(SkColorFilterImageFilter::Create(greenCF));
   1227 
   1228     REPORTER_ASSERT(reporter, greenCF->affectsTransparentBlack());
   1229     REPORTER_ASSERT(reporter, !green->canComputeFastBounds());
   1230 
   1231     SkAutoTUnref<SkImageFilter> greenBlur(SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1, green.get()));
   1232     REPORTER_ASSERT(reporter, !greenBlur->canComputeFastBounds());
   1233 
   1234     uint8_t allOne[256], identity[256];
   1235     for (int i = 0; i < 256; ++i) {
   1236         identity[i] = i;
   1237         allOne[i] = 255;
   1238     }
   1239 
   1240     SkAutoTUnref<SkColorFilter> identityCF(
   1241         SkTableColorFilter::CreateARGB(identity, identity, identity, allOne));
   1242     SkAutoTUnref<SkImageFilter> identityFilter(SkColorFilterImageFilter::Create(identityCF.get()));
   1243     REPORTER_ASSERT(reporter, !identityCF->affectsTransparentBlack());
   1244     REPORTER_ASSERT(reporter, identityFilter->canComputeFastBounds());
   1245 
   1246     SkAutoTUnref<SkColorFilter> forceOpaqueCF(
   1247         SkTableColorFilter::CreateARGB(allOne, identity, identity, identity));
   1248     SkAutoTUnref<SkImageFilter> forceOpaque(SkColorFilterImageFilter::Create(forceOpaqueCF.get()));
   1249     REPORTER_ASSERT(reporter, forceOpaqueCF->affectsTransparentBlack());
   1250     REPORTER_ASSERT(reporter, !forceOpaque->canComputeFastBounds());
   1251 }
   1252 
   1253 // Verify that SkImageSource survives serialization
   1254 DEF_TEST(ImageFilterImageSourceSerialization, reporter) {
   1255     SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(10, 10));
   1256     surface->getCanvas()->clear(SK_ColorGREEN);
   1257     SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
   1258     SkAutoTUnref<SkImageFilter> filter(SkImageSource::Create(image));
   1259 
   1260     SkAutoTUnref<SkData> data(SkValidatingSerializeFlattenable(filter));
   1261     SkAutoTUnref<SkFlattenable> flattenable(SkValidatingDeserializeFlattenable(
   1262         data->data(), data->size(), SkImageFilter::GetFlattenableType()));
   1263     SkImageFilter* unflattenedFilter = static_cast<SkImageFilter*>(flattenable.get());
   1264     REPORTER_ASSERT(reporter, unflattenedFilter);
   1265 
   1266     SkBitmap bm;
   1267     bm.allocN32Pixels(10, 10);
   1268     bm.eraseColor(SK_ColorBLUE);
   1269     SkPaint paint;
   1270     paint.setColor(SK_ColorRED);
   1271     paint.setImageFilter(unflattenedFilter);
   1272 
   1273     SkCanvas canvas(bm);
   1274     canvas.drawRect(SkRect::MakeWH(10, 10), paint);
   1275     REPORTER_ASSERT(reporter, *bm.getAddr32(0, 0) == SkPreMultiplyColor(SK_ColorGREEN));
   1276 }
   1277 
   1278 static void test_large_blur_input(skiatest::Reporter* reporter, SkCanvas* canvas) {
   1279     SkBitmap largeBmp;
   1280     int largeW = 5000;
   1281     int largeH = 5000;
   1282 #if SK_SUPPORT_GPU
   1283     // If we're GPU-backed make the bitmap too large to be converted into a texture.
   1284     if (GrContext* ctx = canvas->getGrContext()) {
   1285         largeW = ctx->caps()->maxTextureSize() + 1;
   1286     }
   1287 #endif
   1288 
   1289     largeBmp.allocN32Pixels(largeW, largeH);
   1290     largeBmp.eraseColor(0);
   1291     if (!largeBmp.getPixels()) {
   1292         ERRORF(reporter, "Failed to allocate large bmp.");
   1293         return;
   1294     }
   1295 
   1296     SkAutoTUnref<SkImage> largeImage(SkImage::NewFromBitmap(largeBmp));
   1297     if (!largeImage) {
   1298         ERRORF(reporter, "Failed to create large image.");
   1299         return;
   1300     }
   1301 
   1302     SkAutoTUnref<SkImageFilter> largeSource(SkImageSource::Create(largeImage));
   1303     if (!largeSource) {
   1304         ERRORF(reporter, "Failed to create large SkImageSource.");
   1305         return;
   1306     }
   1307 
   1308     SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(10.f, 10.f, largeSource));
   1309     if (!blur) {
   1310         ERRORF(reporter, "Failed to create SkBlurImageFilter.");
   1311         return;
   1312     }
   1313 
   1314     SkPaint paint;
   1315     paint.setImageFilter(blur);
   1316 
   1317     // This should not crash (http://crbug.com/570479).
   1318     canvas->drawRect(SkRect::MakeIWH(largeW, largeH), paint);
   1319 }
   1320 
   1321 DEF_TEST(BlurLargeImage, reporter) {
   1322     SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(SkImageInfo::MakeN32Premul(100, 100)));
   1323     test_large_blur_input(reporter, surface->getCanvas());
   1324 }
   1325 
   1326 #if SK_SUPPORT_GPU
   1327 
   1328 DEF_GPUTEST_FOR_NATIVE_CONTEXT(ImageFilterCropRect_Gpu, reporter, context) {
   1329     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
   1330 
   1331     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
   1332                                                          SkBudgeted::kNo,
   1333                                                          SkImageInfo::MakeN32Premul(100, 100),
   1334                                                          0,
   1335                                                          &props,
   1336                                                          SkGpuDevice::kUninit_InitContents));
   1337     SkImageFilter::DeviceProxy proxy(device);
   1338 
   1339     test_crop_rects(&proxy, reporter);
   1340 }
   1341 
   1342 DEF_GPUTEST_FOR_NATIVE_CONTEXT(HugeBlurImageFilter_Gpu, reporter, context) {
   1343     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
   1344 
   1345     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
   1346                                                          SkBudgeted::kNo,
   1347                                                          SkImageInfo::MakeN32Premul(100, 100),
   1348                                                          0,
   1349                                                          &props,
   1350                                                          SkGpuDevice::kUninit_InitContents));
   1351     SkCanvas canvas(device);
   1352 
   1353     test_huge_blur(&canvas, reporter);
   1354 }
   1355 
   1356 DEF_GPUTEST_FOR_NATIVE_CONTEXT(XfermodeImageFilterCroppedInput_Gpu, reporter, context) {
   1357     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
   1358 
   1359     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
   1360                                                          SkBudgeted::kNo,
   1361                                                          SkImageInfo::MakeN32Premul(1, 1),
   1362                                                          0,
   1363                                                          &props,
   1364                                                          SkGpuDevice::kUninit_InitContents));
   1365     SkCanvas canvas(device);
   1366 
   1367     test_xfermode_cropped_input(&canvas, reporter);
   1368 }
   1369 
   1370 DEF_GPUTEST_FOR_NATIVE_CONTEXT(TestNegativeBlurSigma_Gpu, reporter, context) {
   1371     const SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
   1372 
   1373     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
   1374                                                          SkBudgeted::kNo,
   1375                                                          SkImageInfo::MakeN32Premul(1, 1),
   1376                                                          0,
   1377                                                          &props,
   1378                                                          SkGpuDevice::kUninit_InitContents));
   1379     SkImageFilter::DeviceProxy proxy(device);
   1380 
   1381     test_negative_blur_sigma(&proxy, reporter);
   1382 }
   1383 
   1384 DEF_GPUTEST_FOR_ALL_CONTEXTS(BlurLargeImage_Gpu, reporter, context) {
   1385     SkAutoTUnref<SkSurface> surface(
   1386         SkSurface::NewRenderTarget(context, SkBudgeted::kYes,
   1387                                    SkImageInfo::MakeN32Premul(100, 100)));
   1388     test_large_blur_input(reporter, surface->getCanvas());
   1389 }
   1390 #endif
   1391