OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrBlurUtils.h" | 8 #include "GrBlurUtils.h" |
9 #include "GrDrawContext.h" | 9 #include "GrDrawContext.h" |
10 #include "GrCaps.h" | 10 #include "GrCaps.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 const GrClip& clip, | 29 const GrClip& clip, |
30 const SkMatrix& viewMatrix, | 30 const SkMatrix& viewMatrix, |
31 const SkRect& maskRect, | 31 const SkRect& maskRect, |
32 GrPaint* grp, | 32 GrPaint* grp, |
33 GrTexture* mask) { | 33 GrTexture* mask) { |
34 SkMatrix matrix; | 34 SkMatrix matrix; |
35 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop); | 35 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop); |
36 matrix.postIDiv(mask->width(), mask->height()); | 36 matrix.postIDiv(mask->width(), mask->height()); |
37 | 37 |
38 grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Create(mask, matrix
, | 38 grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Create(mask, matrix
, |
39 kDevice_GrCo
ordSet))->unref(); | 39 kDevice_GrCo
ordSet, drawContext->rt_remove_me()))->unref(); |
40 | 40 |
41 SkMatrix inverse; | 41 SkMatrix inverse; |
42 if (!viewMatrix.invert(&inverse)) { | 42 if (!viewMatrix.invert(&inverse)) { |
43 return false; | 43 return false; |
44 } | 44 } |
45 drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), maskRect, in
verse); | 45 drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), maskRect, in
verse); |
46 return true; | 46 return true; |
47 } | 47 } |
48 | 48 |
49 static bool draw_with_mask_filter(GrDrawContext* drawContext, | 49 static bool draw_with_mask_filter(GrDrawContext* drawContext, |
(...skipping 27 matching lines...) Expand all Loading... |
77 // the current clip (and identity matrix) and GrPaint settings | 77 // the current clip (and identity matrix) and GrPaint settings |
78 GrSurfaceDesc desc; | 78 GrSurfaceDesc desc; |
79 desc.fWidth = dstM.fBounds.width(); | 79 desc.fWidth = dstM.fBounds.width(); |
80 desc.fHeight = dstM.fBounds.height(); | 80 desc.fHeight = dstM.fBounds.height(); |
81 desc.fConfig = kAlpha_8_GrPixelConfig; | 81 desc.fConfig = kAlpha_8_GrPixelConfig; |
82 | 82 |
83 SkAutoTUnref<GrTexture> texture(textureProvider->createApproxTexture(desc)); | 83 SkAutoTUnref<GrTexture> texture(textureProvider->createApproxTexture(desc)); |
84 if (!texture) { | 84 if (!texture) { |
85 return false; | 85 return false; |
86 } | 86 } |
87 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, | 87 texture->writePixels(NULL, 0, 0, desc.fWidth, desc.fHeight, desc.fConfig, |
88 dstM.fImage, dstM.fRowBytes); | 88 dstM.fImage, dstM.fRowBytes); |
89 | 89 |
| 90 texture->setFromRawPixels(true); |
| 91 texture->setException(true); |
| 92 |
90 SkRect maskRect = SkRect::Make(dstM.fBounds); | 93 SkRect maskRect = SkRect::Make(dstM.fBounds); |
91 | 94 |
92 return draw_mask(drawContext, clipData, viewMatrix, maskRect, grp, texture); | 95 return draw_mask(drawContext, clipData, viewMatrix, maskRect, grp, texture); |
93 } | 96 } |
94 | 97 |
95 // Create a mask of 'devPath' and place the result in 'mask'. | 98 // Create a mask of 'devPath' and place the result in 'mask'. |
| 99 // If this returns non-NULL then 'outputDrawContext' will be set to the |
| 100 // drawContext used to create it (and it will have an associated rendertarget). |
| 101 // TODO: just return drawContext? |
96 static GrTexture* create_mask_GPU(GrContext* context, | 102 static GrTexture* create_mask_GPU(GrContext* context, |
97 SkRect* maskRect, | 103 SkRect* maskRect, |
98 const SkPath& devPath, | 104 const SkPath& devPath, |
99 const GrStrokeInfo& strokeInfo, | 105 const GrStrokeInfo& strokeInfo, |
100 bool doAA, | 106 bool doAA, |
101 int sampleCnt) { | 107 int sampleCnt) { |
102 // This mask will ultimately be drawn as a non-AA rect (see draw_mask). | 108 // This mask will ultimately be drawn as a non-AA rect (see draw_mask). |
103 // Non-AA rects have a bad habit of snapping arbitrarily. Integerize here | 109 // Non-AA rects have a bad habit of snapping arbitrarily. Integerize here |
104 // so the mask draws in a reproducible manner. | 110 // so the mask draws in a reproducible manner. |
105 *maskRect = SkRect::Make(maskRect->roundOut()); | 111 *maskRect = SkRect::Make(maskRect->roundOut()); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 // should I push prePathMatrix on our MV stack temporarily, instead | 314 // should I push prePathMatrix on our MV stack temporarily, instead |
309 // of applying it here? See SkDraw.cpp | 315 // of applying it here? See SkDraw.cpp |
310 pathPtr->transform(*prePathMatrix, result); | 316 pathPtr->transform(*prePathMatrix, result); |
311 pathPtr = result; | 317 pathPtr = result; |
312 } | 318 } |
313 } | 319 } |
314 // at this point we're done with prePathMatrix | 320 // at this point we're done with prePathMatrix |
315 SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) | 321 SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) |
316 | 322 |
317 GrPaint grPaint; | 323 GrPaint grPaint; |
318 if (!SkPaintToGrPaint(context, paint, viewMatrix, &grPaint)) { | 324 if (!SkPaintToGrPaint(context, paint, viewMatrix, &grPaint, renderTarget)) { |
319 return; | 325 return; |
320 } | 326 } |
321 | 327 |
322 if (paint.getMaskFilter()) { | 328 if (paint.getMaskFilter()) { |
323 draw_path_with_mask_filter(context, drawContext, renderTarget, clip, &gr
Paint, viewMatrix, | 329 draw_path_with_mask_filter(context, drawContext, renderTarget, clip, &gr
Paint, viewMatrix, |
324 paint.getMaskFilter(), paint.getPathEffect(),
strokeInfo, | 330 paint.getMaskFilter(), paint.getPathEffect(),
strokeInfo, |
325 pathPtr, pathIsMutable); | 331 pathPtr, pathIsMutable); |
326 } else { | 332 } else { |
327 SkTLazy<SkPath> tmpPath2; | 333 SkTLazy<SkPath> tmpPath2; |
328 if (!strokeInfo.isDashed() && pathEffect && | 334 if (!strokeInfo.isDashed() && pathEffect && |
329 pathEffect->filterPath(tmpPath2.init(), *pathPtr, &strokeInfo, nullp
tr)) { | 335 pathEffect->filterPath(tmpPath2.init(), *pathPtr, &strokeInfo, nullp
tr)) { |
330 pathPtr = tmpPath2.get(); | 336 pathPtr = tmpPath2.get(); |
331 pathPtr->setIsVolatile(true); | 337 pathPtr->setIsVolatile(true); |
332 pathIsMutable = true; | 338 pathIsMutable = true; |
333 } | 339 } |
| 340 #if 1 |
334 drawContext->drawPath(clip, grPaint, viewMatrix, *pathPtr, strokeInfo); | 341 drawContext->drawPath(clip, grPaint, viewMatrix, *pathPtr, strokeInfo); |
| 342 #else |
| 343 // avoid possibly allocating a new path in transform if we can |
| 344 SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init(); |
| 345 if (!pathIsMutable) { |
| 346 devPathPtr->setIsVolatile(true); |
| 347 } |
| 348 |
| 349 // transform the path into device space |
| 350 pathPtr->transform(viewMatrix, devPathPtr); |
| 351 |
| 352 SkRect maskRect; |
| 353 if (paint.getMaskFilter()->canFilterMaskGPU(SkRRect::MakeRect(devPathPtr
->getBounds()), |
| 354 clipBounds, |
| 355 viewMatrix, |
| 356 &maskRect)) { |
| 357 SkIRect finalIRect; |
| 358 maskRect.roundOut(&finalIRect); |
| 359 if (clip_bounds_quick_reject(clipBounds, finalIRect)) { |
| 360 // clipped out |
| 361 return; |
| 362 } |
| 363 |
| 364 if (paint.getMaskFilter()->directFilterMaskGPU(context->textureProvi
der(), |
| 365 drawContext, |
| 366 &grPaint, |
| 367 clip, |
| 368 viewMatrix, |
| 369 strokeInfo, |
| 370 *devPathPtr)) { |
| 371 // the mask filter was able to draw itself directly, so there's
nothing |
| 372 // left to do. |
| 373 return; |
| 374 } |
| 375 |
| 376 SkAutoTUnref<GrTexture> mask(create_mask_GPU(context, |
| 377 &maskRect, |
| 378 *devPathPtr, |
| 379 strokeInfo, |
| 380 grPaint.isAntiAlias(), |
| 381 renderTarget->numColorS
amples())); |
| 382 if (mask) { |
| 383 SkASSERT(mask->asRenderTarget()); |
| 384 |
| 385 GrTexture* filtered; |
| 386 |
| 387 if (paint.getMaskFilter()->filterMaskGPU(mask, viewMatrix, maskR
ect, |
| 388 &filtered, true)) { |
| 389 // filterMaskGPU gives us ownership of a ref to the result |
| 390 SkAutoTUnref<GrTexture> atu(filtered); |
| 391 if (draw_mask(drawContext, |
| 392 clip, |
| 393 viewMatrix, |
| 394 maskRect, |
| 395 &grPaint, |
| 396 filtered)) { |
| 397 // This path is completely drawn |
| 398 return; |
| 399 } |
| 400 } |
| 401 } |
| 402 } |
| 403 |
| 404 // draw the mask on the CPU - this is a fallthrough path in case the |
| 405 // GPU path fails |
| 406 SkPaint::Style style = strokeInfo.isHairlineStyle() ? SkPaint::kStroke_S
tyle : |
| 407 SkPaint::kFill_Sty
le; |
| 408 draw_with_mask_filter(drawContext, context->textureProvider(), |
| 409 clip, viewMatrix, *devPathPtr, |
| 410 paint.getMaskFilter(), clipBounds, &grPaint, style
); |
| 411 return; |
| 412 #endif |
335 } | 413 } |
336 } | 414 } |
337 | 415 |
OLD | NEW |