| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkMatrixConvolutionImageFilter.h" | 8 #include "SkMatrixConvolutionImageFilter.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| 11 #include "SkFlattenableBuffers.h" | 11 #include "SkFlattenableBuffers.h" |
| 12 #include "SkRect.h" | 12 #include "SkRect.h" |
| 13 #include "SkUnPreMultiply.h" | 13 #include "SkUnPreMultiply.h" |
| 14 | 14 |
| 15 #if SK_SUPPORT_GPU | 15 #if SK_SUPPORT_GPU |
| 16 #include "gl/GrGLEffect.h" | 16 #include "gl/GrGLEffect.h" |
| 17 #include "effects/GrSingleTextureEffect.h" | 17 #include "effects/GrSingleTextureEffect.h" |
| 18 #include "GrTBackendEffectFactory.h" | 18 #include "GrTBackendEffectFactory.h" |
| 19 #include "GrTexture.h" | 19 #include "GrTexture.h" |
| 20 #include "SkMatrix.h" | 20 #include "SkMatrix.h" |
| 21 | |
| 22 #endif | 21 #endif |
| 23 | 22 |
| 24 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(const SkISize& ke
rnelSize, const SkScalar* kernel, SkScalar gain, SkScalar bias, const SkIPoint&
target, TileMode tileMode, bool convolveAlpha, SkImageFilter* input) | 23 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( |
| 25 : INHERITED(input), | 24 const SkISize& kernelSize, |
| 25 const SkScalar* kernel, |
| 26 SkScalar gain, |
| 27 SkScalar bias, |
| 28 const SkIPoint& target, |
| 29 TileMode tileMode, |
| 30 bool convolveAlpha, |
| 31 SkImageFilter* input, |
| 32 const CropRect* cropRect) |
| 33 : INHERITED(input, cropRect), |
| 26 fKernelSize(kernelSize), | 34 fKernelSize(kernelSize), |
| 27 fGain(gain), | 35 fGain(gain), |
| 28 fBias(bias), | 36 fBias(bias), |
| 29 fTarget(target), | 37 fTarget(target), |
| 30 fTileMode(tileMode), | 38 fTileMode(tileMode), |
| 31 fConvolveAlpha(convolveAlpha) { | 39 fConvolveAlpha(convolveAlpha) { |
| 32 uint32_t size = fKernelSize.fWidth * fKernelSize.fHeight; | 40 uint32_t size = fKernelSize.fWidth * fKernelSize.fHeight; |
| 33 fKernel = SkNEW_ARRAY(SkScalar, size); | 41 fKernel = SkNEW_ARRAY(SkScalar, size); |
| 34 memcpy(fKernel, kernel, size * sizeof(SkScalar)); | 42 memcpy(fKernel, kernel, size * sizeof(SkScalar)); |
| 35 SkASSERT(kernelSize.fWidth >= 1 && kernelSize.fHeight >= 1); | 43 SkASSERT(kernelSize.fWidth >= 1 && kernelSize.fHeight >= 1); |
| 36 SkASSERT(target.fX >= 0 && target.fX < kernelSize.fWidth); | 44 SkASSERT(target.fX >= 0 && target.fX < kernelSize.fWidth); |
| 37 SkASSERT(target.fY >= 0 && target.fY < kernelSize.fHeight); | 45 SkASSERT(target.fY >= 0 && target.fY < kernelSize.fHeight); |
| 38 } | 46 } |
| 39 | 47 |
| 40 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(SkFlattenableRead
Buffer& buffer) : INHERITED(buffer) { | 48 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(SkFlattenableRead
Buffer& buffer) |
| 49 : INHERITED(buffer) { |
| 41 fKernelSize.fWidth = buffer.readInt(); | 50 fKernelSize.fWidth = buffer.readInt(); |
| 42 fKernelSize.fHeight = buffer.readInt(); | 51 fKernelSize.fHeight = buffer.readInt(); |
| 43 uint32_t size = fKernelSize.fWidth * fKernelSize.fHeight; | 52 uint32_t size = fKernelSize.fWidth * fKernelSize.fHeight; |
| 44 fKernel = SkNEW_ARRAY(SkScalar, size); | 53 fKernel = SkNEW_ARRAY(SkScalar, size); |
| 45 SkDEBUGCODE(uint32_t readSize = )buffer.readScalarArray(fKernel); | 54 SkDEBUGCODE(uint32_t readSize = )buffer.readScalarArray(fKernel); |
| 46 SkASSERT(readSize == size); | 55 SkASSERT(readSize == size); |
| 47 fGain = buffer.readScalar(); | 56 fGain = buffer.readScalar(); |
| 48 fBias = buffer.readScalar(); | 57 fBias = buffer.readScalar(); |
| 49 fTarget.fX = buffer.readInt(); | 58 fTarget.fX = buffer.readInt(); |
| 50 fTarget.fY = buffer.readInt(); | 59 fTarget.fY = buffer.readInt(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 64 buffer.writeInt((int) fTileMode); | 73 buffer.writeInt((int) fTileMode); |
| 65 buffer.writeBool(fConvolveAlpha); | 74 buffer.writeBool(fConvolveAlpha); |
| 66 } | 75 } |
| 67 | 76 |
| 68 SkMatrixConvolutionImageFilter::~SkMatrixConvolutionImageFilter() { | 77 SkMatrixConvolutionImageFilter::~SkMatrixConvolutionImageFilter() { |
| 69 delete[] fKernel; | 78 delete[] fKernel; |
| 70 } | 79 } |
| 71 | 80 |
| 72 class UncheckedPixelFetcher { | 81 class UncheckedPixelFetcher { |
| 73 public: | 82 public: |
| 74 static inline SkPMColor fetch(const SkBitmap& src, int x, int y) { | 83 static inline SkPMColor fetch(const SkBitmap& src, int x, int y, const SkIRe
ct& bounds) { |
| 75 return *src.getAddr32(x, y); | 84 return *src.getAddr32(x, y); |
| 76 } | 85 } |
| 77 }; | 86 }; |
| 78 | 87 |
| 79 class ClampPixelFetcher { | 88 class ClampPixelFetcher { |
| 80 public: | 89 public: |
| 81 static inline SkPMColor fetch(const SkBitmap& src, int x, int y) { | 90 static inline SkPMColor fetch(const SkBitmap& src, int x, int y, const SkIRe
ct& bounds) { |
| 82 x = SkClampMax(x, src.width() - 1); | 91 x = SkPin32(x, bounds.fLeft, bounds.fRight - 1); |
| 83 y = SkClampMax(y, src.height() - 1); | 92 y = SkPin32(y, bounds.fTop, bounds.fBottom - 1); |
| 84 return *src.getAddr32(x, y); | 93 return *src.getAddr32(x, y); |
| 85 } | 94 } |
| 86 }; | 95 }; |
| 87 | 96 |
| 88 class RepeatPixelFetcher { | 97 class RepeatPixelFetcher { |
| 89 public: | 98 public: |
| 90 static inline SkPMColor fetch(const SkBitmap& src, int x, int y) { | 99 static inline SkPMColor fetch(const SkBitmap& src, int x, int y, const SkIRe
ct& bounds) { |
| 91 x %= src.width(); | 100 x = (x - bounds.left()) % bounds.width() + bounds.left(); |
| 92 y %= src.height(); | 101 y = (y - bounds.top()) % bounds.height() + bounds.top(); |
| 93 if (x < 0) { | 102 if (x < bounds.left()) { |
| 94 x += src.width(); | 103 x += bounds.width(); |
| 95 } | 104 } |
| 96 if (y < 0) { | 105 if (y < bounds.top()) { |
| 97 y += src.height(); | 106 y += bounds.height(); |
| 98 } | 107 } |
| 99 return *src.getAddr32(x, y); | 108 return *src.getAddr32(x, y); |
| 100 } | 109 } |
| 101 }; | 110 }; |
| 102 | 111 |
| 103 class ClampToBlackPixelFetcher { | 112 class ClampToBlackPixelFetcher { |
| 104 public: | 113 public: |
| 105 static inline SkPMColor fetch(const SkBitmap& src, int x, int y) { | 114 static inline SkPMColor fetch(const SkBitmap& src, int x, int y, const SkIRe
ct& bounds) { |
| 106 if (x < 0 || x >= src.width() || y < 0 || y >= src.height()) { | 115 if (x < bounds.fLeft || x >= bounds.fRight || y < bounds.fTop || y >= bo
unds.fBottom) { |
| 107 return 0; | 116 return 0; |
| 108 } else { | 117 } else { |
| 109 return *src.getAddr32(x, y); | 118 return *src.getAddr32(x, y); |
| 110 } | 119 } |
| 111 } | 120 } |
| 112 }; | 121 }; |
| 113 | 122 |
| 114 template<class PixelFetcher, bool convolveAlpha> | 123 template<class PixelFetcher, bool convolveAlpha> |
| 115 void SkMatrixConvolutionImageFilter::filterPixels(const SkBitmap& src, SkBitmap*
result, const SkIRect& rect) { | 124 void SkMatrixConvolutionImageFilter::filterPixels(const SkBitmap& src, |
| 125 SkBitmap* result, |
| 126 const SkIRect& rect, |
| 127 const SkIRect& bounds) { |
| 116 for (int y = rect.fTop; y < rect.fBottom; ++y) { | 128 for (int y = rect.fTop; y < rect.fBottom; ++y) { |
| 117 SkPMColor* dptr = result->getAddr32(rect.fLeft, y); | 129 SkPMColor* dptr = result->getAddr32(rect.fLeft - bounds.fLeft, y - bound
s.fTop); |
| 118 for (int x = rect.fLeft; x < rect.fRight; ++x) { | 130 for (int x = rect.fLeft; x < rect.fRight; ++x) { |
| 119 SkScalar sumA = 0, sumR = 0, sumG = 0, sumB = 0; | 131 SkScalar sumA = 0, sumR = 0, sumG = 0, sumB = 0; |
| 120 for (int cy = 0; cy < fKernelSize.fHeight; cy++) { | 132 for (int cy = 0; cy < fKernelSize.fHeight; cy++) { |
| 121 for (int cx = 0; cx < fKernelSize.fWidth; cx++) { | 133 for (int cx = 0; cx < fKernelSize.fWidth; cx++) { |
| 122 SkPMColor s = PixelFetcher::fetch(src, x + cx - fTarget.fX,
y + cy - fTarget.fY); | 134 SkPMColor s = PixelFetcher::fetch(src, |
| 135 x + cx - fTarget.fX, |
| 136 y + cy - fTarget.fY, |
| 137 bounds); |
| 123 SkScalar k = fKernel[cy * fKernelSize.fWidth + cx]; | 138 SkScalar k = fKernel[cy * fKernelSize.fWidth + cx]; |
| 124 if (convolveAlpha) { | 139 if (convolveAlpha) { |
| 125 sumA += SkScalarMul(SkIntToScalar(SkGetPackedA32(s)), k)
; | 140 sumA += SkScalarMul(SkIntToScalar(SkGetPackedA32(s)), k)
; |
| 126 } | 141 } |
| 127 sumR += SkScalarMul(SkIntToScalar(SkGetPackedR32(s)), k); | 142 sumR += SkScalarMul(SkIntToScalar(SkGetPackedR32(s)), k); |
| 128 sumG += SkScalarMul(SkIntToScalar(SkGetPackedG32(s)), k); | 143 sumG += SkScalarMul(SkIntToScalar(SkGetPackedG32(s)), k); |
| 129 sumB += SkScalarMul(SkIntToScalar(SkGetPackedB32(s)), k); | 144 sumB += SkScalarMul(SkIntToScalar(SkGetPackedB32(s)), k); |
| 130 } | 145 } |
| 131 } | 146 } |
| 132 int a = convolveAlpha | 147 int a = convolveAlpha |
| 133 ? SkClampMax(SkScalarFloorToInt(SkScalarMul(sumA, fGain) + fBi
as), 255) | 148 ? SkClampMax(SkScalarFloorToInt(SkScalarMul(sumA, fGain) + fBi
as), 255) |
| 134 : 255; | 149 : 255; |
| 135 int r = SkClampMax(SkScalarFloorToInt(SkScalarMul(sumR, fGain) + fBi
as), a); | 150 int r = SkClampMax(SkScalarFloorToInt(SkScalarMul(sumR, fGain) + fBi
as), a); |
| 136 int g = SkClampMax(SkScalarFloorToInt(SkScalarMul(sumG, fGain) + fBi
as), a); | 151 int g = SkClampMax(SkScalarFloorToInt(SkScalarMul(sumG, fGain) + fBi
as), a); |
| 137 int b = SkClampMax(SkScalarFloorToInt(SkScalarMul(sumB, fGain) + fBi
as), a); | 152 int b = SkClampMax(SkScalarFloorToInt(SkScalarMul(sumB, fGain) + fBi
as), a); |
| 138 if (!convolveAlpha) { | 153 if (!convolveAlpha) { |
| 139 a = SkGetPackedA32(PixelFetcher::fetch(src, x, y)); | 154 a = SkGetPackedA32(PixelFetcher::fetch(src, x, y, bounds)); |
| 140 *dptr++ = SkPreMultiplyARGB(a, r, g, b); | 155 *dptr++ = SkPreMultiplyARGB(a, r, g, b); |
| 141 } else { | 156 } else { |
| 142 *dptr++ = SkPackARGB32(a, r, g, b); | 157 *dptr++ = SkPackARGB32(a, r, g, b); |
| 143 } | 158 } |
| 144 } | 159 } |
| 145 } | 160 } |
| 146 } | 161 } |
| 147 | 162 |
| 148 template<class PixelFetcher> | 163 template<class PixelFetcher> |
| 149 void SkMatrixConvolutionImageFilter::filterPixels(const SkBitmap& src, SkBitmap*
result, const SkIRect& rect) { | 164 void SkMatrixConvolutionImageFilter::filterPixels(const SkBitmap& src, |
| 165 SkBitmap* result, |
| 166 const SkIRect& rect, |
| 167 const SkIRect& bounds) { |
| 150 if (fConvolveAlpha) { | 168 if (fConvolveAlpha) { |
| 151 filterPixels<PixelFetcher, true>(src, result, rect); | 169 filterPixels<PixelFetcher, true>(src, result, rect, bounds); |
| 152 } else { | 170 } else { |
| 153 filterPixels<PixelFetcher, false>(src, result, rect); | 171 filterPixels<PixelFetcher, false>(src, result, rect, bounds); |
| 154 } | 172 } |
| 155 } | 173 } |
| 156 | 174 |
| 157 void SkMatrixConvolutionImageFilter::filterInteriorPixels(const SkBitmap& src, S
kBitmap* result, const SkIRect& rect) { | 175 void SkMatrixConvolutionImageFilter::filterInteriorPixels(const SkBitmap& src, |
| 158 filterPixels<UncheckedPixelFetcher>(src, result, rect); | 176 SkBitmap* result, |
| 177 const SkIRect& rect, |
| 178 const SkIRect& bounds)
{ |
| 179 filterPixels<UncheckedPixelFetcher>(src, result, rect, bounds); |
| 159 } | 180 } |
| 160 | 181 |
| 161 void SkMatrixConvolutionImageFilter::filterBorderPixels(const SkBitmap& src, SkB
itmap* result, const SkIRect& rect) { | 182 void SkMatrixConvolutionImageFilter::filterBorderPixels(const SkBitmap& src, |
| 183 SkBitmap* result, |
| 184 const SkIRect& rect, |
| 185 const SkIRect& bounds) { |
| 162 switch (fTileMode) { | 186 switch (fTileMode) { |
| 163 case kClamp_TileMode: | 187 case kClamp_TileMode: |
| 164 filterPixels<ClampPixelFetcher>(src, result, rect); | 188 filterPixels<ClampPixelFetcher>(src, result, rect, bounds); |
| 165 break; | 189 break; |
| 166 case kRepeat_TileMode: | 190 case kRepeat_TileMode: |
| 167 filterPixels<RepeatPixelFetcher>(src, result, rect); | 191 filterPixels<RepeatPixelFetcher>(src, result, rect, bounds); |
| 168 break; | 192 break; |
| 169 case kClampToBlack_TileMode: | 193 case kClampToBlack_TileMode: |
| 170 filterPixels<ClampToBlackPixelFetcher>(src, result, rect); | 194 filterPixels<ClampToBlackPixelFetcher>(src, result, rect, bounds); |
| 171 break; | 195 break; |
| 172 } | 196 } |
| 173 } | 197 } |
| 174 | 198 |
| 175 // FIXME: This should be refactored to SkImageFilterUtils for | 199 // FIXME: This should be refactored to SkImageFilterUtils for |
| 176 // use by other filters. For now, we assume the input is always | 200 // use by other filters. For now, we assume the input is always |
| 177 // premultiplied and unpremultiply it | 201 // premultiplied and unpremultiply it |
| 178 static SkBitmap unpremultiplyBitmap(const SkBitmap& src) | 202 static SkBitmap unpremultiplyBitmap(const SkBitmap& src) |
| 179 { | 203 { |
| 180 SkAutoLockPixels alp(src); | 204 SkAutoLockPixels alp(src); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 204 SkIPoint* loc) { | 228 SkIPoint* loc) { |
| 205 SkBitmap src = source; | 229 SkBitmap src = source; |
| 206 if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, lo
c)) { | 230 if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, lo
c)) { |
| 207 return false; | 231 return false; |
| 208 } | 232 } |
| 209 | 233 |
| 210 if (src.config() != SkBitmap::kARGB_8888_Config) { | 234 if (src.config() != SkBitmap::kARGB_8888_Config) { |
| 211 return false; | 235 return false; |
| 212 } | 236 } |
| 213 | 237 |
| 238 SkIRect bounds; |
| 239 src.getBounds(&bounds); |
| 240 if (!this->applyCropRect(&bounds, matrix)) { |
| 241 return false; |
| 242 } |
| 243 |
| 214 if (!fConvolveAlpha && !src.isOpaque()) { | 244 if (!fConvolveAlpha && !src.isOpaque()) { |
| 215 src = unpremultiplyBitmap(src); | 245 src = unpremultiplyBitmap(src); |
| 216 } | 246 } |
| 217 | 247 |
| 218 SkAutoLockPixels alp(src); | 248 SkAutoLockPixels alp(src); |
| 219 if (!src.getPixels()) { | 249 if (!src.getPixels()) { |
| 220 return false; | 250 return false; |
| 221 } | 251 } |
| 222 | 252 |
| 223 result->setConfig(src.config(), src.width(), src.height()); | 253 result->setConfig(src.config(), bounds.width(), bounds.height()); |
| 224 result->allocPixels(); | 254 result->allocPixels(); |
| 225 | 255 |
| 226 SkIRect interior = SkIRect::MakeXYWH(fTarget.fX, fTarget.fY, | 256 SkIRect interior = SkIRect::MakeXYWH(bounds.left() + fTarget.fX, |
| 227 src.width() - fKernelSize.fWidth + 1, | 257 bounds.top() + fTarget.fY, |
| 228 src.height() - fKernelSize.fHeight + 1)
; | 258 bounds.width() - fKernelSize.fWidth + 1
, |
| 229 SkIRect top = SkIRect::MakeWH(src.width(), fTarget.fY); | 259 bounds.height() - fKernelSize.fHeight +
1); |
| 230 SkIRect bottom = SkIRect::MakeLTRB(0, interior.bottom(), | 260 SkIRect top = SkIRect::MakeLTRB(bounds.left(), bounds.top(), bounds.right(),
interior.top()); |
| 231 src.width(), src.height()); | 261 SkIRect bottom = SkIRect::MakeLTRB(bounds.left(), interior.bottom(), |
| 232 SkIRect left = SkIRect::MakeXYWH(0, interior.top(), | 262 bounds.right(), bounds.bottom()); |
| 233 fTarget.fX, interior.height()); | 263 SkIRect left = SkIRect::MakeLTRB(bounds.left(), interior.top(), |
| 264 interior.left(), interior.bottom()); |
| 234 SkIRect right = SkIRect::MakeLTRB(interior.right(), interior.top(), | 265 SkIRect right = SkIRect::MakeLTRB(interior.right(), interior.top(), |
| 235 src.width(), interior.bottom()); | 266 bounds.right(), interior.bottom()); |
| 236 filterBorderPixels(src, result, top); | 267 filterBorderPixels(src, result, top, bounds); |
| 237 filterBorderPixels(src, result, left); | 268 filterBorderPixels(src, result, left, bounds); |
| 238 filterInteriorPixels(src, result, interior); | 269 filterInteriorPixels(src, result, interior, bounds); |
| 239 filterBorderPixels(src, result, right); | 270 filterBorderPixels(src, result, right, bounds); |
| 240 filterBorderPixels(src, result, bottom); | 271 filterBorderPixels(src, result, bottom, bounds); |
| 272 loc->fX += bounds.fLeft; |
| 273 loc->fY += bounds.fTop; |
| 241 return true; | 274 return true; |
| 242 } | 275 } |
| 243 | 276 |
| 244 #if SK_SUPPORT_GPU | 277 #if SK_SUPPORT_GPU |
| 245 | 278 |
| 246 /////////////////////////////////////////////////////////////////////////////// | 279 /////////////////////////////////////////////////////////////////////////////// |
| 247 | 280 |
| 248 class GrGLMatrixConvolutionEffect; | 281 class GrGLMatrixConvolutionEffect; |
| 249 | 282 |
| 250 class GrMatrixConvolutionEffect : public GrSingleTextureEffect { | 283 class GrMatrixConvolutionEffect : public GrSingleTextureEffect { |
| 251 public: | 284 public: |
| 252 typedef SkMatrixConvolutionImageFilter::TileMode TileMode; | 285 typedef SkMatrixConvolutionImageFilter::TileMode TileMode; |
| 253 static GrEffectRef* Create(GrTexture* texture, | 286 static GrEffectRef* Create(GrTexture* texture, |
| 287 const SkIRect& bounds, |
| 254 const SkISize& kernelSize, | 288 const SkISize& kernelSize, |
| 255 const SkScalar* kernel, | 289 const SkScalar* kernel, |
| 256 SkScalar gain, | 290 SkScalar gain, |
| 257 SkScalar bias, | 291 SkScalar bias, |
| 258 const SkIPoint& target, | 292 const SkIPoint& target, |
| 259 TileMode tileMode, | 293 TileMode tileMode, |
| 260 bool convolveAlpha) { | 294 bool convolveAlpha) { |
| 261 AutoEffectUnref effect(SkNEW_ARGS(GrMatrixConvolutionEffect, (texture, | 295 AutoEffectUnref effect(SkNEW_ARGS(GrMatrixConvolutionEffect, (texture, |
| 296 bounds, |
| 262 kernelSize
, | 297 kernelSize
, |
| 263 kernel, | 298 kernel, |
| 264 gain, | 299 gain, |
| 265 bias, | 300 bias, |
| 266 target, | 301 target, |
| 267 tileMode, | 302 tileMode, |
| 268 convolveAl
pha))); | 303 convolveAl
pha))); |
| 269 return CreateEffectRef(effect); | 304 return CreateEffectRef(effect); |
| 270 } | 305 } |
| 271 virtual ~GrMatrixConvolutionEffect(); | 306 virtual ~GrMatrixConvolutionEffect(); |
| 272 | 307 |
| 273 virtual void getConstantColorComponents(GrColor* color, | 308 virtual void getConstantColorComponents(GrColor* color, |
| 274 uint32_t* validFlags) const SK_OVERR
IDE { | 309 uint32_t* validFlags) const SK_OVERR
IDE { |
| 275 // TODO: Try to do better? | 310 // TODO: Try to do better? |
| 276 *validFlags = 0; | 311 *validFlags = 0; |
| 277 } | 312 } |
| 278 | 313 |
| 279 static const char* Name() { return "MatrixConvolution"; } | 314 static const char* Name() { return "MatrixConvolution"; } |
| 315 const SkIRect& bounds() const { return fBounds; } |
| 280 const SkISize& kernelSize() const { return fKernelSize; } | 316 const SkISize& kernelSize() const { return fKernelSize; } |
| 281 const float* target() const { return fTarget; } | 317 const float* target() const { return fTarget; } |
| 282 const float* kernel() const { return fKernel; } | 318 const float* kernel() const { return fKernel; } |
| 283 float gain() const { return fGain; } | 319 float gain() const { return fGain; } |
| 284 float bias() const { return fBias; } | 320 float bias() const { return fBias; } |
| 285 TileMode tileMode() const { return fTileMode; } | 321 TileMode tileMode() const { return fTileMode; } |
| 286 bool convolveAlpha() const { return fConvolveAlpha; } | 322 bool convolveAlpha() const { return fConvolveAlpha; } |
| 287 | 323 |
| 288 typedef GrGLMatrixConvolutionEffect GLEffect; | 324 typedef GrGLMatrixConvolutionEffect GLEffect; |
| 289 | 325 |
| 290 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 326 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
| 291 | 327 |
| 292 private: | 328 private: |
| 293 GrMatrixConvolutionEffect(GrTexture*, | 329 GrMatrixConvolutionEffect(GrTexture*, |
| 330 const SkIRect& bounds, |
| 294 const SkISize& kernelSize, | 331 const SkISize& kernelSize, |
| 295 const SkScalar* kernel, | 332 const SkScalar* kernel, |
| 296 SkScalar gain, | 333 SkScalar gain, |
| 297 SkScalar bias, | 334 SkScalar bias, |
| 298 const SkIPoint& target, | 335 const SkIPoint& target, |
| 299 TileMode tileMode, | 336 TileMode tileMode, |
| 300 bool convolveAlpha); | 337 bool convolveAlpha); |
| 301 | 338 |
| 302 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | 339 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
| 303 | 340 |
| 341 SkIRect fBounds; |
| 304 SkISize fKernelSize; | 342 SkISize fKernelSize; |
| 305 float *fKernel; | 343 float *fKernel; |
| 306 float fGain; | 344 float fGain; |
| 307 float fBias; | 345 float fBias; |
| 308 float fTarget[2]; | 346 float fTarget[2]; |
| 309 TileMode fTileMode; | 347 TileMode fTileMode; |
| 310 bool fConvolveAlpha; | 348 bool fConvolveAlpha; |
| 311 | 349 |
| 312 GR_DECLARE_EFFECT_TEST; | 350 GR_DECLARE_EFFECT_TEST; |
| 313 | 351 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 330 | 368 |
| 331 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; | 369 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; |
| 332 | 370 |
| 333 private: | 371 private: |
| 334 typedef GrGLUniformManager::UniformHandle UniformHandle; | 372 typedef GrGLUniformManager::UniformHandle UniformHandle; |
| 335 typedef SkMatrixConvolutionImageFilter::TileMode TileMode; | 373 typedef SkMatrixConvolutionImageFilter::TileMode TileMode; |
| 336 SkISize fKernelSize; | 374 SkISize fKernelSize; |
| 337 TileMode fTileMode; | 375 TileMode fTileMode; |
| 338 bool fConvolveAlpha; | 376 bool fConvolveAlpha; |
| 339 | 377 |
| 378 UniformHandle fBoundsUni; |
| 340 UniformHandle fKernelUni; | 379 UniformHandle fKernelUni; |
| 341 UniformHandle fImageIncrementUni; | 380 UniformHandle fImageIncrementUni; |
| 342 UniformHandle fTargetUni; | 381 UniformHandle fTargetUni; |
| 343 UniformHandle fGainUni; | 382 UniformHandle fGainUni; |
| 344 UniformHandle fBiasUni; | 383 UniformHandle fBiasUni; |
| 345 | 384 |
| 346 typedef GrGLEffect INHERITED; | 385 typedef GrGLEffect INHERITED; |
| 347 }; | 386 }; |
| 348 | 387 |
| 349 GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFa
ctory& factory, | 388 GrGLMatrixConvolutionEffect::GrGLMatrixConvolutionEffect(const GrBackendEffectFa
ctory& factory, |
| 350 const GrDrawEffect& dra
wEffect) | 389 const GrDrawEffect& dra
wEffect) |
| 351 : INHERITED(factory) { | 390 : INHERITED(factory) { |
| 352 const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvoluti
onEffect>(); | 391 const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvoluti
onEffect>(); |
| 353 fKernelSize = m.kernelSize(); | 392 fKernelSize = m.kernelSize(); |
| 354 fTileMode = m.tileMode(); | 393 fTileMode = m.tileMode(); |
| 355 fConvolveAlpha = m.convolveAlpha(); | 394 fConvolveAlpha = m.convolveAlpha(); |
| 356 } | 395 } |
| 357 | 396 |
| 358 static void appendTextureLookup(GrGLShaderBuilder* builder, | 397 static void appendTextureLookup(GrGLShaderBuilder* builder, |
| 359 const GrGLShaderBuilder::TextureSampler& sampler
, | 398 const GrGLShaderBuilder::TextureSampler& sampler
, |
| 360 const char* coord, | 399 const char* coord, |
| 400 const char* bounds, |
| 361 SkMatrixConvolutionImageFilter::TileMode tileMod
e) { | 401 SkMatrixConvolutionImageFilter::TileMode tileMod
e) { |
| 362 SkString clampedCoord; | 402 SkString clampedCoord; |
| 363 switch (tileMode) { | 403 switch (tileMode) { |
| 364 case SkMatrixConvolutionImageFilter::kClamp_TileMode: | 404 case SkMatrixConvolutionImageFilter::kClamp_TileMode: |
| 365 clampedCoord.printf("clamp(%s, 0.0, 1.0)", coord); | 405 clampedCoord.printf("clamp(%s, %s.xy, %s.zw)", coord, bounds, bounds
); |
| 366 coord = clampedCoord.c_str(); | 406 coord = clampedCoord.c_str(); |
| 367 break; | 407 break; |
| 368 case SkMatrixConvolutionImageFilter::kRepeat_TileMode: | 408 case SkMatrixConvolutionImageFilter::kRepeat_TileMode: |
| 369 clampedCoord.printf("fract(%s)", coord); | 409 clampedCoord.printf("mod(%s - %s.xy, %s.zw - %s.xy) + %s.xy", coord,
bounds, bounds, bounds, bounds); |
| 370 coord = clampedCoord.c_str(); | 410 coord = clampedCoord.c_str(); |
| 371 break; | 411 break; |
| 372 case SkMatrixConvolutionImageFilter::kClampToBlack_TileMode: | 412 case SkMatrixConvolutionImageFilter::kClampToBlack_TileMode: |
| 373 builder->fsCodeAppendf("clamp(%s, 0.0, 1.0) != %s ? vec4(0, 0, 0, 0)
: ", coord, coord); | 413 builder->fsCodeAppendf("clamp(%s, %s.xy, %s.zw) != %s ? vec4(0, 0, 0
, 0) : ", coord, bounds, bounds, coord); |
| 374 break; | 414 break; |
| 375 } | 415 } |
| 376 builder->fsAppendTextureLookup(sampler, coord); | 416 builder->fsAppendTextureLookup(sampler, coord); |
| 377 } | 417 } |
| 378 | 418 |
| 379 void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder, | 419 void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder, |
| 380 const GrDrawEffect&, | 420 const GrDrawEffect&, |
| 381 EffectKey key, | 421 EffectKey key, |
| 382 const char* outputColor, | 422 const char* outputColor, |
| 383 const char* inputColor, | 423 const char* inputColor, |
| 384 const TransformedCoordsArray& coords, | 424 const TransformedCoordsArray& coords, |
| 385 const TextureSamplerArray& samplers)
{ | 425 const TextureSamplerArray& samplers)
{ |
| 386 SkString coords2D = builder->ensureFSCoords2D(coords, 0); | 426 SkString coords2D = builder->ensureFSCoords2D(coords, 0); |
| 427 fBoundsUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
| 428 kVec4f_GrSLType, "Bounds"); |
| 387 fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibi
lity, | 429 fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibi
lity, |
| 388 kVec2f_GrSLType, "ImageIncrement"); | 430 kVec2f_GrSLType, "ImageIncrement"); |
| 389 fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibilit
y, | 431 fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibilit
y, |
| 390 kFloat_GrSLType, "Kernel", fKernelS
ize.width() * fKernelSize.height()); | 432 kFloat_GrSLType, |
| 433 "Kernel", |
| 434 fKernelSize.width() * fKernelSize.h
eight()); |
| 391 fTargetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | 435 fTargetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
| 392 kVec2f_GrSLType, "Target"); | 436 kVec2f_GrSLType, "Target"); |
| 393 fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | 437 fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
| 394 kFloat_GrSLType, "Gain"); | 438 kFloat_GrSLType, "Gain"); |
| 395 fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | 439 fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
| 396 kFloat_GrSLType, "Bias"); | 440 kFloat_GrSLType, "Bias"); |
| 397 | 441 |
| 442 const char* bounds = builder->getUniformCStr(fBoundsUni); |
| 398 const char* target = builder->getUniformCStr(fTargetUni); | 443 const char* target = builder->getUniformCStr(fTargetUni); |
| 399 const char* imgInc = builder->getUniformCStr(fImageIncrementUni); | 444 const char* imgInc = builder->getUniformCStr(fImageIncrementUni); |
| 400 const char* kernel = builder->getUniformCStr(fKernelUni); | 445 const char* kernel = builder->getUniformCStr(fKernelUni); |
| 401 const char* gain = builder->getUniformCStr(fGainUni); | 446 const char* gain = builder->getUniformCStr(fGainUni); |
| 402 const char* bias = builder->getUniformCStr(fBiasUni); | 447 const char* bias = builder->getUniformCStr(fBiasUni); |
| 403 int kWidth = fKernelSize.width(); | 448 int kWidth = fKernelSize.width(); |
| 404 int kHeight = fKernelSize.height(); | 449 int kHeight = fKernelSize.height(); |
| 405 | 450 |
| 406 builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n"); | 451 builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n"); |
| 407 builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(),
target, imgInc); | 452 builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(),
target, imgInc); |
| 408 builder->fsCodeAppendf("\t\tfor (int y = 0; y < %d; y++) {\n", kHeight); | 453 builder->fsCodeAppendf("\t\tfor (int y = 0; y < %d; y++) {\n", kHeight); |
| 409 builder->fsCodeAppendf("\t\t\tfor (int x = 0; x < %d; x++) {\n", kWidth); | 454 builder->fsCodeAppendf("\t\t\tfor (int x = 0; x < %d; x++) {\n", kWidth); |
| 410 builder->fsCodeAppendf("\t\t\t\tfloat k = %s[y * %d + x];\n", kernel, kWidth
); | 455 builder->fsCodeAppendf("\t\t\t\tfloat k = %s[y * %d + x];\n", kernel, kWidth
); |
| 411 builder->fsCodeAppendf("\t\t\t\tvec2 coord2 = coord + vec2(x, y) * %s;\n", i
mgInc); | 456 builder->fsCodeAppendf("\t\t\t\tvec2 coord2 = coord + vec2(x, y) * %s;\n", i
mgInc); |
| 412 builder->fsCodeAppend("\t\t\t\tvec4 c = "); | 457 builder->fsCodeAppend("\t\t\t\tvec4 c = "); |
| 413 appendTextureLookup(builder, samplers[0], "coord2", fTileMode); | 458 appendTextureLookup(builder, samplers[0], "coord2", bounds, fTileMode); |
| 414 builder->fsCodeAppend(";\n"); | 459 builder->fsCodeAppend(";\n"); |
| 415 if (!fConvolveAlpha) { | 460 if (!fConvolveAlpha) { |
| 416 builder->fsCodeAppend("\t\t\t\tc.rgb /= c.a;\n"); | 461 builder->fsCodeAppend("\t\t\t\tc.rgb /= c.a;\n"); |
| 417 } | 462 } |
| 418 builder->fsCodeAppend("\t\t\t\tsum += c * k;\n"); | 463 builder->fsCodeAppend("\t\t\t\tsum += c * k;\n"); |
| 419 builder->fsCodeAppend("\t\t\t}\n"); | 464 builder->fsCodeAppend("\t\t\t}\n"); |
| 420 builder->fsCodeAppend("\t\t}\n"); | 465 builder->fsCodeAppend("\t\t}\n"); |
| 421 if (fConvolveAlpha) { | 466 if (fConvolveAlpha) { |
| 422 builder->fsCodeAppendf("\t\t%s = sum * %s + %s;\n", outputColor, gain, b
ias); | 467 builder->fsCodeAppendf("\t\t%s = sum * %s + %s;\n", outputColor, gain, b
ias); |
| 423 builder->fsCodeAppendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n", outpu
tColor, outputColor, outputColor); | 468 builder->fsCodeAppendf("\t\t%s.rgb = clamp(%s.rgb, 0.0, %s.a);\n", |
| 469 outputColor, outputColor, outputColor); |
| 424 } else { | 470 } else { |
| 425 builder->fsCodeAppend("\t\tvec4 c = "); | 471 builder->fsCodeAppend("\t\tvec4 c = "); |
| 426 appendTextureLookup(builder, samplers[0], coords2D.c_str(), fTileMode); | 472 appendTextureLookup(builder, samplers[0], coords2D.c_str(), bounds, fTil
eMode); |
| 427 builder->fsCodeAppend(";\n"); | 473 builder->fsCodeAppend(";\n"); |
| 428 builder->fsCodeAppendf("\t\t%s.a = c.a;\n", outputColor); | 474 builder->fsCodeAppendf("\t\t%s.a = c.a;\n", outputColor); |
| 429 builder->fsCodeAppendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor,
gain, bias); | 475 builder->fsCodeAppendf("\t\t%s.rgb = sum.rgb * %s + %s;\n", outputColor,
gain, bias); |
| 430 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor
); | 476 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor
); |
| 431 } | 477 } |
| 432 } | 478 } |
| 433 | 479 |
| 434 namespace { | 480 namespace { |
| 435 | 481 |
| 436 int encodeXY(int x, int y) { | 482 int encodeXY(int x, int y) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 461 SkASSERT(conv.tileMode() == fTileMode); | 507 SkASSERT(conv.tileMode() == fTileMode); |
| 462 float imageIncrement[2]; | 508 float imageIncrement[2]; |
| 463 float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f; | 509 float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f; |
| 464 imageIncrement[0] = 1.0f / texture.width(); | 510 imageIncrement[0] = 1.0f / texture.width(); |
| 465 imageIncrement[1] = ySign / texture.height(); | 511 imageIncrement[1] = ySign / texture.height(); |
| 466 uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement); | 512 uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement); |
| 467 uman.set2fv(fTargetUni, 0, 1, conv.target()); | 513 uman.set2fv(fTargetUni, 0, 1, conv.target()); |
| 468 uman.set1fv(fKernelUni, 0, fKernelSize.width() * fKernelSize.height(), conv.
kernel()); | 514 uman.set1fv(fKernelUni, 0, fKernelSize.width() * fKernelSize.height(), conv.
kernel()); |
| 469 uman.set1f(fGainUni, conv.gain()); | 515 uman.set1f(fGainUni, conv.gain()); |
| 470 uman.set1f(fBiasUni, conv.bias()); | 516 uman.set1f(fBiasUni, conv.bias()); |
| 517 const SkIRect& bounds = conv.bounds(); |
| 518 uman.set4f(fBoundsUni, |
| 519 (float) bounds.left() / texture.width(), |
| 520 (float) bounds.top() / texture.height(), |
| 521 (float) bounds.right() / texture.width(), |
| 522 (float) bounds.bottom() / texture.height()); |
| 471 } | 523 } |
| 472 | 524 |
| 473 GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, | 525 GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, |
| 526 const SkIRect& bounds, |
| 474 const SkISize& kernelSize, | 527 const SkISize& kernelSize, |
| 475 const SkScalar* kernel, | 528 const SkScalar* kernel, |
| 476 SkScalar gain, | 529 SkScalar gain, |
| 477 SkScalar bias, | 530 SkScalar bias, |
| 478 const SkIPoint& target, | 531 const SkIPoint& target, |
| 479 TileMode tileMode, | 532 TileMode tileMode, |
| 480 bool convolveAlpha) | 533 bool convolveAlpha) |
| 481 : INHERITED(texture, MakeDivByTextureWHMatrix(texture)), | 534 : INHERITED(texture, MakeDivByTextureWHMatrix(texture)), |
| 535 fBounds(bounds), |
| 482 fKernelSize(kernelSize), | 536 fKernelSize(kernelSize), |
| 483 fGain(SkScalarToFloat(gain)), | 537 fGain(SkScalarToFloat(gain)), |
| 484 fBias(SkScalarToFloat(bias) / 255.0f), | 538 fBias(SkScalarToFloat(bias) / 255.0f), |
| 485 fTileMode(tileMode), | 539 fTileMode(tileMode), |
| 486 fConvolveAlpha(convolveAlpha) { | 540 fConvolveAlpha(convolveAlpha) { |
| 487 fKernel = new float[kernelSize.width() * kernelSize.height()]; | 541 fKernel = new float[kernelSize.width() * kernelSize.height()]; |
| 488 for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) { | 542 for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) { |
| 489 fKernel[i] = SkScalarToFloat(kernel[i]); | 543 fKernel[i] = SkScalarToFloat(kernel[i]); |
| 490 } | 544 } |
| 491 fTarget[0] = static_cast<float>(target.x()); | 545 fTarget[0] = static_cast<float>(target.x()); |
| 492 fTarget[1] = static_cast<float>(target.y()); | 546 fTarget[1] = static_cast<float>(target.y()); |
| 493 } | 547 } |
| 494 | 548 |
| 495 GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() { | 549 GrMatrixConvolutionEffect::~GrMatrixConvolutionEffect() { |
| 496 delete[] fKernel; | 550 delete[] fKernel; |
| 497 } | 551 } |
| 498 | 552 |
| 499 const GrBackendEffectFactory& GrMatrixConvolutionEffect::getFactory() const { | 553 const GrBackendEffectFactory& GrMatrixConvolutionEffect::getFactory() const { |
| 500 return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance(); | 554 return GrTBackendEffectFactory<GrMatrixConvolutionEffect>::getInstance(); |
| 501 } | 555 } |
| 502 | 556 |
| 503 bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const { | 557 bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const { |
| 504 const GrMatrixConvolutionEffect& s = CastEffect<GrMatrixConvolutionEffect>(s
Base); | 558 const GrMatrixConvolutionEffect& s = CastEffect<GrMatrixConvolutionEffect>(s
Base); |
| 505 return this->texture(0) == s.texture(0) && | 559 return this->texture(0) == s.texture(0) && |
| 506 fKernelSize == s.kernelSize() && | 560 fKernelSize == s.kernelSize() && |
| 507 !memcmp(fKernel, s.kernel(), fKernelSize.width() * fKernelSize.height
() * sizeof(float)) && | 561 !memcmp(fKernel, s.kernel(), |
| 562 fKernelSize.width() * fKernelSize.height() * sizeof(float)) &
& |
| 508 fGain == s.gain() && | 563 fGain == s.gain() && |
| 509 fBias == s.bias() && | 564 fBias == s.bias() && |
| 510 fTarget == s.target() && | 565 fTarget == s.target() && |
| 511 fTileMode == s.tileMode() && | 566 fTileMode == s.tileMode() && |
| 512 fConvolveAlpha == s.convolveAlpha(); | 567 fConvolveAlpha == s.convolveAlpha(); |
| 513 } | 568 } |
| 514 | 569 |
| 515 GR_DEFINE_EFFECT_TEST(GrMatrixConvolutionEffect); | 570 GR_DEFINE_EFFECT_TEST(GrMatrixConvolutionEffect); |
| 516 | 571 |
| 517 // A little bit less than the minimum # uniforms required by DX9SM2 (32). | 572 // A little bit less than the minimum # uniforms required by DX9SM2 (32). |
| (...skipping 10 matching lines...) Expand all Loading... |
| 528 int height = random->nextRangeU(1, MAX_KERNEL_SIZE / width); | 583 int height = random->nextRangeU(1, MAX_KERNEL_SIZE / width); |
| 529 SkISize kernelSize = SkISize::Make(width, height); | 584 SkISize kernelSize = SkISize::Make(width, height); |
| 530 SkAutoTDeleteArray<SkScalar> kernel(new SkScalar[width * height]); | 585 SkAutoTDeleteArray<SkScalar> kernel(new SkScalar[width * height]); |
| 531 for (int i = 0; i < width * height; i++) { | 586 for (int i = 0; i < width * height; i++) { |
| 532 kernel.get()[i] = random->nextSScalar1(); | 587 kernel.get()[i] = random->nextSScalar1(); |
| 533 } | 588 } |
| 534 SkScalar gain = random->nextSScalar1(); | 589 SkScalar gain = random->nextSScalar1(); |
| 535 SkScalar bias = random->nextSScalar1(); | 590 SkScalar bias = random->nextSScalar1(); |
| 536 SkIPoint target = SkIPoint::Make(random->nextRangeU(0, kernelSize.width()), | 591 SkIPoint target = SkIPoint::Make(random->nextRangeU(0, kernelSize.width()), |
| 537 random->nextRangeU(0, kernelSize.height()))
; | 592 random->nextRangeU(0, kernelSize.height()))
; |
| 593 SkIRect bounds = SkIRect::MakeXYWH(random->nextRangeU(0, textures[texIdx]->w
idth()), |
| 594 random->nextRangeU(0, textures[texIdx]->h
eight()), |
| 595 random->nextRangeU(0, textures[texIdx]->w
idth()), |
| 596 random->nextRangeU(0, textures[texIdx]->h
eight())); |
| 538 TileMode tileMode = static_cast<TileMode>(random->nextRangeU(0, 2)); | 597 TileMode tileMode = static_cast<TileMode>(random->nextRangeU(0, 2)); |
| 539 bool convolveAlpha = random->nextBool(); | 598 bool convolveAlpha = random->nextBool(); |
| 540 return GrMatrixConvolutionEffect::Create(textures[texIdx], | 599 return GrMatrixConvolutionEffect::Create(textures[texIdx], |
| 600 bounds, |
| 541 kernelSize, | 601 kernelSize, |
| 542 kernel.get(), | 602 kernel.get(), |
| 543 gain, | 603 gain, |
| 544 bias, | 604 bias, |
| 545 target, | 605 target, |
| 546 tileMode, | 606 tileMode, |
| 547 convolveAlpha); | 607 convolveAlpha); |
| 548 } | 608 } |
| 549 | 609 |
| 550 bool SkMatrixConvolutionImageFilter::asNewEffect(GrEffectRef** effect, | 610 bool SkMatrixConvolutionImageFilter::asNewEffect(GrEffectRef** effect, |
| 551 GrTexture* texture, | 611 GrTexture* texture, |
| 552 const SkMatrix&) const { | 612 const SkMatrix&, |
| 613 const SkIRect& bounds |
| 614 ) const { |
| 553 if (!effect) { | 615 if (!effect) { |
| 554 return fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE; | 616 return fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE; |
| 555 } | 617 } |
| 556 SkASSERT(fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE); | 618 SkASSERT(fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE); |
| 557 *effect = GrMatrixConvolutionEffect::Create(texture, | 619 *effect = GrMatrixConvolutionEffect::Create(texture, |
| 620 bounds, |
| 558 fKernelSize, | 621 fKernelSize, |
| 559 fKernel, | 622 fKernel, |
| 560 fGain, | 623 fGain, |
| 561 fBias, | 624 fBias, |
| 562 fTarget, | 625 fTarget, |
| 563 fTileMode, | 626 fTileMode, |
| 564 fConvolveAlpha); | 627 fConvolveAlpha); |
| 565 return true; | 628 return true; |
| 566 } | 629 } |
| 567 | 630 |
| 568 /////////////////////////////////////////////////////////////////////////////// | 631 /////////////////////////////////////////////////////////////////////////////// |
| 569 | 632 |
| 570 #endif | 633 #endif |
| OLD | NEW |