| 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 "GrCaps.h" |
| 14 #include "GrContext.h" |
| 15 #include "GrFixedClip.h" |
| 16 #include "GrRenderTargetContext.h" |
| 17 #include "GrTextureProxy.h" |
| 18 |
| 13 #include "effects/GrConvolutionEffect.h" | 19 #include "effects/GrConvolutionEffect.h" |
| 14 #include "effects/GrMatrixConvolutionEffect.h" | 20 #include "effects/GrMatrixConvolutionEffect.h" |
| 15 #include "GrContext.h" | |
| 16 #include "GrCaps.h" | |
| 17 #include "GrRenderTargetContext.h" | |
| 18 #include "GrFixedClip.h" | |
| 19 | 21 |
| 20 #define MAX_BLUR_SIGMA 4.0f | 22 #define MAX_BLUR_SIGMA 4.0f |
| 21 | 23 |
| 22 static void scale_irect_roundout(SkIRect* rect, float xScale, float yScale) { | 24 static void scale_irect_roundout(SkIRect* rect, float xScale, float yScale) { |
| 23 rect->fLeft = SkScalarFloorToInt(SkScalarMul(rect->fLeft, xScale)); | 25 rect->fLeft = SkScalarFloorToInt(SkScalarMul(rect->fLeft, xScale)); |
| 24 rect->fTop = SkScalarFloorToInt(SkScalarMul(rect->fTop, yScale)); | 26 rect->fTop = SkScalarFloorToInt(SkScalarMul(rect->fTop, yScale)); |
| 25 rect->fRight = SkScalarCeilToInt(SkScalarMul(rect->fRight, xScale)); | 27 rect->fRight = SkScalarCeilToInt(SkScalarMul(rect->fRight, xScale)); |
| 26 rect->fBottom = SkScalarCeilToInt(SkScalarMul(rect->fBottom, yScale)); | 28 rect->fBottom = SkScalarCeilToInt(SkScalarMul(rect->fBottom, yScale)); |
| 27 } | 29 } |
| 28 | 30 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 } | 64 } |
| 63 *radius = static_cast<int>(ceilf(sigma * 3.0f)); | 65 *radius = static_cast<int>(ceilf(sigma * 3.0f)); |
| 64 SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius); | 66 SkASSERT(*radius <= GrConvolutionEffect::kMaxKernelRadius); |
| 65 return sigma; | 67 return sigma; |
| 66 } | 68 } |
| 67 | 69 |
| 68 static void convolve_gaussian_1d(GrRenderTargetContext* renderTargetContext, | 70 static void convolve_gaussian_1d(GrRenderTargetContext* renderTargetContext, |
| 69 const GrClip& clip, | 71 const GrClip& clip, |
| 70 const SkIRect& dstRect, | 72 const SkIRect& dstRect, |
| 71 const SkIPoint& srcOffset, | 73 const SkIPoint& srcOffset, |
| 72 GrTexture* texture, | 74 GrTextureProxy* texture, |
| 73 Gr1DKernelEffect::Direction direction, | 75 Gr1DKernelEffect::Direction direction, |
| 74 int radius, | 76 int radius, |
| 75 float sigma, | 77 float sigma, |
| 76 bool useBounds, | 78 bool useBounds, |
| 77 float bounds[2]) { | 79 float bounds[2]) { |
| 78 GrPaint paint; | 80 GrPaint paint; |
| 79 paint.setGammaCorrect(renderTargetContext->isGammaCorrect()); | 81 paint.setGammaCorrect(renderTargetContext->isGammaCorrect()); |
| 80 sk_sp<GrFragmentProcessor> conv(GrConvolutionEffect::MakeGaussian( | 82 sk_sp<GrFragmentProcessor> conv(GrConvolutionEffect::MakeGaussian( |
| 81 texture, direction, radius, sigma, useBounds, bounds)); | 83 texture, direction, radius, sigma, useBounds, bounds)); |
| 82 paint.addColorFragmentProcessor(std::move(conv)); | 84 paint.addColorFragmentProcessor(std::move(conv)); |
| 83 paint.setPorterDuffXPFactory(SkBlendMode::kSrc); | 85 paint.setPorterDuffXPFactory(SkBlendMode::kSrc); |
| 84 SkMatrix localMatrix = SkMatrix::MakeTrans(-SkIntToScalar(srcOffset.x()), | 86 SkMatrix localMatrix = SkMatrix::MakeTrans(-SkIntToScalar(srcOffset.x()), |
| 85 -SkIntToScalar(srcOffset.y())); | 87 -SkIntToScalar(srcOffset.y())); |
| 86 renderTargetContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), | 88 renderTargetContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), |
| 87 SkRect::Make(dstRect), localMat
rix); | 89 SkRect::Make(dstRect), localMat
rix); |
| 88 } | 90 } |
| 89 | 91 |
| 90 static void convolve_gaussian_2d(GrRenderTargetContext* renderTargetContext, | 92 static void convolve_gaussian_2d(GrRenderTargetContext* renderTargetContext, |
| 91 const GrClip& clip, | 93 const GrClip& clip, |
| 92 const SkIRect& dstRect, | 94 const SkIRect& dstRect, |
| 93 const SkIPoint& srcOffset, | 95 const SkIPoint& srcOffset, |
| 94 GrTexture* texture, | 96 GrTextureProxy* texture, |
| 95 int radiusX, | 97 int radiusX, |
| 96 int radiusY, | 98 int radiusY, |
| 97 SkScalar sigmaX, | 99 SkScalar sigmaX, |
| 98 SkScalar sigmaY, | 100 SkScalar sigmaY, |
| 99 const SkIRect* srcBounds) { | 101 const SkIRect* srcBounds) { |
| 100 SkMatrix localMatrix = SkMatrix::MakeTrans(-SkIntToScalar(srcOffset.x()), | 102 SkMatrix localMatrix = SkMatrix::MakeTrans(-SkIntToScalar(srcOffset.x()), |
| 101 -SkIntToScalar(srcOffset.y())); | 103 -SkIntToScalar(srcOffset.y())); |
| 102 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); | 104 SkISize size = SkISize::Make(2 * radiusX + 1, 2 * radiusY + 1); |
| 103 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); | 105 SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY); |
| 104 GrPaint paint; | 106 GrPaint paint; |
| 105 paint.setGammaCorrect(renderTargetContext->isGammaCorrect()); | 107 paint.setGammaCorrect(renderTargetContext->isGammaCorrect()); |
| 106 SkIRect bounds = srcBounds ? *srcBounds : SkIRect::EmptyIRect(); | 108 SkIRect bounds = srcBounds ? *srcBounds : SkIRect::EmptyIRect(); |
| 107 | 109 |
| 108 sk_sp<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::MakeGaussian( | 110 sk_sp<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::MakeGaussian( |
| 109 texture, bounds, size, 1.0, 0.0, kernelOffset, | 111 texture, bounds, size, 1.0, 0.0, kernelOffset, |
| 110 srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_
Mode, | 112 srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_
Mode, |
| 111 true, sigmaX, sigmaY)); | 113 true, sigmaX, sigmaY)); |
| 112 paint.addColorFragmentProcessor(std::move(conv)); | 114 paint.addColorFragmentProcessor(std::move(conv)); |
| 113 paint.setPorterDuffXPFactory(SkBlendMode::kSrc); | 115 paint.setPorterDuffXPFactory(SkBlendMode::kSrc); |
| 114 renderTargetContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), | 116 renderTargetContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), |
| 115 SkRect::Make(dstRect), localMat
rix); | 117 SkRect::Make(dstRect), localMat
rix); |
| 116 } | 118 } |
| 117 | 119 |
| 118 static void convolve_gaussian(GrRenderTargetContext* renderTargetContext, | 120 static void convolve_gaussian(GrRenderTargetContext* renderTargetContext, |
| 119 const GrClip& clip, | 121 const GrClip& clip, |
| 120 const SkIRect& srcRect, | 122 const SkIRect& srcRect, |
| 121 GrTexture* texture, | 123 GrTextureProxy* texture, |
| 122 Gr1DKernelEffect::Direction direction, | 124 Gr1DKernelEffect::Direction direction, |
| 123 int radius, | 125 int radius, |
| 124 float sigma, | 126 float sigma, |
| 125 const SkIRect* srcBounds, | 127 const SkIRect* srcBounds, |
| 126 const SkIPoint& srcOffset) { | 128 const SkIPoint& srcOffset) { |
| 127 float bounds[2] = { 0.0f, 1.0f }; | 129 float bounds[2] = { 0.0f, 1.0f }; |
| 128 SkIRect dstRect = SkIRect::MakeWH(srcRect.width(), srcRect.height()); | 130 SkIRect dstRect = SkIRect::MakeWH(srcRect.width(), srcRect.height()); |
| 129 if (!srcBounds) { | 131 if (!srcBounds) { |
| 130 convolve_gaussian_1d(renderTargetContext, clip, dstRect, srcOffset, text
ure, | 132 convolve_gaussian_1d(renderTargetContext, clip, dstRect, srcOffset, text
ure, |
| 131 direction, radius, sigma, false, bounds); | 133 direction, radius, sigma, false, bounds); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 convolve_gaussian_1d(renderTargetContext, clip, rightRect, srcOffset, te
xture, | 177 convolve_gaussian_1d(renderTargetContext, clip, rightRect, srcOffset, te
xture, |
| 176 direction, radius, sigma, true, bounds); | 178 direction, radius, sigma, true, bounds); |
| 177 convolve_gaussian_1d(renderTargetContext, clip, midRect, srcOffset, text
ure, | 179 convolve_gaussian_1d(renderTargetContext, clip, midRect, srcOffset, text
ure, |
| 178 direction, radius, sigma, false, bounds); | 180 direction, radius, sigma, false, bounds); |
| 179 } | 181 } |
| 180 } | 182 } |
| 181 | 183 |
| 182 namespace SkGpuBlurUtils { | 184 namespace SkGpuBlurUtils { |
| 183 | 185 |
| 184 sk_sp<GrRenderTargetContext> GaussianBlur(GrContext* context, | 186 sk_sp<GrRenderTargetContext> GaussianBlur(GrContext* context, |
| 185 GrTexture* origSrc, | 187 GrTextureProxy* origSrc, |
| 186 sk_sp<SkColorSpace> colorSpace, | 188 sk_sp<SkColorSpace> colorSpace, |
| 187 const SkIRect& dstBounds, | 189 const SkIRect& dstBounds, |
| 188 const SkIRect* srcBounds, | 190 const SkIRect* srcBounds, |
| 189 float sigmaX, | 191 float sigmaX, |
| 190 float sigmaY, | 192 float sigmaY, |
| 191 SkBackingFit fit) { | 193 SkBackingFit fit) { |
| 192 SkASSERT(context); | 194 SkASSERT(context); |
| 193 SkIRect clearRect; | 195 SkIRect clearRect; |
| 194 int scaleFactorX, radiusX; | 196 int scaleFactorX, radiusX; |
| 195 int scaleFactorY, radiusY; | 197 int scaleFactorY, radiusY; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 209 } else { | 211 } else { |
| 210 srcRect = localDstBounds; | 212 srcRect = localDstBounds; |
| 211 } | 213 } |
| 212 | 214 |
| 213 scale_irect_roundout(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); | 215 scale_irect_roundout(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); |
| 214 scale_irect(&srcRect, scaleFactorX, scaleFactorY); | 216 scale_irect(&srcRect, scaleFactorX, scaleFactorY); |
| 215 | 217 |
| 216 // setup new clip | 218 // setup new clip |
| 217 GrFixedClip clip(localDstBounds); | 219 GrFixedClip clip(localDstBounds); |
| 218 | 220 |
| 219 sk_sp<GrTexture> srcTexture(sk_ref_sp(origSrc)); | 221 sk_sp<GrTextureProxy> srcTexture(sk_ref_sp(origSrc)); |
| 220 | 222 |
| 221 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() || | 223 SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() || |
| 222 kRGBA_8888_GrPixelConfig == srcTexture->config() || | 224 kRGBA_8888_GrPixelConfig == srcTexture->config() || |
| 223 kSRGBA_8888_GrPixelConfig == srcTexture->config() || | 225 kSRGBA_8888_GrPixelConfig == srcTexture->config() || |
| 224 kSBGRA_8888_GrPixelConfig == srcTexture->config() || | 226 kSBGRA_8888_GrPixelConfig == srcTexture->config() || |
| 225 kRGBA_half_GrPixelConfig == srcTexture->config() || | 227 kRGBA_half_GrPixelConfig == srcTexture->config() || |
| 226 kAlpha_8_GrPixelConfig == srcTexture->config()); | 228 kAlpha_8_GrPixelConfig == srcTexture->config()); |
| 227 | 229 |
| 228 const int width = dstBounds.width(); | 230 const int width = dstBounds.width(); |
| 229 const int height = dstBounds.height(); | 231 const int height = dstBounds.height(); |
| 230 const GrPixelConfig config = srcTexture->config(); | 232 const GrPixelConfig config = srcTexture->config(); |
| 231 | 233 |
| 232 sk_sp<GrRenderTargetContext> dstRenderTargetContext(context->makeRenderTarge
tContext( | 234 sk_sp<GrRenderTargetContext> dstDeferredRenderTargetContext( |
| 233 fit, width, height, config, colorSpace, 0, kDefault_GrSurfaceOrigin)); | 235 context->makeDeferredRenderTargetContext(fit, width, height, config, col
orSpace, |
| 234 if (!dstRenderTargetContext) { | 236 0, kDefault_GrSurfaceOrigin)); |
| 237 if (!dstDeferredRenderTargetContext) { |
| 235 return nullptr; | 238 return nullptr; |
| 236 } | 239 } |
| 237 | 240 |
| 238 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i
s faster to just | 241 // For really small blurs (certainly no wider than 5x5 on desktop gpus) it i
s faster to just |
| 239 // launch a single non separable kernel vs two launches | 242 // launch a single non separable kernel vs two launches |
| 240 if (sigmaX > 0.0f && sigmaY > 0.0f && | 243 if (sigmaX > 0.0f && sigmaY > 0.0f && |
| 241 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { | 244 (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { |
| 242 // We shouldn't be scaling because this is a small size blur | 245 // We shouldn't be scaling because this is a small size blur |
| 243 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY)); | 246 SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY)); |
| 244 | 247 |
| 245 convolve_gaussian_2d(dstRenderTargetContext.get(), clip, localDstBounds,
srcOffset, | 248 convolve_gaussian_2d(dstDeferredRenderTargetContext.get(), clip, localDs
tBounds, srcOffset, |
| 246 srcTexture.get(), radiusX, radiusY, sigmaX, sigmaY,
srcBounds); | 249 srcTexture.get(), radiusX, radiusY, sigmaX, sigmaY,
srcBounds); |
| 247 | 250 |
| 248 return dstRenderTargetContext; | 251 return dstDeferredRenderTargetContext; |
| 249 } | 252 } |
| 250 | 253 |
| 251 sk_sp<GrRenderTargetContext> tmpRenderTargetContext(context->makeRenderTarge
tContext( | 254 sk_sp<GrRenderTargetContext> tmpRenderTargetContext(context->makeDeferredRen
derTargetContext( |
| 252 fit, width, height, config, colorSpace, 0, kDefault_GrSurfaceOrigin)); | 255 fit, width, height, config, colorSpace, 0, kDefault_GrSurfaceOrigin)); |
| 253 if (!tmpRenderTargetContext) { | 256 if (!tmpRenderTargetContext) { |
| 254 return nullptr; | 257 return nullptr; |
| 255 } | 258 } |
| 256 | 259 |
| 257 sk_sp<GrRenderTargetContext> srcRenderTargetContext; | 260 sk_sp<GrRenderTargetContext> srcRenderTargetContext; |
| 258 | 261 |
| 259 SkASSERT(SkIsPow2(scaleFactorX) && SkIsPow2(scaleFactorY)); | 262 SkASSERT(SkIsPow2(scaleFactorX) && SkIsPow2(scaleFactorY)); |
| 260 | 263 |
| 261 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { | 264 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { |
| 262 GrPaint paint; | 265 GrPaint paint; |
| 263 paint.setGammaCorrect(dstRenderTargetContext->isGammaCorrect()); | 266 paint.setGammaCorrect(dstDeferredRenderTargetContext->isGammaCorrect()); |
| 264 SkMatrix matrix; | 267 SkMatrix matrix; |
| 265 matrix.setIDiv(srcTexture->width(), srcTexture->height()); | 268 matrix.setIDiv(srcTexture->width(), srcTexture->height()); |
| 266 SkIRect dstRect(srcRect); | 269 SkIRect dstRect(srcRect); |
| 267 if (srcBounds && i == 1) { | 270 if (srcBounds && i == 1) { |
| 268 SkRect domain; | 271 SkRect domain; |
| 269 matrix.mapRect(&domain, SkRect::Make(*srcBounds)); | 272 matrix.mapRect(&domain, SkRect::Make(*srcBounds)); |
| 270 domain.inset((i < scaleFactorX) ? SK_ScalarHalf / srcTexture->width(
) : 0.0f, | 273 domain.inset((i < scaleFactorX) ? SK_ScalarHalf / srcTexture->width(
) : 0.0f, |
| 271 (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height
() : 0.0f); | 274 (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height
() : 0.0f); |
| 272 sk_sp<GrFragmentProcessor> fp(GrTextureDomainEffect::Make( | 275 sk_sp<GrFragmentProcessor> fp(GrTextureDomainEffect::Make( |
| 273 srcTexture.get(), | 276 srcTexture.get(), |
| 274 nullptr, | 277 nullptr, |
| 275 matrix, | 278 matrix, |
| 276 domain, | 279 domain, |
| 277 GrTextureDomain::kDecal_
Mode, | 280 GrTextureDomain::kDecal_
Mode, |
| 278 GrTextureParams::kBilerp
_FilterMode)); | 281 GrTextureParams::kBilerp
_FilterMode)); |
| 279 paint.addColorFragmentProcessor(std::move(fp)); | 282 paint.addColorFragmentProcessor(std::move(fp)); |
| 280 srcRect.offset(-srcOffset); | 283 srcRect.offset(-srcOffset); |
| 281 srcOffset.set(0, 0); | 284 srcOffset.set(0, 0); |
| 282 } else { | 285 } else { |
| 283 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k
Bilerp_FilterMode); | 286 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k
Bilerp_FilterMode); |
| 284 paint.addColorTextureProcessor(srcTexture.get(), nullptr, matrix, pa
rams); | 287 paint.addColorTextureProcessor(srcTexture.get(), nullptr, matrix, pa
rams); |
| 285 } | 288 } |
| 286 paint.setPorterDuffXPFactory(SkBlendMode::kSrc); | 289 paint.setPorterDuffXPFactory(SkBlendMode::kSrc); |
| 287 shrink_irect_by_2(&dstRect, i < scaleFactorX, i < scaleFactorY); | 290 shrink_irect_by_2(&dstRect, i < scaleFactorX, i < scaleFactorY); |
| 288 | 291 |
| 289 dstRenderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(), | 292 dstDeferredRenderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(
), |
| 290 SkRect::Make(dstRect), SkRect::Ma
ke(srcRect)); | 293 SkRect::Make(dstRect), Sk
Rect::Make(srcRect)); |
| 291 | 294 |
| 292 srcRenderTargetContext = dstRenderTargetContext; | 295 srcRenderTargetContext = dstDeferredRenderTargetContext; |
| 293 srcRect = dstRect; | 296 srcRect = dstRect; |
| 294 srcTexture = srcRenderTargetContext->asTexture(); | 297 srcTexture = sk_ref_sp(srcRenderTargetContext->asDeferredTexture()); |
| 295 dstRenderTargetContext.swap(tmpRenderTargetContext); | 298 dstDeferredRenderTargetContext.swap(tmpRenderTargetContext); |
| 296 localSrcBounds = srcRect; | 299 localSrcBounds = srcRect; |
| 297 } | 300 } |
| 298 | 301 |
| 299 srcRect = localDstBounds; | 302 srcRect = localDstBounds; |
| 300 scale_irect_roundout(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); | 303 scale_irect_roundout(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); |
| 301 if (sigmaX > 0.0f) { | 304 if (sigmaX > 0.0f) { |
| 302 if (scaleFactorX > 1) { | 305 if (scaleFactorX > 1) { |
| 303 SkASSERT(srcRenderTargetContext); | 306 SkASSERT(srcRenderTargetContext); |
| 304 | 307 |
| 305 // Clear out a radius to the right of the srcRect to prevent the | 308 // Clear out a radius to the right of the srcRect to prevent the |
| 306 // X convolution from reading garbage. | 309 // X convolution from reading garbage. |
| 307 clearRect = SkIRect::MakeXYWH(srcRect.fRight, srcRect.fTop, | 310 clearRect = SkIRect::MakeXYWH(srcRect.fRight, srcRect.fTop, |
| 308 radiusX, srcRect.height()); | 311 radiusX, srcRect.height()); |
| 309 srcRenderTargetContext->clear(&clearRect, 0x0, false); | 312 srcRenderTargetContext->clear(&clearRect, 0x0, false); |
| 310 } | 313 } |
| 311 | 314 |
| 312 convolve_gaussian(dstRenderTargetContext.get(), clip, srcRect, | 315 convolve_gaussian(dstDeferredRenderTargetContext.get(), clip, srcRect, |
| 313 srcTexture.get(), Gr1DKernelEffect::kX_Direction, radi
usX, sigmaX, | 316 srcTexture.get(), Gr1DKernelEffect::kX_Direction, radi
usX, sigmaX, |
| 314 srcBounds, srcOffset); | 317 srcBounds, srcOffset); |
| 315 srcRenderTargetContext = dstRenderTargetContext; | 318 srcRenderTargetContext = dstDeferredRenderTargetContext; |
| 316 srcTexture = srcRenderTargetContext->asTexture(); | 319 srcTexture = sk_ref_sp(srcRenderTargetContext->asDeferredTexture()); |
| 317 srcRect.offsetTo(0, 0); | 320 srcRect.offsetTo(0, 0); |
| 318 dstRenderTargetContext.swap(tmpRenderTargetContext); | 321 dstDeferredRenderTargetContext.swap(tmpRenderTargetContext); |
| 319 localSrcBounds = srcRect; | 322 localSrcBounds = srcRect; |
| 320 srcOffset.set(0, 0); | 323 srcOffset.set(0, 0); |
| 321 } | 324 } |
| 322 | 325 |
| 323 if (sigmaY > 0.0f) { | 326 if (sigmaY > 0.0f) { |
| 324 if (scaleFactorY > 1 || sigmaX > 0.0f) { | 327 if (scaleFactorY > 1 || sigmaX > 0.0f) { |
| 325 SkASSERT(srcRenderTargetContext); | 328 SkASSERT(srcRenderTargetContext); |
| 326 | 329 |
| 327 // Clear out a radius below the srcRect to prevent the Y | 330 // Clear out a radius below the srcRect to prevent the Y |
| 328 // convolution from reading garbage. | 331 // convolution from reading garbage. |
| 329 clearRect = SkIRect::MakeXYWH(srcRect.fLeft, srcRect.fBottom, | 332 clearRect = SkIRect::MakeXYWH(srcRect.fLeft, srcRect.fBottom, |
| 330 srcRect.width(), radiusY); | 333 srcRect.width(), radiusY); |
| 331 srcRenderTargetContext->clear(&clearRect, 0x0, false); | 334 srcRenderTargetContext->clear(&clearRect, 0x0, false); |
| 332 } | 335 } |
| 333 | 336 |
| 334 convolve_gaussian(dstRenderTargetContext.get(), clip, srcRect, | 337 convolve_gaussian(dstDeferredRenderTargetContext.get(), clip, srcRect, |
| 335 srcTexture.get(), Gr1DKernelEffect::kY_Direction, radi
usY, sigmaY, | 338 srcTexture.get(), Gr1DKernelEffect::kY_Direction, radi
usY, sigmaY, |
| 336 srcBounds, srcOffset); | 339 srcBounds, srcOffset); |
| 337 | 340 |
| 338 srcRenderTargetContext = dstRenderTargetContext; | 341 srcRenderTargetContext = dstDeferredRenderTargetContext; |
| 339 srcRect.offsetTo(0, 0); | 342 srcRect.offsetTo(0, 0); |
| 340 dstRenderTargetContext.swap(tmpRenderTargetContext); | 343 dstDeferredRenderTargetContext.swap(tmpRenderTargetContext); |
| 341 } | 344 } |
| 342 | 345 |
| 343 SkASSERT(srcRenderTargetContext); | 346 SkASSERT(srcRenderTargetContext); |
| 344 srcTexture = nullptr; // we don't use this from here on out | 347 srcTexture = nullptr; // we don't use this from here on out |
| 345 | 348 |
| 346 if (scaleFactorX > 1 || scaleFactorY > 1) { | 349 if (scaleFactorX > 1 || scaleFactorY > 1) { |
| 347 // Clear one pixel to the right and below, to accommodate bilinear upsam
pling. | 350 // Clear one pixel to the right and below, to accommodate bilinear upsam
pling. |
| 348 clearRect = SkIRect::MakeXYWH(srcRect.fLeft, srcRect.fBottom, srcRect.wi
dth() + 1, 1); | 351 clearRect = SkIRect::MakeXYWH(srcRect.fLeft, srcRect.fBottom, srcRect.wi
dth() + 1, 1); |
| 349 srcRenderTargetContext->clear(&clearRect, 0x0, false); | 352 srcRenderTargetContext->clear(&clearRect, 0x0, false); |
| 350 clearRect = SkIRect::MakeXYWH(srcRect.fRight, srcRect.fTop, 1, srcRect.h
eight()); | 353 clearRect = SkIRect::MakeXYWH(srcRect.fRight, srcRect.fTop, 1, srcRect.h
eight()); |
| 351 srcRenderTargetContext->clear(&clearRect, 0x0, false); | 354 srcRenderTargetContext->clear(&clearRect, 0x0, false); |
| 352 | 355 |
| 353 SkMatrix matrix; | 356 SkMatrix matrix; |
| 354 matrix.setIDiv(srcRenderTargetContext->width(), srcRenderTargetContext->
height()); | 357 matrix.setIDiv(srcRenderTargetContext->width(), srcRenderTargetContext->
height()); |
| 355 | 358 |
| 356 GrPaint paint; | 359 GrPaint paint; |
| 357 paint.setGammaCorrect(dstRenderTargetContext->isGammaCorrect()); | 360 paint.setGammaCorrect(dstDeferredRenderTargetContext->isGammaCorrect()); |
| 358 // FIXME: this should be mitchell, not bilinear. | 361 // FIXME: this should be mitchell, not bilinear. |
| 359 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile
rp_FilterMode); | 362 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile
rp_FilterMode); |
| 360 sk_sp<GrTexture> tex(srcRenderTargetContext->asTexture()); | 363 sk_sp<GrTextureProxy> tex(srcRenderTargetContext->asDeferredTexture()); |
| 361 paint.addColorTextureProcessor(tex.get(), nullptr, matrix, params); | 364 paint.addColorTextureProcessor(tex.get(), nullptr, matrix, params); |
| 362 paint.setPorterDuffXPFactory(SkBlendMode::kSrc); | 365 paint.setPorterDuffXPFactory(SkBlendMode::kSrc); |
| 363 | 366 |
| 364 SkIRect dstRect(srcRect); | 367 SkIRect dstRect(srcRect); |
| 365 scale_irect(&dstRect, scaleFactorX, scaleFactorY); | 368 scale_irect(&dstRect, scaleFactorX, scaleFactorY); |
| 366 | 369 |
| 367 dstRenderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(), | 370 dstDeferredRenderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(
), |
| 368 SkRect::Make(dstRect), SkRect::Ma
ke(srcRect)); | 371 SkRect::Make(dstRect), Sk
Rect::Make(srcRect)); |
| 369 | 372 |
| 370 srcRenderTargetContext = dstRenderTargetContext; | 373 srcRenderTargetContext = dstDeferredRenderTargetContext; |
| 371 srcRect = dstRect; | 374 srcRect = dstRect; |
| 372 dstRenderTargetContext.swap(tmpRenderTargetContext); | 375 dstDeferredRenderTargetContext.swap(tmpRenderTargetContext); |
| 373 } | 376 } |
| 374 | 377 |
| 375 return srcRenderTargetContext; | 378 return srcRenderTargetContext; |
| 376 } | 379 } |
| 377 | 380 |
| 378 } | 381 } |
| 379 | 382 |
| 380 #endif | 383 #endif |
| 381 | 384 |
| OLD | NEW |