| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 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 "SkGpuBlurUtils.h" | 8 #include "SkGpuBlurUtils.h" |
| 9 | 9 |
| 10 #include "SkRect.h" | 10 #include "SkRect.h" |
| 11 | 11 |
| 12 #if SK_SUPPORT_GPU | 12 #if SK_SUPPORT_GPU |
| 13 #include "effects/GrConvolutionEffect.h" | 13 #include "effects/GrConvolutionEffect.h" |
| 14 #include "effects/GrMatrixConvolutionEffect.h" | 14 #include "effects/GrMatrixConvolutionEffect.h" |
| 15 #include "GrContext.h" | 15 #include "GrContext.h" |
| 16 #include "GrDrawContext.h" |
| 16 #endif | 17 #endif |
| 17 | 18 |
| 18 namespace SkGpuBlurUtils { | 19 namespace SkGpuBlurUtils { |
| 19 | 20 |
| 20 #if SK_SUPPORT_GPU | 21 #if SK_SUPPORT_GPU |
| 21 | 22 |
| 22 #define MAX_BLUR_SIGMA 4.0f | 23 #define MAX_BLUR_SIGMA 4.0f |
| 23 | 24 |
| 24 static void scale_rect(SkRect* rect, float xScale, float yScale) { | 25 static void scale_rect(SkRect* rect, float xScale, float yScale) { |
| 25 rect->fLeft = SkScalarMul(rect->fLeft, xScale); | 26 rect->fLeft = SkScalarMul(rect->fLeft, xScale); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 36 if (*scaleFactor > maxTextureSize) { | 37 if (*scaleFactor > maxTextureSize) { |
| 37 *scaleFactor = maxTextureSize; | 38 *scaleFactor = maxTextureSize; |
| 38 sigma = MAX_BLUR_SIGMA; | 39 sigma = MAX_BLUR_SIGMA; |
| 39 } | 40 } |
| 40 } | 41 } |
| 41 *radius = static_cast<int>(ceilf(sigma * 3.0f)); | 42 *radius = static_cast<int>(ceilf(sigma * 3.0f)); |
| 42 SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius); | 43 SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius); |
| 43 return sigma; | 44 return sigma; |
| 44 } | 45 } |
| 45 | 46 |
| 46 static void convolve_gaussian_1d(GrContext* context, | 47 static void convolve_gaussian_1d(GrDrawContext* drawContext, |
| 47 GrRenderTarget* rt, | 48 GrRenderTarget* rt, |
| 48 const GrClip& clip, | 49 const GrClip& clip, |
| 49 const SkRect& srcRect, | 50 const SkRect& srcRect, |
| 50 const SkRect& dstRect, | 51 const SkRect& dstRect, |
| 51 GrTexture* texture, | 52 GrTexture* texture, |
| 52 Gr1DKernelEffect::Direction direction, | 53 Gr1DKernelEffect::Direction direction, |
| 53 int radius, | 54 int radius, |
| 54 float sigma, | 55 float sigma, |
| 55 bool useBounds, | 56 bool useBounds, |
| 56 float bounds[2]) { | 57 float bounds[2]) { |
| 57 GrPaint paint; | 58 GrPaint paint; |
| 58 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian( | 59 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian( |
| 59 texture, direction, radius, sigma, useBounds, bounds)); | 60 texture, direction, radius, sigma, useBounds, bounds)); |
| 60 paint.addColorProcessor(conv); | 61 paint.addColorProcessor(conv); |
| 61 context->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, srcRec
t); | 62 drawContext->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, sr
cRect); |
| 62 } | 63 } |
| 63 | 64 |
| 64 static void convolve_gaussian_2d(GrContext* context, | 65 static void convolve_gaussian_2d(GrDrawContext* drawContext, |
| 65 GrRenderTarget* rt, | 66 GrRenderTarget* rt, |
| 66 const GrClip& clip, | 67 const GrClip& clip, |
| 67 const SkRect& srcRect, | 68 const SkRect& srcRect, |
| 68 const SkRect& dstRect, | 69 const SkRect& dstRect, |
| 69 GrTexture* texture, | 70 GrTexture* texture, |
| 70 int radiusX, | 71 int radiusX, |
| 71 int radiusY, | 72 int radiusY, |
| 72 SkScalar sigmaX, | 73 SkScalar sigmaX, |
| 73 SkScalar sigmaY, | 74 SkScalar sigmaY, |
| 74 bool useBounds, | 75 bool useBounds, |
| 75 SkIRect bounds) { | 76 SkIRect bounds) { |
| 76 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); | 77 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); |
| 77 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); | 78 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); |
| 78 GrPaint paint; | 79 GrPaint paint; |
| 79 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus
sian( | 80 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus
sian( |
| 80 texture, bounds, size, 1.0, 0.0, kernelOffset, | 81 texture, bounds, size, 1.0, 0.0, kernelOffset, |
| 81 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_
Mode, | 82 useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_
Mode, |
| 82 true, sigmaX, sigmaY)); | 83 true, sigmaX, sigmaY)); |
| 83 paint.addColorProcessor(conv); | 84 paint.addColorProcessor(conv); |
| 84 context->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, srcRec
t); | 85 drawContext->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, sr
cRect); |
| 85 } | 86 } |
| 86 | 87 |
| 87 static void convolve_gaussian(GrContext* context, | 88 static void convolve_gaussian(GrDrawContext* drawContext, |
| 88 GrRenderTarget* rt, | 89 GrRenderTarget* rt, |
| 89 const GrClip& clip, | 90 const GrClip& clip, |
| 90 const SkRect& srcRect, | 91 const SkRect& srcRect, |
| 91 const SkRect& dstRect, | 92 const SkRect& dstRect, |
| 92 GrTexture* texture, | 93 GrTexture* texture, |
| 93 Gr1DKernelEffect::Direction direction, | 94 Gr1DKernelEffect::Direction direction, |
| 94 int radius, | 95 int radius, |
| 95 float sigma, | 96 float sigma, |
| 96 bool cropToSrcRect) { | 97 bool cropToSrcRect) { |
| 97 float bounds[2] = { 0.0f, 1.0f }; | 98 float bounds[2] = { 0.0f, 1.0f }; |
| 98 if (!cropToSrcRect) { | 99 if (!cropToSrcRect) { |
| 99 convolve_gaussian_1d(context, rt, clip, srcRect, dstRect, texture, | 100 convolve_gaussian_1d(drawContext, rt, clip, srcRect, dstRect, texture, |
| 100 direction, radius, sigma, false, bounds); | 101 direction, radius, sigma, false, bounds); |
| 101 return; | 102 return; |
| 102 } | 103 } |
| 103 SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect; | 104 SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect; |
| 104 SkRect middleSrcRect = srcRect, middleDstRect = dstRect; | 105 SkRect middleSrcRect = srcRect, middleDstRect = dstRect; |
| 105 SkRect upperSrcRect = srcRect, upperDstRect = dstRect; | 106 SkRect upperSrcRect = srcRect, upperDstRect = dstRect; |
| 106 SkScalar size; | 107 SkScalar size; |
| 107 SkScalar rad = SkIntToScalar(radius); | 108 SkScalar rad = SkIntToScalar(radius); |
| 108 if (direction == Gr1DKernelEffect::kX_Direction) { | 109 if (direction == Gr1DKernelEffect::kX_Direction) { |
| 109 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width(); | 110 bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 121 size = srcRect.height(); | 122 size = srcRect.height(); |
| 122 lowerSrcRect.fBottom = srcRect.top() + rad; | 123 lowerSrcRect.fBottom = srcRect.top() + rad; |
| 123 lowerDstRect.fBottom = dstRect.top() + rad; | 124 lowerDstRect.fBottom = dstRect.top() + rad; |
| 124 upperSrcRect.fTop = srcRect.bottom() - rad; | 125 upperSrcRect.fTop = srcRect.bottom() - rad; |
| 125 upperDstRect.fTop = dstRect.bottom() - rad; | 126 upperDstRect.fTop = dstRect.bottom() - rad; |
| 126 middleSrcRect.inset(0, rad); | 127 middleSrcRect.inset(0, rad); |
| 127 middleDstRect.inset(0, rad); | 128 middleDstRect.inset(0, rad); |
| 128 } | 129 } |
| 129 if (radius >= size * SK_ScalarHalf) { | 130 if (radius >= size * SK_ScalarHalf) { |
| 130 // Blur radius covers srcRect; use bounds over entire draw | 131 // Blur radius covers srcRect; use bounds over entire draw |
| 131 convolve_gaussian_1d(context, rt, clip, srcRect, dstRect, texture, | 132 convolve_gaussian_1d(drawContext, rt, clip, srcRect, dstRect, texture, |
| 132 direction, radius, sigma, true, bounds); | 133 direction, radius, sigma, true, bounds); |
| 133 } else { | 134 } else { |
| 134 // Draw upper and lower margins with bounds; middle without. | 135 // Draw upper and lower margins with bounds; middle without. |
| 135 convolve_gaussian_1d(context, rt, clip, lowerSrcRect, lowerDstRect, text
ure, | 136 convolve_gaussian_1d(drawContext, rt, clip, lowerSrcRect, lowerDstRect,
texture, |
| 136 direction, radius, sigma, true, bounds); | 137 direction, radius, sigma, true, bounds); |
| 137 convolve_gaussian_1d(context, rt, clip, upperSrcRect, upperDstRect, text
ure, | 138 convolve_gaussian_1d(drawContext, rt, clip, upperSrcRect, upperDstRect,
texture, |
| 138 direction, radius, sigma, true, bounds); | 139 direction, radius, sigma, true, bounds); |
| 139 convolve_gaussian_1d(context, rt, clip, middleSrcRect, middleDstRect, te
xture, | 140 convolve_gaussian_1d(drawContext, rt, clip, middleSrcRect, middleDstRect
, texture, |
| 140 direction, radius, sigma, false, bounds); | 141 direction, radius, sigma, false, bounds); |
| 141 } | 142 } |
| 142 } | 143 } |
| 143 | 144 |
| 144 GrTexture* GaussianBlur(GrContext* context, | 145 GrTexture* GaussianBlur(GrContext* context, |
| 145 GrTexture* srcTexture, | 146 GrTexture* srcTexture, |
| 146 bool canClobberSrc, | 147 bool canClobberSrc, |
| 147 const SkRect& rect, | 148 const SkRect& rect, |
| 148 bool cropToRect, | 149 bool cropToRect, |
| 149 float sigmaX, | 150 float sigmaX, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 } else { | 189 } else { |
| 189 temp2.reset(context->textureProvider()->refScratchTexture( | 190 temp2.reset(context->textureProvider()->refScratchTexture( |
| 190 desc, GrTextureProvider::kApprox_ScratchTexMatch)); | 191 desc, GrTextureProvider::kApprox_ScratchTexMatch)); |
| 191 tempTexture = temp2.get(); | 192 tempTexture = temp2.get(); |
| 192 } | 193 } |
| 193 | 194 |
| 194 if (NULL == dstTexture || NULL == tempTexture) { | 195 if (NULL == dstTexture || NULL == tempTexture) { |
| 195 return NULL; | 196 return NULL; |
| 196 } | 197 } |
| 197 | 198 |
| 199 GrDrawContext* drawContext = context->drawContext(); |
| 200 if (!drawContext) { |
| 201 return NULL; |
| 202 } |
| 203 |
| 198 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { | 204 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { |
| 199 GrPaint paint; | 205 GrPaint paint; |
| 200 SkMatrix matrix; | 206 SkMatrix matrix; |
| 201 matrix.setIDiv(srcTexture->width(), srcTexture->height()); | 207 matrix.setIDiv(srcTexture->width(), srcTexture->height()); |
| 202 SkRect dstRect(srcRect); | 208 SkRect dstRect(srcRect); |
| 203 if (cropToRect && i == 1) { | 209 if (cropToRect && i == 1) { |
| 204 dstRect.offset(-dstRect.fLeft, -dstRect.fTop); | 210 dstRect.offset(-dstRect.fLeft, -dstRect.fTop); |
| 205 SkRect domain; | 211 SkRect domain; |
| 206 matrix.mapRect(&domain, rect); | 212 matrix.mapRect(&domain, rect); |
| 207 domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width()
: 0.0f, | 213 domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width()
: 0.0f, |
| 208 i < scaleFactorY ? SK_ScalarHalf / srcTexture->height()
: 0.0f); | 214 i < scaleFactorY ? SK_ScalarHalf / srcTexture->height()
: 0.0f); |
| 209 SkAutoTUnref<GrFragmentProcessor> fp( GrTextureDomainEffect::Creat
e( | 215 SkAutoTUnref<GrFragmentProcessor> fp( GrTextureDomainEffect::Creat
e( |
| 210 srcTexture, | 216 srcTexture, |
| 211 matrix, | 217 matrix, |
| 212 domain, | 218 domain, |
| 213 GrTextureDomain::kDecal_Mode, | 219 GrTextureDomain::kDecal_Mode, |
| 214 GrTextureParams::kBilerp_FilterMode)); | 220 GrTextureParams::kBilerp_FilterMode)); |
| 215 paint.addColorProcessor(fp); | 221 paint.addColorProcessor(fp); |
| 216 } else { | 222 } else { |
| 217 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k
Bilerp_FilterMode); | 223 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k
Bilerp_FilterMode); |
| 218 paint.addColorTextureProcessor(srcTexture, matrix, params); | 224 paint.addColorTextureProcessor(srcTexture, matrix, params); |
| 219 } | 225 } |
| 220 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, | 226 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, |
| 221 i < scaleFactorY ? 0.5f : 1.0f); | 227 i < scaleFactorY ? 0.5f : 1.0f); |
| 222 context->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint,
SkMatrix::I(), | 228 drawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, pai
nt, SkMatrix::I(), |
| 223 dstRect, srcRect); | 229 dstRect, srcRect); |
| 224 srcRect = dstRect; | 230 srcRect = dstRect; |
| 225 srcTexture = dstTexture; | 231 srcTexture = dstTexture; |
| 226 SkTSwap(dstTexture, tempTexture); | 232 SkTSwap(dstTexture, tempTexture); |
| 227 } | 233 } |
| 228 | 234 |
| 229 const SkIRect srcIRect = srcRect.roundOut(); | 235 const SkIRect srcIRect = srcRect.roundOut(); |
| 230 | 236 |
| 231 // For really small blurs(Certainly no wider than 5x5 on desktop gpus) it is
faster to just | 237 // For really small blurs(Certainly no wider than 5x5 on desktop gpus) it is
faster to just |
| 232 // launch a single non separable kernel vs two launches | 238 // launch a single non separable kernel vs two launches |
| 233 if (sigmaX > 0.0f && sigmaY > 0 && | 239 if (sigmaX > 0.0f && sigmaY > 0 && |
| 234 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { | 240 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { |
| 235 // We shouldn't be scaling because this is a small size blur | 241 // We shouldn't be scaling because this is a small size blur |
| 236 SkASSERT((scaleFactorX == scaleFactorY) == 1); | 242 SkASSERT((scaleFactorX == scaleFactorY) == 1); |
| 237 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); | 243 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); |
| 238 convolve_gaussian_2d(context, dstTexture->asRenderTarget(), clip, srcRec
t, dstRect, | 244 convolve_gaussian_2d(drawContext, dstTexture->asRenderTarget(), clip, sr
cRect, dstRect, |
| 239 srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropT
oRect, srcIRect); | 245 srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropT
oRect, srcIRect); |
| 240 srcTexture = dstTexture; | 246 srcTexture = dstTexture; |
| 241 srcRect = dstRect; | 247 srcRect = dstRect; |
| 242 SkTSwap(dstTexture, tempTexture); | 248 SkTSwap(dstTexture, tempTexture); |
| 243 | 249 |
| 244 } else { | 250 } else { |
| 245 if (sigmaX > 0.0f) { | 251 if (sigmaX > 0.0f) { |
| 246 if (scaleFactorX > 1) { | 252 if (scaleFactorX > 1) { |
| 247 // Clear out a radius to the right of the srcRect to prevent the | 253 // Clear out a radius to the right of the srcRect to prevent the |
| 248 // X convolution from reading garbage. | 254 // X convolution from reading garbage. |
| 249 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, | 255 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, |
| 250 radiusX, srcIRect.height()); | 256 radiusX, srcIRect.height()); |
| 251 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarge
t()); | 257 drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0
, false); |
| 252 } | 258 } |
| 253 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); | 259 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); |
| 254 convolve_gaussian(context, dstTexture->asRenderTarget(), clip, srcRe
ct, dstRect, | 260 convolve_gaussian(drawContext, dstTexture->asRenderTarget(), clip, s
rcRect, dstRect, |
| 255 srcTexture, Gr1DKernelEffect::kX_Direction, radius
X, sigmaX, | 261 srcTexture, Gr1DKernelEffect::kX_Direction, radius
X, sigmaX, |
| 256 cropToRect); | 262 cropToRect); |
| 257 srcTexture = dstTexture; | 263 srcTexture = dstTexture; |
| 258 srcRect = dstRect; | 264 srcRect = dstRect; |
| 259 SkTSwap(dstTexture, tempTexture); | 265 SkTSwap(dstTexture, tempTexture); |
| 260 } | 266 } |
| 261 | 267 |
| 262 if (sigmaY > 0.0f) { | 268 if (sigmaY > 0.0f) { |
| 263 if (scaleFactorY > 1 || sigmaX > 0.0f) { | 269 if (scaleFactorY > 1 || sigmaX > 0.0f) { |
| 264 // Clear out a radius below the srcRect to prevent the Y | 270 // Clear out a radius below the srcRect to prevent the Y |
| 265 // convolution from reading garbage. | 271 // convolution from reading garbage. |
| 266 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, | 272 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, |
| 267 srcIRect.width(), radiusY); | 273 srcIRect.width(), radiusY); |
| 268 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarge
t()); | 274 drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0
, false); |
| 269 } | 275 } |
| 270 | 276 |
| 271 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); | 277 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); |
| 272 convolve_gaussian(context, dstTexture->asRenderTarget(), clip, srcRe
ct, | 278 convolve_gaussian(drawContext, dstTexture->asRenderTarget(), clip, s
rcRect, |
| 273 dstRect, srcTexture, Gr1DKernelEffect::kY_Directio
n, radiusY, sigmaY, | 279 dstRect, srcTexture, Gr1DKernelEffect::kY_Directio
n, radiusY, sigmaY, |
| 274 cropToRect); | 280 cropToRect); |
| 275 srcTexture = dstTexture; | 281 srcTexture = dstTexture; |
| 276 srcRect = dstRect; | 282 srcRect = dstRect; |
| 277 SkTSwap(dstTexture, tempTexture); | 283 SkTSwap(dstTexture, tempTexture); |
| 278 } | 284 } |
| 279 } | 285 } |
| 280 | 286 |
| 281 if (scaleFactorX > 1 || scaleFactorY > 1) { | 287 if (scaleFactorX > 1 || scaleFactorY > 1) { |
| 282 // Clear one pixel to the right and below, to accommodate bilinear | 288 // Clear one pixel to the right and below, to accommodate bilinear |
| 283 // upsampling. | 289 // upsampling. |
| 284 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, | 290 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, |
| 285 srcIRect.width() + 1, 1); | 291 srcIRect.width() + 1, 1); |
| 286 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarget()); | 292 drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false)
; |
| 287 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, | 293 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, |
| 288 1, srcIRect.height()); | 294 1, srcIRect.height()); |
| 289 context->clear(&clearRect, 0x0, false, srcTexture->asRenderTarget()); | 295 drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false)
; |
| 290 SkMatrix matrix; | 296 SkMatrix matrix; |
| 291 matrix.setIDiv(srcTexture->width(), srcTexture->height()); | 297 matrix.setIDiv(srcTexture->width(), srcTexture->height()); |
| 292 | 298 |
| 293 GrPaint paint; | 299 GrPaint paint; |
| 294 // FIXME: this should be mitchell, not bilinear. | 300 // FIXME: this should be mitchell, not bilinear. |
| 295 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile
rp_FilterMode); | 301 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile
rp_FilterMode); |
| 296 paint.addColorTextureProcessor(srcTexture, matrix, params); | 302 paint.addColorTextureProcessor(srcTexture, matrix, params); |
| 297 | 303 |
| 298 SkRect dstRect(srcRect); | 304 SkRect dstRect(srcRect); |
| 299 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); | 305 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); |
| 300 context->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint, | 306 drawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, pai
nt, |
| 301 SkMatrix::I(), dstRect, srcRect); | 307 SkMatrix::I(), dstRect, srcRect); |
| 302 srcRect = dstRect; | 308 srcRect = dstRect; |
| 303 srcTexture = dstTexture; | 309 srcTexture = dstTexture; |
| 304 SkTSwap(dstTexture, tempTexture); | 310 SkTSwap(dstTexture, tempTexture); |
| 305 } | 311 } |
| 306 return SkRef(srcTexture); | 312 return SkRef(srcTexture); |
| 307 } | 313 } |
| 308 #endif | 314 #endif |
| 309 | 315 |
| 310 } | 316 } |
| OLD | NEW |