| 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 "GrRenderTargetContext.h" | 9 #include "GrRenderTargetContext.h" |
| 10 #include "GrCaps.h" | 10 #include "GrCaps.h" |
| 11 #include "GrContext.h" | 11 #include "GrContext.h" |
| 12 #include "GrFixedClip.h" | 12 #include "GrFixedClip.h" |
| 13 #include "effects/GrSimpleTextureEffect.h" | 13 #include "effects/GrSimpleTextureEffect.h" |
| 14 #include "GrStyle.h" | 14 #include "GrStyle.h" |
| 15 #include "GrTexture.h" | 15 #include "GrTexture.h" |
| 16 #include "GrTextureProxy.h" |
| 16 #include "GrTextureProvider.h" | 17 #include "GrTextureProvider.h" |
| 17 #include "SkDraw.h" | 18 #include "SkDraw.h" |
| 18 #include "SkGrPriv.h" | 19 #include "SkGrPriv.h" |
| 19 #include "SkMaskFilter.h" | 20 #include "SkMaskFilter.h" |
| 20 #include "SkPaint.h" | 21 #include "SkPaint.h" |
| 21 #include "SkTLazy.h" | 22 #include "SkTLazy.h" |
| 22 | 23 |
| 23 static bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& r
ect) { | 24 static bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& r
ect) { |
| 24 return clipBounds.isEmpty() || rect.isEmpty() || !SkIRect::Intersects(clipBo
unds, rect); | 25 return clipBounds.isEmpty() || rect.isEmpty() || !SkIRect::Intersects(clipBo
unds, rect); |
| 25 } | 26 } |
| 26 | 27 |
| 27 // Draw a mask using the supplied paint. Since the coverage/geometry | 28 // Draw a mask using the supplied paint. Since the coverage/geometry |
| 28 // is already burnt into the mask this boils down to a rect draw. | 29 // is already burnt into the mask this boils down to a rect draw. |
| 29 // Return true if the mask was successfully drawn. | 30 // Return true if the mask was successfully drawn. |
| 30 static bool draw_mask(GrRenderTargetContext* renderTargetContext, | 31 static bool draw_mask(GrRenderTargetContext* renderTargetContext, |
| 31 const GrClip& clip, | 32 const GrClip& clip, |
| 32 const SkMatrix& viewMatrix, | 33 const SkMatrix& viewMatrix, |
| 33 const SkIRect& maskRect, | 34 const SkIRect& maskRect, |
| 34 GrPaint* grp, | 35 GrPaint* grp, |
| 35 GrTexture* mask) { | 36 GrTextureProxy* mask) { |
| 36 SkMatrix matrix; | 37 SkMatrix matrix; |
| 37 matrix.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.
fTop)); | 38 matrix.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.
fTop)); |
| 38 matrix.postIDiv(mask->width(), mask->height()); | 39 matrix.postIDiv(mask->width(), mask->height()); |
| 39 matrix.preConcat(viewMatrix); | 40 matrix.preConcat(viewMatrix); |
| 40 grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(mask, nullptr,
matrix)); | 41 grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(mask, nullptr,
matrix)); |
| 41 | 42 |
| 42 SkMatrix inverse; | 43 SkMatrix inverse; |
| 43 if (!viewMatrix.invert(&inverse)) { | 44 if (!viewMatrix.invert(&inverse)) { |
| 44 return false; | 45 return false; |
| 45 } | 46 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 desc.fHeight = dstM.fBounds.height(); | 82 desc.fHeight = dstM.fBounds.height(); |
| 82 desc.fConfig = kAlpha_8_GrPixelConfig; | 83 desc.fConfig = kAlpha_8_GrPixelConfig; |
| 83 | 84 |
| 84 sk_sp<GrTexture> texture(textureProvider->createApproxTexture(desc)); | 85 sk_sp<GrTexture> texture(textureProvider->createApproxTexture(desc)); |
| 85 if (!texture) { | 86 if (!texture) { |
| 86 return false; | 87 return false; |
| 87 } | 88 } |
| 88 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, | 89 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, |
| 89 dstM.fImage, dstM.fRowBytes); | 90 dstM.fImage, dstM.fRowBytes); |
| 90 | 91 |
| 91 return draw_mask(renderTargetContext, clipData, viewMatrix, dstM.fBounds, gr
p, texture.get()); | 92 sk_sp<GrTextureProxy> proxy(GrTextureProxy::Make(texture)); |
| 93 return draw_mask(renderTargetContext, clipData, viewMatrix, dstM.fBounds, gr
p, proxy.get()); |
| 92 } | 94 } |
| 93 | 95 |
| 94 // Create a mask of 'devPath' and place the result in 'mask'. | 96 // Create a mask of 'devPath' and place the result in 'mask'. |
| 95 static sk_sp<GrTexture> create_mask_GPU(GrContext* context, | 97 static sk_sp<GrTextureProxy> create_mask_GPU(GrContext* context, |
| 96 const SkIRect& maskRect, | 98 const SkIRect& maskRect, |
| 97 const SkPath& devPath, | 99 const SkPath& devPath, |
| 98 SkStrokeRec::InitStyle fillOrHairline, | 100 SkStrokeRec::InitStyle fillOrHairli
ne, |
| 99 bool doAA, | 101 bool doAA, |
| 100 int sampleCnt) { | 102 int sampleCnt) { |
| 101 if (!doAA) { | 103 if (!doAA) { |
| 102 // Don't need MSAA if mask isn't AA | 104 // Don't need MSAA if mask isn't AA |
| 103 sampleCnt = 0; | 105 sampleCnt = 0; |
| 104 } | 106 } |
| 105 | 107 |
| 106 sk_sp<GrRenderTargetContext> renderTargetContext(context->makeRenderTargetCo
ntextWithFallback( | 108 sk_sp<GrRenderTargetContext> renderTargetContext(context->makeRenderTargetCo
ntextWithFallback( |
| 107 SkBackingFit::kApprox, maskRect.width(), maskRect.height(), kAlpha_8_GrP
ixelConfig, nullptr, | 109 SkBackingFit::kApprox, maskRect.width(), maskRect.height(), kAlpha_8_GrP
ixelConfig, nullptr, |
| 108 sampleCnt)); | 110 sampleCnt)); |
| 109 if (!renderTargetContext) { | 111 if (!renderTargetContext) { |
| 110 return nullptr; | 112 return nullptr; |
| 111 } | 113 } |
| 112 | 114 |
| 113 renderTargetContext->clear(nullptr, 0x0, true); | 115 renderTargetContext->clear(nullptr, 0x0, true); |
| 114 | 116 |
| 115 GrPaint tempPaint; | 117 GrPaint tempPaint; |
| 116 tempPaint.setAntiAlias(doAA); | 118 tempPaint.setAntiAlias(doAA); |
| 117 tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op); | 119 tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op); |
| 118 | 120 |
| 119 // setup new clip | 121 // setup new clip |
| 120 const SkIRect clipRect = SkIRect::MakeWH(maskRect.width(), maskRect.height()
); | 122 const SkIRect clipRect = SkIRect::MakeWH(maskRect.width(), maskRect.height()
); |
| 121 GrFixedClip clip(clipRect); | 123 GrFixedClip clip(clipRect); |
| 122 | 124 |
| 123 // Draw the mask into maskTexture with the path's integerized top-left at | 125 // Draw the mask into maskTexture with the path's integerized top-left at |
| 124 // the origin using tempPaint. | 126 // the origin using tempPaint. |
| 125 SkMatrix translate; | 127 SkMatrix translate; |
| 126 translate.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRe
ct.fTop)); | 128 translate.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRe
ct.fTop)); |
| 127 renderTargetContext->drawPath(clip, tempPaint, translate, devPath, GrStyle(f
illOrHairline)); | 129 renderTargetContext->drawPath(clip, tempPaint, translate, devPath, GrStyle(f
illOrHairline)); |
| 128 return renderTargetContext->asTexture();; | 130 return sk_ref_sp(renderTargetContext->asDeferredTexture()); |
| 129 } | 131 } |
| 130 | 132 |
| 131 static void draw_path_with_mask_filter(GrContext* context, | 133 static void draw_path_with_mask_filter(GrContext* context, |
| 132 GrRenderTargetContext* renderTargetContex
t, | 134 GrRenderTargetContext* renderTargetContex
t, |
| 133 const GrClip& clip, | 135 const GrClip& clip, |
| 134 GrPaint* paint, | 136 GrPaint* paint, |
| 135 const SkMatrix& viewMatrix, | 137 const SkMatrix& viewMatrix, |
| 136 const SkMaskFilter* maskFilter, | 138 const SkMaskFilter* maskFilter, |
| 137 const GrStyle& style, | 139 const GrStyle& style, |
| 138 const SkPath* path, | 140 const SkPath* path, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 paint, | 199 paint, |
| 198 clip, | 200 clip, |
| 199 viewMatrix, | 201 viewMatrix, |
| 200 SkStrokeRec(fillOrHairline), | 202 SkStrokeRec(fillOrHairline), |
| 201 *path)) { | 203 *path)) { |
| 202 // the mask filter was able to draw itself directly, so there's noth
ing | 204 // the mask filter was able to draw itself directly, so there's noth
ing |
| 203 // left to do. | 205 // left to do. |
| 204 return; | 206 return; |
| 205 } | 207 } |
| 206 | 208 |
| 207 sk_sp<GrTexture> mask(create_mask_GPU(context, | 209 sk_sp<GrTextureProxy> mask(create_mask_GPU(context, |
| 208 finalIRect, | 210 finalIRect, |
| 209 *path, | 211 *path, |
| 210 fillOrHairline, | 212 fillOrHairline, |
| 211 paint->isAntiAlias(), | 213 paint->isAntiAlias(), |
| 212 renderTargetContext->numColorSampl
es())); | 214 renderTargetContext->numColor
Samples())); |
| 213 if (mask) { | 215 if (mask) { |
| 214 GrTexture* filtered; | 216 GrTextureProxy* filtered; |
| 215 | 217 |
| 216 if (maskFilter->filterMaskGPU(mask.get(), viewMatrix, finalIRect, &f
iltered)) { | 218 if (maskFilter->filterMaskGPU(mask.get(), viewMatrix, finalIRect, &f
iltered)) { |
| 217 // filterMaskGPU gives us ownership of a ref to the result | 219 // filterMaskGPU gives us ownership of a ref to the result |
| 218 sk_sp<GrTexture> atu(filtered); | 220 sk_sp<GrTextureProxy> atu(filtered); |
| 219 if (draw_mask(renderTargetContext, clip, viewMatrix, finalIRect,
paint, filtered)) { | 221 if (draw_mask(renderTargetContext, clip, viewMatrix, finalIRect,
paint, filtered)) { |
| 220 // This path is completely drawn | 222 // This path is completely drawn |
| 221 return; | 223 return; |
| 222 } | 224 } |
| 223 } | 225 } |
| 224 } | 226 } |
| 225 } | 227 } |
| 226 | 228 |
| 227 sw_draw_with_mask_filter(renderTargetContext, context->textureProvider(), | 229 sw_draw_with_mask_filter(renderTargetContext, context->textureProvider(), |
| 228 clip, viewMatrix, *path, | 230 clip, viewMatrix, *path, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 SkMaskFilter* mf = paint.getMaskFilter(); | 288 SkMaskFilter* mf = paint.getMaskFilter(); |
| 287 if (mf && !mf->asFragmentProcessor(nullptr, nullptr, viewMatrix)) { | 289 if (mf && !mf->asFragmentProcessor(nullptr, nullptr, viewMatrix)) { |
| 288 // The MaskFilter wasn't already handled in SkPaintToGrPaint | 290 // The MaskFilter wasn't already handled in SkPaintToGrPaint |
| 289 draw_path_with_mask_filter(context, renderTargetContext, clip, &grPaint,
viewMatrix, | 291 draw_path_with_mask_filter(context, renderTargetContext, clip, &grPaint,
viewMatrix, |
| 290 mf, style, | 292 mf, style, |
| 291 path, pathIsMutable); | 293 path, pathIsMutable); |
| 292 } else { | 294 } else { |
| 293 renderTargetContext->drawPath(clip, grPaint, viewMatrix, *path, style); | 295 renderTargetContext->drawPath(clip, grPaint, viewMatrix, *path, style); |
| 294 } | 296 } |
| 295 } | 297 } |
| OLD | NEW |