1194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org/* 2194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org * Copyright 2013 Google Inc. 3194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org * 4194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be 5194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org * found in the LICENSE file. 6194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org */ 7194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 84b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org#include "SkBitmap.h" 98f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkBlurImageFilter.h" 104b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org#include "SkCanvas.h" 11194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org#include "SkColorFilterImageFilter.h" 128f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkColorMatrixFilter.h" 135788faaa2ac4203827c68006b669e277d441e2e4ajuma#include "SkComposeImageFilter.h" 146776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkDisplacementMapEffect.h" 156776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkDropShadowImageFilter.h" 1697f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org#include "SkFlattenableSerialization.h" 170a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org#include "SkGradientShader.h" 185598b63cd2443a608a74a222d0206bb2455383b7fmalita#include "SkImage.h" 19cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita#include "SkImageSource.h" 204b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org#include "SkLightingImageFilter.h" 218f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkMatrixConvolutionImageFilter.h" 226776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkMergeImageFilter.h" 236776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkMorphologyImageFilter.h" 246776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkOffsetImageFilter.h" 2577b6ba3b6e23b84a3a4f3a62812e4a9eb6de4c23ajuma#include "SkPaintImageFilter.h" 268f3937d9fcb28018ec14db6697d41b645716d589senorblanco#include "SkPerlinNoiseShader.h" 275251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org#include "SkPicture.h" 28910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org#include "SkPictureImageFilter.h" 29770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com#include "SkPictureRecorder.h" 303d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips#include "SkPoint3.h" 3197d2c0a216e8feae251a6af1e50579df3e026434halcanary#include "SkReadBuffer.h" 328f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkRect.h" 334418dbac3386f26c8da62ab242be9c178961eb18robertphillips#include "SkSpecialImage.h" 344418dbac3386f26c8da62ab242be9c178961eb18robertphillips#include "SkSpecialSurface.h" 35cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita#include "SkSurface.h" 360abdf766d395ed3b7059511425f431589eca05f6senorblanco#include "SkTableColorFilter.h" 376776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkTileImageFilter.h" 386776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkXfermodeImageFilter.h" 398f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h" 40194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 41aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org#if SK_SUPPORT_GPU 421530283c483cb88aa725bce50a6d193dd00ee570kkinnunen#include "GrContext.h" 43aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org#endif 44aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 459f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.orgstatic const int kBitmapSize = 4; 469f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 475251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.orgnamespace { 485251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 495251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.orgclass MatrixTestImageFilter : public SkImageFilter { 505251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.orgpublic: 5143c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips static sk_sp<SkImageFilter> Make(skiatest::Reporter* reporter, 5243c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips const SkMatrix& expectedMatrix) { 5343c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips return sk_sp<SkImageFilter>(new MatrixTestImageFilter(reporter, expectedMatrix)); 545251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org } 555251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 5643c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips SK_TO_STRING_OVERRIDE() 5743c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(MatrixTestImageFilter) 5843c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips 5943c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillipsprotected: 604ba94e26106a4ecab4d3841d702b57487b82334erobertphillips sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context& ctx, 614ba94e26106a4ecab4d3841d702b57487b82334erobertphillips SkIPoint* offset) const override { 624cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org REPORTER_ASSERT(fReporter, ctx.ctm() == fExpectedMatrix); 634ba94e26106a4ecab4d3841d702b57487b82334erobertphillips offset->fX = offset->fY = 0; 644ba94e26106a4ecab4d3841d702b57487b82334erobertphillips return sk_ref_sp<SkSpecialImage>(source); 655251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org } 665251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 6736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void flatten(SkWriteBuffer& buffer) const override { 6818f13f3673c20fec220a1594b3174f9dcab35c5dbrianosman SkDEBUGFAIL("Should never get here"); 695251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org } 705251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 715251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.orgprivate: 7243c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips MatrixTestImageFilter(skiatest::Reporter* reporter, const SkMatrix& expectedMatrix) 7343c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips : INHERITED(nullptr, 0, nullptr) 7443c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips , fReporter(reporter) 7543c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips , fExpectedMatrix(expectedMatrix) { 7643c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips } 7743c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips 785251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org skiatest::Reporter* fReporter; 795251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkMatrix fExpectedMatrix; 803f3b3d003527861dc0bd89733857576408906431mtklein 819fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed typedef SkImageFilter INHERITED; 825251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org}; 835251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 846a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblancoclass FailImageFilter : public SkImageFilter { 856a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblancopublic: 866b13473dd4d5915309cc2caddbab2e22f2f21d5frobertphillips FailImageFilter() : SkImageFilter(nullptr, 0, nullptr) { } 876a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco 886a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, 896a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco const Context& ctx, 906a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco SkIPoint* offset) const override { 916a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco return nullptr; 926a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco } 936a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco 946a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco SK_TO_STRING_OVERRIDE() 956a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter) 966a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco 976a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblancoprivate: 986a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco typedef SkImageFilter INHERITED; 996a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco}; 1006a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco 1016a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblancosk_sp<SkFlattenable> FailImageFilter::CreateProc(SkReadBuffer& buffer) { 1026a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0); 1036a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco return sk_sp<SkFlattenable>(new FailImageFilter()); 1046a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco} 1056a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco 1066a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco#ifndef SK_IGNORE_TO_STRING 1076a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblancovoid FailImageFilter::toString(SkString* str) const { 1086a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco str->appendf("FailImageFilter: ("); 1096a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco str->append(")"); 1106a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco} 1116a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco#endif 1126a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco 113297f7ce2bb6184849adf0e5479e92f76764ec76asenorblancovoid draw_gradient_circle(SkCanvas* canvas, int width, int height) { 114297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkScalar x = SkIntToScalar(width / 2); 115297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkScalar y = SkIntToScalar(height / 2); 116297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkScalar radius = SkMinScalar(x, y) * 0.8f; 117297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco canvas->clear(0x00000000); 118297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkColor colors[2]; 119297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco colors[0] = SK_ColorWHITE; 120297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco colors[1] = SK_ColorBLACK; 121297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco sk_sp<SkShader> shader( 122297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkGradientShader::MakeRadial(SkPoint::Make(x, y), radius, colors, nullptr, 2, 123297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkShader::kClamp_TileMode) 124297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco ); 125297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkPaint paint; 126297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco paint.setShader(shader); 127297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco canvas->drawCircle(x, y, radius, paint); 128297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco} 129297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco 130297f7ce2bb6184849adf0e5479e92f76764ec76asenorblancoSkBitmap make_gradient_circle(int width, int height) { 131297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkBitmap bitmap; 132297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco bitmap.allocN32Pixels(width, height); 133297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkCanvas canvas(bitmap); 134297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco draw_gradient_circle(&canvas, width, height); 135297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco return bitmap; 136297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco} 137297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco 138297f7ce2bb6184849adf0e5479e92f76764ec76asenorblancoclass FilterList { 139297f7ce2bb6184849adf0e5479e92f76764ec76asenorblancopublic: 140fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips FilterList(sk_sp<SkImageFilter> input, const SkImageFilter::CropRect* cropRect = nullptr) { 141297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkPoint3 location = SkPoint3::Make(0, 0, SK_Scalar1); 142297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco const SkScalar five = SkIntToScalar(5); 143297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco 1446e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips { 1456e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkColorFilter> cf(SkColorFilter::MakeModeFilter(SK_ColorRED, 1467d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed SkBlendMode::kSrcIn)); 147297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco 1486e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips this->addFilter("color filter", 14912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkColorFilterImageFilter::Make(std::move(cf), input, cropRect)); 1506e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips } 151297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco 1526e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips { 1536e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImage> gradientImage(SkImage::MakeFromBitmap(make_gradient_circle(64, 64))); 1546e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> gradientSource(SkImageSource::Make(std::move(gradientImage))); 1556e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 156bfebe22ed54d1e3a00888292f10ed8b9714135d3liyuqian this->addFilter("displacement map", 157bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips SkDisplacementMapEffect::Make(SkDisplacementMapEffect::kR_ChannelSelectorType, 158bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips SkDisplacementMapEffect::kB_ChannelSelectorType, 159bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips 20.0f, 160bfe11fc9a6e660f83a454b6a5f5945089a4800f3robertphillips std::move(gradientSource), input, cropRect)); 1616e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips } 1626e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 1636e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips this->addFilter("blur", SkBlurImageFilter::Make(SK_Scalar1, 1646e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SK_Scalar1, 165fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips input, 16612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips cropRect)); 167c416912da4840af0c49bd8cdcf00044ed39500f6robertphillips this->addFilter("drop shadow", SkDropShadowImageFilter::Make( 168297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN, 169fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, 17012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips input, cropRect)); 17112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips this->addFilter("diffuse lighting", 17212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkLightingImageFilter::MakePointLitDiffuse(location, SK_ColorGREEN, 0, 0, 17312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips input, cropRect)); 174297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco this->addFilter("specular lighting", 17512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkLightingImageFilter::MakePointLitSpecular(location, SK_ColorGREEN, 0, 0, 0, 17612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips input, cropRect)); 17712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips { 17812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkScalar kernel[9] = { 17912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkIntToScalar(1), SkIntToScalar(1), SkIntToScalar(1), 18012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkIntToScalar(1), SkIntToScalar(-7), SkIntToScalar(1), 18112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkIntToScalar(1), SkIntToScalar(1), SkIntToScalar(1), 18212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips }; 18312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const SkISize kernelSize = SkISize::Make(3, 3); 18412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips const SkScalar gain = SK_Scalar1, bias = 0; 18512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips 18612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips this->addFilter("matrix convolution", 187ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips SkMatrixConvolutionImageFilter::Make( 188297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco kernelSize, kernel, gain, bias, SkIPoint::Make(1, 1), 189fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips SkMatrixConvolutionImageFilter::kRepeat_TileMode, false, 19012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips input, cropRect)); 19112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips } 19212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips 193fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips this->addFilter("merge", SkMergeImageFilter::Make(input, input, 1947d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed SkBlendMode::kSrcOver, 19512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips cropRect)); 19612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips 1976e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips { 1986e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkPaint greenColorShaderPaint; 1996e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips greenColorShaderPaint.setShader(SkShader::MakeColorShader(SK_ColorGREEN)); 2006e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 2016e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkImageFilter::CropRect leftSideCropRect(SkRect::MakeXYWH(0, 0, 32, 64)); 2026e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> paintFilterLeft(SkPaintImageFilter::Make(greenColorShaderPaint, 2036e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips &leftSideCropRect)); 2046e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkImageFilter::CropRect rightSideCropRect(SkRect::MakeXYWH(32, 0, 32, 64)); 2056e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> paintFilterRight(SkPaintImageFilter::Make(greenColorShaderPaint, 2066e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips &rightSideCropRect)); 2076e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 2086e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 2096e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips this->addFilter("merge with disjoint inputs", SkMergeImageFilter::Make( 2102238c9dbca4b791edc512957728a18ce14d55912robertphillips std::move(paintFilterLeft), std::move(paintFilterRight), 2117d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed SkBlendMode::kSrcOver, cropRect)); 2126e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips } 2136e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 214297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco this->addFilter("offset", 215fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips SkOffsetImageFilter::Make(SK_Scalar1, SK_Scalar1, input, 21612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips cropRect)); 21712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips this->addFilter("dilate", SkDilateImageFilter::Make(3, 2, input, cropRect)); 21812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips this->addFilter("erode", SkErodeImageFilter::Make(2, 3, input, cropRect)); 219534c270465a9824893d5c9d6c5bacef7726cc389robertphillips this->addFilter("tile", SkTileImageFilter::Make( 220534c270465a9824893d5c9d6c5bacef7726cc389robertphillips SkRect::MakeXYWH(0, 0, 50, 50), 221534c270465a9824893d5c9d6c5bacef7726cc389robertphillips cropRect ? cropRect->rect() : SkRect::MakeXYWH(0, 0, 100, 100), 222534c270465a9824893d5c9d6c5bacef7726cc389robertphillips input)); 22312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips 224297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco if (!cropRect) { 22512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkMatrix matrix; 22612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips 22712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips matrix.setTranslate(SK_Scalar1, SK_Scalar1); 22812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips matrix.postRotate(SkIntToScalar(45), SK_Scalar1, SK_Scalar1); 22912fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips 230ae8c933ca89315c1256bcf23749b5ee5cbc0d53crobertphillips this->addFilter("matrix", 23112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkImageFilter::MakeMatrixFilter(matrix, kLow_SkFilterQuality, input)); 232297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco } 2336e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips { 234fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips sk_sp<SkImageFilter> blur(SkBlurImageFilter::Make(five, five, input)); 2356e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 2366e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips this->addFilter("blur and offset", SkOffsetImageFilter::Make(five, five, 2376e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips std::move(blur), 23812fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips cropRect)); 2396e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips } 2406e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips { 2416e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkRTreeFactory factory; 2426e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkPictureRecorder recorder; 2436e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkCanvas* recordingCanvas = recorder.beginRecording(64, 64, &factory, 0); 2446e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 2456e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkPaint greenPaint; 2466e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips greenPaint.setColor(SK_ColorGREEN); 2476e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeXYWH(10, 10, 30, 20)), greenPaint); 2486e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 2496e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> pictureFilter(SkPictureImageFilter::Make(std::move(picture))); 2506e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 2516e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips this->addFilter("picture and blur", SkBlurImageFilter::Make(five, five, 2526e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips std::move(pictureFilter), 25312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips cropRect)); 2546e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips } 2556e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips { 2566e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkPaint paint; 2576e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips paint.setShader(SkPerlinNoiseShader::MakeTurbulence(SK_Scalar1, SK_Scalar1, 1, 0)); 2586e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> paintFilter(SkPaintImageFilter::Make(paint)); 2596e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 2606e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips this->addFilter("paint and blur", SkBlurImageFilter::Make(five, five, 2616e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips std::move(paintFilter), 26212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips cropRect)); 2636e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips } 264374772bd61951f01bf84fe17bf53d8867681c9aereed this->addFilter("xfermode", SkXfermodeImageFilter::Make(SkBlendMode::kSrc, input, input, 265374772bd61951f01bf84fe17bf53d8867681c9aereed cropRect)); 266297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco } 267297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco int count() const { return fFilters.count(); } 268297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkImageFilter* getFilter(int index) const { return fFilters[index].fFilter.get(); } 269297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco const char* getName(int index) const { return fFilters[index].fName; } 270297f7ce2bb6184849adf0e5479e92f76764ec76asenorblancoprivate: 271297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco struct Filter { 27212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips Filter() : fName(nullptr) {} 27312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips Filter(const char* name, sk_sp<SkImageFilter> filter) 27412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips : fName(name) 27512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips , fFilter(std::move(filter)) { 27612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips } 277297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco const char* fName; 278297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco sk_sp<SkImageFilter> fFilter; 279297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco }; 28012fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips void addFilter(const char* name, sk_sp<SkImageFilter> filter) { 28112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips fFilters.push_back(Filter(name, std::move(filter))); 282297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco } 283297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco 284297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkTArray<Filter> fFilters; 285297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco}; 286297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco 2875251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org} 2885251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 28960c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> MatrixTestImageFilter::CreateProc(SkReadBuffer& buffer) { 29018f13f3673c20fec220a1594b3174f9dcab35c5dbrianosman SkDEBUGFAIL("Should never get here"); 29118f13f3673c20fec220a1594b3174f9dcab35c5dbrianosman return nullptr; 2929fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 2939fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 294f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#ifndef SK_IGNORE_TO_STRING 295f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillipsvoid MatrixTestImageFilter::toString(SkString* str) const { 296f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->appendf("MatrixTestImageFilter: ("); 297f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->append(")"); 298f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips} 299f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#endif 300f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips 3019ce9d6772df650ceb0511f275e1a83dffa78ff72reedstatic sk_sp<SkImage> make_small_image() { 302e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(SkSurface::MakeRasterN32Premul(kBitmapSize, kBitmapSize)); 3035598b63cd2443a608a74a222d0206bb2455383b7fmalita SkCanvas* canvas = surface->getCanvas(); 3045598b63cd2443a608a74a222d0206bb2455383b7fmalita canvas->clear(0x00000000); 3059f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkPaint darkPaint; 3069f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org darkPaint.setColor(0xFF804020); 3079f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkPaint lightPaint; 3089f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org lightPaint.setColor(0xFF244484); 3099f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org const int i = kBitmapSize / 4; 3109f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org for (int y = 0; y < kBitmapSize; y += i) { 3119f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org for (int x = 0; x < kBitmapSize; x += i) { 3125598b63cd2443a608a74a222d0206bb2455383b7fmalita canvas->save(); 3135598b63cd2443a608a74a222d0206bb2455383b7fmalita canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); 3145598b63cd2443a608a74a222d0206bb2455383b7fmalita canvas->drawRect(SkRect::MakeXYWH(0, 0, 3159f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 3169f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i)), darkPaint); 3175598b63cd2443a608a74a222d0206bb2455383b7fmalita canvas->drawRect(SkRect::MakeXYWH(SkIntToScalar(i), 3189f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 0, 3199f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 3209f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i)), lightPaint); 3215598b63cd2443a608a74a222d0206bb2455383b7fmalita canvas->drawRect(SkRect::MakeXYWH(0, 3229f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 3239f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 3249f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i)), lightPaint); 3255598b63cd2443a608a74a222d0206bb2455383b7fmalita canvas->drawRect(SkRect::MakeXYWH(SkIntToScalar(i), 3269f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 3279f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 3289f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i)), darkPaint); 3295598b63cd2443a608a74a222d0206bb2455383b7fmalita canvas->restore(); 3304b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org } 3314b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org } 3325598b63cd2443a608a74a222d0206bb2455383b7fmalita 3339ce9d6772df650ceb0511f275e1a83dffa78ff72reed return surface->makeImageSnapshot(); 3349f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org} 3359f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 3365605b56afa5bd89f3148b397318b616fccfd4004robertphillipsstatic sk_sp<SkImageFilter> make_scale(float amount, sk_sp<SkImageFilter> input) { 3379f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkScalar s = amount; 3389f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkScalar matrix[20] = { s, 0, 0, 0, 0, 3399f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 0, s, 0, 0, 0, 3409f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 0, 0, s, 0, 0, 3419f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 0, 0, 0, s, 0 }; 3425605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkColorFilter> filter(SkColorFilter::MakeMatrixFilterRowMajor255(matrix)); 3435605b56afa5bd89f3148b397318b616fccfd4004robertphillips return SkColorFilterImageFilter::Make(std::move(filter), std::move(input)); 3449f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org} 3459f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 3465605b56afa5bd89f3148b397318b616fccfd4004robertphillipsstatic sk_sp<SkImageFilter> make_grayscale(sk_sp<SkImageFilter> input, 3475605b56afa5bd89f3148b397318b616fccfd4004robertphillips const SkImageFilter::CropRect* cropRect) { 3489f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkScalar matrix[20]; 3499f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org memset(matrix, 0, 20 * sizeof(SkScalar)); 3509f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org matrix[0] = matrix[5] = matrix[10] = 0.2126f; 3519f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org matrix[1] = matrix[6] = matrix[11] = 0.7152f; 3529f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org matrix[2] = matrix[7] = matrix[12] = 0.0722f; 3539f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org matrix[18] = 1.0f; 3545605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkColorFilter> filter(SkColorFilter::MakeMatrixFilterRowMajor255(matrix)); 3555605b56afa5bd89f3148b397318b616fccfd4004robertphillips return SkColorFilterImageFilter::Make(std::move(filter), std::move(input), cropRect); 3569f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org} 3579f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 3585605b56afa5bd89f3148b397318b616fccfd4004robertphillipsstatic sk_sp<SkImageFilter> make_blue(sk_sp<SkImageFilter> input, 3595605b56afa5bd89f3148b397318b616fccfd4004robertphillips const SkImageFilter::CropRect* cropRect) { 3605605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkColorFilter> filter(SkColorFilter::MakeModeFilter(SK_ColorBLUE, 3617d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed SkBlendMode::kSrcIn)); 3625605b56afa5bd89f3148b397318b616fccfd4004robertphillips return SkColorFilterImageFilter::Make(std::move(filter), std::move(input), cropRect); 363cedc36f18b2254c5ee21f6348124886b6db4f4c2reed} 364cedc36f18b2254c5ee21f6348124886b6db4f4c2reed 3653e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic sk_sp<SkSpecialSurface> create_empty_special_surface(GrContext* context, int widthHeight) { 366c91fd3447e1d3452d5e43e70e371896c80645b61robertphillips#if SK_SUPPORT_GPU 3674418dbac3386f26c8da62ab242be9c178961eb18robertphillips if (context) { 3684df1656f0f728ed428c3ab8f7beb19703b27c28erobertphillips return SkSpecialSurface::MakeRenderTarget(context, 3694df1656f0f728ed428c3ab8f7beb19703b27c28erobertphillips widthHeight, widthHeight, 370777b5633f599f2a99e2035fdb7ab600779ab95acBrian Osman kRGBA_8888_GrPixelConfig, nullptr); 371c91fd3447e1d3452d5e43e70e371896c80645b61robertphillips } else 372c91fd3447e1d3452d5e43e70e371896c80645b61robertphillips#endif 373c91fd3447e1d3452d5e43e70e371896c80645b61robertphillips { 3744418dbac3386f26c8da62ab242be9c178961eb18robertphillips const SkImageInfo info = SkImageInfo::MakeN32(widthHeight, widthHeight, 3754418dbac3386f26c8da62ab242be9c178961eb18robertphillips kOpaque_SkAlphaType); 3763e302275b324172c845627cbd00cee8a06571bafrobertphillips return SkSpecialSurface::MakeRaster(info); 3774418dbac3386f26c8da62ab242be9c178961eb18robertphillips } 378bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco} 379bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco 3805878dbdf1b5d86201d299c6e07d53e35048713c7senorblancostatic sk_sp<SkSurface> create_surface(GrContext* context, int width, int height) { 3815878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco const SkImageInfo info = SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType); 3825878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco#if SK_SUPPORT_GPU 3835878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco if (context) { 3845878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco return SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info); 3855878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco } else 3865878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco#endif 3875878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco { 3885878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco return SkSurface::MakeRaster(info); 3895878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco } 3905878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco} 3915878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 3923e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic sk_sp<SkSpecialImage> create_empty_special_image(GrContext* context, int widthHeight) { 3933e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialSurface> surf(create_empty_special_surface(context, widthHeight)); 3944418dbac3386f26c8da62ab242be9c178961eb18robertphillips 3954418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkASSERT(surf); 3964418dbac3386f26c8da62ab242be9c178961eb18robertphillips 3974418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkCanvas* canvas = surf->getCanvas(); 3984418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkASSERT(canvas); 3994418dbac3386f26c8da62ab242be9c178961eb18robertphillips 4004418dbac3386f26c8da62ab242be9c178961eb18robertphillips canvas->clear(0x0); 4014418dbac3386f26c8da62ab242be9c178961eb18robertphillips 40237bd7c3aca66697fff2db79c21771a0b3cbe3b4crobertphillips return surf->makeImageSnapshot(); 4034418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 4044418dbac3386f26c8da62ab242be9c178961eb18robertphillips 4054418dbac3386f26c8da62ab242be9c178961eb18robertphillips 4069f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.orgDEF_TEST(ImageFilter, reporter) { 4079f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org { 408cedc36f18b2254c5ee21f6348124886b6db4f4c2reed // Check that two non-clipping color-matrice-filters concatenate into a single filter. 4095605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> halfBrightness(make_scale(0.5f, nullptr)); 4105605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> quarterBrightness(make_scale(0.5f, std::move(halfBrightness))); 41196fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == quarterBrightness->getInput(0)); 412cedc36f18b2254c5ee21f6348124886b6db4f4c2reed SkColorFilter* cf; 413cedc36f18b2254c5ee21f6348124886b6db4f4c2reed REPORTER_ASSERT(reporter, quarterBrightness->asColorFilter(&cf)); 41496fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, cf->asColorMatrix(nullptr)); 415cedc36f18b2254c5ee21f6348124886b6db4f4c2reed cf->unref(); 416194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 417194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 4189f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org { 419cedc36f18b2254c5ee21f6348124886b6db4f4c2reed // Check that a clipping color-matrice-filter followed by a color-matrice-filters 420cedc36f18b2254c5ee21f6348124886b6db4f4c2reed // concatenates into a single filter, but not a matrixfilter (due to clamping). 4215605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> doubleBrightness(make_scale(2.0f, nullptr)); 4225605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> halfBrightness(make_scale(0.5f, std::move(doubleBrightness))); 42396fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == halfBrightness->getInput(0)); 424cedc36f18b2254c5ee21f6348124886b6db4f4c2reed SkColorFilter* cf; 425cedc36f18b2254c5ee21f6348124886b6db4f4c2reed REPORTER_ASSERT(reporter, halfBrightness->asColorFilter(&cf)); 42696fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, !cf->asColorMatrix(nullptr)); 427cedc36f18b2254c5ee21f6348124886b6db4f4c2reed cf->unref(); 428194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 429194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 4309f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org { 4319f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // Check that a color filter image filter without a crop rect can be 4329f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // expressed as a color filter. 4335605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> gray(make_grayscale(nullptr, nullptr)); 43496fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, true == gray->asColorFilter(nullptr)); 435cedc36f18b2254c5ee21f6348124886b6db4f4c2reed } 4362afbe23753bf97402a47408c83107042eea3c476mtklein 437cedc36f18b2254c5ee21f6348124886b6db4f4c2reed { 438cedc36f18b2254c5ee21f6348124886b6db4f4c2reed // Check that a colorfilterimage filter without a crop rect but with an input 439cedc36f18b2254c5ee21f6348124886b6db4f4c2reed // that is another colorfilterimage can be expressed as a colorfilter (composed). 4405605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> mode(make_blue(nullptr, nullptr)); 4415605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> gray(make_grayscale(std::move(mode), nullptr)); 44296fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, true == gray->asColorFilter(nullptr)); 443194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 4445c518a862264225f0a378e4728e037966ddf4cc2reed 4459f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org { 446cedc36f18b2254c5ee21f6348124886b6db4f4c2reed // Test that if we exceed the limit of what ComposeColorFilter can combine, we still 447cedc36f18b2254c5ee21f6348124886b6db4f4c2reed // can build the DAG and won't assert if we call asColorFilter. 4485605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> filter(make_blue(nullptr, nullptr)); 449cedc36f18b2254c5ee21f6348124886b6db4f4c2reed const int kWayTooManyForComposeColorFilter = 100; 450cedc36f18b2254c5ee21f6348124886b6db4f4c2reed for (int i = 0; i < kWayTooManyForComposeColorFilter; ++i) { 4515605b56afa5bd89f3148b397318b616fccfd4004robertphillips filter = make_blue(filter, nullptr); 452cedc36f18b2254c5ee21f6348124886b6db4f4c2reed // the first few of these will succeed, but after we hit the internal limit, 453cedc36f18b2254c5ee21f6348124886b6db4f4c2reed // it will then return false. 45496fcdcc219d2a0d3579719b84b28bede76efba64halcanary (void)filter->asColorFilter(nullptr); 455cedc36f18b2254c5ee21f6348124886b6db4f4c2reed } 456cedc36f18b2254c5ee21f6348124886b6db4f4c2reed } 457cedc36f18b2254c5ee21f6348124886b6db4f4c2reed 458cedc36f18b2254c5ee21f6348124886b6db4f4c2reed { 4599f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // Check that a color filter image filter with a crop rect cannot 4609f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // be expressed as a color filter. 4619f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(0, 0, 100, 100)); 4625605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> grayWithCrop(make_grayscale(nullptr, &cropRect)); 46396fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, false == grayWithCrop->asColorFilter(nullptr)); 4649f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org } 465194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 4669f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org { 4673df05015efce95c306fb79c21efc77c79f1ac1basenorblanco // Check that two non-commutative matrices are concatenated in 4683df05015efce95c306fb79c21efc77c79f1ac1basenorblanco // the correct order. 4693df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkScalar blueToRedMatrix[20] = { 0 }; 4703df05015efce95c306fb79c21efc77c79f1ac1basenorblanco blueToRedMatrix[2] = blueToRedMatrix[18] = SK_Scalar1; 4713df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkScalar redToGreenMatrix[20] = { 0 }; 4723df05015efce95c306fb79c21efc77c79f1ac1basenorblanco redToGreenMatrix[5] = redToGreenMatrix[18] = SK_Scalar1; 4735605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkColorFilter> blueToRed(SkColorFilter::MakeMatrixFilterRowMajor255(blueToRedMatrix)); 4745605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> filter1(SkColorFilterImageFilter::Make(std::move(blueToRed), 4755605b56afa5bd89f3148b397318b616fccfd4004robertphillips nullptr)); 4765605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkColorFilter> redToGreen(SkColorFilter::MakeMatrixFilterRowMajor255(redToGreenMatrix)); 4775605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> filter2(SkColorFilterImageFilter::Make(std::move(redToGreen), 4785605b56afa5bd89f3148b397318b616fccfd4004robertphillips std::move(filter1))); 4793df05015efce95c306fb79c21efc77c79f1ac1basenorblanco 4803df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkBitmap result; 4813df05015efce95c306fb79c21efc77c79f1ac1basenorblanco result.allocN32Pixels(kBitmapSize, kBitmapSize); 4823df05015efce95c306fb79c21efc77c79f1ac1basenorblanco 4833df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkPaint paint; 4843df05015efce95c306fb79c21efc77c79f1ac1basenorblanco paint.setColor(SK_ColorBLUE); 4855605b56afa5bd89f3148b397318b616fccfd4004robertphillips paint.setImageFilter(std::move(filter2)); 4863df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkCanvas canvas(result); 4873df05015efce95c306fb79c21efc77c79f1ac1basenorblanco canvas.clear(0x0); 4883df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkRect rect = SkRect::Make(SkIRect::MakeWH(kBitmapSize, kBitmapSize)); 4893df05015efce95c306fb79c21efc77c79f1ac1basenorblanco canvas.drawRect(rect, paint); 4903df05015efce95c306fb79c21efc77c79f1ac1basenorblanco uint32_t pixel = *result.getAddr32(0, 0); 4913df05015efce95c306fb79c21efc77c79f1ac1basenorblanco // The result here should be green, since we have effectively shifted blue to green. 4923df05015efce95c306fb79c21efc77c79f1ac1basenorblanco REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 4933df05015efce95c306fb79c21efc77c79f1ac1basenorblanco } 4943df05015efce95c306fb79c21efc77c79f1ac1basenorblanco 4953df05015efce95c306fb79c21efc77c79f1ac1basenorblanco { 4969f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // Tests pass by not asserting 4979ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(make_small_image()); 4985598b63cd2443a608a74a222d0206bb2455383b7fmalita SkBitmap result; 499deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org result.allocN32Pixels(kBitmapSize, kBitmapSize); 500194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 501194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org { 5029f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // This tests for : 5039f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // 1 ) location at (0,0,1) 5043d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkPoint3 location = SkPoint3::Make(0, 0, SK_Scalar1); 5059f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // 2 ) location and target at same value 5063d32d768cd8b66c49c070495c08f7933b9dd2423robertphillips SkPoint3 target = SkPoint3::Make(location.fX, location.fY, location.fZ); 5079f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // 3 ) large negative specular exponent value 5089f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkScalar specularExponent = -1000; 5099f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 510549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips sk_sp<SkImageFilter> bmSrc(SkImageSource::Make(std::move(image))); 5119f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkPaint paint; 51212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips paint.setImageFilter(SkLightingImageFilter::MakeSpotLitSpecular( 5139f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org location, target, specularExponent, 180, 5149f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 0xFFFFFFFF, SK_Scalar1, SK_Scalar1, SK_Scalar1, 51512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips std::move(bmSrc))); 5169f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkCanvas canvas(result); 5179f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkRect r = SkRect::MakeWH(SkIntToScalar(kBitmapSize), 5189f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(kBitmapSize)); 5199f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org canvas.drawRect(r, paint); 520194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 521194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 522aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org} 5236776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org 5243e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic void test_crop_rects(skiatest::Reporter* reporter, 5254418dbac3386f26c8da62ab242be9c178961eb18robertphillips GrContext* context) { 526aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org // Check that all filters offset to their absolute crop rect, 527aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org // unaffected by the input crop rect. 528aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org // Tests pass by not asserting. 5293e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialImage> srcImg(create_empty_special_image(context, 100)); 5304418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkASSERT(srcImg); 531aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 532aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkImageFilter::CropRect inputCropRect(SkRect::MakeXYWH(8, 13, 80, 80)); 533aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(20, 30, 60, 60)); 534fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips sk_sp<SkImageFilter> input(make_grayscale(nullptr, &inputCropRect)); 535aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 536fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips FilterList filters(input, &cropRect); 537aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 538297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco for (int i = 0; i < filters.count(); ++i) { 539297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco SkImageFilter* filter = filters.getFilter(i); 540aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkIPoint offset; 5412a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::OutputProperties noColorSpace(nullptr); 5422a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr, noColorSpace); 5432302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg.get(), ctx, &offset)); 544297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco REPORTER_ASSERT_MESSAGE(reporter, resultImg, filters.getName(i)); 545297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco REPORTER_ASSERT_MESSAGE(reporter, offset.fX == 20 && offset.fY == 30, filters.getName(i)); 5466776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org } 5479f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org} 548aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 5493e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic void test_negative_blur_sigma(skiatest::Reporter* reporter, 5504418dbac3386f26c8da62ab242be9c178961eb18robertphillips GrContext* context) { 55132673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco // Check that SkBlurImageFilter will accept a negative sigma, either in 55232673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco // the given arguments or after CTM application. 5535ea95df02de9cd774d0b84d1341599bbd9c0d8dbreed const int width = 32, height = 32; 5545ea95df02de9cd774d0b84d1341599bbd9c0d8dbreed const SkScalar five = SkIntToScalar(5); 55532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 5566e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> positiveFilter(SkBlurImageFilter::Make(five, five, nullptr)); 5576e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> negativeFilter(SkBlurImageFilter::Make(-five, five, nullptr)); 55832673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 55932673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkBitmap gradient = make_gradient_circle(width, height); 5603e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialImage> imgSrc(SkSpecialImage::MakeFromRaster(SkIRect::MakeWH(width, height), 56137bd7c3aca66697fff2db79c21771a0b3cbe3b4crobertphillips gradient)); 5624418dbac3386f26c8da62ab242be9c178961eb18robertphillips 56332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkIPoint offset; 5642a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::OutputProperties noColorSpace(nullptr); 5652a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(32, 32), nullptr, noColorSpace); 5664418dbac3386f26c8da62ab242be9c178961eb18robertphillips 5672302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> positiveResult1(positiveFilter->filterImage(imgSrc.get(), ctx, &offset)); 5684418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, positiveResult1); 5694418dbac3386f26c8da62ab242be9c178961eb18robertphillips 5702302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> negativeResult1(negativeFilter->filterImage(imgSrc.get(), ctx, &offset)); 5714418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, negativeResult1); 5724418dbac3386f26c8da62ab242be9c178961eb18robertphillips 57332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkMatrix negativeScale; 57432673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco negativeScale.setScale(-SK_Scalar1, SK_Scalar1); 5752a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context negativeCTX(negativeScale, SkIRect::MakeWH(32, 32), nullptr, 5762a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman noColorSpace); 5774418dbac3386f26c8da62ab242be9c178961eb18robertphillips 5782302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> negativeResult2(positiveFilter->filterImage(imgSrc.get(), 5792302de920e5434809bd0e85b871a6e002856dfdbrobertphillips negativeCTX, 5802302de920e5434809bd0e85b871a6e002856dfdbrobertphillips &offset)); 5814418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, negativeResult2); 5824418dbac3386f26c8da62ab242be9c178961eb18robertphillips 5832302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> positiveResult2(negativeFilter->filterImage(imgSrc.get(), 5842302de920e5434809bd0e85b871a6e002856dfdbrobertphillips negativeCTX, 5852302de920e5434809bd0e85b871a6e002856dfdbrobertphillips &offset)); 5864418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, positiveResult2); 5874418dbac3386f26c8da62ab242be9c178961eb18robertphillips 5884418dbac3386f26c8da62ab242be9c178961eb18robertphillips 5894418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkBitmap positiveResultBM1, positiveResultBM2; 5904418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkBitmap negativeResultBM1, negativeResultBM2; 5914418dbac3386f26c8da62ab242be9c178961eb18robertphillips 592646125114b42b24e5ada3c9f8fac53a85f9ad2a0robertphillips REPORTER_ASSERT(reporter, positiveResult1->getROPixels(&positiveResultBM1)); 593646125114b42b24e5ada3c9f8fac53a85f9ad2a0robertphillips REPORTER_ASSERT(reporter, positiveResult2->getROPixels(&positiveResultBM2)); 594646125114b42b24e5ada3c9f8fac53a85f9ad2a0robertphillips REPORTER_ASSERT(reporter, negativeResult1->getROPixels(&negativeResultBM1)); 595646125114b42b24e5ada3c9f8fac53a85f9ad2a0robertphillips REPORTER_ASSERT(reporter, negativeResult2->getROPixels(&negativeResultBM2)); 5964418dbac3386f26c8da62ab242be9c178961eb18robertphillips 5974418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkAutoLockPixels lockP1(positiveResultBM1); 5984418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkAutoLockPixels lockP2(positiveResultBM2); 5994418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkAutoLockPixels lockN1(negativeResultBM1); 6004418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkAutoLockPixels lockN2(negativeResultBM2); 60132673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco for (int y = 0; y < height; y++) { 6024418dbac3386f26c8da62ab242be9c178961eb18robertphillips int diffs = memcmp(positiveResultBM1.getAddr32(0, y), 6034418dbac3386f26c8da62ab242be9c178961eb18robertphillips negativeResultBM1.getAddr32(0, y), 6044418dbac3386f26c8da62ab242be9c178961eb18robertphillips positiveResultBM1.rowBytes()); 60532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco REPORTER_ASSERT(reporter, !diffs); 60632673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco if (diffs) { 60732673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco break; 60832673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco } 6094418dbac3386f26c8da62ab242be9c178961eb18robertphillips diffs = memcmp(positiveResultBM1.getAddr32(0, y), 6104418dbac3386f26c8da62ab242be9c178961eb18robertphillips negativeResultBM2.getAddr32(0, y), 6114418dbac3386f26c8da62ab242be9c178961eb18robertphillips positiveResultBM1.rowBytes()); 61232673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco REPORTER_ASSERT(reporter, !diffs); 61332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco if (diffs) { 61432673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco break; 61532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco } 6164418dbac3386f26c8da62ab242be9c178961eb18robertphillips diffs = memcmp(positiveResultBM1.getAddr32(0, y), 6174418dbac3386f26c8da62ab242be9c178961eb18robertphillips positiveResultBM2.getAddr32(0, y), 6184418dbac3386f26c8da62ab242be9c178961eb18robertphillips positiveResultBM1.rowBytes()); 61932673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco REPORTER_ASSERT(reporter, !diffs); 62032673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco if (diffs) { 62132673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco break; 62232673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco } 62332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco } 62432673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco} 62532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 62621a465d7f4c5e639044e79971aeaa1194fc73078senorblancoDEF_TEST(ImageFilterNegativeBlurSigma, reporter) { 6273e302275b324172c845627cbd00cee8a06571bafrobertphillips test_negative_blur_sigma(reporter, nullptr); 6284418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 6294418dbac3386f26c8da62ab242be9c178961eb18robertphillips 6304418dbac3386f26c8da62ab242be9c178961eb18robertphillips#if SK_SUPPORT_GPU 63168d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterNegativeBlurSigma_Gpu, reporter, ctxInfo) { 6328b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon test_negative_blur_sigma(reporter, ctxInfo.grContext()); 63332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco} 6344418dbac3386f26c8da62ab242be9c178961eb18robertphillips#endif 63532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 6363e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic void test_zero_blur_sigma(skiatest::Reporter* reporter, GrContext* context) { 637bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco // Check that SkBlurImageFilter with a zero sigma and a non-zero srcOffset works correctly. 638bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco SkImageFilter::CropRect cropRect(SkRect::Make(SkIRect::MakeXYWH(5, 0, 5, 10))); 63951a315eff9b86bd60e7884240c4efc199129d37arobertphillips sk_sp<SkImageFilter> input(SkOffsetImageFilter::Make(0, 0, nullptr, &cropRect)); 6406e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> filter(SkBlurImageFilter::Make(0, 0, std::move(input), &cropRect)); 641bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco 6423e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialSurface> surf(create_empty_special_surface(context, 10)); 643bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco surf->getCanvas()->clear(SK_ColorGREEN); 64437bd7c3aca66697fff2db79c21771a0b3cbe3b4crobertphillips sk_sp<SkSpecialImage> image(surf->makeImageSnapshot()); 645bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco 646bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco SkIPoint offset; 6472a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::OutputProperties noColorSpace(nullptr); 6482a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(32, 32), nullptr, noColorSpace); 649bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco 6502302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> result(filter->filterImage(image.get(), ctx, &offset)); 651bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco REPORTER_ASSERT(reporter, offset.fX == 5 && offset.fY == 0); 652bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco REPORTER_ASSERT(reporter, result); 653bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco REPORTER_ASSERT(reporter, result->width() == 5 && result->height() == 10); 654bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco 655bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco SkBitmap resultBM; 656bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco 657646125114b42b24e5ada3c9f8fac53a85f9ad2a0robertphillips REPORTER_ASSERT(reporter, result->getROPixels(&resultBM)); 658bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco 659bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco SkAutoLockPixels lock(resultBM); 660bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco for (int y = 0; y < resultBM.height(); y++) { 661bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco for (int x = 0; x < resultBM.width(); x++) { 662bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco bool diff = *resultBM.getAddr32(x, y) != SK_ColorGREEN; 663bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco REPORTER_ASSERT(reporter, !diff); 664bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco if (diff) { 665bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco break; 666bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco } 667bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco } 668bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco } 669bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco} 670bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco 67121a465d7f4c5e639044e79971aeaa1194fc73078senorblancoDEF_TEST(ImageFilterZeroBlurSigma, reporter) { 6723e302275b324172c845627cbd00cee8a06571bafrobertphillips test_zero_blur_sigma(reporter, nullptr); 673bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco} 674bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco 675bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco#if SK_SUPPORT_GPU 67668d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterZeroBlurSigma_Gpu, reporter, ctxInfo) { 6778b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon test_zero_blur_sigma(reporter, ctxInfo.grContext()); 678bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco} 679bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco#endif 680bf680c30a280d4d7b3b8d5fedf23defff348cb50senorblanco 6816a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco 6826a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco// Tests that, even when an upstream filter has returned null (due to failure or clipping), a 6836a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco// downstream filter that affects transparent black still does so even with a nullptr input. 6843e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic void test_fail_affects_transparent_black(skiatest::Reporter* reporter, GrContext* context) { 6856a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco sk_sp<FailImageFilter> failFilter(new FailImageFilter()); 6863e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialImage> source(create_empty_special_image(context, 5)); 6872a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::OutputProperties noColorSpace(nullptr); 6882a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(0, 0, 1, 1), nullptr, noColorSpace); 6897d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed sk_sp<SkColorFilter> green(SkColorFilter::MakeModeFilter(SK_ColorGREEN, SkBlendMode::kSrc)); 6906a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco SkASSERT(green->affectsTransparentBlack()); 6915605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> greenFilter(SkColorFilterImageFilter::Make(std::move(green), 6925605b56afa5bd89f3148b397318b616fccfd4004robertphillips std::move(failFilter))); 6936a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco SkIPoint offset; 6946a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco sk_sp<SkSpecialImage> result(greenFilter->filterImage(source.get(), ctx, &offset)); 6956a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco REPORTER_ASSERT(reporter, nullptr != result.get()); 6966a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco if (result.get()) { 6976a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco SkBitmap resultBM; 698646125114b42b24e5ada3c9f8fac53a85f9ad2a0robertphillips REPORTER_ASSERT(reporter, result->getROPixels(&resultBM)); 6996a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco SkAutoLockPixels lock(resultBM); 7006a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco REPORTER_ASSERT(reporter, *resultBM.getAddr32(0, 0) == SK_ColorGREEN); 7016a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco } 7026a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco} 7036a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco 7046a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblancoDEF_TEST(ImageFilterFailAffectsTransparentBlack, reporter) { 7053e302275b324172c845627cbd00cee8a06571bafrobertphillips test_fail_affects_transparent_black(reporter, nullptr); 7066a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco} 7076a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco 7086a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco#if SK_SUPPORT_GPU 70968d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterFailAffectsTransparentBlack_Gpu, reporter, ctxInfo) { 7108b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon test_fail_affects_transparent_black(reporter, ctxInfo.grContext()); 7116a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco} 7126a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco#endif 7136a93fa1a4526ba14782f7f17a73479ca5a4a8e3asenorblanco 7140a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.orgDEF_TEST(ImageFilterDrawTiled, reporter) { 7150a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org // Check that all filters when drawn tiled (with subsequent clip rects) exactly 7160a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org // match the same filters drawn with a single full-canvas bitmap draw. 7170a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org // Tests pass by not asserting. 7180a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 719fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips FilterList filters(nullptr); 7200a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 7210a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkBitmap untiledResult, tiledResult; 7225ea95df02de9cd774d0b84d1341599bbd9c0d8dbreed const int width = 64, height = 64; 7230a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org untiledResult.allocN32Pixels(width, height); 7240a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org tiledResult.allocN32Pixels(width, height); 7250a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkCanvas tiledCanvas(tiledResult); 7260a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkCanvas untiledCanvas(untiledResult); 727d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org int tileSize = 8; 7280a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 729d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org for (int scale = 1; scale <= 2; ++scale) { 730297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco for (int i = 0; i < filters.count(); ++i) { 731d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.clear(0); 732d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.clear(0); 733d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org SkPaint paint; 7345e25717ab6313b011ec54eac0109c414aa8ffc17Mike Reed paint.setImageFilter(sk_ref_sp(filters.getFilter(i))); 735d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org paint.setTextSize(SkIntToScalar(height)); 736d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org paint.setColor(SK_ColorWHITE); 737d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org SkString str; 738d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org const char* text = "ABC"; 739d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org SkScalar ypos = SkIntToScalar(height); 740d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.save(); 741d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.scale(SkIntToScalar(scale), SkIntToScalar(scale)); 742d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.drawText(text, strlen(text), 0, ypos, paint); 743d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.restore(); 744d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org for (int y = 0; y < height; y += tileSize) { 745d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org for (int x = 0; x < width; x += tileSize) { 746d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.save(); 747d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.clipRect(SkRect::Make(SkIRect::MakeXYWH(x, y, tileSize, tileSize))); 748d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.scale(SkIntToScalar(scale), SkIntToScalar(scale)); 749d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.drawText(text, strlen(text), 0, ypos, paint); 750d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.restore(); 751d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org } 7520a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } 753d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.flush(); 754d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.flush(); 755d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org for (int y = 0; y < height; y++) { 756d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org int diffs = memcmp(untiledResult.getAddr32(0, y), tiledResult.getAddr32(0, y), untiledResult.rowBytes()); 757297f7ce2bb6184849adf0e5479e92f76764ec76asenorblanco REPORTER_ASSERT_MESSAGE(reporter, !diffs, filters.getName(i)); 758d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org if (diffs) { 759d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org break; 760d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org } 7610a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } 7620a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } 7630a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } 7640a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org} 7650a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 7663f3b3d003527861dc0bd89733857576408906431mtkleinstatic void draw_saveLayer_picture(int width, int height, int tileSize, 767a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkBBHFactory* factory, SkBitmap* result) { 768d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 769d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkMatrix matrix; 770d910f544439fffa6c2bcc5181b79b2811a4c130amtklein matrix.setTranslate(SkIntToScalar(50), 0); 771d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 7727d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed sk_sp<SkColorFilter> cf(SkColorFilter::MakeModeFilter(SK_ColorWHITE, SkBlendMode::kSrc)); 7735605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> cfif(SkColorFilterImageFilter::Make(std::move(cf), nullptr)); 774ae8c933ca89315c1256bcf23749b5ee5cbc0d53crobertphillips sk_sp<SkImageFilter> imageFilter(SkImageFilter::MakeMatrixFilter(matrix, 775ae8c933ca89315c1256bcf23749b5ee5cbc0d53crobertphillips kNone_SkFilterQuality, 776ae8c933ca89315c1256bcf23749b5ee5cbc0d53crobertphillips std::move(cfif))); 777d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 778d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkPaint paint; 7795605b56afa5bd89f3148b397318b616fccfd4004robertphillips paint.setImageFilter(std::move(imageFilter)); 780d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkPictureRecorder recorder; 781d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkRect bounds = SkRect::Make(SkIRect::MakeXYWH(0, 0, 50, 50)); 7823f3b3d003527861dc0bd89733857576408906431mtklein SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(width), 7833f3b3d003527861dc0bd89733857576408906431mtklein SkIntToScalar(height), 784a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips factory, 0); 785d910f544439fffa6c2bcc5181b79b2811a4c130amtklein recordingCanvas->translate(-55, 0); 786d910f544439fffa6c2bcc5181b79b2811a4c130amtklein recordingCanvas->saveLayer(&bounds, &paint); 787d910f544439fffa6c2bcc5181b79b2811a4c130amtklein recordingCanvas->restore(); 788ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> picture1(recorder.finishRecordingAsPicture()); 789d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 790d910f544439fffa6c2bcc5181b79b2811a4c130amtklein result->allocN32Pixels(width, height); 791d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkCanvas canvas(*result); 792d910f544439fffa6c2bcc5181b79b2811a4c130amtklein canvas.clear(0); 793d910f544439fffa6c2bcc5181b79b2811a4c130amtklein canvas.clipRect(SkRect::Make(SkIRect::MakeWH(tileSize, tileSize))); 794d910f544439fffa6c2bcc5181b79b2811a4c130amtklein canvas.drawPicture(picture1.get()); 795d910f544439fffa6c2bcc5181b79b2811a4c130amtklein} 796d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 797d910f544439fffa6c2bcc5181b79b2811a4c130amtkleinDEF_TEST(ImageFilterDrawMatrixBBH, reporter) { 798d910f544439fffa6c2bcc5181b79b2811a4c130amtklein // Check that matrix filter when drawn tiled with BBH exactly 799d910f544439fffa6c2bcc5181b79b2811a4c130amtklein // matches the same thing drawn without BBH. 800d910f544439fffa6c2bcc5181b79b2811a4c130amtklein // Tests pass by not asserting. 801d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 802d910f544439fffa6c2bcc5181b79b2811a4c130amtklein const int width = 200, height = 200; 803d910f544439fffa6c2bcc5181b79b2811a4c130amtklein const int tileSize = 100; 804d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkBitmap result1, result2; 805d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkRTreeFactory factory; 806d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 807a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips draw_saveLayer_picture(width, height, tileSize, &factory, &result1); 80896fcdcc219d2a0d3579719b84b28bede76efba64halcanary draw_saveLayer_picture(width, height, tileSize, nullptr, &result2); 809d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 810d910f544439fffa6c2bcc5181b79b2811a4c130amtklein for (int y = 0; y < height; y++) { 811d910f544439fffa6c2bcc5181b79b2811a4c130amtklein int diffs = memcmp(result1.getAddr32(0, y), result2.getAddr32(0, y), result1.rowBytes()); 812d910f544439fffa6c2bcc5181b79b2811a4c130amtklein REPORTER_ASSERT(reporter, !diffs); 813d910f544439fffa6c2bcc5181b79b2811a4c130amtklein if (diffs) { 814d910f544439fffa6c2bcc5181b79b2811a4c130amtklein break; 815d910f544439fffa6c2bcc5181b79b2811a4c130amtklein } 816d910f544439fffa6c2bcc5181b79b2811a4c130amtklein } 817d910f544439fffa6c2bcc5181b79b2811a4c130amtklein} 818d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 8196e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillipsstatic sk_sp<SkImageFilter> make_blur(sk_sp<SkImageFilter> input) { 8206e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips return SkBlurImageFilter::Make(SK_Scalar1, SK_Scalar1, std::move(input)); 8211150a6d151571fb6ee816dadec844ae7ab53948asenorblanco} 8221150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 8236e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillipsstatic sk_sp<SkImageFilter> make_drop_shadow(sk_sp<SkImageFilter> input) { 824c416912da4840af0c49bd8cdcf00044ed39500f6robertphillips return SkDropShadowImageFilter::Make( 8251150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIntToScalar(100), SkIntToScalar(100), 8261150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIntToScalar(10), SkIntToScalar(10), 827234f036b3e731e06e616c5291157d3bb4fbfdee2sugoi SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, 828c416912da4840af0c49bd8cdcf00044ed39500f6robertphillips std::move(input)); 8291150a6d151571fb6ee816dadec844ae7ab53948asenorblanco} 8301150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 8311150a6d151571fb6ee816dadec844ae7ab53948asenorblancoDEF_TEST(ImageFilterBlurThenShadowBounds, reporter) { 8326e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> filter1(make_blur(nullptr)); 8336e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> filter2(make_drop_shadow(std::move(filter1))); 8341150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 8351150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100); 8361150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect expectedBounds = SkIRect::MakeXYWH(-133, -133, 236, 236); 837e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco bounds = filter2->filterBounds(bounds, SkMatrix::I()); 8381150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 8391150a6d151571fb6ee816dadec844ae7ab53948asenorblanco REPORTER_ASSERT(reporter, bounds == expectedBounds); 8401150a6d151571fb6ee816dadec844ae7ab53948asenorblanco} 8411150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 8421150a6d151571fb6ee816dadec844ae7ab53948asenorblancoDEF_TEST(ImageFilterShadowThenBlurBounds, reporter) { 8436e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> filter1(make_drop_shadow(nullptr)); 8446e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> filter2(make_blur(std::move(filter1))); 8451150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 8461150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100); 8471150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect expectedBounds = SkIRect::MakeXYWH(-133, -133, 236, 236); 848e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco bounds = filter2->filterBounds(bounds, SkMatrix::I()); 8491150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 8501150a6d151571fb6ee816dadec844ae7ab53948asenorblanco REPORTER_ASSERT(reporter, bounds == expectedBounds); 8511150a6d151571fb6ee816dadec844ae7ab53948asenorblanco} 8521150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 8531150a6d151571fb6ee816dadec844ae7ab53948asenorblancoDEF_TEST(ImageFilterDilateThenBlurBounds, reporter) { 854fc11b0afe0ca922a42767d4a656ed640008da1bbrobertphillips sk_sp<SkImageFilter> filter1(SkDilateImageFilter::Make(2, 2, nullptr)); 8556e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> filter2(make_drop_shadow(std::move(filter1))); 8561150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 8571150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100); 8581150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect expectedBounds = SkIRect::MakeXYWH(-132, -132, 234, 234); 859e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco bounds = filter2->filterBounds(bounds, SkMatrix::I()); 8601150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 8611150a6d151571fb6ee816dadec844ae7ab53948asenorblanco REPORTER_ASSERT(reporter, bounds == expectedBounds); 8621150a6d151571fb6ee816dadec844ae7ab53948asenorblanco} 8631150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 864203a993c77ea146e0a4e7f1e0c079cc79fd09167jbromanDEF_TEST(ImageFilterScaledBlurRadius, reporter) { 865203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman // Each blur should spread 3*sigma, so 3 for the blur and 30 for the shadow 866203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman // (before the CTM). Bounds should be computed correctly in the presence of 867203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman // a (possibly negative) scale. 868203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman sk_sp<SkImageFilter> blur(make_blur(nullptr)); 869203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman sk_sp<SkImageFilter> dropShadow(make_drop_shadow(nullptr)); 870203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman { 871203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman // Uniform scale by 2. 872203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkMatrix scaleMatrix; 873203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman scaleMatrix.setScale(2, 2); 874203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect bounds = SkIRect::MakeLTRB(0, 0, 200, 200); 875203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman 876203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect expectedBlurBounds = SkIRect::MakeLTRB(-6, -6, 206, 206); 877203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect blurBounds = blur->filterBounds( 878203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman bounds, scaleMatrix, SkImageFilter::kForward_MapDirection); 879203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman REPORTER_ASSERT(reporter, blurBounds == expectedBlurBounds); 880203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect reverseBlurBounds = blur->filterBounds( 881203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman bounds, scaleMatrix, SkImageFilter::kReverse_MapDirection); 882203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman REPORTER_ASSERT(reporter, reverseBlurBounds == expectedBlurBounds); 883203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman 884203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect expectedShadowBounds = SkIRect::MakeLTRB(0, 0, 460, 460); 885203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect shadowBounds = dropShadow->filterBounds( 886203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman bounds, scaleMatrix, SkImageFilter::kForward_MapDirection); 887203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman REPORTER_ASSERT(reporter, shadowBounds == expectedShadowBounds); 888203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect expectedReverseShadowBounds = 889203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect::MakeLTRB(-260, -260, 200, 200); 890203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect reverseShadowBounds = dropShadow->filterBounds( 891203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman bounds, scaleMatrix, SkImageFilter::kReverse_MapDirection); 892203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman REPORTER_ASSERT(reporter, 893203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman reverseShadowBounds == expectedReverseShadowBounds); 894203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman } 895203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman { 896203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman // Vertical flip. 897203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkMatrix scaleMatrix; 898203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman scaleMatrix.setScale(1, -1); 899203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect bounds = SkIRect::MakeLTRB(0, -100, 100, 0); 900203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman 901203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect expectedBlurBounds = SkIRect::MakeLTRB(-3, -103, 103, 3); 902203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect blurBounds = blur->filterBounds( 903203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman bounds, scaleMatrix, SkImageFilter::kForward_MapDirection); 904203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman REPORTER_ASSERT(reporter, blurBounds == expectedBlurBounds); 905203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect reverseBlurBounds = blur->filterBounds( 906203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman bounds, scaleMatrix, SkImageFilter::kReverse_MapDirection); 907203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman REPORTER_ASSERT(reporter, reverseBlurBounds == expectedBlurBounds); 908203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman 909203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect expectedShadowBounds = SkIRect::MakeLTRB(0, -230, 230, 0); 910203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect shadowBounds = dropShadow->filterBounds( 911203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman bounds, scaleMatrix, SkImageFilter::kForward_MapDirection); 912203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman REPORTER_ASSERT(reporter, shadowBounds == expectedShadowBounds); 913203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect expectedReverseShadowBounds = 914203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect::MakeLTRB(-130, -100, 100, 130); 915203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman SkIRect reverseShadowBounds = dropShadow->filterBounds( 916203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman bounds, scaleMatrix, SkImageFilter::kReverse_MapDirection); 917203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman REPORTER_ASSERT(reporter, 918203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman reverseShadowBounds == expectedReverseShadowBounds); 919203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman } 920203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman} 921203a993c77ea146e0a4e7f1e0c079cc79fd09167jbroman 9225788faaa2ac4203827c68006b669e277d441e2e4ajumaDEF_TEST(ImageFilterComposedBlurFastBounds, reporter) { 9236e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> filter1(make_blur(nullptr)); 9246e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> filter2(make_blur(nullptr)); 925491fb17cab07574a9d5656c1c97ad0acc3af5c70robertphillips sk_sp<SkImageFilter> composedFilter(SkComposeImageFilter::Make(std::move(filter1), 926491fb17cab07574a9d5656c1c97ad0acc3af5c70robertphillips std::move(filter2))); 9275788faaa2ac4203827c68006b669e277d441e2e4ajuma 9285788faaa2ac4203827c68006b669e277d441e2e4ajuma SkRect boundsSrc = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100)); 9295788faaa2ac4203827c68006b669e277d441e2e4ajuma SkRect expectedBounds = SkRect::MakeXYWH( 9305788faaa2ac4203827c68006b669e277d441e2e4ajuma SkIntToScalar(-6), SkIntToScalar(-6), SkIntToScalar(112), SkIntToScalar(112)); 931e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco SkRect boundsDst = composedFilter->computeFastBounds(boundsSrc); 9325788faaa2ac4203827c68006b669e277d441e2e4ajuma 9335788faaa2ac4203827c68006b669e277d441e2e4ajuma REPORTER_ASSERT(reporter, boundsDst == expectedBounds); 9345788faaa2ac4203827c68006b669e277d441e2e4ajuma} 9355788faaa2ac4203827c68006b669e277d441e2e4ajuma 9360e3129d734212089f872f0e7de8f2537861a3f89jbromanDEF_TEST(ImageFilterUnionBounds, reporter) { 93751a315eff9b86bd60e7884240c4efc199129d37arobertphillips sk_sp<SkImageFilter> offset(SkOffsetImageFilter::Make(50, 0, nullptr)); 9380e3129d734212089f872f0e7de8f2537861a3f89jbroman // Regardless of which order they appear in, the image filter bounds should 9390e3129d734212089f872f0e7de8f2537861a3f89jbroman // be combined correctly. 9400e3129d734212089f872f0e7de8f2537861a3f89jbroman { 941374772bd61951f01bf84fe17bf53d8867681c9aereed sk_sp<SkImageFilter> composite(SkXfermodeImageFilter::Make(SkBlendMode::kSrcOver, offset)); 9420e3129d734212089f872f0e7de8f2537861a3f89jbroman SkRect bounds = SkRect::MakeWH(100, 100); 9430e3129d734212089f872f0e7de8f2537861a3f89jbroman // Intentionally aliasing here, as that's what the real callers do. 944e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco bounds = composite->computeFastBounds(bounds); 9450e3129d734212089f872f0e7de8f2537861a3f89jbroman REPORTER_ASSERT(reporter, bounds == SkRect::MakeWH(150, 100)); 9460e3129d734212089f872f0e7de8f2537861a3f89jbroman } 9470e3129d734212089f872f0e7de8f2537861a3f89jbroman { 948374772bd61951f01bf84fe17bf53d8867681c9aereed sk_sp<SkImageFilter> composite(SkXfermodeImageFilter::Make(SkBlendMode::kSrcOver, nullptr, 9498c0326df5f600da43a054dad3b354221dd6b790frobertphillips offset, nullptr)); 9500e3129d734212089f872f0e7de8f2537861a3f89jbroman SkRect bounds = SkRect::MakeWH(100, 100); 9510e3129d734212089f872f0e7de8f2537861a3f89jbroman // Intentionally aliasing here, as that's what the real callers do. 952e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco bounds = composite->computeFastBounds(bounds); 9530e3129d734212089f872f0e7de8f2537861a3f89jbroman REPORTER_ASSERT(reporter, bounds == SkRect::MakeWH(150, 100)); 9540e3129d734212089f872f0e7de8f2537861a3f89jbroman } 9550e3129d734212089f872f0e7de8f2537861a3f89jbroman} 9560e3129d734212089f872f0e7de8f2537861a3f89jbroman 9573e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic void test_imagefilter_merge_result_size(skiatest::Reporter* reporter, GrContext* context) { 9584a24398391536f7b176b44a8c45dc288655b4adbsenorblanco SkBitmap greenBM; 9594a24398391536f7b176b44a8c45dc288655b4adbsenorblanco greenBM.allocN32Pixels(20, 20); 9604a24398391536f7b176b44a8c45dc288655b4adbsenorblanco greenBM.eraseColor(SK_ColorGREEN); 9619ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> greenImage(SkImage::MakeFromBitmap(greenBM)); 962549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips sk_sp<SkImageFilter> source(SkImageSource::Make(std::move(greenImage))); 9637d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed sk_sp<SkImageFilter> merge(SkMergeImageFilter::Make(source, source, SkBlendMode::kSrcOver)); 9644a24398391536f7b176b44a8c45dc288655b4adbsenorblanco 9653e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialImage> srcImg(create_empty_special_image(context, 1)); 9664418dbac3386f26c8da62ab242be9c178961eb18robertphillips 9672a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::OutputProperties noColorSpace(nullptr); 9682a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(0, 0, 100, 100), nullptr, 9692a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman noColorSpace); 9704a24398391536f7b176b44a8c45dc288655b4adbsenorblanco SkIPoint offset; 9714418dbac3386f26c8da62ab242be9c178961eb18robertphillips 9722302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> resultImg(merge->filterImage(srcImg.get(), ctx, &offset)); 9734418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, resultImg); 9744418dbac3386f26c8da62ab242be9c178961eb18robertphillips 9754418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, resultImg->width() == 20 && resultImg->height() == 20); 9764418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 9774418dbac3386f26c8da62ab242be9c178961eb18robertphillips 9784418dbac3386f26c8da62ab242be9c178961eb18robertphillipsDEF_TEST(ImageFilterMergeResultSize, reporter) { 9793e302275b324172c845627cbd00cee8a06571bafrobertphillips test_imagefilter_merge_result_size(reporter, nullptr); 9804418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 9814418dbac3386f26c8da62ab242be9c178961eb18robertphillips 9824418dbac3386f26c8da62ab242be9c178961eb18robertphillips#if SK_SUPPORT_GPU 983ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterMergeResultSize_Gpu, reporter, ctxInfo) { 9848b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon test_imagefilter_merge_result_size(reporter, ctxInfo.grContext()); 9854a24398391536f7b176b44a8c45dc288655b4adbsenorblanco} 9864418dbac3386f26c8da62ab242be9c178961eb18robertphillips#endif 9874a24398391536f7b176b44a8c45dc288655b4adbsenorblanco 988a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillipsstatic void draw_blurred_rect(SkCanvas* canvas) { 989837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkPaint filterPaint; 990837f5321a409228a27fc710eb71c87866b820cfbsenorblanco filterPaint.setColor(SK_ColorWHITE); 9916e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips filterPaint.setImageFilter(SkBlurImageFilter::Make(SkIntToScalar(8), 0, nullptr)); 99296fcdcc219d2a0d3579719b84b28bede76efba64halcanary canvas->saveLayer(nullptr, &filterPaint); 993837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkPaint whitePaint; 994837f5321a409228a27fc710eb71c87866b820cfbsenorblanco whitePaint.setColor(SK_ColorWHITE); 995837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->drawRect(SkRect::Make(SkIRect::MakeWH(4, 4)), whitePaint); 996837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->restore(); 997837f5321a409228a27fc710eb71c87866b820cfbsenorblanco} 998837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 999a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillipsstatic void draw_picture_clipped(SkCanvas* canvas, const SkRect& clipRect, const SkPicture* picture) { 1000837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->save(); 1001837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->clipRect(clipRect); 1002837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->drawPicture(picture); 1003837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->restore(); 1004837f5321a409228a27fc710eb71c87866b820cfbsenorblanco} 1005837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 1006837f5321a409228a27fc710eb71c87866b820cfbsenorblancoDEF_TEST(ImageFilterDrawTiledBlurRTree, reporter) { 1007837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // Check that the blur filter when recorded with RTree acceleration, 1008837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // and drawn tiled (with subsequent clip rects) exactly 1009837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // matches the same filter drawn with without RTree acceleration. 1010837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // This tests that the "bleed" from the blur into the otherwise-blank 1011837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // tiles is correctly rendered. 1012837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // Tests pass by not asserting. 1013837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 1014837f5321a409228a27fc710eb71c87866b820cfbsenorblanco int width = 16, height = 8; 1015837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkBitmap result1, result2; 1016837f5321a409228a27fc710eb71c87866b820cfbsenorblanco result1.allocN32Pixels(width, height); 1017837f5321a409228a27fc710eb71c87866b820cfbsenorblanco result2.allocN32Pixels(width, height); 1018837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkCanvas canvas1(result1); 1019837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkCanvas canvas2(result2); 1020837f5321a409228a27fc710eb71c87866b820cfbsenorblanco int tileSize = 8; 1021837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 1022837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas1.clear(0); 1023837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas2.clear(0); 1024837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 1025837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkRTreeFactory factory; 1026837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 1027837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkPictureRecorder recorder1, recorder2; 1028837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // The only difference between these two pictures is that one has RTree aceleration. 10293f3b3d003527861dc0bd89733857576408906431mtklein SkCanvas* recordingCanvas1 = recorder1.beginRecording(SkIntToScalar(width), 10303f3b3d003527861dc0bd89733857576408906431mtklein SkIntToScalar(height), 103196fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 0); 10323f3b3d003527861dc0bd89733857576408906431mtklein SkCanvas* recordingCanvas2 = recorder2.beginRecording(SkIntToScalar(width), 10333f3b3d003527861dc0bd89733857576408906431mtklein SkIntToScalar(height), 1034a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips &factory, 0); 1035a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips draw_blurred_rect(recordingCanvas1); 1036a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips draw_blurred_rect(recordingCanvas2); 1037ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> picture1(recorder1.finishRecordingAsPicture()); 1038ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> picture2(recorder2.finishRecordingAsPicture()); 1039837f5321a409228a27fc710eb71c87866b820cfbsenorblanco for (int y = 0; y < height; y += tileSize) { 1040837f5321a409228a27fc710eb71c87866b820cfbsenorblanco for (int x = 0; x < width; x += tileSize) { 1041837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkRect tileRect = SkRect::Make(SkIRect::MakeXYWH(x, y, tileSize, tileSize)); 1042ca2622ba051829fed5f30facd74c5b41cd4b931creed draw_picture_clipped(&canvas1, tileRect, picture1.get()); 1043ca2622ba051829fed5f30facd74c5b41cd4b931creed draw_picture_clipped(&canvas2, tileRect, picture2.get()); 1044837f5321a409228a27fc710eb71c87866b820cfbsenorblanco } 1045837f5321a409228a27fc710eb71c87866b820cfbsenorblanco } 1046837f5321a409228a27fc710eb71c87866b820cfbsenorblanco for (int y = 0; y < height; y++) { 1047837f5321a409228a27fc710eb71c87866b820cfbsenorblanco int diffs = memcmp(result1.getAddr32(0, y), result2.getAddr32(0, y), result1.rowBytes()); 1048837f5321a409228a27fc710eb71c87866b820cfbsenorblanco REPORTER_ASSERT(reporter, !diffs); 1049837f5321a409228a27fc710eb71c87866b820cfbsenorblanco if (diffs) { 1050837f5321a409228a27fc710eb71c87866b820cfbsenorblanco break; 1051837f5321a409228a27fc710eb71c87866b820cfbsenorblanco } 1052837f5321a409228a27fc710eb71c87866b820cfbsenorblanco } 1053837f5321a409228a27fc710eb71c87866b820cfbsenorblanco} 1054837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 10559195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.orgDEF_TEST(ImageFilterMatrixConvolution, reporter) { 10569195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org // Check that a 1x3 filter does not cause a spurious assert. 10579195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkScalar kernel[3] = { 10589195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1), 10599195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org }; 10609195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkISize kernelSize = SkISize::Make(1, 3); 10619195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkScalar gain = SK_Scalar1, bias = 0; 10629195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkIPoint kernelOffset = SkIPoint::Make(0, 0); 10639195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org 1064ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips sk_sp<SkImageFilter> filter(SkMatrixConvolutionImageFilter::Make( 1065ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips kernelSize, kernel, 1066ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips gain, bias, kernelOffset, 1067ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips SkMatrixConvolutionImageFilter::kRepeat_TileMode, 1068ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips false, nullptr)); 10699195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org 10709195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkBitmap result; 10719195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org int width = 16, height = 16; 10729195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org result.allocN32Pixels(width, height); 10739195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkCanvas canvas(result); 10749195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org canvas.clear(0); 10759195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org 10769195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkPaint paint; 1077ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips paint.setImageFilter(std::move(filter)); 10789195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkRect rect = SkRect::Make(SkIRect::MakeWH(width, height)); 10799195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org canvas.drawRect(rect, paint); 10809195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org} 10819195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org 10828c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.orgDEF_TEST(ImageFilterMatrixConvolutionBorder, reporter) { 10838c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org // Check that a filter with borders outside the target bounds 10848c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org // does not crash. 10858c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkScalar kernel[3] = { 10868c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 0, 0, 0, 10878c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org }; 10888c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkISize kernelSize = SkISize::Make(3, 1); 10898c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkScalar gain = SK_Scalar1, bias = 0; 10908c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkIPoint kernelOffset = SkIPoint::Make(2, 0); 10918c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 1092ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips sk_sp<SkImageFilter> filter(SkMatrixConvolutionImageFilter::Make( 1093ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips kernelSize, kernel, gain, bias, kernelOffset, 1094ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips SkMatrixConvolutionImageFilter::kClamp_TileMode, 1095ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips true, nullptr)); 10968c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 10978c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkBitmap result; 10988c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 10998c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org int width = 10, height = 10; 11008c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org result.allocN32Pixels(width, height); 11018c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkCanvas canvas(result); 11028c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org canvas.clear(0); 11038c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 11048c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkPaint filterPaint; 1105ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips filterPaint.setImageFilter(std::move(filter)); 11068c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkRect bounds = SkRect::MakeWH(1, 10); 11078c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkRect rect = SkRect::Make(SkIRect::MakeWH(width, height)); 11088c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkPaint rectPaint; 11098c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org canvas.saveLayer(&bounds, &filterPaint); 11108c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org canvas.drawRect(rect, rectPaint); 11118c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org canvas.restore(); 11128c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org} 11138c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 11143e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic void test_big_kernel(skiatest::Reporter* reporter, GrContext* context) { 1115dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips // Check that a kernel that is too big for the GPU still works 1116dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips SkScalar identityKernel[49] = { 1117dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 0, 0, 0, 0, 0, 0, 0, 1118dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 0, 0, 0, 0, 0, 0, 0, 1119dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 0, 0, 0, 0, 0, 0, 0, 1120dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 0, 0, 0, 1, 0, 0, 0, 1121dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 0, 0, 0, 0, 0, 0, 0, 1122dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 0, 0, 0, 0, 0, 0, 0, 1123dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 0, 0, 0, 0, 0, 0, 0 1124dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips }; 1125dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips SkISize kernelSize = SkISize::Make(7, 7); 1126dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips SkScalar gain = SK_Scalar1, bias = 0; 1127dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips SkIPoint kernelOffset = SkIPoint::Make(0, 0); 1128dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 1129dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips sk_sp<SkImageFilter> filter(SkMatrixConvolutionImageFilter::Make( 1130dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips kernelSize, identityKernel, gain, bias, kernelOffset, 1131dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips SkMatrixConvolutionImageFilter::kClamp_TileMode, 1132dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips true, nullptr)); 1133dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 11343e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialImage> srcImg(create_empty_special_image(context, 100)); 1135dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips SkASSERT(srcImg); 1136dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 1137dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips SkIPoint offset; 11382a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::OutputProperties noColorSpace(nullptr); 11392a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr, noColorSpace); 1140dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg.get(), ctx, &offset)); 1141dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips REPORTER_ASSERT(reporter, resultImg); 1142dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips REPORTER_ASSERT(reporter, SkToBool(context) == resultImg->isTextureBacked()); 1143dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips REPORTER_ASSERT(reporter, resultImg->width() == 100 && resultImg->height() == 100); 1144dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips REPORTER_ASSERT(reporter, offset.fX == 0 && offset.fY == 0); 1145dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips} 1146dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 1147dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillipsDEF_TEST(ImageFilterMatrixConvolutionBigKernel, reporter) { 11483e302275b324172c845627cbd00cee8a06571bafrobertphillips test_big_kernel(reporter, nullptr); 1149dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips} 1150dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 1151dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips#if SK_SUPPORT_GPU 1152ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterMatrixConvolutionBigKernel_Gpu, 1153ab527a5bbfb1eae4f99a1435d349a44d00477d82egdaniel reporter, ctxInfo) { 11548b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon test_big_kernel(reporter, ctxInfo.grContext()); 1155dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips} 1156dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips#endif 1157dada4dd9cf03e42369ca5b38086dba77f01a68e6robertphillips 1158aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.orgDEF_TEST(ImageFilterCropRect, reporter) { 11593e302275b324172c845627cbd00cee8a06571bafrobertphillips test_crop_rects(reporter, nullptr); 11604418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 11619a53fd7c41554630124522f4b6eedc16912abbb7robertphillips 11624418dbac3386f26c8da62ab242be9c178961eb18robertphillips#if SK_SUPPORT_GPU 116368d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCropRect_Gpu, reporter, ctxInfo) { 11648b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon test_crop_rects(reporter, ctxInfo.grContext()); 1165aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org} 11664418dbac3386f26c8da62ab242be9c178961eb18robertphillips#endif 1167aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 11689ea53f93e79ba312c4b3943923450a8b4aa57c82tfarinaDEF_TEST(ImageFilterMatrix, reporter) { 11695251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkBitmap temp; 1170deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org temp.allocN32Pixels(100, 100); 11719a53fd7c41554630124522f4b6eedc16912abbb7robertphillips SkCanvas canvas(temp); 11725251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org canvas.scale(SkIntToScalar(2), SkIntToScalar(2)); 11735251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 11745251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkMatrix expectedMatrix = canvas.getTotalMatrix(); 11755251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 11765fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkRTreeFactory factory; 11775fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkPictureRecorder recorder; 11785fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkCanvas* recordingCanvas = recorder.beginRecording(100, 100, &factory, 0); 11795251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 11805251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkPaint paint; 118143c2ad4e8f9ed84f46caa57e0b471f7393f1280arobertphillips paint.setImageFilter(MatrixTestImageFilter::Make(reporter, expectedMatrix)); 118296fcdcc219d2a0d3579719b84b28bede76efba64halcanary recordingCanvas->saveLayer(nullptr, &paint); 11835251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkPaint solidPaint; 11845251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org solidPaint.setColor(0xFFFFFFFF); 11855251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org recordingCanvas->save(); 11865251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org recordingCanvas->scale(SkIntToScalar(10), SkIntToScalar(10)); 11875251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(100, 100)), solidPaint); 11885251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org recordingCanvas->restore(); // scale 11895251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org recordingCanvas->restore(); // saveLayer 11905251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 1191ca2622ba051829fed5f30facd74c5b41cd4b931creed canvas.drawPicture(recorder.finishRecordingAsPicture()); 11925251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org} 11935251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 11943d822c29d4272a6749e59801b202b1ed6d611be8senorblancoDEF_TEST(ImageFilterCrossProcessPictureImageFilter, reporter) { 119597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkRTreeFactory factory; 119697f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPictureRecorder recorder; 119797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkCanvas* recordingCanvas = recorder.beginRecording(1, 1, &factory, 0); 119897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 119997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // Create an SkPicture which simply draws a green 1x1 rectangle. 120097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPaint greenPaint; 120197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org greenPaint.setColor(SK_ColorGREEN); 120297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), greenPaint); 1203ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 120497f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 120597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // Wrap that SkPicture in an SkPictureImageFilter. 12065ff17b13524eea03e4b672ee3b3a49b649dd09fbrobertphillips sk_sp<SkImageFilter> imageFilter(SkPictureImageFilter::Make(picture)); 120797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 120897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // Check that SkPictureImageFilter successfully serializes its contained 120997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // SkPicture when not in cross-process mode. 121097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPaint paint; 12115ff17b13524eea03e4b672ee3b3a49b649dd09fbrobertphillips paint.setImageFilter(imageFilter); 121297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPictureRecorder outerRecorder; 121397f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkCanvas* outerCanvas = outerRecorder.beginRecording(1, 1, &factory, 0); 121497f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPaint redPaintWithFilter; 121597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org redPaintWithFilter.setColor(SK_ColorRED); 12165ff17b13524eea03e4b672ee3b3a49b649dd09fbrobertphillips redPaintWithFilter.setImageFilter(imageFilter); 121797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org outerCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), redPaintWithFilter); 1218ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> outerPicture(outerRecorder.finishRecordingAsPicture()); 121997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 122097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkBitmap bitmap; 122197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org bitmap.allocN32Pixels(1, 1); 12229a53fd7c41554630124522f4b6eedc16912abbb7robertphillips SkCanvas canvas(bitmap); 122397f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 122497f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // The result here should be green, since the filter replaces the primitive's red interior. 122597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org canvas.clear(0x0); 12269b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(outerPicture); 122797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org uint32_t pixel = *bitmap.getAddr32(0, 0); 122897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 122997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 123097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // Check that, for now, SkPictureImageFilter does not serialize or 123197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // deserialize its contained picture when the filter is serialized 123297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // cross-process. Do this by "laundering" it through SkValidatingReadBuffer. 123312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkData> data(SkValidatingSerializeFlattenable(imageFilter.get())); 12345e25717ab6313b011ec54eac0109c414aa8ffc17Mike Reed sk_sp<SkImageFilter> unflattenedFilter = SkValidatingDeserializeImageFilter(data->data(), 12355e25717ab6313b011ec54eac0109c414aa8ffc17Mike Reed data->size()); 123697f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 123797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org redPaintWithFilter.setImageFilter(unflattenedFilter); 123897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPictureRecorder crossProcessRecorder; 123997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkCanvas* crossProcessCanvas = crossProcessRecorder.beginRecording(1, 1, &factory, 0); 124097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org crossProcessCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), redPaintWithFilter); 1241ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> crossProcessPicture(crossProcessRecorder.finishRecordingAsPicture()); 124297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 124397f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org canvas.clear(0x0); 12449b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(crossProcessPicture); 124597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org pixel = *bitmap.getAddr32(0, 0); 1246446ee67fda73b11281b8e28a68edec811347c0c5hendrikw // If the security precautions are enabled, the result here should not be green, since the 1247446ee67fda73b11281b8e28a68edec811347c0c5hendrikw // filter draws nothing. 12482afbe23753bf97402a47408c83107042eea3c476mtklein REPORTER_ASSERT(reporter, SkPicture::PictureIOSecurityPrecautionsEnabled() 1249446ee67fda73b11281b8e28a68edec811347c0c5hendrikw ? pixel != SK_ColorGREEN : pixel == SK_ColorGREEN); 125097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org} 125197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 12523e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic void test_clipped_picture_imagefilter(skiatest::Reporter* reporter, GrContext* context) { 1253ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> picture; 12543d822c29d4272a6749e59801b202b1ed6d611be8senorblanco 12554418dbac3386f26c8da62ab242be9c178961eb18robertphillips { 12564418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkRTreeFactory factory; 12574418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkPictureRecorder recorder; 12584418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkCanvas* recordingCanvas = recorder.beginRecording(1, 1, &factory, 0); 12594418dbac3386f26c8da62ab242be9c178961eb18robertphillips 12604418dbac3386f26c8da62ab242be9c178961eb18robertphillips // Create an SkPicture which simply draws a green 1x1 rectangle. 12614418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkPaint greenPaint; 12624418dbac3386f26c8da62ab242be9c178961eb18robertphillips greenPaint.setColor(SK_ColorGREEN); 12634418dbac3386f26c8da62ab242be9c178961eb18robertphillips recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), greenPaint); 1264ca2622ba051829fed5f30facd74c5b41cd4b931creed picture = recorder.finishRecordingAsPicture(); 12654418dbac3386f26c8da62ab242be9c178961eb18robertphillips } 12664418dbac3386f26c8da62ab242be9c178961eb18robertphillips 12673e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialImage> srcImg(create_empty_special_image(context, 2)); 12683d822c29d4272a6749e59801b202b1ed6d611be8senorblanco 12695ff17b13524eea03e4b672ee3b3a49b649dd09fbrobertphillips sk_sp<SkImageFilter> imageFilter(SkPictureImageFilter::Make(picture)); 12703d822c29d4272a6749e59801b202b1ed6d611be8senorblanco 12713d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkIPoint offset; 12722a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::OutputProperties noColorSpace(nullptr); 12732a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(1, 1, 1, 1), nullptr, noColorSpace); 12744418dbac3386f26c8da62ab242be9c178961eb18robertphillips 12752302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> resultImage(imageFilter->filterImage(srcImg.get(), ctx, &offset)); 12764418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, !resultImage); 12774418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 12784418dbac3386f26c8da62ab242be9c178961eb18robertphillips 12794418dbac3386f26c8da62ab242be9c178961eb18robertphillipsDEF_TEST(ImageFilterClippedPictureImageFilter, reporter) { 12803e302275b324172c845627cbd00cee8a06571bafrobertphillips test_clipped_picture_imagefilter(reporter, nullptr); 12814418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 12824418dbac3386f26c8da62ab242be9c178961eb18robertphillips 12834418dbac3386f26c8da62ab242be9c178961eb18robertphillips#if SK_SUPPORT_GPU 128468d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterClippedPictureImageFilter_Gpu, reporter, ctxInfo) { 12858b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon test_clipped_picture_imagefilter(reporter, ctxInfo.grContext()); 12863d822c29d4272a6749e59801b202b1ed6d611be8senorblanco} 12874418dbac3386f26c8da62ab242be9c178961eb18robertphillips#endif 12883d822c29d4272a6749e59801b202b1ed6d611be8senorblanco 12899ea53f93e79ba312c4b3943923450a8b4aa57c82tfarinaDEF_TEST(ImageFilterEmptySaveLayer, reporter) { 129068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org // Even when there's an empty saveLayer()/restore(), ensure that an image 129168250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org // filter or color filter which affects transparent black still draws. 129268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 129368250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkBitmap bitmap; 129468250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org bitmap.allocN32Pixels(10, 10); 12959a53fd7c41554630124522f4b6eedc16912abbb7robertphillips SkCanvas canvas(bitmap); 129668250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 129768250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkRTreeFactory factory; 129868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkPictureRecorder recorder; 129968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 13005605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkColorFilter> green(SkColorFilter::MakeModeFilter(SK_ColorGREEN, 13017d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed SkBlendMode::kSrc)); 13025605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> imageFilter(SkColorFilterImageFilter::Make(green, nullptr)); 130368250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkPaint imageFilterPaint; 13045605b56afa5bd89f3148b397318b616fccfd4004robertphillips imageFilterPaint.setImageFilter(std::move(imageFilter)); 130568250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkPaint colorFilterPaint; 1306d053ce9c54d4e5937a142278359e5a4cde18095ereed colorFilterPaint.setColorFilter(green); 130768250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 130868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkRect bounds = SkRect::MakeWH(10, 10); 130968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 131068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkCanvas* recordingCanvas = recorder.beginRecording(10, 10, &factory, 0); 131168250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->saveLayer(&bounds, &imageFilterPaint); 131268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->restore(); 1313ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 131468250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 131568250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org canvas.clear(0); 13169b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(picture); 131768250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org uint32_t pixel = *bitmap.getAddr32(0, 0); 131868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 131968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 132068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas = recorder.beginRecording(10, 10, &factory, 0); 132196fcdcc219d2a0d3579719b84b28bede76efba64halcanary recordingCanvas->saveLayer(nullptr, &imageFilterPaint); 132268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->restore(); 1323ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> picture2(recorder.finishRecordingAsPicture()); 132468250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 132568250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org canvas.clear(0); 13269b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(picture2); 132768250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org pixel = *bitmap.getAddr32(0, 0); 132868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 132968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 133068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas = recorder.beginRecording(10, 10, &factory, 0); 133168250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->saveLayer(&bounds, &colorFilterPaint); 133268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->restore(); 1333ca2622ba051829fed5f30facd74c5b41cd4b931creed sk_sp<SkPicture> picture3(recorder.finishRecordingAsPicture()); 133468250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 133568250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org canvas.clear(0); 13369b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(picture3); 133768250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org pixel = *bitmap.getAddr32(0, 0); 133868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 133968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org} 134068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 13419a53fd7c41554630124522f4b6eedc16912abbb7robertphillipsstatic void test_huge_blur(SkCanvas* canvas, skiatest::Reporter* reporter) { 134209843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkBitmap bitmap; 134309843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org bitmap.allocN32Pixels(100, 100); 134409843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org bitmap.eraseARGB(0, 0, 0, 0); 134509843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 134609843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org // Check that a blur with an insane radius does not crash or assert. 134709843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkPaint paint; 13486e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips paint.setImageFilter(SkBlurImageFilter::Make(SkIntToScalar(1<<30), 13496e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkIntToScalar(1<<30), 13506e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips nullptr)); 1351da420b976e61071cfe5de10556b4b23e519091d6reed canvas->drawBitmap(bitmap, 0, 0, &paint); 135209843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org} 135309843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 135409843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.orgDEF_TEST(HugeBlurImageFilter, reporter) { 135509843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkBitmap temp; 135609843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org temp.allocN32Pixels(100, 100); 13579a53fd7c41554630124522f4b6eedc16912abbb7robertphillips SkCanvas canvas(temp); 13589a53fd7c41554630124522f4b6eedc16912abbb7robertphillips test_huge_blur(&canvas, reporter); 135909843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org} 136009843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 136121a465d7f4c5e639044e79971aeaa1194fc73078senorblancoDEF_TEST(ImageFilterMatrixConvolutionSanityTest, reporter) { 13623a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkScalar kernel[1] = { 0 }; 13633a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkScalar gain = SK_Scalar1, bias = 0; 13643a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkIPoint kernelOffset = SkIPoint::Make(1, 1); 13653a49520696b2eca69e57884657d23fd2402ccfd1senorblanco 136696fcdcc219d2a0d3579719b84b28bede76efba64halcanary // Check that an enormous (non-allocatable) kernel gives a nullptr filter. 1367ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips sk_sp<SkImageFilter> conv(SkMatrixConvolutionImageFilter::Make( 13683a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkISize::Make(1<<30, 1<<30), 13693a49520696b2eca69e57884657d23fd2402ccfd1senorblanco kernel, 13703a49520696b2eca69e57884657d23fd2402ccfd1senorblanco gain, 13713a49520696b2eca69e57884657d23fd2402ccfd1senorblanco bias, 13723a49520696b2eca69e57884657d23fd2402ccfd1senorblanco kernelOffset, 13733a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkMatrixConvolutionImageFilter::kRepeat_TileMode, 1374ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips false, 1375ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips nullptr)); 13763a49520696b2eca69e57884657d23fd2402ccfd1senorblanco 137796fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == conv.get()); 13783a49520696b2eca69e57884657d23fd2402ccfd1senorblanco 137996fcdcc219d2a0d3579719b84b28bede76efba64halcanary // Check that a nullptr kernel gives a nullptr filter. 1380ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips conv = SkMatrixConvolutionImageFilter::Make( 13813a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkISize::Make(1, 1), 138296fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, 13833a49520696b2eca69e57884657d23fd2402ccfd1senorblanco gain, 13843a49520696b2eca69e57884657d23fd2402ccfd1senorblanco bias, 13853a49520696b2eca69e57884657d23fd2402ccfd1senorblanco kernelOffset, 13863a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkMatrixConvolutionImageFilter::kRepeat_TileMode, 1387ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips false, 1388ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips nullptr); 13893a49520696b2eca69e57884657d23fd2402ccfd1senorblanco 139096fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == conv.get()); 13913a49520696b2eca69e57884657d23fd2402ccfd1senorblanco 139296fcdcc219d2a0d3579719b84b28bede76efba64halcanary // Check that a kernel width < 1 gives a nullptr filter. 1393ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips conv = SkMatrixConvolutionImageFilter::Make( 13943a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkISize::Make(0, 1), 13953a49520696b2eca69e57884657d23fd2402ccfd1senorblanco kernel, 13963a49520696b2eca69e57884657d23fd2402ccfd1senorblanco gain, 13973a49520696b2eca69e57884657d23fd2402ccfd1senorblanco bias, 13983a49520696b2eca69e57884657d23fd2402ccfd1senorblanco kernelOffset, 13993a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkMatrixConvolutionImageFilter::kRepeat_TileMode, 1400ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips false, 1401ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips nullptr); 14023a49520696b2eca69e57884657d23fd2402ccfd1senorblanco 140396fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == conv.get()); 14043a49520696b2eca69e57884657d23fd2402ccfd1senorblanco 140596fcdcc219d2a0d3579719b84b28bede76efba64halcanary // Check that kernel height < 1 gives a nullptr filter. 1406ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips conv = SkMatrixConvolutionImageFilter::Make( 14073a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkISize::Make(1, -1), 14083a49520696b2eca69e57884657d23fd2402ccfd1senorblanco kernel, 14093a49520696b2eca69e57884657d23fd2402ccfd1senorblanco gain, 14103a49520696b2eca69e57884657d23fd2402ccfd1senorblanco bias, 14113a49520696b2eca69e57884657d23fd2402ccfd1senorblanco kernelOffset, 14123a49520696b2eca69e57884657d23fd2402ccfd1senorblanco SkMatrixConvolutionImageFilter::kRepeat_TileMode, 1413ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips false, 1414ef6a47b4af1ebf621682b3398916fefb90fc912erobertphillips nullptr); 14153a49520696b2eca69e57884657d23fd2402ccfd1senorblanco 141696fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == conv.get()); 14173a49520696b2eca69e57884657d23fd2402ccfd1senorblanco} 14183a49520696b2eca69e57884657d23fd2402ccfd1senorblanco 14199a53fd7c41554630124522f4b6eedc16912abbb7robertphillipsstatic void test_xfermode_cropped_input(SkCanvas* canvas, skiatest::Reporter* reporter) { 14209a53fd7c41554630124522f4b6eedc16912abbb7robertphillips canvas->clear(0); 1421ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 1422ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkBitmap bitmap; 1423ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org bitmap.allocN32Pixels(1, 1); 1424ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org bitmap.eraseARGB(255, 255, 255, 255); 1425ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 14265605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkColorFilter> green(SkColorFilter::MakeModeFilter(SK_ColorGREEN, 14277d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed SkBlendMode::kSrcIn)); 14285605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> greenFilter(SkColorFilterImageFilter::Make(green, nullptr)); 1429ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkImageFilter::CropRect cropRect(SkRect::MakeEmpty()); 14305605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> croppedOut(SkColorFilterImageFilter::Make(green, nullptr, &cropRect)); 1431ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 1432ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org // Check that an xfermode image filter whose input has been cropped out still draws the other 1433ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org // input. Also check that drawing with both inputs cropped out doesn't cause a GPU warning. 1434374772bd61951f01bf84fe17bf53d8867681c9aereed SkBlendMode mode = SkBlendMode::kSrcOver; 14358c0326df5f600da43a054dad3b354221dd6b790frobertphillips sk_sp<SkImageFilter> xfermodeNoFg(SkXfermodeImageFilter::Make(mode, greenFilter, 14368c0326df5f600da43a054dad3b354221dd6b790frobertphillips croppedOut, nullptr)); 14378c0326df5f600da43a054dad3b354221dd6b790frobertphillips sk_sp<SkImageFilter> xfermodeNoBg(SkXfermodeImageFilter::Make(mode, croppedOut, 14388c0326df5f600da43a054dad3b354221dd6b790frobertphillips greenFilter, nullptr)); 14398c0326df5f600da43a054dad3b354221dd6b790frobertphillips sk_sp<SkImageFilter> xfermodeNoFgNoBg(SkXfermodeImageFilter::Make(mode, croppedOut, 14408c0326df5f600da43a054dad3b354221dd6b790frobertphillips croppedOut, nullptr)); 1441ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 1442ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkPaint paint; 14438c0326df5f600da43a054dad3b354221dd6b790frobertphillips paint.setImageFilter(std::move(xfermodeNoFg)); 1444da420b976e61071cfe5de10556b4b23e519091d6reed canvas->drawBitmap(bitmap, 0, 0, &paint); // drawSprite 1445ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 1446ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org uint32_t pixel; 1447a9d9a392380952006303d83c35a63a32dffd0b36kkinnunen SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType); 14489a53fd7c41554630124522f4b6eedc16912abbb7robertphillips canvas->readPixels(info, &pixel, 4, 0, 0); 1449ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 1450ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 14518c0326df5f600da43a054dad3b354221dd6b790frobertphillips paint.setImageFilter(std::move(xfermodeNoBg)); 1452da420b976e61071cfe5de10556b4b23e519091d6reed canvas->drawBitmap(bitmap, 0, 0, &paint); // drawSprite 14539a53fd7c41554630124522f4b6eedc16912abbb7robertphillips canvas->readPixels(info, &pixel, 4, 0, 0); 1454ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 1455ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 14568c0326df5f600da43a054dad3b354221dd6b790frobertphillips paint.setImageFilter(std::move(xfermodeNoFgNoBg)); 1457da420b976e61071cfe5de10556b4b23e519091d6reed canvas->drawBitmap(bitmap, 0, 0, &paint); // drawSprite 14589a53fd7c41554630124522f4b6eedc16912abbb7robertphillips canvas->readPixels(info, &pixel, 4, 0, 0); 1459ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 1460ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org} 1461ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 1462d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.orgDEF_TEST(ImageFilterNestedSaveLayer, reporter) { 1463d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkBitmap temp; 1464d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org temp.allocN32Pixels(50, 50); 14659a53fd7c41554630124522f4b6eedc16912abbb7robertphillips SkCanvas canvas(temp); 1466d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.clear(0x0); 1467d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1468d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkBitmap bitmap; 1469d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org bitmap.allocN32Pixels(10, 10); 1470d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org bitmap.eraseColor(SK_ColorGREEN); 1471d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1472d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkMatrix matrix; 1473d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.setScale(SkIntToScalar(2), SkIntToScalar(2)); 1474d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-20), SkIntToScalar(-20)); 1475ae8c933ca89315c1256bcf23749b5ee5cbc0d53crobertphillips sk_sp<SkImageFilter> matrixFilter( 1476ae8c933ca89315c1256bcf23749b5ee5cbc0d53crobertphillips SkImageFilter::MakeMatrixFilter(matrix, kLow_SkFilterQuality, nullptr)); 1477d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1478d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org // Test that saveLayer() with a filter nested inside another saveLayer() applies the 1479d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org // correct offset to the filter matrix. 1480d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkRect bounds1 = SkRect::MakeXYWH(10, 10, 30, 30); 148196fcdcc219d2a0d3579719b84b28bede76efba64halcanary canvas.saveLayer(&bounds1, nullptr); 1482d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkPaint filterPaint; 1483ae8c933ca89315c1256bcf23749b5ee5cbc0d53crobertphillips filterPaint.setImageFilter(std::move(matrixFilter)); 1484d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkRect bounds2 = SkRect::MakeXYWH(20, 20, 10, 10); 1485d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.saveLayer(&bounds2, &filterPaint); 1486d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkPaint greenPaint; 1487d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org greenPaint.setColor(SK_ColorGREEN); 1488d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.drawRect(bounds2, greenPaint); 1489d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.restore(); 1490d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.restore(); 1491d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkPaint strokePaint; 1492d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org strokePaint.setStyle(SkPaint::kStroke_Style); 1493d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org strokePaint.setColor(SK_ColorRED); 1494d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1495a9d9a392380952006303d83c35a63a32dffd0b36kkinnunen SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType); 1496d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org uint32_t pixel; 1497d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.readPixels(info, &pixel, 4, 25, 25); 1498d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 1499d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1500d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org // Test that drawSprite() with a filter nested inside a saveLayer() applies the 1501d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org // correct offset to the filter matrix. 1502d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.clear(0x0); 1503d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.readPixels(info, &pixel, 4, 25, 25); 150496fcdcc219d2a0d3579719b84b28bede76efba64halcanary canvas.saveLayer(&bounds1, nullptr); 1505da420b976e61071cfe5de10556b4b23e519091d6reed canvas.drawBitmap(bitmap, 20, 20, &filterPaint); // drawSprite 1506d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.restore(); 1507d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1508d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.readPixels(info, &pixel, 4, 25, 25); 1509d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 1510d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org} 1511d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1512ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.orgDEF_TEST(XfermodeImageFilterCroppedInput, reporter) { 1513ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkBitmap temp; 1514ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org temp.allocN32Pixels(100, 100); 15159a53fd7c41554630124522f4b6eedc16912abbb7robertphillips SkCanvas canvas(temp); 15169a53fd7c41554630124522f4b6eedc16912abbb7robertphillips test_xfermode_cropped_input(&canvas, reporter); 1517ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org} 151809843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 15193e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic void test_composed_imagefilter_offset(skiatest::Reporter* reporter, GrContext* context) { 15203e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialImage> srcImg(create_empty_special_image(context, 100)); 15215788faaa2ac4203827c68006b669e277d441e2e4ajuma 15225788faaa2ac4203827c68006b669e277d441e2e4ajuma SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(1, 0, 20, 20)); 152351a315eff9b86bd60e7884240c4efc199129d37arobertphillips sk_sp<SkImageFilter> offsetFilter(SkOffsetImageFilter::Make(0, 0, nullptr, &cropRect)); 15246e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> blurFilter(SkBlurImageFilter::Make(SK_Scalar1, SK_Scalar1, 15256e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips nullptr, &cropRect)); 1526491fb17cab07574a9d5656c1c97ad0acc3af5c70robertphillips sk_sp<SkImageFilter> composedFilter(SkComposeImageFilter::Make(std::move(blurFilter), 1527491fb17cab07574a9d5656c1c97ad0acc3af5c70robertphillips std::move(offsetFilter))); 15285788faaa2ac4203827c68006b669e277d441e2e4ajuma SkIPoint offset; 15292a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::OutputProperties noColorSpace(nullptr); 15302a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr, noColorSpace); 15314418dbac3386f26c8da62ab242be9c178961eb18robertphillips 15322302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> resultImg(composedFilter->filterImage(srcImg.get(), ctx, &offset)); 15334418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, resultImg); 15345788faaa2ac4203827c68006b669e277d441e2e4ajuma REPORTER_ASSERT(reporter, offset.fX == 1 && offset.fY == 0); 15355788faaa2ac4203827c68006b669e277d441e2e4ajuma} 15365788faaa2ac4203827c68006b669e277d441e2e4ajuma 15374418dbac3386f26c8da62ab242be9c178961eb18robertphillipsDEF_TEST(ComposedImageFilterOffset, reporter) { 15383e302275b324172c845627cbd00cee8a06571bafrobertphillips test_composed_imagefilter_offset(reporter, nullptr); 15394418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 15404418dbac3386f26c8da62ab242be9c178961eb18robertphillips 15414418dbac3386f26c8da62ab242be9c178961eb18robertphillips#if SK_SUPPORT_GPU 154268d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ComposedImageFilterOffset_Gpu, reporter, ctxInfo) { 15438b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon test_composed_imagefilter_offset(reporter, ctxInfo.grContext()); 15444418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 15454418dbac3386f26c8da62ab242be9c178961eb18robertphillips#endif 15464418dbac3386f26c8da62ab242be9c178961eb18robertphillips 15473e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic void test_composed_imagefilter_bounds(skiatest::Reporter* reporter, GrContext* context) { 154817a652017a0243c57c954662e08a7976b9990feejbroman // The bounds passed to the inner filter must be filtered by the outer 154917a652017a0243c57c954662e08a7976b9990feejbroman // filter, so that the inner filter produces the pixels that the outer 155017a652017a0243c57c954662e08a7976b9990feejbroman // filter requires as input. This matters if the outer filter moves pixels. 155117a652017a0243c57c954662e08a7976b9990feejbroman // Here, accounting for the outer offset is necessary so that the green 155217a652017a0243c57c954662e08a7976b9990feejbroman // pixels of the picture are not clipped. 155317a652017a0243c57c954662e08a7976b9990feejbroman 155417a652017a0243c57c954662e08a7976b9990feejbroman SkPictureRecorder recorder; 155517a652017a0243c57c954662e08a7976b9990feejbroman SkCanvas* recordingCanvas = recorder.beginRecording(SkRect::MakeWH(200, 100)); 155617a652017a0243c57c954662e08a7976b9990feejbroman recordingCanvas->clipRect(SkRect::MakeXYWH(100, 0, 100, 100)); 155717a652017a0243c57c954662e08a7976b9990feejbroman recordingCanvas->clear(SK_ColorGREEN); 1558491fb17cab07574a9d5656c1c97ad0acc3af5c70robertphillips sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture()); 15595ff17b13524eea03e4b672ee3b3a49b649dd09fbrobertphillips sk_sp<SkImageFilter> pictureFilter(SkPictureImageFilter::Make(picture)); 156017a652017a0243c57c954662e08a7976b9990feejbroman SkImageFilter::CropRect cropRect(SkRect::MakeWH(100, 100)); 156151a315eff9b86bd60e7884240c4efc199129d37arobertphillips sk_sp<SkImageFilter> offsetFilter(SkOffsetImageFilter::Make(-100, 0, nullptr, &cropRect)); 1562491fb17cab07574a9d5656c1c97ad0acc3af5c70robertphillips sk_sp<SkImageFilter> composedFilter(SkComposeImageFilter::Make(std::move(offsetFilter), 1563491fb17cab07574a9d5656c1c97ad0acc3af5c70robertphillips std::move(pictureFilter))); 156417a652017a0243c57c954662e08a7976b9990feejbroman 15653e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialImage> sourceImage(create_empty_special_image(context, 100)); 15662a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::OutputProperties noColorSpace(nullptr); 15672a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr, noColorSpace); 156817a652017a0243c57c954662e08a7976b9990feejbroman SkIPoint offset; 156917a652017a0243c57c954662e08a7976b9990feejbroman sk_sp<SkSpecialImage> result(composedFilter->filterImage(sourceImage.get(), ctx, &offset)); 157017a652017a0243c57c954662e08a7976b9990feejbroman REPORTER_ASSERT(reporter, offset.isZero()); 157117a652017a0243c57c954662e08a7976b9990feejbroman REPORTER_ASSERT(reporter, result); 157217a652017a0243c57c954662e08a7976b9990feejbroman REPORTER_ASSERT(reporter, result->subset().size() == SkISize::Make(100, 100)); 157317a652017a0243c57c954662e08a7976b9990feejbroman 157417a652017a0243c57c954662e08a7976b9990feejbroman SkBitmap resultBM; 1575646125114b42b24e5ada3c9f8fac53a85f9ad2a0robertphillips REPORTER_ASSERT(reporter, result->getROPixels(&resultBM)); 157617a652017a0243c57c954662e08a7976b9990feejbroman SkAutoLockPixels lock(resultBM); 157717a652017a0243c57c954662e08a7976b9990feejbroman REPORTER_ASSERT(reporter, resultBM.getColor(50, 50) == SK_ColorGREEN); 157817a652017a0243c57c954662e08a7976b9990feejbroman} 157917a652017a0243c57c954662e08a7976b9990feejbroman 158017a652017a0243c57c954662e08a7976b9990feejbromanDEF_TEST(ComposedImageFilterBounds, reporter) { 15813e302275b324172c845627cbd00cee8a06571bafrobertphillips test_composed_imagefilter_bounds(reporter, nullptr); 158217a652017a0243c57c954662e08a7976b9990feejbroman} 158317a652017a0243c57c954662e08a7976b9990feejbroman 158417a652017a0243c57c954662e08a7976b9990feejbroman#if SK_SUPPORT_GPU 1585ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ComposedImageFilterBounds_Gpu, reporter, ctxInfo) { 15868b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon test_composed_imagefilter_bounds(reporter, ctxInfo.grContext()); 158717a652017a0243c57c954662e08a7976b9990feejbroman} 158817a652017a0243c57c954662e08a7976b9990feejbroman#endif 158917a652017a0243c57c954662e08a7976b9990feejbroman 15903e302275b324172c845627cbd00cee8a06571bafrobertphillipsstatic void test_partial_crop_rect(skiatest::Reporter* reporter, GrContext* context) { 15913e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialImage> srcImg(create_empty_special_image(context, 100)); 159224d2a7b463d585f9300ceac946431e822531d504senorblanco 159324d2a7b463d585f9300ceac946431e822531d504senorblanco SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(100, 0, 20, 30), 1594ed7cf273226ca5818a9d58b0f9183d665bb1ff58senorblanco SkImageFilter::CropRect::kHasWidth_CropEdge | SkImageFilter::CropRect::kHasHeight_CropEdge); 15955605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> filter(make_grayscale(nullptr, &cropRect)); 159624d2a7b463d585f9300ceac946431e822531d504senorblanco SkIPoint offset; 15972a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::OutputProperties noColorSpace(nullptr); 15982a75e5df300a2838f943ca52a52a85a5cf69802bbrianosman SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeWH(100, 100), nullptr, noColorSpace); 15994418dbac3386f26c8da62ab242be9c178961eb18robertphillips 16002302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg.get(), ctx, &offset)); 16014418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, resultImg); 16024418dbac3386f26c8da62ab242be9c178961eb18robertphillips 160324d2a7b463d585f9300ceac946431e822531d504senorblanco REPORTER_ASSERT(reporter, offset.fX == 0); 160424d2a7b463d585f9300ceac946431e822531d504senorblanco REPORTER_ASSERT(reporter, offset.fY == 0); 16054418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, resultImg->width() == 20); 16064418dbac3386f26c8da62ab242be9c178961eb18robertphillips REPORTER_ASSERT(reporter, resultImg->height() == 30); 16074418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 16084418dbac3386f26c8da62ab242be9c178961eb18robertphillips 160921a465d7f4c5e639044e79971aeaa1194fc73078senorblancoDEF_TEST(ImageFilterPartialCropRect, reporter) { 16103e302275b324172c845627cbd00cee8a06571bafrobertphillips test_partial_crop_rect(reporter, nullptr); 161124d2a7b463d585f9300ceac946431e822531d504senorblanco} 161224d2a7b463d585f9300ceac946431e822531d504senorblanco 16134418dbac3386f26c8da62ab242be9c178961eb18robertphillips#if SK_SUPPORT_GPU 161468d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterPartialCropRect_Gpu, reporter, ctxInfo) { 16158b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon test_partial_crop_rect(reporter, ctxInfo.grContext()); 16164418dbac3386f26c8da62ab242be9c178961eb18robertphillips} 16174418dbac3386f26c8da62ab242be9c178961eb18robertphillips#endif 16184418dbac3386f26c8da62ab242be9c178961eb18robertphillips 16190abdf766d395ed3b7059511425f431589eca05f6senorblancoDEF_TEST(ImageFilterCanComputeFastBounds, reporter) { 16200abdf766d395ed3b7059511425f431589eca05f6senorblanco 162112fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips { 162212fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SkPoint3 location = SkPoint3::Make(0, 0, SK_Scalar1); 162312fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips sk_sp<SkImageFilter> lighting(SkLightingImageFilter::MakePointLitDiffuse(location, 162412fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips SK_ColorGREEN, 162512fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips 0, 0, nullptr)); 162612fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips REPORTER_ASSERT(reporter, !lighting->canComputeFastBounds()); 162712fa47d33f1e9eb69bb20d9daad2eccfc7288944robertphillips } 16280abdf766d395ed3b7059511425f431589eca05f6senorblanco 16290abdf766d395ed3b7059511425f431589eca05f6senorblanco { 16306e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> gray(make_grayscale(nullptr, nullptr)); 16316e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips REPORTER_ASSERT(reporter, gray->canComputeFastBounds()); 16326e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips { 16336e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkColorFilter* grayCF; 16346e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips REPORTER_ASSERT(reporter, gray->asAColorFilter(&grayCF)); 16356e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips REPORTER_ASSERT(reporter, !grayCF->affectsTransparentBlack()); 16366e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips grayCF->unref(); 16376e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips } 16386e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips REPORTER_ASSERT(reporter, gray->canComputeFastBounds()); 16390abdf766d395ed3b7059511425f431589eca05f6senorblanco 16406e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> grayBlur(SkBlurImageFilter::Make(SK_Scalar1, SK_Scalar1, 16416e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips std::move(gray))); 16426e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips REPORTER_ASSERT(reporter, grayBlur->canComputeFastBounds()); 16436e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips } 16440abdf766d395ed3b7059511425f431589eca05f6senorblanco 16456e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips { 16466e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips SkScalar greenMatrix[20] = { 0, 0, 0, 0, 0, 16476e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 0, 0, 0, 0, 1, 16486e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 0, 0, 0, 0, 0, 16496e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 0, 0, 0, 0, 1 }; 16506e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkColorFilter> greenCF(SkColorFilter::MakeMatrixFilterRowMajor255(greenMatrix)); 16515605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> green(SkColorFilterImageFilter::Make(greenCF, nullptr)); 16526e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 16536e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips REPORTER_ASSERT(reporter, greenCF->affectsTransparentBlack()); 16546e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips REPORTER_ASSERT(reporter, !green->canComputeFastBounds()); 16556e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips 16566e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> greenBlur(SkBlurImageFilter::Make(SK_Scalar1, SK_Scalar1, 16576e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips std::move(green))); 16586e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips REPORTER_ASSERT(reporter, !greenBlur->canComputeFastBounds()); 16596e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips } 16600abdf766d395ed3b7059511425f431589eca05f6senorblanco 16610abdf766d395ed3b7059511425f431589eca05f6senorblanco uint8_t allOne[256], identity[256]; 16620abdf766d395ed3b7059511425f431589eca05f6senorblanco for (int i = 0; i < 256; ++i) { 16630abdf766d395ed3b7059511425f431589eca05f6senorblanco identity[i] = i; 16640abdf766d395ed3b7059511425f431589eca05f6senorblanco allOne[i] = 255; 16650abdf766d395ed3b7059511425f431589eca05f6senorblanco } 16660abdf766d395ed3b7059511425f431589eca05f6senorblanco 16675605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkColorFilter> identityCF(SkTableColorFilter::MakeARGB(identity, identity, 16685605b56afa5bd89f3148b397318b616fccfd4004robertphillips identity, allOne)); 16695605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> identityFilter(SkColorFilterImageFilter::Make(identityCF, nullptr)); 16700abdf766d395ed3b7059511425f431589eca05f6senorblanco REPORTER_ASSERT(reporter, !identityCF->affectsTransparentBlack()); 16710abdf766d395ed3b7059511425f431589eca05f6senorblanco REPORTER_ASSERT(reporter, identityFilter->canComputeFastBounds()); 16720abdf766d395ed3b7059511425f431589eca05f6senorblanco 16735605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkColorFilter> forceOpaqueCF(SkTableColorFilter::MakeARGB(allOne, identity, 16745605b56afa5bd89f3148b397318b616fccfd4004robertphillips identity, identity)); 16755605b56afa5bd89f3148b397318b616fccfd4004robertphillips sk_sp<SkImageFilter> forceOpaque(SkColorFilterImageFilter::Make(forceOpaqueCF, nullptr)); 16760abdf766d395ed3b7059511425f431589eca05f6senorblanco REPORTER_ASSERT(reporter, forceOpaqueCF->affectsTransparentBlack()); 16770abdf766d395ed3b7059511425f431589eca05f6senorblanco REPORTER_ASSERT(reporter, !forceOpaque->canComputeFastBounds()); 16780abdf766d395ed3b7059511425f431589eca05f6senorblanco} 16790abdf766d395ed3b7059511425f431589eca05f6senorblanco 1680cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita// Verify that SkImageSource survives serialization 1681cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalitaDEF_TEST(ImageFilterImageSourceSerialization, reporter) { 1682e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(SkSurface::MakeRasterN32Premul(10, 10)); 1683cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita surface->getCanvas()->clear(SK_ColorGREEN); 16849ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot()); 1685549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips sk_sp<SkImageFilter> filter(SkImageSource::Make(std::move(image))); 1686cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita 1687549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips sk_sp<SkData> data(SkValidatingSerializeFlattenable(filter.get())); 16885e25717ab6313b011ec54eac0109c414aa8ffc17Mike Reed sk_sp<SkImageFilter> unflattenedFilter = SkValidatingDeserializeImageFilter(data->data(), 16895e25717ab6313b011ec54eac0109c414aa8ffc17Mike Reed data->size()); 1690cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita REPORTER_ASSERT(reporter, unflattenedFilter); 1691cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita 1692cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita SkBitmap bm; 1693cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita bm.allocN32Pixels(10, 10); 169423cb88c52cd8bb7a0de80e2c85280375425c5189fmalita bm.eraseColor(SK_ColorBLUE); 1695cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita SkPaint paint; 1696cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita paint.setColor(SK_ColorRED); 1697cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita paint.setImageFilter(unflattenedFilter); 1698cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita 1699cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita SkCanvas canvas(bm); 1700cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita canvas.drawRect(SkRect::MakeWH(10, 10), paint); 1701cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita REPORTER_ASSERT(reporter, *bm.getAddr32(0, 0) == SkPreMultiplyColor(SK_ColorGREEN)); 1702cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita} 1703cd56f812e09fdd8f8322c5c28cbc4423a74b9a0afmalita 170445eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomonstatic void test_large_blur_input(skiatest::Reporter* reporter, SkCanvas* canvas) { 170545eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon SkBitmap largeBmp; 170645eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon int largeW = 5000; 170745eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon int largeH = 5000; 170845eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon#if SK_SUPPORT_GPU 170945eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon // If we're GPU-backed make the bitmap too large to be converted into a texture. 171045eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon if (GrContext* ctx = canvas->getGrContext()) { 171145eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon largeW = ctx->caps()->maxTextureSize() + 1; 171245eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon } 171345eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon#endif 171445eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon 171545eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon largeBmp.allocN32Pixels(largeW, largeH); 17162afbe23753bf97402a47408c83107042eea3c476mtklein largeBmp.eraseColor(0); 171745eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon if (!largeBmp.getPixels()) { 171845eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon ERRORF(reporter, "Failed to allocate large bmp."); 171945eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon return; 172045eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon } 172145eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon 17229ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> largeImage(SkImage::MakeFromBitmap(largeBmp)); 172345eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon if (!largeImage) { 172445eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon ERRORF(reporter, "Failed to create large image."); 172545eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon return; 172645eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon } 172745eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon 1728549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips sk_sp<SkImageFilter> largeSource(SkImageSource::Make(std::move(largeImage))); 172945eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon if (!largeSource) { 173045eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon ERRORF(reporter, "Failed to create large SkImageSource."); 173145eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon return; 173245eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon } 173345eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon 17346e7025ab13dfc4f0037233e67b4b8e18d6dfd1e1robertphillips sk_sp<SkImageFilter> blur(SkBlurImageFilter::Make(10.f, 10.f, std::move(largeSource))); 173545eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon if (!blur) { 173645eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon ERRORF(reporter, "Failed to create SkBlurImageFilter."); 173745eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon return; 173845eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon } 173945eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon 174045eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon SkPaint paint; 1741549c8991959333e5c0f53faebcbbd5d6bc8f6a56robertphillips paint.setImageFilter(std::move(blur)); 174245eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon 174345eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon // This should not crash (http://crbug.com/570479). 174445eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon canvas->drawRect(SkRect::MakeIWH(largeW, largeH), paint); 174545eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon} 174645eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon 174721a465d7f4c5e639044e79971aeaa1194fc73078senorblancoDEF_TEST(ImageFilterBlurLargeImage, reporter) { 1748e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(100, 100))); 174945eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon test_large_blur_input(reporter, surface->getCanvas()); 175045eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon} 175145eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon 17525878dbdf1b5d86201d299c6e07d53e35048713c7senorblancostatic void test_make_with_filter(skiatest::Reporter* reporter, GrContext* context) { 1753a5fdc974a996dca79be8388e61db68043001760bRobert Phillips sk_sp<SkSurface> surface(create_surface(context, 192, 128)); 17545878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco surface->getCanvas()->clear(SK_ColorRED); 17555878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco SkPaint bluePaint; 17565878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco bluePaint.setColor(SK_ColorBLUE); 17575878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco SkIRect subset = SkIRect::MakeXYWH(25, 20, 50, 50); 17585878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco surface->getCanvas()->drawRect(SkRect::Make(subset), bluePaint); 17595878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco sk_sp<SkImage> sourceImage = surface->makeImageSnapshot(); 17605878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 17615878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco sk_sp<SkImageFilter> filter = make_grayscale(nullptr, nullptr); 17625878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco SkIRect clipBounds = SkIRect::MakeXYWH(30, 35, 100, 100); 17635878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco SkIRect outSubset; 17645878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco SkIPoint offset; 17655878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco sk_sp<SkImage> result; 17665878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 17675878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco result = sourceImage->makeWithFilter(nullptr, subset, clipBounds, &outSubset, &offset); 17685878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco REPORTER_ASSERT(reporter, !result); 17695878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 17705878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco result = sourceImage->makeWithFilter(filter.get(), subset, clipBounds, nullptr, &offset); 17715878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco REPORTER_ASSERT(reporter, !result); 17725878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 17735878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco result = sourceImage->makeWithFilter(filter.get(), subset, clipBounds, &outSubset, nullptr); 17745878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco REPORTER_ASSERT(reporter, !result); 17755878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 17765878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco SkIRect bigSubset = SkIRect::MakeXYWH(-10000, -10000, 20000, 20000); 17775878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco result = sourceImage->makeWithFilter(filter.get(), bigSubset, clipBounds, &outSubset, &offset); 17785878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco REPORTER_ASSERT(reporter, !result); 17795878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 17805878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco SkIRect empty = SkIRect::MakeEmpty(); 17815878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco result = sourceImage->makeWithFilter(filter.get(), empty, clipBounds, &outSubset, &offset); 17825878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco REPORTER_ASSERT(reporter, !result); 17835878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 17845878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco result = sourceImage->makeWithFilter(filter.get(), subset, empty, &outSubset, &offset); 17855878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco REPORTER_ASSERT(reporter, !result); 17865878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 17875878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco SkIRect leftField = SkIRect::MakeXYWH(-1000, 0, 100, 100); 17885878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco result = sourceImage->makeWithFilter(filter.get(), subset, leftField, &outSubset, &offset); 17895878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco REPORTER_ASSERT(reporter, !result); 17905878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 17915878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco result = sourceImage->makeWithFilter(filter.get(), subset, clipBounds, &outSubset, &offset); 17925878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 17935878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco REPORTER_ASSERT(reporter, result); 17945878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco REPORTER_ASSERT(reporter, result->bounds().contains(outSubset)); 17955878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco SkIRect destRect = SkIRect::MakeXYWH(offset.x(), offset.y(), 17965878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco outSubset.width(), outSubset.height()); 17975878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco REPORTER_ASSERT(reporter, clipBounds.contains(destRect)); 1798a5fdc974a996dca79be8388e61db68043001760bRobert Phillips 1799a5fdc974a996dca79be8388e61db68043001760bRobert Phillips // In GPU-mode, this case creates a special image with a backing size that differs from 1800a5fdc974a996dca79be8388e61db68043001760bRobert Phillips // the content size 1801a5fdc974a996dca79be8388e61db68043001760bRobert Phillips { 1802a5fdc974a996dca79be8388e61db68043001760bRobert Phillips clipBounds.setXYWH(0, 0, 170, 100); 1803a5fdc974a996dca79be8388e61db68043001760bRobert Phillips subset.setXYWH(0, 0, 160, 90); 1804a5fdc974a996dca79be8388e61db68043001760bRobert Phillips 1805a5fdc974a996dca79be8388e61db68043001760bRobert Phillips filter = SkXfermodeImageFilter::Make(SkBlendMode::kSrc, nullptr); 1806a5fdc974a996dca79be8388e61db68043001760bRobert Phillips result = sourceImage->makeWithFilter(filter.get(), subset, clipBounds, &outSubset, &offset); 1807a5fdc974a996dca79be8388e61db68043001760bRobert Phillips REPORTER_ASSERT(reporter, result); 1808a5fdc974a996dca79be8388e61db68043001760bRobert Phillips } 18095878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco} 18105878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 18115878dbdf1b5d86201d299c6e07d53e35048713c7senorblancoDEF_TEST(ImageFilterMakeWithFilter, reporter) { 18125878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco test_make_with_filter(reporter, nullptr); 18135878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco} 18145878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 18155878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco#if SK_SUPPORT_GPU 18165878dbdf1b5d86201d299c6e07d53e35048713c7senorblancoDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterMakeWithFilter_Gpu, reporter, ctxInfo) { 18175878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco test_make_with_filter(reporter, ctxInfo.grContext()); 18185878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco} 18195878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco#endif 18205878dbdf1b5d86201d299c6e07d53e35048713c7senorblanco 182158d1466c7773984b7ce4bd75ebf7c97cd42f7d12senorblanco@chromium.org#if SK_SUPPORT_GPU 18224a8126e7f81384526629b1e21bf89b632ea13cd9reed 182368d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterHugeBlur_Gpu, reporter, ctxInfo) { 1824efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips 18258b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon sk_sp<SkSurface> surf(SkSurface::MakeRenderTarget(ctxInfo.grContext(), 18263e302275b324172c845627cbd00cee8a06571bafrobertphillips SkBudgeted::kNo, 18273e302275b324172c845627cbd00cee8a06571bafrobertphillips SkImageInfo::MakeN32Premul(100, 100))); 18289a53fd7c41554630124522f4b6eedc16912abbb7robertphillips 18293e302275b324172c845627cbd00cee8a06571bafrobertphillips 18303e302275b324172c845627cbd00cee8a06571bafrobertphillips SkCanvas* canvas = surf->getCanvas(); 18313e302275b324172c845627cbd00cee8a06571bafrobertphillips 18323e302275b324172c845627cbd00cee8a06571bafrobertphillips test_huge_blur(canvas, reporter); 183309843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org} 1834ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 1835ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(XfermodeImageFilterCroppedInput_Gpu, reporter, ctxInfo) { 1836efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips 18378b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon sk_sp<SkSurface> surf(SkSurface::MakeRenderTarget(ctxInfo.grContext(), 18383e302275b324172c845627cbd00cee8a06571bafrobertphillips SkBudgeted::kNo, 18393e302275b324172c845627cbd00cee8a06571bafrobertphillips SkImageInfo::MakeN32Premul(1, 1))); 18409a53fd7c41554630124522f4b6eedc16912abbb7robertphillips 18413e302275b324172c845627cbd00cee8a06571bafrobertphillips 18423e302275b324172c845627cbd00cee8a06571bafrobertphillips SkCanvas* canvas = surf->getCanvas(); 18433e302275b324172c845627cbd00cee8a06571bafrobertphillips 18443e302275b324172c845627cbd00cee8a06571bafrobertphillips test_xfermode_cropped_input(canvas, reporter); 1845ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org} 184632673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 1847ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_ALL_CONTEXTS(ImageFilterBlurLargeImage_Gpu, reporter, ctxInfo) { 18488b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon auto surface(SkSurface::MakeRenderTarget(ctxInfo.grContext(), SkBudgeted::kYes, 1849e8f3062a36d3682f4019309a32b5b84dc9eddf8creed SkImageInfo::MakeN32Premul(100, 100))); 185045eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon test_large_blur_input(reporter, surface->getCanvas()); 185145eefcfec26ee48c0b2ee1d316aae3c3dc529145bsalomon} 185258d1466c7773984b7ce4bd75ebf7c97cd42f7d12senorblanco@chromium.org#endif 1853bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed 1854bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed/* 1855bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed * Test that colorfilterimagefilter does not require its CTM to be decomposed when it has more 1856bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed * than just scale/translate, but that other filters do. 1857bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed */ 185896a04f329926099f0002f97883242793ff04f61creedDEF_TEST(ImageFilterComplexCTM, reporter) { 1859bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed // just need a colorfilter to exercise the corresponding imagefilter 18607d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed sk_sp<SkColorFilter> cf = SkColorFilter::MakeModeFilter(SK_ColorRED, SkBlendMode::kSrcATop); 186196a04f329926099f0002f97883242793ff04f61creed sk_sp<SkImageFilter> cfif = SkColorFilterImageFilter::Make(cf, nullptr); // can handle 186296a04f329926099f0002f97883242793ff04f61creed sk_sp<SkImageFilter> blif = SkBlurImageFilter::Make(3, 3, nullptr); // cannot handle 1863bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed 1864bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed struct { 1865bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed sk_sp<SkImageFilter> fFilter; 1866bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed bool fExpectCanHandle; 1867bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed } recs[] = { 1868bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed { cfif, true }, 1869bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed { SkColorFilterImageFilter::Make(cf, cfif), true }, 18707d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed { SkMergeImageFilter::Make(cfif, cfif, SkBlendMode::kSrcOver), true }, 187196a04f329926099f0002f97883242793ff04f61creed { SkComposeImageFilter::Make(cfif, cfif), true }, 187296a04f329926099f0002f97883242793ff04f61creed 1873bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed { blif, false }, 187496a04f329926099f0002f97883242793ff04f61creed { SkBlurImageFilter::Make(3, 3, cfif), false }, 1875bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed { SkColorFilterImageFilter::Make(cf, blif), false }, 18767d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed { SkMergeImageFilter::Make(cfif, blif, SkBlendMode::kSrcOver), false }, 187796a04f329926099f0002f97883242793ff04f61creed { SkComposeImageFilter::Make(blif, cfif), false }, 1878bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed }; 1879bfebe22ed54d1e3a00888292f10ed8b9714135d3liyuqian 1880bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed for (const auto& rec : recs) { 188196a04f329926099f0002f97883242793ff04f61creed const bool canHandle = rec.fFilter->canHandleComplexCTM(); 1882bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed REPORTER_ASSERT(reporter, canHandle == rec.fExpectCanHandle); 1883bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed } 1884bb34a8ac59850f128d9602e629a7475e3ad1a9d2reed} 1885