| 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" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 const SkRect& dstRect, | 50 const SkRect& dstRect, |
| 51 const SkPoint& srcOffset, | 51 const SkPoint& srcOffset, |
| 52 GrTexture* texture, | 52 GrTexture* texture, |
| 53 Gr1DKernelEffect::Direction direction, | 53 Gr1DKernelEffect::Direction direction, |
| 54 int radius, | 54 int radius, |
| 55 float sigma, | 55 float sigma, |
| 56 bool useBounds, | 56 bool useBounds, |
| 57 float bounds[2]) { | 57 float bounds[2]) { |
| 58 GrPaint paint; | 58 GrPaint paint; |
| 59 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian( | 59 SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian( |
| 60 texture, direction, radius, sigma, useBounds, bounds)); | 60 texture, direction, radius, sigma, useBounds, bounds, drawContext->rt_re
move_me())); |
| 61 paint.addColorFragmentProcessor(conv); | 61 paint.addColorFragmentProcessor(conv); |
| 62 SkMatrix localMatrix = SkMatrix::MakeTrans(srcOffset.x(), srcOffset.y()); | 62 SkMatrix localMatrix = SkMatrix::MakeTrans(srcOffset.x(), srcOffset.y()); |
| 63 drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, lo
calMatrix); | 63 drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, lo
calMatrix); |
| 64 } | 64 } |
| 65 | 65 |
| 66 static void convolve_gaussian_2d(GrDrawContext* drawContext, | 66 static void convolve_gaussian_2d(GrDrawContext* drawContext, |
| 67 const GrClip& clip, | 67 const GrClip& clip, |
| 68 const SkRect& srcRect, | 68 const SkRect& srcRect, |
| 69 GrTexture* texture, | 69 GrTexture* texture, |
| 70 int radiusX, | 70 int radiusX, |
| 71 int radiusY, | 71 int radiusY, |
| 72 SkScalar sigmaX, | 72 SkScalar sigmaX, |
| 73 SkScalar sigmaY, | 73 SkScalar sigmaY, |
| 74 const SkRect* srcBounds) { | 74 const SkRect* srcBounds) { |
| 75 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); | 75 SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); |
| 76 SkMatrix localMatrix = SkMatrix::MakeTrans(srcRect.x(), srcRect.y()); | 76 SkMatrix localMatrix = SkMatrix::MakeTrans(srcRect.x(), srcRect.y()); |
| 77 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); | 77 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); |
| 78 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); | 78 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); |
| 79 GrPaint paint; | 79 GrPaint paint; |
| 80 SkIRect bounds; | 80 SkIRect bounds; |
| 81 if (srcBounds) { | 81 if (srcBounds) { |
| 82 srcBounds->roundOut(&bounds); | 82 srcBounds->roundOut(&bounds); |
| 83 } else { | 83 } else { |
| 84 bounds.setEmpty(); | 84 bounds.setEmpty(); |
| 85 } | 85 } |
| 86 | 86 |
| 87 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus
sian( | 87 SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaus
sian( |
| 88 texture, bounds, size, 1.0, 0.0, kernelOffset, | 88 texture, bounds, size, 1.0, 0.0, kernelOffset, |
| 89 srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_
Mode, | 89 srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_
Mode, |
| 90 true, sigmaX, sigmaY)); | 90 true, sigmaX, sigmaY, drawContext->rt_remove_me())); |
| 91 paint.addColorFragmentProcessor(conv); | 91 paint.addColorFragmentProcessor(conv); |
| 92 drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, lo
calMatrix); | 92 drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, lo
calMatrix); |
| 93 } | 93 } |
| 94 | 94 |
| 95 static void convolve_gaussian(GrDrawContext* drawContext, | 95 static void convolve_gaussian(GrDrawContext* drawContext, |
| 96 const GrClip& clip, | 96 const GrClip& clip, |
| 97 const SkRect& srcRect, | 97 const SkRect& srcRect, |
| 98 GrTexture* texture, | 98 GrTexture* texture, |
| 99 Gr1DKernelEffect::Direction direction, | 99 Gr1DKernelEffect::Direction direction, |
| 100 int radius, | 100 int radius, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 | 161 |
| 162 GrTexture* GaussianBlur(GrContext* context, | 162 GrTexture* GaussianBlur(GrContext* context, |
| 163 GrTexture* srcTexture, | 163 GrTexture* srcTexture, |
| 164 bool canClobberSrc, | 164 bool canClobberSrc, |
| 165 const SkRect& dstBounds, | 165 const SkRect& dstBounds, |
| 166 const SkRect* srcBounds, | 166 const SkRect* srcBounds, |
| 167 float sigmaX, | 167 float sigmaX, |
| 168 float sigmaY, | 168 float sigmaY, |
| 169 GrTextureProvider::SizeConstraint constraint) { | 169 GrTextureProvider::SizeConstraint constraint) { |
| 170 SkASSERT(context); | 170 SkASSERT(context); |
| 171 |
| 172 SkAutoTUnref<GrDrawContext> srcDrawContext; |
| 173 if (srcTexture->asRenderTarget()) { |
| 174 srcDrawContext.reset(context->drawContext(srcTexture->asRenderTarget()))
; |
| 175 } |
| 176 |
| 171 SkIRect clearRect; | 177 SkIRect clearRect; |
| 172 int scaleFactorX, radiusX; | 178 int scaleFactorX, radiusX; |
| 173 int scaleFactorY, radiusY; | 179 int scaleFactorY, radiusY; |
| 174 int maxTextureSize = context->caps()->maxTextureSize(); | 180 int maxTextureSize = context->caps()->maxTextureSize(); |
| 175 sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX); | 181 sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX); |
| 176 sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY); | 182 sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY); |
| 177 | 183 |
| 178 SkPoint srcOffset = SkPoint::Make(-dstBounds.x(), -dstBounds.y()); | 184 SkPoint srcOffset = SkPoint::Make(-dstBounds.x(), -dstBounds.y()); |
| 179 SkRect localDstBounds = SkRect::MakeWH(dstBounds.width(), dstBounds.height()
); | 185 SkRect localDstBounds = SkRect::MakeWH(dstBounds.width(), dstBounds.height()
); |
| 180 SkRect localSrcBounds; | 186 SkRect localSrcBounds; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 198 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() || | 204 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() || |
| 199 kRGBA_8888_GrPixelConfig == srcTexture->config() || | 205 kRGBA_8888_GrPixelConfig == srcTexture->config() || |
| 200 kAlpha_8_GrPixelConfig == srcTexture->config()); | 206 kAlpha_8_GrPixelConfig == srcTexture->config()); |
| 201 | 207 |
| 202 GrSurfaceDesc desc; | 208 GrSurfaceDesc desc; |
| 203 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 209 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 204 desc.fWidth = SkScalarFloorToInt(dstBounds.width()); | 210 desc.fWidth = SkScalarFloorToInt(dstBounds.width()); |
| 205 desc.fHeight = SkScalarFloorToInt(dstBounds.height()); | 211 desc.fHeight = SkScalarFloorToInt(dstBounds.height()); |
| 206 desc.fConfig = srcTexture->config(); | 212 desc.fConfig = srcTexture->config(); |
| 207 | 213 |
| 208 GrTexture* dstTexture; | |
| 209 GrTexture* tempTexture; | |
| 210 SkAutoTUnref<GrTexture> temp1, temp2; | 214 SkAutoTUnref<GrTexture> temp1, temp2; |
| 211 | 215 |
| 212 temp1.reset(context->textureProvider()->createTexture(desc, constraint)); | 216 temp1.reset(context->textureProvider()->createTexture(desc, constraint)); |
| 213 dstTexture = temp1.get(); | 217 GrTexture* dstTexture = temp1.get(); |
| 218 SkAutoTUnref<GrDrawContext> dstDrawContext(context->drawContext(dstTexture->
asRenderTarget())); |
| 219 |
| 220 SkAutoTUnref<GrDrawContext> tmpDrawContext; |
| 221 GrTexture* tempTexture; |
| 214 if (canClobberSrc) { | 222 if (canClobberSrc) { |
| 215 tempTexture = srcTexture; | 223 tempTexture = srcTexture; |
| 224 tmpDrawContext.reset(SkRef(srcDrawContext.get())); |
| 216 } else { | 225 } else { |
| 217 temp2.reset(context->textureProvider()->createTexture(desc, constraint))
; | 226 temp2.reset(context->textureProvider()->createTexture(desc, constraint))
; |
| 218 tempTexture = temp2.get(); | 227 tempTexture = temp2.get(); |
| 228 tmpDrawContext.reset(context->drawContext(tempTexture->asRenderTarget())
); |
| 219 } | 229 } |
| 220 | 230 |
| 221 if (nullptr == dstTexture || nullptr == tempTexture) { | 231 if (srcTexture == tempTexture) { |
| 232 SkASSERT(srcDrawContext == tmpDrawContext); |
| 233 } |
| 234 |
| 235 if (nullptr == dstTexture || nullptr == tempTexture || !dstDrawContext || !t
mpDrawContext) { |
| 222 return nullptr; | 236 return nullptr; |
| 223 } | 237 } |
| 224 | 238 |
| 225 SkAutoTUnref<GrDrawContext> srcDrawContext; | |
| 226 | |
| 227 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { | 239 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { |
| 228 GrPaint paint; | 240 GrPaint paint; |
| 229 SkMatrix matrix; | 241 SkMatrix matrix; |
| 230 matrix.setIDiv(srcTexture->width(), srcTexture->height()); | 242 matrix.setIDiv(srcTexture->width(), srcTexture->height()); |
| 231 SkRect dstRect(srcRect); | 243 SkRect dstRect(srcRect); |
| 232 if (srcBounds && i == 1) { | 244 if (srcBounds && i == 1) { |
| 233 SkRect domain; | 245 SkRect domain; |
| 234 matrix.mapRect(&domain, *srcBounds); | 246 matrix.mapRect(&domain, *srcBounds); |
| 235 domain.inset((i < scaleFactorX) ? SK_ScalarHalf / srcTexture->width(
) : 0.0f, | 247 domain.inset((i < scaleFactorX) ? SK_ScalarHalf / srcTexture->width(
) : 0.0f, |
| 236 (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height
() : 0.0f); | 248 (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height
() : 0.0f); |
| 237 SkAutoTUnref<const GrFragmentProcessor> fp(GrTextureDomainEffect::Cr
eate( | 249 SkAutoTUnref<const GrFragmentProcessor> fp(GrTextureDomainEffect::Cr
eate( |
| 238 srcTexture, | 250 srcTexture, |
| 239 matrix, | 251 matrix, |
| 240 domain, | 252 domain, |
| 241 GrTextureDomain::kDecal_Mode, | 253 GrTextureDomain::kDecal_Mode, |
| 242 GrTextureParams::kBilerp_FilterMode)); | 254 GrTextureParams::kBilerp_FilterMode, |
| 255 kLocal_GrCoordSet, |
| 256 dstTexture->asRenderTarget())); |
| 243 paint.addColorFragmentProcessor(fp); | 257 paint.addColorFragmentProcessor(fp); |
| 244 srcRect.offset(-srcOffset); | 258 srcRect.offset(-srcOffset); |
| 245 srcOffset.set(0, 0); | 259 srcOffset.set(0, 0); |
| 246 } else { | 260 } else { |
| 247 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k
Bilerp_FilterMode); | 261 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k
Bilerp_FilterMode); |
| 248 paint.addColorTextureProcessor(srcTexture, matrix, params); | 262 paint.addColorTextureProcessor(srcTexture, matrix, params, dstTextur
e->asRenderTarget()); |
| 249 } | 263 } |
| 250 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, | 264 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, |
| 251 i < scaleFactorY ? 0.5f : 1.0f); | 265 i < scaleFactorY ? 0.5f : 1.0f); |
| 252 | 266 |
| 253 SkAutoTUnref<GrDrawContext> dstDrawContext( | |
| 254 context->drawContext(dstTexture->as
RenderTarget())); | |
| 255 if (!dstDrawContext) { | |
| 256 return nullptr; | |
| 257 } | |
| 258 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcR
ect); | 267 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcR
ect); |
| 259 | 268 |
| 260 srcDrawContext.swap(dstDrawContext); | 269 if (srcTexture == tempTexture) { |
| 270 // This guy was closed by the preceding draw since a dependant read |
| 271 // on him was created by the draw call - reopen him |
| 272 SkASSERT(srcDrawContext == tmpDrawContext); |
| 273 srcDrawContext.reset(context->drawContext(srcTexture->asRenderTarget
())); |
| 274 tmpDrawContext.reset(SkRef(srcDrawContext.get())); |
| 275 } |
| 276 |
| 277 dstDrawContext.reset(context->drawContext(dstTexture->asRenderTarget()))
; |
| 278 |
| 279 srcDrawContext.reset(SkRef(dstDrawContext.get())); |
| 280 |
| 261 srcRect = dstRect; | 281 srcRect = dstRect; |
| 262 srcTexture = dstTexture; | 282 srcTexture = dstTexture; |
| 283 |
| 284 dstDrawContext.swap(tmpDrawContext); |
| 263 SkTSwap(dstTexture, tempTexture); | 285 SkTSwap(dstTexture, tempTexture); |
| 264 localSrcBounds = srcRect; | 286 localSrcBounds = srcRect; |
| 287 |
| 288 if (srcTexture == tempTexture) { |
| 289 SkASSERT(srcDrawContext == tmpDrawContext); |
| 290 } |
| 265 } | 291 } |
| 266 | 292 |
| 267 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i
s faster to just | 293 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i
s faster to just |
| 268 // launch a single non separable kernel vs two launches | 294 // launch a single non separable kernel vs two launches |
| 269 if (sigmaX > 0.0f && sigmaY > 0.0f && | 295 if (sigmaX > 0.0f && sigmaY > 0.0f && |
| 270 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { | 296 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { |
| 271 // We shouldn't be scaling because this is a small size blur | 297 // We shouldn't be scaling because this is a small size blur |
| 272 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY)); | 298 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY)); |
| 273 | 299 |
| 274 SkAutoTUnref<GrDrawContext> dstDrawContext( | |
| 275 context->drawContext(dstTexture->as
RenderTarget())); | |
| 276 if (!dstDrawContext) { | |
| 277 return nullptr; | |
| 278 } | |
| 279 convolve_gaussian_2d(dstDrawContext, clip, srcRect, | 300 convolve_gaussian_2d(dstDrawContext, clip, srcRect, |
| 280 srcTexture, radiusX, radiusY, sigmaX, sigmaY, srcBo
unds); | 301 srcTexture, radiusX, radiusY, sigmaX, sigmaY, srcBo
unds); |
| 281 | 302 |
| 282 srcDrawContext.swap(dstDrawContext); | 303 srcDrawContext.reset(SkRef(dstDrawContext.get())); |
| 304 |
| 283 srcRect.offsetTo(0, 0); | 305 srcRect.offsetTo(0, 0); |
| 284 srcTexture = dstTexture; | 306 srcTexture = dstTexture; |
| 307 |
| 308 dstDrawContext.swap(tmpDrawContext); |
| 285 SkTSwap(dstTexture, tempTexture); | 309 SkTSwap(dstTexture, tempTexture); |
| 286 | 310 |
| 311 if (srcTexture == tempTexture) { |
| 312 SkASSERT(srcDrawContext == tmpDrawContext); |
| 313 } |
| 287 } else { | 314 } else { |
| 288 srcRect = localDstBounds; | 315 srcRect = localDstBounds; |
| 289 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); | 316 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); |
| 290 srcRect.roundOut(&srcRect); | 317 srcRect.roundOut(&srcRect); |
| 291 const SkIRect srcIRect = srcRect.roundOut(); | 318 const SkIRect srcIRect = srcRect.roundOut(); |
| 292 if (sigmaX > 0.0f) { | 319 if (sigmaX > 0.0f) { |
| 293 if (scaleFactorX > 1) { | 320 if (scaleFactorX > 1) { |
| 294 // TODO: if we pass in the source draw context we don't need thi
s here | 321 // TODO: if we pass in the source draw context we don't need thi
s here |
| 295 if (!srcDrawContext) { | 322 if (!srcDrawContext) { |
| 296 srcDrawContext.reset(context->drawContext(srcTexture->asRend
erTarget())); | 323 srcDrawContext.reset(context->drawContext(srcTexture->asRend
erTarget())); |
| 297 if (!srcDrawContext) { | 324 if (!srcDrawContext) { |
| 298 return nullptr; | 325 return nullptr; |
| 299 } | 326 } |
| 300 } | 327 } |
| 301 | 328 |
| 302 // Clear out a radius to the right of the srcRect to prevent the | 329 // Clear out a radius to the right of the srcRect to prevent the |
| 303 // X convolution from reading garbage. | 330 // X convolution from reading garbage. |
| 304 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, | 331 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, |
| 305 radiusX, srcIRect.height()); | 332 radiusX, srcIRect.height()); |
| 306 srcDrawContext->clear(&clearRect, 0x0, false); | 333 srcDrawContext->clear(&clearRect, 0x0, false); |
| 307 } | 334 } |
| 308 | 335 |
| 309 SkAutoTUnref<GrDrawContext> dstDrawContext( | |
| 310 context->drawContext(dstTexture->as
RenderTarget())); | |
| 311 if (!dstDrawContext) { | |
| 312 return nullptr; | |
| 313 } | |
| 314 convolve_gaussian(dstDrawContext, clip, srcRect, | 336 convolve_gaussian(dstDrawContext, clip, srcRect, |
| 315 srcTexture, Gr1DKernelEffect::kX_Direction, radius
X, sigmaX, | 337 srcTexture, Gr1DKernelEffect::kX_Direction, radius
X, sigmaX, |
| 316 srcBounds, srcOffset); | 338 srcBounds, srcOffset); |
| 317 srcDrawContext.swap(dstDrawContext); | 339 if (srcTexture == tempTexture) { |
| 340 // This guy was closed by the preceding draw - reopen him |
| 341 SkASSERT(srcDrawContext == tmpDrawContext); |
| 342 srcDrawContext.reset(context->drawContext(srcTexture->asRenderTa
rget())); |
| 343 tmpDrawContext.reset(SkRef(srcDrawContext.get())); |
| 344 } |
| 345 |
| 346 dstDrawContext.reset(context->drawContext(dstTexture->asRenderTarget
())); |
| 347 |
| 348 |
| 349 srcDrawContext.reset(SkRef(dstDrawContext.get())); |
| 350 |
| 318 srcTexture = dstTexture; | 351 srcTexture = dstTexture; |
| 319 srcRect.offsetTo(0, 0); | 352 srcRect.offsetTo(0, 0); |
| 353 |
| 354 dstDrawContext.swap(tmpDrawContext); |
| 320 SkTSwap(dstTexture, tempTexture); | 355 SkTSwap(dstTexture, tempTexture); |
| 321 localSrcBounds = srcRect; | 356 localSrcBounds = srcRect; |
| 322 srcOffset.set(0, 0); | 357 srcOffset.set(0, 0); |
| 323 } | 358 } |
| 324 | 359 |
| 325 if (sigmaY > 0.0f) { | 360 if (sigmaY > 0.0f) { |
| 326 if (scaleFactorY > 1 || sigmaX > 0.0f) { | 361 if (scaleFactorY > 1 || sigmaX > 0.0f) { |
| 327 // TODO: if we pass in the source draw context we don't need thi
s here | 362 // TODO: if we pass in the source draw context we don't need thi
s here |
| 328 if (!srcDrawContext) { | 363 if (!srcDrawContext) { |
| 329 srcDrawContext.reset(context->drawContext(srcTexture->asRend
erTarget())); | 364 srcDrawContext.reset(context->drawContext(srcTexture->asRend
erTarget())); |
| 330 if (!srcDrawContext) { | 365 if (!srcDrawContext) { |
| 331 return nullptr; | 366 return nullptr; |
| 332 } | 367 } |
| 333 } | 368 } |
| 334 | 369 |
| 335 // Clear out a radius below the srcRect to prevent the Y | 370 // Clear out a radius below the srcRect to prevent the Y |
| 336 // convolution from reading garbage. | 371 // convolution from reading garbage. |
| 337 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, | 372 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, |
| 338 srcIRect.width(), radiusY); | 373 srcIRect.width(), radiusY); |
| 339 srcDrawContext->clear(&clearRect, 0x0, false); | 374 srcDrawContext->clear(&clearRect, 0x0, false); |
| 340 } | 375 } |
| 341 | 376 |
| 342 SkAutoTUnref<GrDrawContext> dstDrawContext( | 377 // SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height())
; |
| 343 context->drawContext(dstTexture->
asRenderTarget())); | 378 |
| 344 if (!dstDrawContext) { | |
| 345 return nullptr; | |
| 346 } | |
| 347 convolve_gaussian(dstDrawContext, clip, srcRect, | 379 convolve_gaussian(dstDrawContext, clip, srcRect, |
| 348 srcTexture, Gr1DKernelEffect::kY_Direction, radius
Y, sigmaY, | 380 srcTexture, Gr1DKernelEffect::kY_Direction, radius
Y, sigmaY, |
| 349 srcBounds, srcOffset); | 381 srcBounds, srcOffset); |
| 350 | 382 |
| 351 srcDrawContext.swap(dstDrawContext); | 383 if (srcTexture == tempTexture) { |
| 384 // This guy was closed by the preceding draw - reopen him |
| 385 SkASSERT(srcDrawContext == tmpDrawContext); |
| 386 srcDrawContext.reset(context->drawContext(srcTexture->asRenderTa
rget())); |
| 387 tmpDrawContext.reset(SkRef(srcDrawContext.get())); |
| 388 } |
| 389 |
| 390 dstDrawContext.reset(context->drawContext(dstTexture->asRenderTarget
())); |
| 391 |
| 392 srcDrawContext.reset(SkRef(dstDrawContext.get())); |
| 393 |
| 352 srcTexture = dstTexture; | 394 srcTexture = dstTexture; |
| 353 srcRect.offsetTo(0, 0); | 395 srcRect.offsetTo(0, 0); |
| 396 |
| 397 dstDrawContext.swap(tmpDrawContext); |
| 354 SkTSwap(dstTexture, tempTexture); | 398 SkTSwap(dstTexture, tempTexture); |
| 355 } | 399 } |
| 356 } | 400 } |
| 357 const SkIRect srcIRect = srcRect.roundOut(); | 401 const SkIRect srcIRect = srcRect.roundOut(); |
| 358 | 402 |
| 359 if (scaleFactorX > 1 || scaleFactorY > 1) { | 403 if (scaleFactorX > 1 || scaleFactorY > 1) { |
| 360 SkASSERT(srcDrawContext); | 404 SkASSERT(srcDrawContext); |
| 361 | 405 |
| 362 // Clear one pixel to the right and below, to accommodate bilinear | 406 // Clear one pixel to the right and below, to accommodate bilinear |
| 363 // upsampling. | 407 // upsampling. |
| 364 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, | 408 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, |
| 365 srcIRect.width() + 1, 1); | 409 srcIRect.width() + 1, 1); |
| 366 srcDrawContext->clear(&clearRect, 0x0, false); | 410 srcDrawContext->clear(&clearRect, 0x0, false); |
| 367 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, | 411 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, |
| 368 1, srcIRect.height()); | 412 1, srcIRect.height()); |
| 369 srcDrawContext->clear(&clearRect, 0x0, false); | 413 srcDrawContext->clear(&clearRect, 0x0, false); |
| 370 SkMatrix matrix; | 414 SkMatrix matrix; |
| 371 matrix.setIDiv(srcTexture->width(), srcTexture->height()); | 415 matrix.setIDiv(srcTexture->width(), srcTexture->height()); |
| 372 | 416 |
| 373 GrPaint paint; | 417 GrPaint paint; |
| 374 // FIXME: this should be mitchell, not bilinear. | 418 // FIXME: this should be mitchell, not bilinear. |
| 375 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile
rp_FilterMode); | 419 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile
rp_FilterMode); |
| 376 paint.addColorTextureProcessor(srcTexture, matrix, params); | 420 paint.addColorTextureProcessor(srcTexture, matrix, params, dstTexture->a
sRenderTarget()); |
| 377 | 421 |
| 378 SkRect dstRect(srcRect); | 422 SkRect dstRect(srcRect); |
| 379 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); | 423 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); |
| 380 | 424 |
| 381 SkAutoTUnref<GrDrawContext> dstDrawContext( | |
| 382 context->drawContext(dstTexture->asRenderTarget(
))); | |
| 383 if (!dstDrawContext) { | |
| 384 return nullptr; | |
| 385 } | |
| 386 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcR
ect); | 425 dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcR
ect); |
| 387 | 426 |
| 388 srcDrawContext.swap(dstDrawContext); | 427 // Don't need to do this since we're exiting |
| 428 if (false && srcTexture == tempTexture) { |
| 429 // This guy was closed by the preceding draw - reopen him |
| 430 SkASSERT(srcDrawContext == tmpDrawContext); |
| 431 srcDrawContext.reset(context->drawContext(srcTexture->asRenderTarget
())); |
| 432 tmpDrawContext.reset(SkRef(srcDrawContext.get())); |
| 433 } |
| 434 |
| 435 dstDrawContext.reset(context->drawContext(dstTexture->asRenderTarget()))
; |
| 436 |
| 437 srcDrawContext.reset(SkRef(dstDrawContext.get())); |
| 438 |
| 389 srcRect = dstRect; | 439 srcRect = dstRect; |
| 390 srcTexture = dstTexture; | 440 srcTexture = dstTexture; |
| 441 |
| 442 dstDrawContext.swap(tmpDrawContext); |
| 391 SkTSwap(dstTexture, tempTexture); | 443 SkTSwap(dstTexture, tempTexture); |
| 444 |
| 445 // Since we're exiting some of the DC's can now be closed |
| 392 } | 446 } |
| 393 | 447 |
| 394 return SkRef(srcTexture); | 448 return SkRef(srcTexture); |
| 395 } | 449 } |
| 396 #endif | 450 #endif |
| 397 | 451 |
| 398 } | 452 } |
| OLD | NEW |