15faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org/* 25faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * Copyright 2012 The Android Open Source Project 35faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * 45faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be 55faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org * found in the LICENSE file. 65faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org */ 75faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 85faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org#include "SkMatrixConvolutionImageFilter.h" 95faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org#include "SkBitmap.h" 105faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org#include "SkColorPriv.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 135faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org#include "SkRect.h" 148640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org#include "SkUnPreMultiply.h" 155faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 163bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#if SK_SUPPORT_GPU 17ac9779234ef7a8cf3d791ab7690ef8c388662836joshualitt#include "effects/GrMatrixConvolutionEffect.h" 183bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#endif 193bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org 20aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White// We need to be able to read at most SK_MaxS32 bytes, so divide that 21aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White// by the size of a scalar to know how many scalars we can read. 22aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen Whitestatic const int32_t gMaxKernelSize = SK_MaxS32 / sizeof(SkScalar); 23aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 247938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgSkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( 257938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org const SkISize& kernelSize, 267938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org const SkScalar* kernel, 277938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkScalar gain, 287938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkScalar bias, 29cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org const SkIPoint& kernelOffset, 307938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org TileMode tileMode, 317938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org bool convolveAlpha, 327938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkImageFilter* input, 335e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco const CropRect* cropRect, 345e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco uint32_t uniqueID) 355e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco : INHERITED(1, &input, cropRect, uniqueID), 365faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fKernelSize(kernelSize), 375faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fGain(gain), 385faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fBias(bias), 39cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org fKernelOffset(kernelOffset), 408640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org fTileMode(tileMode), 418640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org fConvolveAlpha(convolveAlpha) { 42aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White size_t size = (size_t) sk_64_mul(fKernelSize.width(), fKernelSize.height()); 435faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fKernel = SkNEW_ARRAY(SkScalar, size); 445faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org memcpy(fKernel, kernel, size * sizeof(SkScalar)); 453bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org SkASSERT(kernelSize.fWidth >= 1 && kernelSize.fHeight >= 1); 46cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkASSERT(kernelOffset.fX >= 0 && kernelOffset.fX < kernelSize.fWidth); 47cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkASSERT(kernelOffset.fY >= 0 && kernelOffset.fY < kernelSize.fHeight); 485faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 495faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 50aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen WhiteSkMatrixConvolutionImageFilter* SkMatrixConvolutionImageFilter::Create( 51aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White const SkISize& kernelSize, 52aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White const SkScalar* kernel, 53aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkScalar gain, 54aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkScalar bias, 55aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White const SkIPoint& kernelOffset, 56aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White TileMode tileMode, 57aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White bool convolveAlpha, 58aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White SkImageFilter* input, 59aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White const CropRect* cropRect, 60aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White uint32_t uniqueID) { 61aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White if (kernelSize.width() < 1 || kernelSize.height() < 1) { 62aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White return NULL; 63aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White } 64aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White if (gMaxKernelSize / kernelSize.fWidth < kernelSize.fHeight) { 65aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White return NULL; 66aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White } 67aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White if (!kernel) { 68aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White return NULL; 69aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White } 70aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White return SkNEW_ARGS(SkMatrixConvolutionImageFilter, (kernelSize, kernel, gain, bias, 71aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White kernelOffset, tileMode, convolveAlpha, 72aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White input, cropRect, uniqueID)); 73aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White} 74aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White 759fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 769fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedstatic bool tile_mode_is_valid(SkMatrixConvolutionImageFilter::TileMode tileMode) { 779fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed switch (tileMode) { 789fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed case SkMatrixConvolutionImageFilter::kClamp_TileMode: 799fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed case SkMatrixConvolutionImageFilter::kRepeat_TileMode: 809fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed case SkMatrixConvolutionImageFilter::kClampToBlack_TileMode: 819fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return true; 829fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed default: 839fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed break; 849fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 859fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return false; 869fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 879fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 888b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(SkReadBuffer& buffer) 89ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org : INHERITED(1, buffer) { 905faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fKernelSize.fWidth = buffer.readInt(); 915faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fKernelSize.fHeight = buffer.readInt(); 92d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org if ((fKernelSize.fWidth >= 1) && (fKernelSize.fHeight >= 1) && 93d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org // Make sure size won't be larger than a signed int, 94d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org // which would still be extremely large for a kernel, 95d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org // but we don't impose a hard limit for kernel size 96aafcb54f27d30c63602a0a0232f0b9fc8b310d19Stephen White (gMaxKernelSize / fKernelSize.fWidth >= fKernelSize.fHeight)) { 97025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org size_t size = fKernelSize.fWidth * fKernelSize.fHeight; 98d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org fKernel = SkNEW_ARRAY(SkScalar, size); 99025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org SkDEBUGCODE(bool success =) buffer.readScalarArray(fKernel, size); 100025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org SkASSERT(success); 101d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org } else { 102d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org fKernel = 0; 103d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org } 1045faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fGain = buffer.readScalar(); 1055faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fBias = buffer.readScalar(); 106cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org fKernelOffset.fX = buffer.readInt(); 107cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org fKernelOffset.fY = buffer.readInt(); 1085faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org fTileMode = (TileMode) buffer.readInt(); 1098640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org fConvolveAlpha = buffer.readBool(); 110d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org buffer.validate((fKernel != 0) && 111d594dbec0407343b7ac13af9c4580ec5933ab060commit-bot@chromium.org SkScalarIsFinite(fGain) && 112c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org SkScalarIsFinite(fBias) && 11356d135c03e1d38f0b9e17d79a3cbf8db2a915086sugoi tile_mode_is_valid(fTileMode) && 11456d135c03e1d38f0b9e17d79a3cbf8db2a915086sugoi (fKernelOffset.fX >= 0) && (fKernelOffset.fX < fKernelSize.fWidth) && 11556d135c03e1d38f0b9e17d79a3cbf8db2a915086sugoi (fKernelOffset.fY >= 0) && (fKernelOffset.fY < fKernelSize.fHeight)); 1165faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 1179fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 1189fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 1199fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkMatrixConvolutionImageFilter::CreateProc(SkReadBuffer& buffer) { 1209fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 1219fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkISize kernelSize; 1229fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed kernelSize.fWidth = buffer.readInt(); 1239fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed kernelSize.fHeight = buffer.readInt(); 1249fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const int count = buffer.getArrayCount(); 1259fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 1269fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const int64_t kernelArea = sk_64_mul(kernelSize.width(), kernelSize.height()); 1279fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed if (!buffer.validate(kernelArea == count)) { 1289fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return NULL; 1299fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 1309fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkAutoSTArray<16, SkScalar> kernel(count); 1319fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed if (!buffer.readScalarArray(kernel.get(), count)) { 1329fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return NULL; 1339fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 1349fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar gain = buffer.readScalar(); 1359fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar bias = buffer.readScalar(); 1369fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkIPoint kernelOffset; 1379fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed kernelOffset.fX = buffer.readInt(); 1389fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed kernelOffset.fY = buffer.readInt(); 1399fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed TileMode tileMode = (TileMode)buffer.readInt(); 1409fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed bool convolveAlpha = buffer.readBool(); 1419fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return Create(kernelSize, kernel.get(), gain, bias, kernelOffset, tileMode, convolveAlpha, 1425e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco common.getInput(0), &common.cropRect(), common.uniqueID()); 1439fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 1445faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1458b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkMatrixConvolutionImageFilter::flatten(SkWriteBuffer& buffer) const { 1465faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org this->INHERITED::flatten(buffer); 1475faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org buffer.writeInt(fKernelSize.fWidth); 1485faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org buffer.writeInt(fKernelSize.fHeight); 1495faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org buffer.writeScalarArray(fKernel, fKernelSize.fWidth * fKernelSize.fHeight); 1505faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org buffer.writeScalar(fGain); 1515faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org buffer.writeScalar(fBias); 152cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org buffer.writeInt(fKernelOffset.fX); 153cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org buffer.writeInt(fKernelOffset.fY); 1545faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org buffer.writeInt((int) fTileMode); 1558640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org buffer.writeBool(fConvolveAlpha); 1565faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 1575faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1585faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgSkMatrixConvolutionImageFilter::~SkMatrixConvolutionImageFilter() { 1595faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org delete[] fKernel; 1605faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 1615faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1625faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgclass UncheckedPixelFetcher { 1635faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgpublic: 1647938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org static inline SkPMColor fetch(const SkBitmap& src, int x, int y, const SkIRect& bounds) { 1655faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return *src.getAddr32(x, y); 1665faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 1675faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org}; 1685faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1695faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgclass ClampPixelFetcher { 1705faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgpublic: 1717938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org static inline SkPMColor fetch(const SkBitmap& src, int x, int y, const SkIRect& bounds) { 1727938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org x = SkPin32(x, bounds.fLeft, bounds.fRight - 1); 1737938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org y = SkPin32(y, bounds.fTop, bounds.fBottom - 1); 1745faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return *src.getAddr32(x, y); 1755faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 1765faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org}; 1775faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1785faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgclass RepeatPixelFetcher { 1795faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgpublic: 1807938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org static inline SkPMColor fetch(const SkBitmap& src, int x, int y, const SkIRect& bounds) { 1817938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org x = (x - bounds.left()) % bounds.width() + bounds.left(); 1827938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org y = (y - bounds.top()) % bounds.height() + bounds.top(); 1837938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (x < bounds.left()) { 1847938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org x += bounds.width(); 1855faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 1867938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (y < bounds.top()) { 1877938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org y += bounds.height(); 1885faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 1895faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return *src.getAddr32(x, y); 1905faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 1915faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org}; 1925faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 1935faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgclass ClampToBlackPixelFetcher { 1945faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgpublic: 1957938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org static inline SkPMColor fetch(const SkBitmap& src, int x, int y, const SkIRect& bounds) { 1967938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org if (x < bounds.fLeft || x >= bounds.fRight || y < bounds.fTop || y >= bounds.fBottom) { 1975faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return 0; 1985faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } else { 1995faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return *src.getAddr32(x, y); 2005faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 2015faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 2025faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org}; 2035faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 2048640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.orgtemplate<class PixelFetcher, bool convolveAlpha> 2057938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgvoid SkMatrixConvolutionImageFilter::filterPixels(const SkBitmap& src, 2067938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkBitmap* result, 2078c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org const SkIRect& r, 208ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org const SkIRect& bounds) const { 2098c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org SkIRect rect(r); 2108c7372bbe8949f2864bd3d9df00d85c5669a74b1senorblanco@chromium.org if (!rect.intersect(bounds)) { 2119195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org return; 2129195743aac79a4fa82059ab614b9795f215475f7senorblanco@chromium.org } 2135faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org for (int y = rect.fTop; y < rect.fBottom; ++y) { 2147938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkPMColor* dptr = result->getAddr32(rect.fLeft - bounds.fLeft, y - bounds.fTop); 2155faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org for (int x = rect.fLeft; x < rect.fRight; ++x) { 2165faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org SkScalar sumA = 0, sumR = 0, sumG = 0, sumB = 0; 2175faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org for (int cy = 0; cy < fKernelSize.fHeight; cy++) { 2185faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org for (int cx = 0; cx < fKernelSize.fWidth; cx++) { 2197938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkPMColor s = PixelFetcher::fetch(src, 220cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org x + cx - fKernelOffset.fX, 221cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org y + cy - fKernelOffset.fY, 2227938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org bounds); 2235faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org SkScalar k = fKernel[cy * fKernelSize.fWidth + cx]; 2248640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (convolveAlpha) { 2258640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org sumA += SkScalarMul(SkIntToScalar(SkGetPackedA32(s)), k); 2268640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 2275faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org sumR += SkScalarMul(SkIntToScalar(SkGetPackedR32(s)), k); 2285faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org sumG += SkScalarMul(SkIntToScalar(SkGetPackedG32(s)), k); 2295faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org sumB += SkScalarMul(SkIntToScalar(SkGetPackedB32(s)), k); 2305faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 2315faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 2328640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org int a = convolveAlpha 2338640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org ? SkClampMax(SkScalarFloorToInt(SkScalarMul(sumA, fGain) + fBias), 255) 2343bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org : 255; 235cc9471c36d3967270f7eb26f8b53ce0f17bc9fbbsenorblanco@chromium.org int r = SkClampMax(SkScalarFloorToInt(SkScalarMul(sumR, fGain) + fBias), a); 236cc9471c36d3967270f7eb26f8b53ce0f17bc9fbbsenorblanco@chromium.org int g = SkClampMax(SkScalarFloorToInt(SkScalarMul(sumG, fGain) + fBias), a); 237cc9471c36d3967270f7eb26f8b53ce0f17bc9fbbsenorblanco@chromium.org int b = SkClampMax(SkScalarFloorToInt(SkScalarMul(sumB, fGain) + fBias), a); 2388640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (!convolveAlpha) { 2397938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org a = SkGetPackedA32(PixelFetcher::fetch(src, x, y, bounds)); 2408640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org *dptr++ = SkPreMultiplyARGB(a, r, g, b); 2418640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } else { 2428640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org *dptr++ = SkPackARGB32(a, r, g, b); 2438640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 2445faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 2455faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 2465faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 2475faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 2488640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.orgtemplate<class PixelFetcher> 2497938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgvoid SkMatrixConvolutionImageFilter::filterPixels(const SkBitmap& src, 2507938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkBitmap* result, 2517938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org const SkIRect& rect, 252ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org const SkIRect& bounds) const { 2538640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (fConvolveAlpha) { 2547938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterPixels<PixelFetcher, true>(src, result, rect, bounds); 2558640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } else { 2567938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterPixels<PixelFetcher, false>(src, result, rect, bounds); 2578640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 2588640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org} 2598640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 2607938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgvoid SkMatrixConvolutionImageFilter::filterInteriorPixels(const SkBitmap& src, 2617938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkBitmap* result, 2627938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org const SkIRect& rect, 263ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org const SkIRect& bounds) const { 2647938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterPixels<UncheckedPixelFetcher>(src, result, rect, bounds); 2655faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 2665faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 2677938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.orgvoid SkMatrixConvolutionImageFilter::filterBorderPixels(const SkBitmap& src, 2687938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkBitmap* result, 2697938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org const SkIRect& rect, 270ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org const SkIRect& bounds) const { 2715faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org switch (fTileMode) { 2725faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org case kClamp_TileMode: 2737938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterPixels<ClampPixelFetcher>(src, result, rect, bounds); 2745faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org break; 2755faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org case kRepeat_TileMode: 2767938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterPixels<RepeatPixelFetcher>(src, result, rect, bounds); 2775faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org break; 2785faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org case kClampToBlack_TileMode: 2797938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterPixels<ClampToBlackPixelFetcher>(src, result, rect, bounds); 2805faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org break; 2815faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 2825faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 2835faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 284377c14a1e648f4427bd11474fad8ac264d98aff2senorblanco@chromium.org// FIXME: This should be refactored to SkImageFilterUtils for 2858640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org// use by other filters. For now, we assume the input is always 2868640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org// premultiplied and unpremultiply it 2878640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.orgstatic SkBitmap unpremultiplyBitmap(const SkBitmap& src) 2888640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org{ 2898640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org SkAutoLockPixels alp(src); 2908640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (!src.getPixels()) { 2918640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org return SkBitmap(); 2928640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 2938640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org SkBitmap result; 294848250415eddc54075f7eb8795e8db79e749c6abreed if (!result.tryAllocPixels(src.info())) { 2958640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org return SkBitmap(); 2968640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 2978640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org for (int y = 0; y < src.height(); ++y) { 2988640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org const uint32_t* srcRow = src.getAddr32(0, y); 2998640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org uint32_t* dstRow = result.getAddr32(0, y); 3008640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org for (int x = 0; x < src.width(); ++x) { 3018640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org dstRow[x] = SkUnPreMultiply::PMColorToColor(srcRow[x]); 3028640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 3038640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 3048640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org return result; 3058640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org} 3068640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 3075faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.orgbool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy, 3085faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org const SkBitmap& source, 3094cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const Context& ctx, 3105faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org SkBitmap* result, 311ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkIPoint* offset) const { 31268400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org SkBitmap src = source; 3136776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint srcOffset = SkIPoint::Make(0, 0); 3144cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { 31568400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org return false; 31668400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org } 31768400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org 31828fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org if (src.colorType() != kN32_SkColorType) { 3195faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return false; 3205faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 3215faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 3227938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkIRect bounds; 323118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { 3247938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org return false; 3257938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org } 3267938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org 3278640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org if (!fConvolveAlpha && !src.isOpaque()) { 3288640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org src = unpremultiplyBitmap(src); 3298640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org } 3308640d5024d57da5508bdf7585849e3b1f1cb365bsenorblanco@chromium.org 3315faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org SkAutoLockPixels alp(src); 3325faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org if (!src.getPixels()) { 3335faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return false; 3345faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org } 3355faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 336848250415eddc54075f7eb8795e8db79e749c6abreed if (!result->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height()))) { 337cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org return false; 338cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org } 3395faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org 3406776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fX = bounds.fLeft; 3416776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fY = bounds.fTop; 3426776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org bounds.offset(-srcOffset); 343cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkIRect interior = SkIRect::MakeXYWH(bounds.left() + fKernelOffset.fX, 344cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org bounds.top() + fKernelOffset.fY, 3457938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org bounds.width() - fKernelSize.fWidth + 1, 3467938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org bounds.height() - fKernelSize.fHeight + 1); 3477938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkIRect top = SkIRect::MakeLTRB(bounds.left(), bounds.top(), bounds.right(), interior.top()); 3487938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkIRect bottom = SkIRect::MakeLTRB(bounds.left(), interior.bottom(), 3497938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org bounds.right(), bounds.bottom()); 3507938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org SkIRect left = SkIRect::MakeLTRB(bounds.left(), interior.top(), 3517938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org interior.left(), interior.bottom()); 3525faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org SkIRect right = SkIRect::MakeLTRB(interior.right(), interior.top(), 3537938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org bounds.right(), interior.bottom()); 3547938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterBorderPixels(src, result, top, bounds); 3557938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterBorderPixels(src, result, left, bounds); 3567938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterInteriorPixels(src, result, interior, bounds); 3577938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterBorderPixels(src, result, right, bounds); 3587938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org filterBorderPixels(src, result, bottom, bounds); 3595faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org return true; 3605faa2dc266ec933b3961f985e5718236f1ecbe47senorblanco@chromium.org} 3613bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org 3620a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.orgbool SkMatrixConvolutionImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 3630a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkIRect* dst) const { 3640a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org SkIRect bounds = src; 3650a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org bounds.fRight += fKernelSize.width() - 1; 3660a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org bounds.fBottom += fKernelSize.height() - 1; 3670a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org bounds.offset(-fKernelOffset); 3680a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { 3690a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org return false; 3700a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org } 3710a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org *dst = bounds; 3720a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org return true; 3730a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org} 3740a5c233e3b911232c0d6f9a88ded99ecf88b8a97senorblanco@chromium.org 3753bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#if SK_SUPPORT_GPU 3763bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org 3775ae5fc59b27a48711e514b3ede548b228e393e9bjoshualittstatic GrTextureDomain::Mode convert_tilemodes( 378ac9779234ef7a8cf3d791ab7690ef8c388662836joshualitt SkMatrixConvolutionImageFilter::TileMode tileMode) { 3795ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt switch (tileMode) { 3805ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt case SkMatrixConvolutionImageFilter::kClamp_TileMode: 3815ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt return GrTextureDomain::kClamp_Mode; 3825ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt case SkMatrixConvolutionImageFilter::kRepeat_TileMode: 3835ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt return GrTextureDomain::kRepeat_Mode; 3845ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt case SkMatrixConvolutionImageFilter::kClampToBlack_TileMode: 3855ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt return GrTextureDomain::kDecal_Mode; 3865ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt default: 3875ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt SkASSERT(false); 3885ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt } 3895ae5fc59b27a48711e514b3ede548b228e393e9bjoshualitt return GrTextureDomain::kIgnore_Mode; 3903bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org} 3913bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org 392b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool SkMatrixConvolutionImageFilter::asFragmentProcessor(GrFragmentProcessor** fp, 393b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* texture, 394b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const SkMatrix&, 395b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const SkIRect& bounds) const { 396b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (!fp) { 397d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org return fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE; 3983bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org } 399d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org SkASSERT(fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE); 400b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt *fp = GrMatrixConvolutionEffect::Create(texture, 401b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt bounds, 402b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fKernelSize, 403b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fKernel, 404b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fGain, 405b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fBias, 406b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fKernelOffset, 407b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt convert_tilemodes(fTileMode), 408b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fConvolveAlpha); 409d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org return true; 4103bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org} 4113bc16c8bc1ecb9ac4450f58093cc9e3edb8a50b8senorblanco@chromium.org#endif 412