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 |