robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #include "GrBlurUtils.h" |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 9 | |
bsalomon | 7622863 | 2015-05-29 08:02:10 -0700 | [diff] [blame] | 10 | #include "GrCaps.h" |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 11 | #include "GrContext.h" |
Robert Phillips | c949ce9 | 2017-01-19 16:59:04 -0500 | [diff] [blame] | 12 | #include "GrContextPriv.h" |
csmartdalton | 02fa32c | 2016-08-19 13:29:27 -0700 | [diff] [blame] | 13 | #include "GrFixedClip.h" |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 14 | #include "GrProxyProvider.h" |
| 15 | #include "GrRenderTargetContext.h" |
Robert Phillips | 784b7bf | 2016-12-09 13:35:02 -0500 | [diff] [blame] | 16 | #include "GrRenderTargetContextPriv.h" |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 17 | #include "GrStyle.h" |
robertphillips | d728f0c | 2016-11-21 11:05:03 -0800 | [diff] [blame] | 18 | #include "GrTextureProxy.h" |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 19 | #include "effects/GrSimpleTextureEffect.h" |
| 20 | |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 21 | #include "SkDraw.h" |
Brian Osman | 3b65598 | 2017-03-07 16:58:08 -0500 | [diff] [blame] | 22 | #include "SkGr.h" |
Mike Reed | 80747ef | 2018-01-23 15:29:32 -0500 | [diff] [blame] | 23 | #include "SkMaskFilterBase.h" |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 24 | #include "SkPaint.h" |
csmartdalton | c6f411e | 2016-08-05 22:32:12 -0700 | [diff] [blame] | 25 | #include "SkTLazy.h" |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 26 | |
| 27 | static bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& rect) { |
| 28 | return clipBounds.isEmpty() || rect.isEmpty() || !SkIRect::Intersects(clipBounds, rect); |
| 29 | } |
| 30 | |
| 31 | // Draw a mask using the supplied paint. Since the coverage/geometry |
| 32 | // is already burnt into the mask this boils down to a rect draw. |
| 33 | // Return true if the mask was successfully drawn. |
Robert Phillips | 296b1cc | 2017-03-15 10:42:12 -0400 | [diff] [blame] | 34 | static bool draw_mask(GrRenderTargetContext* renderTargetContext, |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 35 | const GrClip& clip, |
| 36 | const SkMatrix& viewMatrix, |
robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 37 | const SkIRect& maskRect, |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 38 | GrPaint&& paint, |
Robert Phillips | 4a24da5 | 2016-12-14 09:00:07 -0500 | [diff] [blame] | 39 | sk_sp<GrTextureProxy> mask) { |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 40 | SkMatrix inverse; |
| 41 | if (!viewMatrix.invert(&inverse)) { |
| 42 | return false; |
| 43 | } |
Robert Phillips | 4a24da5 | 2016-12-14 09:00:07 -0500 | [diff] [blame] | 44 | |
Robert Phillips | 67c18d6 | 2017-01-20 12:44:06 -0500 | [diff] [blame] | 45 | SkMatrix matrix = SkMatrix::MakeTrans(-SkIntToScalar(maskRect.fLeft), |
| 46 | -SkIntToScalar(maskRect.fTop)); |
Brian Salomon | 2ebd0c8 | 2016-10-03 17:15:28 -0400 | [diff] [blame] | 47 | matrix.preConcat(viewMatrix); |
Brian Osman | 2240be9 | 2017-10-18 13:15:13 -0400 | [diff] [blame] | 48 | paint.addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(std::move(mask), matrix)); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 49 | |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 50 | renderTargetContext->fillRectWithLocalMatrix(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), |
Brian Salomon | 0e8fc8b | 2016-12-09 15:10:07 -0500 | [diff] [blame] | 51 | SkRect::Make(maskRect), inverse); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 52 | return true; |
| 53 | } |
| 54 | |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 55 | static void mask_release_proc(void* addr, void* /*context*/) { |
| 56 | SkMask::FreeImage(addr); |
| 57 | } |
| 58 | |
Robert Phillips | 4a24da5 | 2016-12-14 09:00:07 -0500 | [diff] [blame] | 59 | static bool sw_draw_with_mask_filter(GrContext* context, |
| 60 | GrRenderTargetContext* renderTargetContext, |
robertphillips | 0e7029e | 2015-11-30 05:45:06 -0800 | [diff] [blame] | 61 | const GrClip& clipData, |
| 62 | const SkMatrix& viewMatrix, |
| 63 | const SkPath& devPath, |
| 64 | const SkMaskFilter* filter, |
| 65 | const SkIRect& clipBounds, |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 66 | GrPaint&& paint, |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 67 | SkStrokeRec::InitStyle fillOrHairline) { |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 68 | SkMask srcM, dstM; |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 69 | if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM, |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 70 | SkMask::kComputeBoundsAndRenderImage_CreateMode, fillOrHairline)) { |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 71 | return false; |
| 72 | } |
| 73 | SkAutoMaskFreeImage autoSrc(srcM.fImage); |
| 74 | |
Mike Reed | 80747ef | 2018-01-23 15:29:32 -0500 | [diff] [blame] | 75 | if (!as_MFB(filter)->filterMask(&dstM, srcM, viewMatrix, nullptr)) { |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 76 | return false; |
| 77 | } |
| 78 | // this will free-up dstM when we're done (allocated in filterMask()) |
| 79 | SkAutoMaskFreeImage autoDst(dstM.fImage); |
| 80 | |
| 81 | if (clip_bounds_quick_reject(clipBounds, dstM.fBounds)) { |
| 82 | return false; |
| 83 | } |
| 84 | |
| 85 | // we now have a device-aligned 8bit mask in dstM, ready to be drawn using |
| 86 | // the current clip (and identity matrix) and GrPaint settings |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 87 | SkBitmap bm; |
| 88 | if (!bm.installPixels(SkImageInfo::MakeA8(dstM.fBounds.width(), dstM.fBounds.height()), |
| 89 | autoDst.release(), dstM.fRowBytes, mask_release_proc, nullptr)) { |
Robert Phillips | 4a24da5 | 2016-12-14 09:00:07 -0500 | [diff] [blame] | 90 | return false; |
| 91 | } |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 92 | bm.setImmutable(); |
Robert Phillips | 4a24da5 | 2016-12-14 09:00:07 -0500 | [diff] [blame] | 93 | |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 94 | sk_sp<SkImage> image = SkImage::MakeFromBitmap(bm); |
Robert Phillips | 48ce22b | 2018-03-23 10:33:12 -0400 | [diff] [blame] | 95 | if (!image) { |
| 96 | return false; |
| 97 | } |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 98 | |
| 99 | auto proxyProvider = context->contextPriv().proxyProvider(); |
| 100 | sk_sp<GrTextureProxy> maskProxy = proxyProvider->createTextureProxy(std::move(image), |
| 101 | kNone_GrSurfaceFlags, |
| 102 | 1, SkBudgeted::kYes, |
| 103 | SkBackingFit::kApprox); |
Robert Phillips | 48ce22b | 2018-03-23 10:33:12 -0400 | [diff] [blame] | 104 | if (!maskProxy) { |
| 105 | return false; |
| 106 | } |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 107 | |
Robert Phillips | 296b1cc | 2017-03-15 10:42:12 -0400 | [diff] [blame] | 108 | return draw_mask(renderTargetContext, clipData, viewMatrix, |
Robert Phillips | c7c2baf | 2018-03-08 09:51:04 -0500 | [diff] [blame] | 109 | dstM.fBounds, std::move(paint), std::move(maskProxy)); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | // Create a mask of 'devPath' and place the result in 'mask'. |
robertphillips | d728f0c | 2016-11-21 11:05:03 -0800 | [diff] [blame] | 113 | static sk_sp<GrTextureProxy> create_mask_GPU(GrContext* context, |
| 114 | const SkIRect& maskRect, |
| 115 | const SkPath& devPath, |
| 116 | SkStrokeRec::InitStyle fillOrHairline, |
Brian Salomon | 0e8fc8b | 2016-12-09 15:10:07 -0500 | [diff] [blame] | 117 | GrAA aa, |
robertphillips | d728f0c | 2016-11-21 11:05:03 -0800 | [diff] [blame] | 118 | int sampleCnt) { |
Brian Salomon | 0e8fc8b | 2016-12-09 15:10:07 -0500 | [diff] [blame] | 119 | if (GrAA::kNo == aa) { |
robertphillips | d4c741e | 2016-04-28 09:55:15 -0700 | [diff] [blame] | 120 | // Don't need MSAA if mask isn't AA |
Brian Salomon | bdecacf | 2018-02-02 20:32:49 -0500 | [diff] [blame] | 121 | sampleCnt = 1; |
robertphillips | d4c741e | 2016-04-28 09:55:15 -0700 | [diff] [blame] | 122 | } |
| 123 | |
Robert Phillips | 0c4b7b1 | 2018-03-06 08:20:37 -0500 | [diff] [blame] | 124 | sk_sp<GrRenderTargetContext> rtContext( |
| 125 | context->contextPriv().makeDeferredRenderTargetContextWithFallback( |
| 126 | SkBackingFit::kApprox, maskRect.width(), maskRect.height(), kAlpha_8_GrPixelConfig, |
| 127 | nullptr, sampleCnt)); |
robertphillips | d728f0c | 2016-11-21 11:05:03 -0800 | [diff] [blame] | 128 | if (!rtContext) { |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 129 | return nullptr; |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 130 | } |
| 131 | |
Robert Phillips | 784b7bf | 2016-12-09 13:35:02 -0500 | [diff] [blame] | 132 | rtContext->priv().absClear(nullptr, 0x0); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 133 | |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 134 | GrPaint maskPaint; |
| 135 | maskPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 136 | |
| 137 | // setup new clip |
cdalton | 846c051 | 2016-05-13 10:25:00 -0700 | [diff] [blame] | 138 | const SkIRect clipRect = SkIRect::MakeWH(maskRect.width(), maskRect.height()); |
| 139 | GrFixedClip clip(clipRect); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 140 | |
robertphillips | 3833daa | 2015-09-14 11:18:13 -0700 | [diff] [blame] | 141 | // Draw the mask into maskTexture with the path's integerized top-left at |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 142 | // the origin using maskPaint. |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 143 | SkMatrix translate; |
robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 144 | translate.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop)); |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 145 | rtContext->drawPath(clip, std::move(maskPaint), aa, translate, devPath, |
| 146 | GrStyle(fillOrHairline)); |
Robert Phillips | f200a90 | 2017-01-30 13:27:37 -0500 | [diff] [blame] | 147 | return rtContext->asTextureProxyRef(); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 148 | } |
| 149 | |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 150 | static void draw_path_with_mask_filter(GrContext* context, |
Brian Osman | 1105224 | 2016-10-27 14:47:55 -0400 | [diff] [blame] | 151 | GrRenderTargetContext* renderTargetContext, |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 152 | const GrClip& clip, |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 153 | GrPaint&& paint, |
Brian Salomon | 0e8fc8b | 2016-12-09 15:10:07 -0500 | [diff] [blame] | 154 | GrAA aa, |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 155 | const SkMatrix& viewMatrix, |
Mike Reed | 80747ef | 2018-01-23 15:29:32 -0500 | [diff] [blame] | 156 | const SkMaskFilterBase* maskFilter, |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 157 | const GrStyle& style, |
| 158 | const SkPath* path, |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 159 | bool pathIsMutable) { |
| 160 | SkASSERT(maskFilter); |
| 161 | |
| 162 | SkIRect clipBounds; |
Robert Phillips | 784b7bf | 2016-12-09 13:35:02 -0500 | [diff] [blame] | 163 | clip.getConservativeBounds(renderTargetContext->width(), |
| 164 | renderTargetContext->height(), |
Brian Osman | 1105224 | 2016-10-27 14:47:55 -0400 | [diff] [blame] | 165 | &clipBounds); |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 166 | SkTLazy<SkPath> tmpPath; |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 167 | SkStrokeRec::InitStyle fillOrHairline; |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 168 | |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 169 | // We just fully apply the style here. |
| 170 | if (style.applies()) { |
senorblanco | b6a40b8 | 2016-08-19 08:07:22 -0700 | [diff] [blame] | 171 | SkScalar scale = GrStyle::MatrixToScaleFactor(viewMatrix); |
| 172 | if (0 == scale || !style.applyToPath(tmpPath.init(), &fillOrHairline, *path, scale)) { |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 173 | return; |
| 174 | } |
| 175 | pathIsMutable = true; |
| 176 | path = tmpPath.get(); |
| 177 | } else if (style.isSimpleHairline()) { |
| 178 | fillOrHairline = SkStrokeRec::kHairline_InitStyle; |
bsalomon | 055e192 | 2016-05-06 07:22:58 -0700 | [diff] [blame] | 179 | } else { |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 180 | SkASSERT(style.isSimpleFill()); |
| 181 | fillOrHairline = SkStrokeRec::kFill_InitStyle; |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 182 | } |
| 183 | |
| 184 | // transform the path into device space |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 185 | if (!viewMatrix.isIdentity()) { |
| 186 | SkPath* result; |
| 187 | if (pathIsMutable) { |
| 188 | result = const_cast<SkPath*>(path); |
| 189 | } else { |
| 190 | if (!tmpPath.isValid()) { |
| 191 | tmpPath.init(); |
| 192 | } |
| 193 | result = tmpPath.get(); |
| 194 | } |
| 195 | path->transform(viewMatrix, result); |
| 196 | path = result; |
| 197 | result->setIsVolatile(true); |
| 198 | pathIsMutable = true; |
| 199 | } |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 200 | |
| 201 | SkRect maskRect; |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 202 | if (maskFilter->canFilterMaskGPU(SkRRect::MakeRect(path->getBounds()), |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 203 | clipBounds, |
| 204 | viewMatrix, |
| 205 | &maskRect)) { |
robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 206 | // This mask will ultimately be drawn as a non-AA rect (see draw_mask). |
| 207 | // Non-AA rects have a bad habit of snapping arbitrarily. Integerize here |
| 208 | // so the mask draws in a reproducible manner. |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 209 | SkIRect finalIRect; |
| 210 | maskRect.roundOut(&finalIRect); |
| 211 | if (clip_bounds_quick_reject(clipBounds, finalIRect)) { |
| 212 | // clipped out |
| 213 | return; |
| 214 | } |
| 215 | |
Robert Phillips | d374948 | 2017-03-14 09:17:43 -0400 | [diff] [blame] | 216 | if (maskFilter->directFilterMaskGPU(context, |
Brian Osman | 1105224 | 2016-10-27 14:47:55 -0400 | [diff] [blame] | 217 | renderTargetContext, |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 218 | std::move(paint), |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 219 | clip, |
| 220 | viewMatrix, |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 221 | SkStrokeRec(fillOrHairline), |
| 222 | *path)) { |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 223 | // the mask filter was able to draw itself directly, so there's nothing |
| 224 | // left to do. |
| 225 | return; |
| 226 | } |
| 227 | |
robertphillips | d728f0c | 2016-11-21 11:05:03 -0800 | [diff] [blame] | 228 | sk_sp<GrTextureProxy> maskProxy(create_mask_GPU(context, |
| 229 | finalIRect, |
| 230 | *path, |
| 231 | fillOrHairline, |
Brian Salomon | 0e8fc8b | 2016-12-09 15:10:07 -0500 | [diff] [blame] | 232 | aa, |
robertphillips | d728f0c | 2016-11-21 11:05:03 -0800 | [diff] [blame] | 233 | renderTargetContext->numColorSamples())); |
| 234 | if (maskProxy) { |
Robert Phillips | 4a24da5 | 2016-12-14 09:00:07 -0500 | [diff] [blame] | 235 | sk_sp<GrTextureProxy> filtered = maskFilter->filterMaskGPU(context, |
| 236 | std::move(maskProxy), |
| 237 | viewMatrix, |
| 238 | finalIRect); |
| 239 | if (filtered) { |
Robert Phillips | 296b1cc | 2017-03-15 10:42:12 -0400 | [diff] [blame] | 240 | if (draw_mask(renderTargetContext, clip, viewMatrix, |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 241 | finalIRect, std::move(paint), std::move(filtered))) { |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 242 | // This path is completely drawn |
| 243 | return; |
| 244 | } |
| 245 | } |
| 246 | } |
| 247 | } |
| 248 | |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 249 | sw_draw_with_mask_filter(context, renderTargetContext, clip, viewMatrix, *path, maskFilter, |
| 250 | clipBounds, std::move(paint), fillOrHairline); |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 251 | } |
| 252 | |
| 253 | void GrBlurUtils::drawPathWithMaskFilter(GrContext* context, |
Brian Osman | 1105224 | 2016-10-27 14:47:55 -0400 | [diff] [blame] | 254 | GrRenderTargetContext* renderTargetContext, |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 255 | const GrClip& clip, |
| 256 | const SkPath& path, |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 257 | GrPaint&& paint, |
Brian Salomon | 0e8fc8b | 2016-12-09 15:10:07 -0500 | [diff] [blame] | 258 | GrAA aa, |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 259 | const SkMatrix& viewMatrix, |
| 260 | const SkMaskFilter* mf, |
| 261 | const GrStyle& style, |
| 262 | bool pathIsMutable) { |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 263 | draw_path_with_mask_filter(context, renderTargetContext, clip, std::move(paint), aa, viewMatrix, |
Mike Reed | 80747ef | 2018-01-23 15:29:32 -0500 | [diff] [blame] | 264 | as_MFB(mf), style, &path, pathIsMutable); |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 265 | } |
| 266 | |
| 267 | void GrBlurUtils::drawPathWithMaskFilter(GrContext* context, |
Brian Osman | 1105224 | 2016-10-27 14:47:55 -0400 | [diff] [blame] | 268 | GrRenderTargetContext* renderTargetContext, |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 269 | const GrClip& clip, |
| 270 | const SkPath& origPath, |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 271 | const SkPaint& paint, |
| 272 | const SkMatrix& origViewMatrix, |
| 273 | const SkMatrix* prePathMatrix, |
| 274 | const SkIRect& clipBounds, |
| 275 | bool pathIsMutable) { |
Khushal | c421ca1 | 2018-06-26 14:38:34 -0700 | [diff] [blame] | 276 | if (context->abandoned()) { |
Robert Phillips | bebfd41 | 2018-03-08 11:07:23 -0500 | [diff] [blame] | 277 | return; |
| 278 | } |
| 279 | |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 280 | SkASSERT(!pathIsMutable || origPath.isVolatile()); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 281 | |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 282 | GrStyle style(paint); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 283 | // If we have a prematrix, apply it to the path, optimizing for the case |
| 284 | // where the original path can in fact be modified in place (even though |
| 285 | // its parameter type is const). |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 286 | |
| 287 | const SkPath* path = &origPath; |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 288 | SkTLazy<SkPath> tmpPath; |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 289 | |
| 290 | SkMatrix viewMatrix = origViewMatrix; |
| 291 | |
| 292 | if (prePathMatrix) { |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 293 | // Styling, blurs, and shading are supposed to be applied *after* the prePathMatrix. |
| 294 | if (!paint.getMaskFilter() && !paint.getShader() && !style.applies()) { |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 295 | viewMatrix.preConcat(*prePathMatrix); |
| 296 | } else { |
bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 297 | SkPath* result = pathIsMutable ? const_cast<SkPath*>(path) : tmpPath.init(); |
| 298 | pathIsMutable = true; |
| 299 | path->transform(*prePathMatrix, result); |
| 300 | path = result; |
| 301 | result->setIsVolatile(true); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 302 | } |
| 303 | } |
| 304 | // at this point we're done with prePathMatrix |
| 305 | SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) |
| 306 | |
| 307 | GrPaint grPaint; |
Brian Salomon | f3569f0 | 2017-10-24 12:52:33 -0400 | [diff] [blame] | 308 | if (!SkPaintToGrPaint(context, renderTargetContext->colorSpaceInfo(), paint, viewMatrix, |
| 309 | &grPaint)) { |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 310 | return; |
| 311 | } |
Chris Dalton | 3b51df1 | 2017-11-27 14:33:06 -0700 | [diff] [blame] | 312 | GrAA aa = GrAA(paint.isAntiAlias()); |
Mike Reed | 80747ef | 2018-01-23 15:29:32 -0500 | [diff] [blame] | 313 | SkMaskFilterBase* mf = as_MFB(paint.getMaskFilter()); |
Mike Reed | bfadcf0 | 2018-01-20 22:24:21 +0000 | [diff] [blame] | 314 | if (mf && !mf->hasFragmentProcessor()) { |
Robert Phillips | a29a956 | 2016-10-20 09:40:55 -0400 | [diff] [blame] | 315 | // The MaskFilter wasn't already handled in SkPaintToGrPaint |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 316 | draw_path_with_mask_filter(context, renderTargetContext, clip, std::move(grPaint), aa, |
| 317 | viewMatrix, mf, style, path, pathIsMutable); |
bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 318 | } else { |
Brian Salomon | 82f4431 | 2017-01-11 13:42:54 -0500 | [diff] [blame] | 319 | renderTargetContext->drawPath(clip, std::move(grPaint), aa, viewMatrix, *path, style); |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 320 | } |
robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 321 | } |