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 |