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" 94b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org#include "SkBitmapDevice.h" 104b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org#include "SkBitmapSource.h" 118f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkBlurImageFilter.h" 124b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org#include "SkCanvas.h" 13194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org#include "SkColorFilterImageFilter.h" 148f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkColorMatrixFilter.h" 154b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org#include "SkDeviceImageFilterProxy.h" 166776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkDisplacementMapEffect.h" 176776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkDropShadowImageFilter.h" 1897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org#include "SkFlattenableSerialization.h" 190a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org#include "SkGradientShader.h" 204b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org#include "SkLightingImageFilter.h" 218f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkMatrixConvolutionImageFilter.h" 22d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org#include "SkMatrixImageFilter.h" 236776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkMergeImageFilter.h" 246776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkMorphologyImageFilter.h" 256776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkOffsetImageFilter.h" 265251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org#include "SkPicture.h" 27910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org#include "SkPictureImageFilter.h" 28770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com#include "SkPictureRecorder.h" 2997d2c0a216e8feae251a6af1e50579df3e026434halcanary#include "SkReadBuffer.h" 308f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkRect.h" 316776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkTileImageFilter.h" 326776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org#include "SkXfermodeImageFilter.h" 338f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h" 34194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 35aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org#if SK_SUPPORT_GPU 36aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org#include "GrContextFactory.h" 37aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org#include "SkGpuDevice.h" 38aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org#endif 39aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 409f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.orgstatic const int kBitmapSize = 4; 419f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 425251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.orgnamespace { 435251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 445251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.orgclass MatrixTestImageFilter : public SkImageFilter { 455251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.orgpublic: 465251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org MatrixTestImageFilter(skiatest::Reporter* reporter, const SkMatrix& expectedMatrix) 479ea3d57fde28a5fe4487a111dc3dd49418235e5esenorblanco : SkImageFilter(0, NULL), fReporter(reporter), fExpectedMatrix(expectedMatrix) { 485251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org } 495251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 504cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context& ctx, 510937335e6b051150e9a42fc685659bac570b0c51senorblanco@chromium.org SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE { 524cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org REPORTER_ASSERT(fReporter, ctx.ctm() == fExpectedMatrix); 535251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org return true; 545251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org } 555251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 565251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(MatrixTestImageFilter) 575251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 585251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.orgprotected: 599fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 609ea3d57fde28a5fe4487a111dc3dd49418235e5esenorblanco explicit MatrixTestImageFilter(SkReadBuffer& buffer) : SkImageFilter(0, NULL) { 615251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org fReporter = static_cast<skiatest::Reporter*>(buffer.readFunctionPtr()); 625251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org buffer.readMatrix(&fExpectedMatrix); 635251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org } 649fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 655251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 665251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE { 679fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed this->INHERITED::flatten(buffer); 685251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org buffer.writeFunctionPtr(fReporter); 695251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org buffer.writeMatrix(fExpectedMatrix); 705251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org } 715251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 725251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.orgprivate: 735251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org skiatest::Reporter* fReporter; 745251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkMatrix fExpectedMatrix; 759fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 769fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed typedef SkImageFilter INHERITED; 775251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org}; 785251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 795251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org} 805251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 819fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* MatrixTestImageFilter::CreateProc(SkReadBuffer& buffer) { 829fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 839fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed skiatest::Reporter* reporter = (skiatest::Reporter*)buffer.readFunctionPtr(); 849fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkMatrix matrix; 859fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.readMatrix(&matrix); 869fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkNEW_ARGS(MatrixTestImageFilter, (reporter, matrix)); 879fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 889fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 899f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.orgstatic void make_small_bitmap(SkBitmap& bitmap) { 90deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org bitmap.allocN32Pixels(kBitmapSize, kBitmapSize); 91deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org SkCanvas canvas(bitmap); 929f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org canvas.clear(0x00000000); 939f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkPaint darkPaint; 949f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org darkPaint.setColor(0xFF804020); 959f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkPaint lightPaint; 969f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org lightPaint.setColor(0xFF244484); 979f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org const int i = kBitmapSize / 4; 989f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org for (int y = 0; y < kBitmapSize; y += i) { 999f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org for (int x = 0; x < kBitmapSize; x += i) { 1009f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org canvas.save(); 1019f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org canvas.translate(SkIntToScalar(x), SkIntToScalar(y)); 1029f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org canvas.drawRect(SkRect::MakeXYWH(0, 0, 1039f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 1049f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i)), darkPaint); 1059f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org canvas.drawRect(SkRect::MakeXYWH(SkIntToScalar(i), 1069f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 0, 1079f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 1089f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i)), lightPaint); 1099f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org canvas.drawRect(SkRect::MakeXYWH(0, 1109f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 1119f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 1129f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i)), lightPaint); 1139f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org canvas.drawRect(SkRect::MakeXYWH(SkIntToScalar(i), 1149f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 1159f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i), 1169f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(i)), darkPaint); 1179f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org canvas.restore(); 1184b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org } 1194b681bc95b14e081f1cc5b68cb755d57fc8eb977commit-bot@chromium.org } 1209f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org} 1219f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 1229f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.orgstatic SkImageFilter* make_scale(float amount, SkImageFilter* input = NULL) { 1239f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkScalar s = amount; 1249f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkScalar matrix[20] = { s, 0, 0, 0, 0, 1259f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 0, s, 0, 0, 0, 1269f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 0, 0, s, 0, 0, 1279f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 0, 0, 0, s, 0 }; 128727a352f7412753d2a3e4d30eab6500a1a4de135commit-bot@chromium.org SkAutoTUnref<SkColorFilter> filter(SkColorMatrixFilter::Create(matrix)); 1299f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org return SkColorFilterImageFilter::Create(filter, input); 1309f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org} 1319f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 1329f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.orgstatic SkImageFilter* make_grayscale(SkImageFilter* input = NULL, const SkImageFilter::CropRect* cropRect = NULL) { 1339f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkScalar matrix[20]; 1349f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org memset(matrix, 0, 20 * sizeof(SkScalar)); 1359f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org matrix[0] = matrix[5] = matrix[10] = 0.2126f; 1369f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org matrix[1] = matrix[6] = matrix[11] = 0.7152f; 1379f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org matrix[2] = matrix[7] = matrix[12] = 0.0722f; 1389f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org matrix[18] = 1.0f; 139727a352f7412753d2a3e4d30eab6500a1a4de135commit-bot@chromium.org SkAutoTUnref<SkColorFilter> filter(SkColorMatrixFilter::Create(matrix)); 1409f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org return SkColorFilterImageFilter::Create(filter, input, cropRect); 1419f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org} 1429f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 1439f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.orgDEF_TEST(ImageFilter, reporter) { 1449f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org { 1459f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // Check that two non-clipping color matrices concatenate into a single filter. 1469f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkAutoTUnref<SkImageFilter> halfBrightness(make_scale(0.5f)); 1479f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkAutoTUnref<SkImageFilter> quarterBrightness(make_scale(0.5f, halfBrightness)); 1489f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org REPORTER_ASSERT(reporter, NULL == quarterBrightness->getInput(0)); 149194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 150194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 1519f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org { 1529f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // Check that a clipping color matrix followed by a grayscale does not concatenate into a single filter. 1539f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkAutoTUnref<SkImageFilter> doubleBrightness(make_scale(2.0f)); 1549f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkAutoTUnref<SkImageFilter> halfBrightness(make_scale(0.5f, doubleBrightness)); 15549f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, halfBrightness->getInput(0)); 156194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 157194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 1589f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org { 1599f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // Check that a color filter image filter without a crop rect can be 1609f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // expressed as a color filter. 1619f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkAutoTUnref<SkImageFilter> gray(make_grayscale()); 1629f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org REPORTER_ASSERT(reporter, true == gray->asColorFilter(NULL)); 163194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 164194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 1659f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org { 1669f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // Check that a color filter image filter with a crop rect cannot 1679f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // be expressed as a color filter. 1689f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(0, 0, 100, 100)); 1699f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkAutoTUnref<SkImageFilter> grayWithCrop(make_grayscale(NULL, &cropRect)); 1709f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org REPORTER_ASSERT(reporter, false == grayWithCrop->asColorFilter(NULL)); 1719f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org } 172194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 1739f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org { 1743df05015efce95c306fb79c21efc77c79f1ac1basenorblanco // Check that two non-commutative matrices are concatenated in 1753df05015efce95c306fb79c21efc77c79f1ac1basenorblanco // the correct order. 1763df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkScalar blueToRedMatrix[20] = { 0 }; 1773df05015efce95c306fb79c21efc77c79f1ac1basenorblanco blueToRedMatrix[2] = blueToRedMatrix[18] = SK_Scalar1; 1783df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkScalar redToGreenMatrix[20] = { 0 }; 1793df05015efce95c306fb79c21efc77c79f1ac1basenorblanco redToGreenMatrix[5] = redToGreenMatrix[18] = SK_Scalar1; 1803df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkAutoTUnref<SkColorFilter> blueToRed(SkColorMatrixFilter::Create(blueToRedMatrix)); 1813df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkAutoTUnref<SkImageFilter> filter1(SkColorFilterImageFilter::Create(blueToRed.get())); 1823df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkAutoTUnref<SkColorFilter> redToGreen(SkColorMatrixFilter::Create(redToGreenMatrix)); 1833df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkAutoTUnref<SkImageFilter> filter2(SkColorFilterImageFilter::Create(redToGreen.get(), filter1.get())); 1843df05015efce95c306fb79c21efc77c79f1ac1basenorblanco 1853df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkBitmap result; 1863df05015efce95c306fb79c21efc77c79f1ac1basenorblanco result.allocN32Pixels(kBitmapSize, kBitmapSize); 1873df05015efce95c306fb79c21efc77c79f1ac1basenorblanco 1883df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkPaint paint; 1893df05015efce95c306fb79c21efc77c79f1ac1basenorblanco paint.setColor(SK_ColorBLUE); 1903df05015efce95c306fb79c21efc77c79f1ac1basenorblanco paint.setImageFilter(filter2.get()); 1913df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkCanvas canvas(result); 1923df05015efce95c306fb79c21efc77c79f1ac1basenorblanco canvas.clear(0x0); 1933df05015efce95c306fb79c21efc77c79f1ac1basenorblanco SkRect rect = SkRect::Make(SkIRect::MakeWH(kBitmapSize, kBitmapSize)); 1943df05015efce95c306fb79c21efc77c79f1ac1basenorblanco canvas.drawRect(rect, paint); 1953df05015efce95c306fb79c21efc77c79f1ac1basenorblanco uint32_t pixel = *result.getAddr32(0, 0); 1963df05015efce95c306fb79c21efc77c79f1ac1basenorblanco // The result here should be green, since we have effectively shifted blue to green. 1973df05015efce95c306fb79c21efc77c79f1ac1basenorblanco REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 1983df05015efce95c306fb79c21efc77c79f1ac1basenorblanco } 1993df05015efce95c306fb79c21efc77c79f1ac1basenorblanco 2003df05015efce95c306fb79c21efc77c79f1ac1basenorblanco { 2019f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // Tests pass by not asserting 2029f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkBitmap bitmap, result; 2039f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org make_small_bitmap(bitmap); 204deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org result.allocN32Pixels(kBitmapSize, kBitmapSize); 205194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 206194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org { 2079f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // This tests for : 2089f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // 1 ) location at (0,0,1) 2099f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkPoint3 location(0, 0, SK_Scalar1); 2109f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // 2 ) location and target at same value 2119f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkPoint3 target(location.fX, location.fY, location.fZ); 2129f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org // 3 ) large negative specular exponent value 2139f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkScalar specularExponent = -1000; 2149f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 215cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkAutoTUnref<SkImageFilter> bmSrc(SkBitmapSource::Create(bitmap)); 2169f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkPaint paint; 2179f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org paint.setImageFilter(SkLightingImageFilter::CreateSpotLitSpecular( 2189f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org location, target, specularExponent, 180, 2199f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org 0xFFFFFFFF, SK_Scalar1, SK_Scalar1, SK_Scalar1, 2209f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org bmSrc))->unref(); 2219f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkCanvas canvas(result); 2229f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkRect r = SkRect::MakeWH(SkIntToScalar(kBitmapSize), 2239f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org SkIntToScalar(kBitmapSize)); 2249f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org canvas.drawRect(r, paint); 225194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 226194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 227aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org} 2286776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org 229aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.orgstatic void test_crop_rects(SkBaseDevice* device, skiatest::Reporter* reporter) { 230aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org // Check that all filters offset to their absolute crop rect, 231aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org // unaffected by the input crop rect. 232aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org // Tests pass by not asserting. 233aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkBitmap bitmap; 234deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org bitmap.allocN32Pixels(100, 100); 235aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org bitmap.eraseARGB(0, 0, 0, 0); 236aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkDeviceImageFilterProxy proxy(device); 237aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 238aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkImageFilter::CropRect inputCropRect(SkRect::MakeXYWH(8, 13, 80, 80)); 239aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(20, 30, 60, 60)); 240aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkAutoTUnref<SkImageFilter> input(make_grayscale(NULL, &inputCropRect)); 241aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 242aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED, SkXfermode::kSrcIn_Mode)); 243aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkPoint3 location(0, 0, SK_Scalar1); 244aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkPoint3 target(SK_Scalar1, SK_Scalar1, SK_Scalar1); 245aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkScalar kernel[9] = { 246aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1), 247aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkIntToScalar( 1), SkIntToScalar(-7), SkIntToScalar( 1), 248aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1), 249aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org }; 250aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkISize kernelSize = SkISize::Make(3, 3); 251aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkScalar gain = SK_Scalar1, bias = 0; 252aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 253aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkImageFilter* filters[] = { 254aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkColorFilterImageFilter::Create(cf.get(), input.get(), &cropRect), 255cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkDisplacementMapEffect::Create(SkDisplacementMapEffect::kR_ChannelSelectorType, 256cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkDisplacementMapEffect::kB_ChannelSelectorType, 257cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org 40.0f, input.get(), input.get(), &cropRect), 258cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1, input.get(), &cropRect), 259cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkDropShadowImageFilter::Create(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN, input.get(), &cropRect), 260aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkLightingImageFilter::CreatePointLitDiffuse(location, SK_ColorGREEN, 0, 0, input.get(), &cropRect), 261aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkLightingImageFilter::CreatePointLitSpecular(location, SK_ColorGREEN, 0, 0, 0, input.get(), &cropRect), 262cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkMatrixConvolutionImageFilter::Create(kernelSize, kernel, gain, bias, SkIPoint::Make(1, 1), SkMatrixConvolutionImageFilter::kRepeat_TileMode, false, input.get(), &cropRect), 263cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkMergeImageFilter::Create(input.get(), input.get(), SkXfermode::kSrcOver_Mode, &cropRect), 264cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkOffsetImageFilter::Create(SK_Scalar1, SK_Scalar1, input.get(), &cropRect), 265cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkOffsetImageFilter::Create(SK_Scalar1, SK_Scalar1, input.get(), &cropRect), 266cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkDilateImageFilter::Create(3, 2, input.get(), &cropRect), 267cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkErodeImageFilter::Create(2, 3, input.get(), &cropRect), 268cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkTileImageFilter::Create(inputCropRect.rect(), cropRect.rect(), input.get()), 269cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkXfermodeImageFilter::Create(SkXfermode::Create(SkXfermode::kSrcOver_Mode), input.get(), input.get(), &cropRect), 270aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org }; 271aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 272aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) { 273aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkImageFilter* filter = filters[i]; 274aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkBitmap result; 275aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkIPoint offset; 276aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkString str; 277f4e1a7614da0cc3738077a1df5d8895a4df6d2f6senorblanco@chromium.org str.printf("filter %d", static_cast<int>(i)); 27855b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeLargest(), NULL); 279f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org REPORTER_ASSERT_MESSAGE(reporter, filter->filterImage(&proxy, bitmap, ctx, 280f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org &result, &offset), str.c_str()); 281aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org REPORTER_ASSERT_MESSAGE(reporter, offset.fX == 20 && offset.fY == 30, str.c_str()); 282aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org } 2836776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org 284aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) { 285aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkSafeUnref(filters[i]); 2866776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org } 2879f9d5829c29d8934fa0d4d348173d5ae39bed4e9tfarina@chromium.org} 288aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 2890a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.orgstatic SkBitmap make_gradient_circle(int width, int height) { 2900a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkBitmap bitmap; 2910a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkScalar x = SkIntToScalar(width / 2); 2920a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkScalar y = SkIntToScalar(height / 2); 2930a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkScalar radius = SkMinScalar(x, y) * 0.8f; 2940a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org bitmap.allocN32Pixels(width, height); 2950a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkCanvas canvas(bitmap); 2960a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org canvas.clear(0x00000000); 2970a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkColor colors[2]; 2980a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org colors[0] = SK_ColorWHITE; 2990a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org colors[1] = SK_ColorBLACK; 3000a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkAutoTUnref<SkShader> shader( 3010a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkGradientShader::CreateRadial(SkPoint::Make(x, y), radius, colors, NULL, 2, 3020a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkShader::kClamp_TileMode) 3030a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org ); 3040a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkPaint paint; 3050a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org paint.setShader(shader); 3060a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org canvas.drawCircle(x, y, radius, paint); 3070a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org return bitmap; 3080a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org} 3090a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 31032673b99a4fb5d798206eb7665b730ed0b4597a0senorblancostatic void test_negative_blur_sigma(SkBaseDevice* device, skiatest::Reporter* reporter) { 31132673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco // Check that SkBlurImageFilter will accept a negative sigma, either in 31232673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco // the given arguments or after CTM application. 31332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco int width = 32, height = 32; 31432673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkDeviceImageFilterProxy proxy(device); 31532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkScalar five = SkIntToScalar(5); 31632673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 31732673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkAutoTUnref<SkBlurImageFilter> positiveFilter( 31832673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkBlurImageFilter::Create(five, five) 31932673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco ); 32032673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 32132673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkAutoTUnref<SkBlurImageFilter> negativeFilter( 32232673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkBlurImageFilter::Create(-five, five) 32332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco ); 32432673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 32532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkBitmap gradient = make_gradient_circle(width, height); 32632673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkBitmap positiveResult1, negativeResult1; 32732673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkBitmap positiveResult2, negativeResult2; 32832673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkIPoint offset; 32932673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeLargest(), NULL); 33032673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco positiveFilter->filterImage(&proxy, gradient, ctx, &positiveResult1, &offset); 33132673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco negativeFilter->filterImage(&proxy, gradient, ctx, &negativeResult1, &offset); 33232673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkMatrix negativeScale; 33332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco negativeScale.setScale(-SK_Scalar1, SK_Scalar1); 33432673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkImageFilter::Context negativeCTX(negativeScale, SkIRect::MakeLargest(), NULL); 33532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco positiveFilter->filterImage(&proxy, gradient, negativeCTX, &negativeResult2, &offset); 33632673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco negativeFilter->filterImage(&proxy, gradient, negativeCTX, &positiveResult2, &offset); 33732673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkAutoLockPixels lockP1(positiveResult1); 33832673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkAutoLockPixels lockP2(positiveResult2); 33932673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkAutoLockPixels lockN1(negativeResult1); 34032673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkAutoLockPixels lockN2(negativeResult2); 34132673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco for (int y = 0; y < height; y++) { 34232673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco int diffs = memcmp(positiveResult1.getAddr32(0, y), negativeResult1.getAddr32(0, y), positiveResult1.rowBytes()); 34332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco REPORTER_ASSERT(reporter, !diffs); 34432673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco if (diffs) { 34532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco break; 34632673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco } 34732673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco diffs = memcmp(positiveResult1.getAddr32(0, y), negativeResult2.getAddr32(0, y), positiveResult1.rowBytes()); 34832673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco REPORTER_ASSERT(reporter, !diffs); 34932673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco if (diffs) { 35032673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco break; 35132673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco } 35232673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco diffs = memcmp(positiveResult1.getAddr32(0, y), positiveResult2.getAddr32(0, y), positiveResult1.rowBytes()); 35332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco REPORTER_ASSERT(reporter, !diffs); 35432673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco if (diffs) { 35532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco break; 35632673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco } 35732673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco } 35832673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco} 35932673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 36032673b99a4fb5d798206eb7665b730ed0b4597a0senorblancoDEF_TEST(TestNegativeBlurSigma, reporter) { 36132673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkBitmap temp; 36232673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco temp.allocN32Pixels(100, 100); 36332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkBitmapDevice device(temp); 36432673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco test_negative_blur_sigma(&device, reporter); 36532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco} 36632673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 3670a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.orgDEF_TEST(ImageFilterDrawTiled, reporter) { 3680a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org // Check that all filters when drawn tiled (with subsequent clip rects) exactly 3690a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org // match the same filters drawn with a single full-canvas bitmap draw. 3700a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org // Tests pass by not asserting. 3710a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 3720a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorRED, SkXfermode::kSrcIn_Mode)); 3730a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkPoint3 location(0, 0, SK_Scalar1); 3740a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkPoint3 target(SK_Scalar1, SK_Scalar1, SK_Scalar1); 3750a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkScalar kernel[9] = { 3760a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1), 3770a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkIntToScalar( 1), SkIntToScalar(-7), SkIntToScalar( 1), 3780a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1), 3790a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org }; 3800a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkISize kernelSize = SkISize::Make(3, 3); 3810a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkScalar gain = SK_Scalar1, bias = 0; 38229ac34ee526578fb0a01cd2d0c23c23e6a823d82senorblanco@chromium.org SkScalar five = SkIntToScalar(5); 3830a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 3840a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkAutoTUnref<SkImageFilter> gradient_source(SkBitmapSource::Create(make_gradient_circle(64, 64))); 38529ac34ee526578fb0a01cd2d0c23c23e6a823d82senorblanco@chromium.org SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(five, five)); 386ba31f1d341bac57ca76a75d67f64434b4b371dc6senorblanco@chromium.org SkMatrix matrix; 38729ac34ee526578fb0a01cd2d0c23c23e6a823d82senorblanco@chromium.org 388ba31f1d341bac57ca76a75d67f64434b4b371dc6senorblanco@chromium.org matrix.setTranslate(SK_Scalar1, SK_Scalar1); 389ba31f1d341bac57ca76a75d67f64434b4b371dc6senorblanco@chromium.org matrix.postRotate(SkIntToScalar(45), SK_Scalar1, SK_Scalar1); 3900a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 391910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org SkRTreeFactory factory; 392910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org SkPictureRecorder recorder; 393910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org SkCanvas* recordingCanvas = recorder.beginRecording(64, 64, &factory, 0); 394910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org 395910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org SkPaint greenPaint; 396910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org greenPaint.setColor(SK_ColorGREEN); 397910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeXYWH(10, 10, 30, 20)), greenPaint); 398910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org SkAutoTUnref<SkPicture> picture(recorder.endRecording()); 399910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org SkAutoTUnref<SkImageFilter> pictureFilter(SkPictureImageFilter::Create(picture.get())); 400910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org 4010a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org struct { 4020a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org const char* fName; 4030a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkImageFilter* fFilter; 4040a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } filters[] = { 4050a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "color filter", SkColorFilterImageFilter::Create(cf.get()) }, 4060a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "displacement map", SkDisplacementMapEffect::Create( 4070a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkDisplacementMapEffect::kR_ChannelSelectorType, 4080a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkDisplacementMapEffect::kB_ChannelSelectorType, 409d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org 20.0f, gradient_source.get()) }, 4100a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "blur", SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1) }, 4110a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "drop shadow", SkDropShadowImageFilter::Create( 4120a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_ColorGREEN) }, 4130a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "diffuse lighting", SkLightingImageFilter::CreatePointLitDiffuse( 4140a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org location, SK_ColorGREEN, 0, 0) }, 4150a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "specular lighting", 4160a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkLightingImageFilter::CreatePointLitSpecular(location, SK_ColorGREEN, 0, 0, 0) }, 4170a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "matrix convolution", 4180a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkMatrixConvolutionImageFilter::Create( 4190a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org kernelSize, kernel, gain, bias, SkIPoint::Make(1, 1), 4200a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkMatrixConvolutionImageFilter::kRepeat_TileMode, false) }, 4210a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "merge", SkMergeImageFilter::Create(NULL, NULL, SkXfermode::kSrcOver_Mode) }, 4220a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "offset", SkOffsetImageFilter::Create(SK_Scalar1, SK_Scalar1) }, 4230a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "dilate", SkDilateImageFilter::Create(3, 2) }, 4240a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "erode", SkErodeImageFilter::Create(2, 3) }, 4250a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org { "tile", SkTileImageFilter::Create(SkRect::MakeXYWH(0, 0, 50, 50), 4260a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkRect::MakeXYWH(0, 0, 100, 100), NULL) }, 427ba31f1d341bac57ca76a75d67f64434b4b371dc6senorblanco@chromium.org { "matrix", SkMatrixImageFilter::Create(matrix, SkPaint::kLow_FilterLevel) }, 42829ac34ee526578fb0a01cd2d0c23c23e6a823d82senorblanco@chromium.org { "blur and offset", SkOffsetImageFilter::Create(five, five, blur.get()) }, 429910702b564048d77e36a68b0f8dda7cc48a8fcffsenorblanco@chromium.org { "picture and blur", SkBlurImageFilter::Create(five, five, pictureFilter.get()) }, 4300a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org }; 4310a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 4320a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkBitmap untiledResult, tiledResult; 4330a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org int width = 64, height = 64; 4340a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org untiledResult.allocN32Pixels(width, height); 4350a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org tiledResult.allocN32Pixels(width, height); 4360a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkCanvas tiledCanvas(tiledResult); 4370a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkCanvas untiledCanvas(untiledResult); 438d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org int tileSize = 8; 4390a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 440d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org for (int scale = 1; scale <= 2; ++scale) { 441d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) { 442d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.clear(0); 443d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.clear(0); 444d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org SkPaint paint; 445d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org paint.setImageFilter(filters[i].fFilter); 446d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org paint.setTextSize(SkIntToScalar(height)); 447d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org paint.setColor(SK_ColorWHITE); 448d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org SkString str; 449d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org const char* text = "ABC"; 450d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org SkScalar ypos = SkIntToScalar(height); 451d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.save(); 452d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.scale(SkIntToScalar(scale), SkIntToScalar(scale)); 453d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.drawText(text, strlen(text), 0, ypos, paint); 454d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.restore(); 455d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org for (int y = 0; y < height; y += tileSize) { 456d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org for (int x = 0; x < width; x += tileSize) { 457d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.save(); 458d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.clipRect(SkRect::Make(SkIRect::MakeXYWH(x, y, tileSize, tileSize))); 459d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.scale(SkIntToScalar(scale), SkIntToScalar(scale)); 460d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.drawText(text, strlen(text), 0, ypos, paint); 461d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.restore(); 462d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org } 4630a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } 464d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org untiledCanvas.flush(); 465d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org tiledCanvas.flush(); 466d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org for (int y = 0; y < height; y++) { 467d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org int diffs = memcmp(untiledResult.getAddr32(0, y), tiledResult.getAddr32(0, y), untiledResult.rowBytes()); 468d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org REPORTER_ASSERT_MESSAGE(reporter, !diffs, filters[i].fName); 469d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org if (diffs) { 470d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org break; 471d4db657bf54ae5346cb142fed2f83ea88544a733senorblanco@chromium.org } 4720a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } 4730a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } 4740a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } 4750a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 4760a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org for (size_t i = 0; i < SK_ARRAY_COUNT(filters); ++i) { 4770a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkSafeUnref(filters[i].fFilter); 4780a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } 4790a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org} 4800a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 481a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillipsstatic void draw_saveLayer_picture(int width, int height, int tileSize, 482a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkBBHFactory* factory, SkBitmap* result) { 483d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 484d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkMatrix matrix; 485d910f544439fffa6c2bcc5181b79b2811a4c130amtklein matrix.setTranslate(SkIntToScalar(50), 0); 486d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 487d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(SK_ColorWHITE, SkXfermode::kSrc_Mode)); 488d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkAutoTUnref<SkImageFilter> cfif(SkColorFilterImageFilter::Create(cf.get())); 489d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkAutoTUnref<SkImageFilter> imageFilter(SkMatrixImageFilter::Create(matrix, SkPaint::kNone_FilterLevel, cfif.get())); 490d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 491d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkPaint paint; 492d910f544439fffa6c2bcc5181b79b2811a4c130amtklein paint.setImageFilter(imageFilter.get()); 493d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkPictureRecorder recorder; 494d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkRect bounds = SkRect::Make(SkIRect::MakeXYWH(0, 0, 50, 50)); 495a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(width), 496a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkIntToScalar(height), 497a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips factory, 0); 498d910f544439fffa6c2bcc5181b79b2811a4c130amtklein recordingCanvas->translate(-55, 0); 499d910f544439fffa6c2bcc5181b79b2811a4c130amtklein recordingCanvas->saveLayer(&bounds, &paint); 500d910f544439fffa6c2bcc5181b79b2811a4c130amtklein recordingCanvas->restore(); 501d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkAutoTUnref<SkPicture> picture1(recorder.endRecording()); 502d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 503d910f544439fffa6c2bcc5181b79b2811a4c130amtklein result->allocN32Pixels(width, height); 504d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkCanvas canvas(*result); 505d910f544439fffa6c2bcc5181b79b2811a4c130amtklein canvas.clear(0); 506d910f544439fffa6c2bcc5181b79b2811a4c130amtklein canvas.clipRect(SkRect::Make(SkIRect::MakeWH(tileSize, tileSize))); 507d910f544439fffa6c2bcc5181b79b2811a4c130amtklein canvas.drawPicture(picture1.get()); 508d910f544439fffa6c2bcc5181b79b2811a4c130amtklein} 509d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 510d910f544439fffa6c2bcc5181b79b2811a4c130amtkleinDEF_TEST(ImageFilterDrawMatrixBBH, reporter) { 511d910f544439fffa6c2bcc5181b79b2811a4c130amtklein // Check that matrix filter when drawn tiled with BBH exactly 512d910f544439fffa6c2bcc5181b79b2811a4c130amtklein // matches the same thing drawn without BBH. 513d910f544439fffa6c2bcc5181b79b2811a4c130amtklein // Tests pass by not asserting. 514d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 515d910f544439fffa6c2bcc5181b79b2811a4c130amtklein const int width = 200, height = 200; 516d910f544439fffa6c2bcc5181b79b2811a4c130amtklein const int tileSize = 100; 517d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkBitmap result1, result2; 518d910f544439fffa6c2bcc5181b79b2811a4c130amtklein SkRTreeFactory factory; 519d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 520a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips draw_saveLayer_picture(width, height, tileSize, &factory, &result1); 521a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips draw_saveLayer_picture(width, height, tileSize, NULL, &result2); 522d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 523d910f544439fffa6c2bcc5181b79b2811a4c130amtklein for (int y = 0; y < height; y++) { 524d910f544439fffa6c2bcc5181b79b2811a4c130amtklein int diffs = memcmp(result1.getAddr32(0, y), result2.getAddr32(0, y), result1.rowBytes()); 525d910f544439fffa6c2bcc5181b79b2811a4c130amtklein REPORTER_ASSERT(reporter, !diffs); 526d910f544439fffa6c2bcc5181b79b2811a4c130amtklein if (diffs) { 527d910f544439fffa6c2bcc5181b79b2811a4c130amtklein break; 528d910f544439fffa6c2bcc5181b79b2811a4c130amtklein } 529d910f544439fffa6c2bcc5181b79b2811a4c130amtklein } 530d910f544439fffa6c2bcc5181b79b2811a4c130amtklein} 531d910f544439fffa6c2bcc5181b79b2811a4c130amtklein 5321150a6d151571fb6ee816dadec844ae7ab53948asenorblancostatic SkImageFilter* makeBlur(SkImageFilter* input = NULL) { 5331150a6d151571fb6ee816dadec844ae7ab53948asenorblanco return SkBlurImageFilter::Create(SK_Scalar1, SK_Scalar1, input); 5341150a6d151571fb6ee816dadec844ae7ab53948asenorblanco} 5351150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 5361150a6d151571fb6ee816dadec844ae7ab53948asenorblancostatic SkImageFilter* makeDropShadow(SkImageFilter* input = NULL) { 5371150a6d151571fb6ee816dadec844ae7ab53948asenorblanco return SkDropShadowImageFilter::Create( 5381150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIntToScalar(100), SkIntToScalar(100), 5391150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIntToScalar(10), SkIntToScalar(10), 5401150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SK_ColorBLUE, input); 5411150a6d151571fb6ee816dadec844ae7ab53948asenorblanco} 5421150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 5431150a6d151571fb6ee816dadec844ae7ab53948asenorblancoDEF_TEST(ImageFilterBlurThenShadowBounds, reporter) { 5441150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkAutoTUnref<SkImageFilter> filter1(makeBlur()); 5451150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkAutoTUnref<SkImageFilter> filter2(makeDropShadow(filter1.get())); 5461150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 5471150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100); 5481150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect expectedBounds = SkIRect::MakeXYWH(-133, -133, 236, 236); 5491150a6d151571fb6ee816dadec844ae7ab53948asenorblanco filter2->filterBounds(bounds, SkMatrix::I(), &bounds); 5501150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 5511150a6d151571fb6ee816dadec844ae7ab53948asenorblanco REPORTER_ASSERT(reporter, bounds == expectedBounds); 5521150a6d151571fb6ee816dadec844ae7ab53948asenorblanco} 5531150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 5541150a6d151571fb6ee816dadec844ae7ab53948asenorblancoDEF_TEST(ImageFilterShadowThenBlurBounds, reporter) { 5551150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkAutoTUnref<SkImageFilter> filter1(makeDropShadow()); 5561150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkAutoTUnref<SkImageFilter> filter2(makeBlur(filter1.get())); 5571150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 5581150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100); 5591150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect expectedBounds = SkIRect::MakeXYWH(-133, -133, 236, 236); 5601150a6d151571fb6ee816dadec844ae7ab53948asenorblanco filter2->filterBounds(bounds, SkMatrix::I(), &bounds); 5611150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 5621150a6d151571fb6ee816dadec844ae7ab53948asenorblanco REPORTER_ASSERT(reporter, bounds == expectedBounds); 5631150a6d151571fb6ee816dadec844ae7ab53948asenorblanco} 5641150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 5651150a6d151571fb6ee816dadec844ae7ab53948asenorblancoDEF_TEST(ImageFilterDilateThenBlurBounds, reporter) { 5661150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkAutoTUnref<SkImageFilter> filter1(SkDilateImageFilter::Create(2, 2)); 5671150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkAutoTUnref<SkImageFilter> filter2(makeDropShadow(filter1.get())); 5681150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 5691150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect bounds = SkIRect::MakeXYWH(0, 0, 100, 100); 5701150a6d151571fb6ee816dadec844ae7ab53948asenorblanco SkIRect expectedBounds = SkIRect::MakeXYWH(-132, -132, 234, 234); 5711150a6d151571fb6ee816dadec844ae7ab53948asenorblanco filter2->filterBounds(bounds, SkMatrix::I(), &bounds); 5721150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 5731150a6d151571fb6ee816dadec844ae7ab53948asenorblanco REPORTER_ASSERT(reporter, bounds == expectedBounds); 5741150a6d151571fb6ee816dadec844ae7ab53948asenorblanco} 5751150a6d151571fb6ee816dadec844ae7ab53948asenorblanco 576a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillipsstatic void draw_blurred_rect(SkCanvas* canvas) { 577837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkAutoTUnref<SkImageFilter> filter(SkBlurImageFilter::Create(SkIntToScalar(8), 0)); 578837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkPaint filterPaint; 579837f5321a409228a27fc710eb71c87866b820cfbsenorblanco filterPaint.setColor(SK_ColorWHITE); 580837f5321a409228a27fc710eb71c87866b820cfbsenorblanco filterPaint.setImageFilter(filter); 581837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->saveLayer(NULL, &filterPaint); 582837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkPaint whitePaint; 583837f5321a409228a27fc710eb71c87866b820cfbsenorblanco whitePaint.setColor(SK_ColorWHITE); 584837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->drawRect(SkRect::Make(SkIRect::MakeWH(4, 4)), whitePaint); 585837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->restore(); 586837f5321a409228a27fc710eb71c87866b820cfbsenorblanco} 587837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 588a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillipsstatic void draw_picture_clipped(SkCanvas* canvas, const SkRect& clipRect, const SkPicture* picture) { 589837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->save(); 590837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->clipRect(clipRect); 591837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->drawPicture(picture); 592837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas->restore(); 593837f5321a409228a27fc710eb71c87866b820cfbsenorblanco} 594837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 595837f5321a409228a27fc710eb71c87866b820cfbsenorblancoDEF_TEST(ImageFilterDrawTiledBlurRTree, reporter) { 596837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // Check that the blur filter when recorded with RTree acceleration, 597837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // and drawn tiled (with subsequent clip rects) exactly 598837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // matches the same filter drawn with without RTree acceleration. 599837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // This tests that the "bleed" from the blur into the otherwise-blank 600837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // tiles is correctly rendered. 601837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // Tests pass by not asserting. 602837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 603837f5321a409228a27fc710eb71c87866b820cfbsenorblanco int width = 16, height = 8; 604837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkBitmap result1, result2; 605837f5321a409228a27fc710eb71c87866b820cfbsenorblanco result1.allocN32Pixels(width, height); 606837f5321a409228a27fc710eb71c87866b820cfbsenorblanco result2.allocN32Pixels(width, height); 607837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkCanvas canvas1(result1); 608837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkCanvas canvas2(result2); 609837f5321a409228a27fc710eb71c87866b820cfbsenorblanco int tileSize = 8; 610837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 611837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas1.clear(0); 612837f5321a409228a27fc710eb71c87866b820cfbsenorblanco canvas2.clear(0); 613837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 614837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkRTreeFactory factory; 615837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 616837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkPictureRecorder recorder1, recorder2; 617837f5321a409228a27fc710eb71c87866b820cfbsenorblanco // The only difference between these two pictures is that one has RTree aceleration. 618a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkCanvas* recordingCanvas1 = recorder1.beginRecording(SkIntToScalar(width), 619a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkIntToScalar(height), 620a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips NULL, 0); 621a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkCanvas* recordingCanvas2 = recorder2.beginRecording(SkIntToScalar(width), 622a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkIntToScalar(height), 623a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips &factory, 0); 624a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips draw_blurred_rect(recordingCanvas1); 625a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips draw_blurred_rect(recordingCanvas2); 626837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkAutoTUnref<SkPicture> picture1(recorder1.endRecording()); 627837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkAutoTUnref<SkPicture> picture2(recorder2.endRecording()); 628837f5321a409228a27fc710eb71c87866b820cfbsenorblanco for (int y = 0; y < height; y += tileSize) { 629837f5321a409228a27fc710eb71c87866b820cfbsenorblanco for (int x = 0; x < width; x += tileSize) { 630837f5321a409228a27fc710eb71c87866b820cfbsenorblanco SkRect tileRect = SkRect::Make(SkIRect::MakeXYWH(x, y, tileSize, tileSize)); 631a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips draw_picture_clipped(&canvas1, tileRect, picture1); 632a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips draw_picture_clipped(&canvas2, tileRect, picture2); 633837f5321a409228a27fc710eb71c87866b820cfbsenorblanco } 634837f5321a409228a27fc710eb71c87866b820cfbsenorblanco } 635837f5321a409228a27fc710eb71c87866b820cfbsenorblanco for (int y = 0; y < height; y++) { 636837f5321a409228a27fc710eb71c87866b820cfbsenorblanco int diffs = memcmp(result1.getAddr32(0, y), result2.getAddr32(0, y), result1.rowBytes()); 637837f5321a409228a27fc710eb71c87866b820cfbsenorblanco REPORTER_ASSERT(reporter, !diffs); 638837f5321a409228a27fc710eb71c87866b820cfbsenorblanco if (diffs) { 639837f5321a409228a27fc710eb71c87866b820cfbsenorblanco break; 640837f5321a409228a27fc710eb71c87866b820cfbsenorblanco } 641837f5321a409228a27fc710eb71c87866b820cfbsenorblanco } 642837f5321a409228a27fc710eb71c87866b820cfbsenorblanco} 643837f5321a409228a27fc710eb71c87866b820cfbsenorblanco 6449195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.orgDEF_TEST(ImageFilterMatrixConvolution, reporter) { 6459195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org // Check that a 1x3 filter does not cause a spurious assert. 6469195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkScalar kernel[3] = { 6479195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkIntToScalar( 1), SkIntToScalar( 1), SkIntToScalar( 1), 6489195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org }; 6499195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkISize kernelSize = SkISize::Make(1, 3); 6509195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkScalar gain = SK_Scalar1, bias = 0; 6519195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkIPoint kernelOffset = SkIPoint::Make(0, 0); 6529195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org 6539195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkAutoTUnref<SkImageFilter> filter( 6549195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkMatrixConvolutionImageFilter::Create( 6559195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org kernelSize, kernel, gain, bias, kernelOffset, 6569195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkMatrixConvolutionImageFilter::kRepeat_TileMode, false)); 6579195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org 6589195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkBitmap result; 6599195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org int width = 16, height = 16; 6609195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org result.allocN32Pixels(width, height); 6619195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkCanvas canvas(result); 6629195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org canvas.clear(0); 6639195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org 6649195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkPaint paint; 6659195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org paint.setImageFilter(filter); 6669195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org SkRect rect = SkRect::Make(SkIRect::MakeWH(width, height)); 6679195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org canvas.drawRect(rect, paint); 6689195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org} 6699195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org 6708c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.orgDEF_TEST(ImageFilterMatrixConvolutionBorder, reporter) { 6718c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org // Check that a filter with borders outside the target bounds 6728c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org // does not crash. 6738c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkScalar kernel[3] = { 6748c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 0, 0, 0, 6758c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org }; 6768c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkISize kernelSize = SkISize::Make(3, 1); 6778c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkScalar gain = SK_Scalar1, bias = 0; 6788c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkIPoint kernelOffset = SkIPoint::Make(2, 0); 6798c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 6808c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkAutoTUnref<SkImageFilter> filter( 6818c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkMatrixConvolutionImageFilter::Create( 6828c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org kernelSize, kernel, gain, bias, kernelOffset, 6838c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkMatrixConvolutionImageFilter::kClamp_TileMode, true)); 6848c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 6858c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkBitmap result; 6868c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 6878c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org int width = 10, height = 10; 6888c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org result.allocN32Pixels(width, height); 6898c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkCanvas canvas(result); 6908c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org canvas.clear(0); 6918c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 6928c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkPaint filterPaint; 6938c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org filterPaint.setImageFilter(filter); 6948c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkRect bounds = SkRect::MakeWH(1, 10); 6958c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkRect rect = SkRect::Make(SkIRect::MakeWH(width, height)); 6968c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkPaint rectPaint; 6978c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org canvas.saveLayer(&bounds, &filterPaint); 6988c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org canvas.drawRect(rect, rectPaint); 6998c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org canvas.restore(); 7008c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org} 7018c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org 702aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.orgDEF_TEST(ImageFilterCropRect, reporter) { 703aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkBitmap temp; 704deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org temp.allocN32Pixels(100, 100); 705aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org SkBitmapDevice device(temp); 706aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org test_crop_rects(&device, reporter); 707aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org} 708aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org 7099ea53f93e79ba312c4b3943923450a8b4aa57c82tfarinaDEF_TEST(ImageFilterMatrix, reporter) { 7105251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkBitmap temp; 711deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org temp.allocN32Pixels(100, 100); 7125251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkBitmapDevice device(temp); 7135251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkCanvas canvas(&device); 7145251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org canvas.scale(SkIntToScalar(2), SkIntToScalar(2)); 7155251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 7165251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkMatrix expectedMatrix = canvas.getTotalMatrix(); 7175251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 7185fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkRTreeFactory factory; 7195fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkPictureRecorder recorder; 7205fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org SkCanvas* recordingCanvas = recorder.beginRecording(100, 100, &factory, 0); 7215251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 7225251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkPaint paint; 7235251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkAutoTUnref<MatrixTestImageFilter> imageFilter( 7245251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org new MatrixTestImageFilter(reporter, expectedMatrix)); 7255251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org paint.setImageFilter(imageFilter.get()); 726091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org recordingCanvas->saveLayer(NULL, &paint); 7275251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org SkPaint solidPaint; 7285251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org solidPaint.setColor(0xFFFFFFFF); 7295251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org recordingCanvas->save(); 7305251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org recordingCanvas->scale(SkIntToScalar(10), SkIntToScalar(10)); 7315251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(100, 100)), solidPaint); 7325251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org recordingCanvas->restore(); // scale 7335251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org recordingCanvas->restore(); // saveLayer 73484b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com SkAutoTUnref<SkPicture> picture(recorder.endRecording()); 7355251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 7369b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(picture); 7375251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org} 7385251e2b91ac976f61e6252d931c1a0e746d2290asenorblanco@chromium.org 7393d822c29d4272a6749e59801b202b1ed6d611be8senorblancoDEF_TEST(ImageFilterCrossProcessPictureImageFilter, reporter) { 74097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkRTreeFactory factory; 74197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPictureRecorder recorder; 74297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkCanvas* recordingCanvas = recorder.beginRecording(1, 1, &factory, 0); 74397f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 74497f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // Create an SkPicture which simply draws a green 1x1 rectangle. 74597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPaint greenPaint; 74697f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org greenPaint.setColor(SK_ColorGREEN); 74797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), greenPaint); 74897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkAutoTUnref<SkPicture> picture(recorder.endRecording()); 74997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 75097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // Wrap that SkPicture in an SkPictureImageFilter. 75197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkAutoTUnref<SkImageFilter> imageFilter( 75297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPictureImageFilter::Create(picture.get())); 75397f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 75497f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // Check that SkPictureImageFilter successfully serializes its contained 75597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // SkPicture when not in cross-process mode. 75697f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPaint paint; 75797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org paint.setImageFilter(imageFilter.get()); 75897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPictureRecorder outerRecorder; 75997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkCanvas* outerCanvas = outerRecorder.beginRecording(1, 1, &factory, 0); 76097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPaint redPaintWithFilter; 76197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org redPaintWithFilter.setColor(SK_ColorRED); 76297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org redPaintWithFilter.setImageFilter(imageFilter.get()); 76397f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org outerCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), redPaintWithFilter); 76497f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkAutoTUnref<SkPicture> outerPicture(outerRecorder.endRecording()); 76597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 76697f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkBitmap bitmap; 76797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org bitmap.allocN32Pixels(1, 1); 76897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkBitmapDevice device(bitmap); 76997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkCanvas canvas(&device); 77097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 77197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // The result here should be green, since the filter replaces the primitive's red interior. 77297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org canvas.clear(0x0); 7739b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(outerPicture); 77497f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org uint32_t pixel = *bitmap.getAddr32(0, 0); 77597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 77697f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 77797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // Check that, for now, SkPictureImageFilter does not serialize or 77897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // deserialize its contained picture when the filter is serialized 77997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // cross-process. Do this by "laundering" it through SkValidatingReadBuffer. 78097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkAutoTUnref<SkData> data(SkValidatingSerializeFlattenable(imageFilter.get())); 78197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkAutoTUnref<SkFlattenable> flattenable(SkValidatingDeserializeFlattenable( 78297f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org data->data(), data->size(), SkImageFilter::GetFlattenableType())); 78397f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkImageFilter* unflattenedFilter = static_cast<SkImageFilter*>(flattenable.get()); 78497f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 78597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org redPaintWithFilter.setImageFilter(unflattenedFilter); 78697f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkPictureRecorder crossProcessRecorder; 78797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkCanvas* crossProcessCanvas = crossProcessRecorder.beginRecording(1, 1, &factory, 0); 78897f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org crossProcessCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), redPaintWithFilter); 78997f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org SkAutoTUnref<SkPicture> crossProcessPicture(crossProcessRecorder.endRecording()); 79097f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 79197f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org canvas.clear(0x0); 7929b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(crossProcessPicture); 79397f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org pixel = *bitmap.getAddr32(0, 0); 79497f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org // The result here should not be green, since the filter draws nothing. 79597f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org REPORTER_ASSERT(reporter, pixel != SK_ColorGREEN); 79697f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org} 79797f5fc651956287e78e35934cf62b9e1b45b4f6csenorblanco@chromium.org 7983d822c29d4272a6749e59801b202b1ed6d611be8senorblancoDEF_TEST(ImageFilterClippedPictureImageFilter, reporter) { 7993d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkRTreeFactory factory; 8003d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkPictureRecorder recorder; 8013d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkCanvas* recordingCanvas = recorder.beginRecording(1, 1, &factory, 0); 8023d822c29d4272a6749e59801b202b1ed6d611be8senorblanco 8033d822c29d4272a6749e59801b202b1ed6d611be8senorblanco // Create an SkPicture which simply draws a green 1x1 rectangle. 8043d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkPaint greenPaint; 8053d822c29d4272a6749e59801b202b1ed6d611be8senorblanco greenPaint.setColor(SK_ColorGREEN); 8063d822c29d4272a6749e59801b202b1ed6d611be8senorblanco recordingCanvas->drawRect(SkRect::Make(SkIRect::MakeWH(1, 1)), greenPaint); 8073d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkAutoTUnref<SkPicture> picture(recorder.endRecording()); 8083d822c29d4272a6749e59801b202b1ed6d611be8senorblanco 8093d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkAutoTUnref<SkImageFilter> imageFilter( 8103d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkPictureImageFilter::Create(picture.get())); 8113d822c29d4272a6749e59801b202b1ed6d611be8senorblanco 8123d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkBitmap result; 8133d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkIPoint offset; 8143d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(1, 1, 1, 1), NULL); 8153d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkBitmap bitmap; 8163d822c29d4272a6749e59801b202b1ed6d611be8senorblanco bitmap.allocN32Pixels(2, 2); 8173d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkBitmapDevice device(bitmap); 8183d822c29d4272a6749e59801b202b1ed6d611be8senorblanco SkDeviceImageFilterProxy proxy(&device); 8193d822c29d4272a6749e59801b202b1ed6d611be8senorblanco REPORTER_ASSERT(reporter, !imageFilter->filterImage(&proxy, bitmap, ctx, &result, &offset)); 8203d822c29d4272a6749e59801b202b1ed6d611be8senorblanco} 8213d822c29d4272a6749e59801b202b1ed6d611be8senorblanco 8229ea53f93e79ba312c4b3943923450a8b4aa57c82tfarinaDEF_TEST(ImageFilterEmptySaveLayer, reporter) { 82368250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org // Even when there's an empty saveLayer()/restore(), ensure that an image 82468250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org // filter or color filter which affects transparent black still draws. 82568250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 82668250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkBitmap bitmap; 82768250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org bitmap.allocN32Pixels(10, 10); 82868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkBitmapDevice device(bitmap); 82968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkCanvas canvas(&device); 83068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 83168250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkRTreeFactory factory; 83268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkPictureRecorder recorder; 83368250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 83468250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkAutoTUnref<SkColorFilter> green( 83568250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkColorFilter::CreateModeFilter(SK_ColorGREEN, SkXfermode::kSrc_Mode)); 83668250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkAutoTUnref<SkColorFilterImageFilter> imageFilter( 83768250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkColorFilterImageFilter::Create(green.get())); 83868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkPaint imageFilterPaint; 83968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org imageFilterPaint.setImageFilter(imageFilter.get()); 84068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkPaint colorFilterPaint; 84168250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org colorFilterPaint.setColorFilter(green.get()); 84268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 84368250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkRect bounds = SkRect::MakeWH(10, 10); 84468250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 84568250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkCanvas* recordingCanvas = recorder.beginRecording(10, 10, &factory, 0); 84668250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->saveLayer(&bounds, &imageFilterPaint); 84768250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->restore(); 84868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkAutoTUnref<SkPicture> picture(recorder.endRecording()); 84968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 85068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org canvas.clear(0); 8519b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(picture); 85268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org uint32_t pixel = *bitmap.getAddr32(0, 0); 85368250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 85468250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 85568250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas = recorder.beginRecording(10, 10, &factory, 0); 85668250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->saveLayer(NULL, &imageFilterPaint); 85768250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->restore(); 85868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkAutoTUnref<SkPicture> picture2(recorder.endRecording()); 85968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 86068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org canvas.clear(0); 8619b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(picture2); 86268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org pixel = *bitmap.getAddr32(0, 0); 86368250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 86468250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 86568250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas = recorder.beginRecording(10, 10, &factory, 0); 86668250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->saveLayer(&bounds, &colorFilterPaint); 86768250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org recordingCanvas->restore(); 86868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org SkAutoTUnref<SkPicture> picture3(recorder.endRecording()); 86968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 87068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org canvas.clear(0); 8719b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips canvas.drawPicture(picture3); 87268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org pixel = *bitmap.getAddr32(0, 0); 87368250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 87468250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org} 87568250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 87628ae55de3c4ec93516901100df1170048f949dfbsenorblanco@chromium.orgstatic void test_huge_blur(SkBaseDevice* device, skiatest::Reporter* reporter) { 87709843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkCanvas canvas(device); 87809843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 87909843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkBitmap bitmap; 88009843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org bitmap.allocN32Pixels(100, 100); 88109843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org bitmap.eraseARGB(0, 0, 0, 0); 88209843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 88309843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org // Check that a blur with an insane radius does not crash or assert. 88409843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkAutoTUnref<SkImageFilter> blur(SkBlurImageFilter::Create(SkIntToScalar(1<<30), SkIntToScalar(1<<30))); 88509843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 88609843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkPaint paint; 88709843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org paint.setImageFilter(blur); 88809843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org canvas.drawSprite(bitmap, 0, 0, &paint); 88909843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org} 89009843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 89109843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.orgDEF_TEST(HugeBlurImageFilter, reporter) { 89209843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkBitmap temp; 89309843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org temp.allocN32Pixels(100, 100); 89409843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkBitmapDevice device(temp); 89509843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org test_huge_blur(&device, reporter); 89609843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org} 89709843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 898aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen WhiteDEF_TEST(MatrixConvolutionSanityTest, reporter) { 899aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkScalar kernel[1] = { 0 }; 900aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkScalar gain = SK_Scalar1, bias = 0; 901aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkIPoint kernelOffset = SkIPoint::Make(1, 1); 902aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 903aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White // Check that an enormous (non-allocatable) kernel gives a NULL filter. 904aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkAutoTUnref<SkImageFilter> conv(SkMatrixConvolutionImageFilter::Create( 905aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkISize::Make(1<<30, 1<<30), 906aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White kernel, 907aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White gain, 908aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White bias, 909aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White kernelOffset, 910aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkMatrixConvolutionImageFilter::kRepeat_TileMode, 911aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White false)); 912aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 913aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White REPORTER_ASSERT(reporter, NULL == conv.get()); 914aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 915aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White // Check that a NULL kernel gives a NULL filter. 916aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White conv.reset(SkMatrixConvolutionImageFilter::Create( 917aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkISize::Make(1, 1), 918aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White NULL, 919aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White gain, 920aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White bias, 921aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White kernelOffset, 922aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkMatrixConvolutionImageFilter::kRepeat_TileMode, 923aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White false)); 924aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 925aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White REPORTER_ASSERT(reporter, NULL == conv.get()); 926aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 927aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White // Check that a kernel width < 1 gives a NULL filter. 928aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White conv.reset(SkMatrixConvolutionImageFilter::Create( 929aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkISize::Make(0, 1), 930aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White kernel, 931aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White gain, 932aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White bias, 933aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White kernelOffset, 934aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkMatrixConvolutionImageFilter::kRepeat_TileMode, 935aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White false)); 936aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 937aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White REPORTER_ASSERT(reporter, NULL == conv.get()); 938aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 939aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White // Check that kernel height < 1 gives a NULL filter. 940aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White conv.reset(SkMatrixConvolutionImageFilter::Create( 941aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkISize::Make(1, -1), 942aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White kernel, 943aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White gain, 944aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White bias, 945aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White kernelOffset, 946aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkMatrixConvolutionImageFilter::kRepeat_TileMode, 947aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White false)); 948aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 949aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White REPORTER_ASSERT(reporter, NULL == conv.get()); 950aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White} 951aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 952ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.orgstatic void test_xfermode_cropped_input(SkBaseDevice* device, skiatest::Reporter* reporter) { 953ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkCanvas canvas(device); 954ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org canvas.clear(0); 955ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 956ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkBitmap bitmap; 957ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org bitmap.allocN32Pixels(1, 1); 958ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org bitmap.eraseARGB(255, 255, 255, 255); 959ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 960ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkAutoTUnref<SkColorFilter> green( 961ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkColorFilter::CreateModeFilter(SK_ColorGREEN, SkXfermode::kSrcIn_Mode)); 962ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkAutoTUnref<SkColorFilterImageFilter> greenFilter( 963ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkColorFilterImageFilter::Create(green.get())); 964ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkImageFilter::CropRect cropRect(SkRect::MakeEmpty()); 965ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkAutoTUnref<SkColorFilterImageFilter> croppedOut( 966ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkColorFilterImageFilter::Create(green.get(), NULL, &cropRect)); 967ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 968ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org // Check that an xfermode image filter whose input has been cropped out still draws the other 969ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org // input. Also check that drawing with both inputs cropped out doesn't cause a GPU warning. 970ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrcOver_Mode); 971ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkAutoTUnref<SkImageFilter> xfermodeNoFg( 972ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkXfermodeImageFilter::Create(mode, greenFilter, croppedOut)); 973ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkAutoTUnref<SkImageFilter> xfermodeNoBg( 974ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkXfermodeImageFilter::Create(mode, croppedOut, greenFilter)); 975ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkAutoTUnref<SkImageFilter> xfermodeNoFgNoBg( 976ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkXfermodeImageFilter::Create(mode, croppedOut, croppedOut)); 977ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 978ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkPaint paint; 979ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org paint.setImageFilter(xfermodeNoFg); 980ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org canvas.drawSprite(bitmap, 0, 0, &paint); 981ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 982ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org uint32_t pixel; 983ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); 984ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org canvas.readPixels(info, &pixel, 4, 0, 0); 985ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 986ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 987ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org paint.setImageFilter(xfermodeNoBg); 988ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org canvas.drawSprite(bitmap, 0, 0, &paint); 989ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org canvas.readPixels(info, &pixel, 4, 0, 0); 990ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 991ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 992ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org paint.setImageFilter(xfermodeNoFgNoBg); 993ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org canvas.drawSprite(bitmap, 0, 0, &paint); 994ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org canvas.readPixels(info, &pixel, 4, 0, 0); 995ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 996ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org} 997ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 998d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.orgDEF_TEST(ImageFilterNestedSaveLayer, reporter) { 999d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkBitmap temp; 1000d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org temp.allocN32Pixels(50, 50); 1001d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkBitmapDevice device(temp); 1002d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkCanvas canvas(&device); 1003d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.clear(0x0); 1004d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1005d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkBitmap bitmap; 1006d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org bitmap.allocN32Pixels(10, 10); 1007d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org bitmap.eraseColor(SK_ColorGREEN); 1008d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1009d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkMatrix matrix; 1010d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.setScale(SkIntToScalar(2), SkIntToScalar(2)); 1011d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-20), SkIntToScalar(-20)); 1012d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkAutoTUnref<SkImageFilter> matrixFilter( 1013d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkMatrixImageFilter::Create(matrix, SkPaint::kLow_FilterLevel)); 1014d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1015d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org // Test that saveLayer() with a filter nested inside another saveLayer() applies the 1016d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org // correct offset to the filter matrix. 1017d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkRect bounds1 = SkRect::MakeXYWH(10, 10, 30, 30); 1018d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.saveLayer(&bounds1, NULL); 1019d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkPaint filterPaint; 1020d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org filterPaint.setImageFilter(matrixFilter); 1021d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkRect bounds2 = SkRect::MakeXYWH(20, 20, 10, 10); 1022d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.saveLayer(&bounds2, &filterPaint); 1023d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkPaint greenPaint; 1024d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org greenPaint.setColor(SK_ColorGREEN); 1025d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.drawRect(bounds2, greenPaint); 1026d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.restore(); 1027d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.restore(); 1028d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkPaint strokePaint; 1029d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org strokePaint.setStyle(SkPaint::kStroke_Style); 1030d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org strokePaint.setColor(SK_ColorRED); 1031d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1032d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); 1033d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org uint32_t pixel; 1034d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.readPixels(info, &pixel, 4, 25, 25); 1035d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 1036d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1037d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org // Test that drawSprite() with a filter nested inside a saveLayer() applies the 1038d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org // correct offset to the filter matrix. 1039d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.clear(0x0); 1040d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.readPixels(info, &pixel, 4, 25, 25); 1041d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.saveLayer(&bounds1, NULL); 1042d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.drawSprite(bitmap, 20, 20, &filterPaint); 1043d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.restore(); 1044d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1045d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org canvas.readPixels(info, &pixel, 4, 25, 25); 1046d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN); 1047d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org} 1048d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org 1049ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.orgDEF_TEST(XfermodeImageFilterCroppedInput, reporter) { 1050ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkBitmap temp; 1051ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org temp.allocN32Pixels(100, 100); 1052ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkBitmapDevice device(temp); 1053ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org test_xfermode_cropped_input(&device, reporter); 1054ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org} 105509843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 105658d1466c7773984b7ce4bd75ebf7c97cd42f7d12senorblanco@chromium.org#if SK_SUPPORT_GPU 10574a8126e7f81384526629b1e21bf89b632ea13cd9reedconst SkSurfaceProps gProps = SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType); 10584a8126e7f81384526629b1e21bf89b632ea13cd9reed 1059aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.orgDEF_GPUTEST(ImageFilterCropRectGPU, reporter, factory) { 1060aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0)); 106115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context, 106215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkImageInfo::MakeN32Premul(100, 100), 10634a8126e7f81384526629b1e21bf89b632ea13cd9reed gProps, 106415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org 0)); 106515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org test_crop_rects(device, reporter); 1066aba651c3f1a1657bbe5367c873500e7c60539a3esenorblanco@chromium.org} 106709843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 106809843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.orgDEF_GPUTEST(HugeBlurImageFilterGPU, reporter, factory) { 106909843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0)); 107009843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context, 107109843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org SkImageInfo::MakeN32Premul(100, 100), 10724a8126e7f81384526629b1e21bf89b632ea13cd9reed gProps, 107309843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org 0)); 107409843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org test_huge_blur(device, reporter); 107509843fd5c15e84e9b14ab511a04d9d639149fa75senorblanco@chromium.org} 1076ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 1077ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.orgDEF_GPUTEST(XfermodeImageFilterCroppedInputGPU, reporter, factory) { 1078ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0)); 1079ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context, 1080ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org SkImageInfo::MakeN32Premul(1, 1), 10814a8126e7f81384526629b1e21bf89b632ea13cd9reed gProps, 1082ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org 0)); 1083ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org test_xfermode_cropped_input(device, reporter); 1084ee845ae4940779280a853269d7d797dc9eb89201senorblanco@chromium.org} 108532673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 108632673b99a4fb5d798206eb7665b730ed0b4597a0senorblancoDEF_GPUTEST(TestNegativeBlurSigmaGPU, reporter, factory) { 108732673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0)); 108832673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context, 108932673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco SkImageInfo::MakeN32Premul(1, 1), 10904a8126e7f81384526629b1e21bf89b632ea13cd9reed gProps, 109132673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco 0)); 109232673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco test_negative_blur_sigma(device, reporter); 109332673b99a4fb5d798206eb7665b730ed0b4597a0senorblanco} 109458d1466c7773984b7ce4bd75ebf7c97cd42f7d12senorblanco@chromium.org#endif 1095