| 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" | 
|  | 9 | #include "GrDrawContext.h" | 
| 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" | 
| csmartdalton | 02fa32c | 2016-08-19 13:29:27 -0700 | [diff] [blame^] | 12 | #include "GrFixedClip.h" | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 13 | #include "effects/GrSimpleTextureEffect.h" | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 14 | #include "GrStyle.h" | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 15 | #include "GrTexture.h" | 
|  | 16 | #include "GrTextureProvider.h" | 
|  | 17 | #include "SkDraw.h" | 
| bsalomon | f1b7a1d | 2015-09-28 06:26:28 -0700 | [diff] [blame] | 18 | #include "SkGrPriv.h" | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 19 | #include "SkMaskFilter.h" | 
|  | 20 | #include "SkPaint.h" | 
| csmartdalton | c6f411e | 2016-08-05 22:32:12 -0700 | [diff] [blame] | 21 | #include "SkTLazy.h" | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 22 |  | 
|  | 23 | static bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& rect) { | 
|  | 24 | return clipBounds.isEmpty() || rect.isEmpty() || !SkIRect::Intersects(clipBounds, rect); | 
|  | 25 | } | 
|  | 26 |  | 
|  | 27 | // 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 | // Return true if the mask was successfully drawn. | 
|  | 30 | static bool draw_mask(GrDrawContext* drawContext, | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 31 | const GrClip& clip, | 
|  | 32 | const SkMatrix& viewMatrix, | 
| robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 33 | const SkIRect& maskRect, | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 34 | GrPaint* grp, | 
|  | 35 | GrTexture* mask) { | 
|  | 36 | SkMatrix matrix; | 
| robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 37 | matrix.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop)); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 38 | matrix.postIDiv(mask->width(), mask->height()); | 
|  | 39 |  | 
| brianosman | 54f30c1 | 2016-07-18 10:53:52 -0700 | [diff] [blame] | 40 | grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(mask, nullptr, matrix, | 
| bungeman | 06ca8ec | 2016-06-09 08:01:03 -0700 | [diff] [blame] | 41 | kDevice_GrCoordSet)); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 42 |  | 
|  | 43 | SkMatrix inverse; | 
|  | 44 | if (!viewMatrix.invert(&inverse)) { | 
|  | 45 | return false; | 
|  | 46 | } | 
| robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 47 | drawContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), | 
|  | 48 | SkRect::Make(maskRect), inverse); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 49 | return true; | 
|  | 50 | } | 
|  | 51 |  | 
| robertphillips | 0e7029e | 2015-11-30 05:45:06 -0800 | [diff] [blame] | 52 | static bool sw_draw_with_mask_filter(GrDrawContext* drawContext, | 
|  | 53 | GrTextureProvider* textureProvider, | 
|  | 54 | const GrClip& clipData, | 
|  | 55 | const SkMatrix& viewMatrix, | 
|  | 56 | const SkPath& devPath, | 
|  | 57 | const SkMaskFilter* filter, | 
|  | 58 | const SkIRect& clipBounds, | 
|  | 59 | GrPaint* grp, | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 60 | SkStrokeRec::InitStyle fillOrHairline) { | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 61 | SkMask  srcM, dstM; | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 62 | if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM, | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 63 | SkMask::kComputeBoundsAndRenderImage_CreateMode, fillOrHairline)) { | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 64 | return false; | 
|  | 65 | } | 
|  | 66 | SkAutoMaskFreeImage autoSrc(srcM.fImage); | 
|  | 67 |  | 
| halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 68 | if (!filter->filterMask(&dstM, srcM, viewMatrix, nullptr)) { | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 69 | return false; | 
|  | 70 | } | 
|  | 71 | // this will free-up dstM when we're done (allocated in filterMask()) | 
|  | 72 | SkAutoMaskFreeImage autoDst(dstM.fImage); | 
|  | 73 |  | 
|  | 74 | if (clip_bounds_quick_reject(clipBounds, dstM.fBounds)) { | 
|  | 75 | return false; | 
|  | 76 | } | 
|  | 77 |  | 
|  | 78 | // we now have a device-aligned 8bit mask in dstM, ready to be drawn using | 
|  | 79 | // the current clip (and identity matrix) and GrPaint settings | 
|  | 80 | GrSurfaceDesc desc; | 
|  | 81 | desc.fWidth = dstM.fBounds.width(); | 
|  | 82 | desc.fHeight = dstM.fBounds.height(); | 
|  | 83 | desc.fConfig = kAlpha_8_GrPixelConfig; | 
|  | 84 |  | 
| bsalomon | eae6200 | 2015-07-31 13:59:30 -0700 | [diff] [blame] | 85 | SkAutoTUnref<GrTexture> texture(textureProvider->createApproxTexture(desc)); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 86 | if (!texture) { | 
|  | 87 | return false; | 
|  | 88 | } | 
|  | 89 | texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, | 
|  | 90 | dstM.fImage, dstM.fRowBytes); | 
|  | 91 |  | 
| robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 92 | return draw_mask(drawContext, clipData, viewMatrix, dstM.fBounds, grp, texture); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 93 | } | 
|  | 94 |  | 
|  | 95 | // Create a mask of 'devPath' and place the result in 'mask'. | 
| robertphillips | d4c741e | 2016-04-28 09:55:15 -0700 | [diff] [blame] | 96 | static sk_sp<GrTexture> create_mask_GPU(GrContext* context, | 
| robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 97 | const SkIRect& maskRect, | 
| robertphillips | d4c741e | 2016-04-28 09:55:15 -0700 | [diff] [blame] | 98 | const SkPath& devPath, | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 99 | SkStrokeRec::InitStyle fillOrHairline, | 
| robertphillips | d4c741e | 2016-04-28 09:55:15 -0700 | [diff] [blame] | 100 | bool doAA, | 
|  | 101 | int sampleCnt) { | 
| robertphillips | d4c741e | 2016-04-28 09:55:15 -0700 | [diff] [blame] | 102 | if (!doAA) { | 
|  | 103 | // Don't need MSAA if mask isn't AA | 
|  | 104 | sampleCnt = 0; | 
|  | 105 | } | 
|  | 106 |  | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 107 | // We actually only need A8, but it often isn't supported as a | 
|  | 108 | // render target so default to RGBA_8888 | 
| robertphillips | d4c741e | 2016-04-28 09:55:15 -0700 | [diff] [blame] | 109 | GrPixelConfig config = kRGBA_8888_GrPixelConfig; | 
|  | 110 | if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, sampleCnt > 0)) { | 
|  | 111 | config = kAlpha_8_GrPixelConfig; | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 112 | } | 
|  | 113 |  | 
| robertphillips | 6738c70 | 2016-07-27 12:13:51 -0700 | [diff] [blame] | 114 | sk_sp<GrDrawContext> drawContext(context->makeDrawContext(SkBackingFit::kApprox, | 
|  | 115 | maskRect.width(), | 
|  | 116 | maskRect.height(), | 
|  | 117 | config, | 
|  | 118 | nullptr, | 
|  | 119 | sampleCnt)); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 120 | if (!drawContext) { | 
| halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 121 | return nullptr; | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 122 | } | 
|  | 123 |  | 
| robertphillips | 2e1e51f | 2015-10-15 08:01:48 -0700 | [diff] [blame] | 124 | drawContext->clear(nullptr, 0x0, true); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 125 |  | 
|  | 126 | GrPaint tempPaint; | 
|  | 127 | tempPaint.setAntiAlias(doAA); | 
|  | 128 | tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op); | 
|  | 129 |  | 
|  | 130 | // setup new clip | 
| cdalton | 846c051 | 2016-05-13 10:25:00 -0700 | [diff] [blame] | 131 | const SkIRect clipRect = SkIRect::MakeWH(maskRect.width(), maskRect.height()); | 
|  | 132 | GrFixedClip clip(clipRect); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 133 |  | 
| robertphillips | 3833daa | 2015-09-14 11:18:13 -0700 | [diff] [blame] | 134 | // Draw the mask into maskTexture with the path's integerized top-left at | 
|  | 135 | // the origin using tempPaint. | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 136 | SkMatrix translate; | 
| robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 137 | translate.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop)); | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 138 | drawContext->drawPath(clip, tempPaint, translate, devPath, GrStyle(fillOrHairline)); | 
| robertphillips | d4c741e | 2016-04-28 09:55:15 -0700 | [diff] [blame] | 139 | return drawContext->asTexture();; | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 140 | } | 
|  | 141 |  | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 142 | static void draw_path_with_mask_filter(GrContext* context, | 
|  | 143 | GrDrawContext* drawContext, | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 144 | const GrClip& clip, | 
|  | 145 | GrPaint* paint, | 
|  | 146 | const SkMatrix& viewMatrix, | 
|  | 147 | const SkMaskFilter* maskFilter, | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 148 | const GrStyle& style, | 
|  | 149 | const SkPath* path, | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 150 | bool pathIsMutable) { | 
|  | 151 | SkASSERT(maskFilter); | 
|  | 152 |  | 
|  | 153 | SkIRect clipBounds; | 
| robertphillips | 7bceedc | 2015-12-01 12:51:26 -0800 | [diff] [blame] | 154 | clip.getConservativeBounds(drawContext->width(), drawContext->height(), &clipBounds); | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 155 | SkTLazy<SkPath> tmpPath; | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 156 | SkStrokeRec::InitStyle fillOrHairline; | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 157 |  | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 158 | // We just fully apply the style here. | 
|  | 159 | if (style.applies()) { | 
| senorblanco | b6a40b8 | 2016-08-19 08:07:22 -0700 | [diff] [blame] | 160 | SkScalar scale = GrStyle::MatrixToScaleFactor(viewMatrix); | 
|  | 161 | if (0 == scale || !style.applyToPath(tmpPath.init(), &fillOrHairline, *path, scale)) { | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 162 | return; | 
|  | 163 | } | 
|  | 164 | pathIsMutable = true; | 
|  | 165 | path = tmpPath.get(); | 
|  | 166 | } else if (style.isSimpleHairline()) { | 
|  | 167 | fillOrHairline = SkStrokeRec::kHairline_InitStyle; | 
| bsalomon | 055e192 | 2016-05-06 07:22:58 -0700 | [diff] [blame] | 168 | } else { | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 169 | SkASSERT(style.isSimpleFill()); | 
|  | 170 | fillOrHairline = SkStrokeRec::kFill_InitStyle; | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 171 | } | 
|  | 172 |  | 
|  | 173 | // transform the path into device space | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 174 | if (!viewMatrix.isIdentity()) { | 
|  | 175 | SkPath* result; | 
|  | 176 | if (pathIsMutable) { | 
|  | 177 | result = const_cast<SkPath*>(path); | 
|  | 178 | } else { | 
|  | 179 | if (!tmpPath.isValid()) { | 
|  | 180 | tmpPath.init(); | 
|  | 181 | } | 
|  | 182 | result = tmpPath.get(); | 
|  | 183 | } | 
|  | 184 | path->transform(viewMatrix, result); | 
|  | 185 | path = result; | 
|  | 186 | result->setIsVolatile(true); | 
|  | 187 | pathIsMutable = true; | 
|  | 188 | } | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 189 |  | 
|  | 190 | SkRect maskRect; | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 191 | if (maskFilter->canFilterMaskGPU(SkRRect::MakeRect(path->getBounds()), | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 192 | clipBounds, | 
|  | 193 | viewMatrix, | 
|  | 194 | &maskRect)) { | 
| robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 195 | // This mask will ultimately be drawn as a non-AA rect (see draw_mask). | 
|  | 196 | // Non-AA rects have a bad habit of snapping arbitrarily. Integerize here | 
|  | 197 | // so the mask draws in a reproducible manner. | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 198 | SkIRect finalIRect; | 
|  | 199 | maskRect.roundOut(&finalIRect); | 
|  | 200 | if (clip_bounds_quick_reject(clipBounds, finalIRect)) { | 
|  | 201 | // clipped out | 
|  | 202 | return; | 
|  | 203 | } | 
|  | 204 |  | 
|  | 205 | if (maskFilter->directFilterMaskGPU(context->textureProvider(), | 
|  | 206 | drawContext, | 
|  | 207 | paint, | 
|  | 208 | clip, | 
|  | 209 | viewMatrix, | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 210 | SkStrokeRec(fillOrHairline), | 
|  | 211 | *path)) { | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 212 | // the mask filter was able to draw itself directly, so there's nothing | 
|  | 213 | // left to do. | 
|  | 214 | return; | 
|  | 215 | } | 
|  | 216 |  | 
| robertphillips | d4c741e | 2016-04-28 09:55:15 -0700 | [diff] [blame] | 217 | sk_sp<GrTexture> mask(create_mask_GPU(context, | 
| robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 218 | finalIRect, | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 219 | *path, | 
|  | 220 | fillOrHairline, | 
| robertphillips | d4c741e | 2016-04-28 09:55:15 -0700 | [diff] [blame] | 221 | paint->isAntiAlias(), | 
|  | 222 | drawContext->numColorSamples())); | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 223 | if (mask) { | 
|  | 224 | GrTexture* filtered; | 
|  | 225 |  | 
| robertphillips | 8bad3ac | 2016-06-27 11:11:05 -0700 | [diff] [blame] | 226 | if (maskFilter->filterMaskGPU(mask.get(), viewMatrix, finalIRect, &filtered)) { | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 227 | // filterMaskGPU gives us ownership of a ref to the result | 
|  | 228 | SkAutoTUnref<GrTexture> atu(filtered); | 
| robertphillips | f054b17 | 2016-05-13 05:06:19 -0700 | [diff] [blame] | 229 | if (draw_mask(drawContext, clip, viewMatrix, finalIRect, paint, filtered)) { | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 230 | // This path is completely drawn | 
|  | 231 | return; | 
|  | 232 | } | 
|  | 233 | } | 
|  | 234 | } | 
|  | 235 | } | 
|  | 236 |  | 
| robertphillips | 0e7029e | 2015-11-30 05:45:06 -0800 | [diff] [blame] | 237 | sw_draw_with_mask_filter(drawContext, context->textureProvider(), | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 238 | clip, viewMatrix, *path, | 
|  | 239 | maskFilter, clipBounds, paint, fillOrHairline); | 
|  | 240 | } | 
|  | 241 |  | 
|  | 242 | void GrBlurUtils::drawPathWithMaskFilter(GrContext* context, | 
|  | 243 | GrDrawContext* drawContext, | 
|  | 244 | const GrClip& clip, | 
|  | 245 | const SkPath& path, | 
|  | 246 | GrPaint* paint, | 
|  | 247 | const SkMatrix& viewMatrix, | 
|  | 248 | const SkMaskFilter* mf, | 
|  | 249 | const GrStyle& style, | 
|  | 250 | bool pathIsMutable) { | 
|  | 251 | draw_path_with_mask_filter(context, drawContext, clip, paint, viewMatrix, mf, | 
|  | 252 | style, &path, pathIsMutable); | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 253 | } | 
|  | 254 |  | 
|  | 255 | void GrBlurUtils::drawPathWithMaskFilter(GrContext* context, | 
|  | 256 | GrDrawContext* drawContext, | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 257 | const GrClip& clip, | 
|  | 258 | const SkPath& origPath, | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 259 | const SkPaint& paint, | 
|  | 260 | const SkMatrix& origViewMatrix, | 
|  | 261 | const SkMatrix* prePathMatrix, | 
|  | 262 | const SkIRect& clipBounds, | 
|  | 263 | bool pathIsMutable) { | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 264 | SkASSERT(!pathIsMutable || origPath.isVolatile()); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 265 |  | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 266 | GrStyle style(paint); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 267 | // If we have a prematrix, apply it to the path, optimizing for the case | 
|  | 268 | // where the original path can in fact be modified in place (even though | 
|  | 269 | // its parameter type is const). | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 270 |  | 
|  | 271 | const SkPath* path = &origPath; | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 272 | SkTLazy<SkPath> tmpPath; | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 273 |  | 
|  | 274 | SkMatrix viewMatrix = origViewMatrix; | 
|  | 275 |  | 
|  | 276 | if (prePathMatrix) { | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 277 | // Styling, blurs, and shading are supposed to be applied *after* the prePathMatrix. | 
|  | 278 | if (!paint.getMaskFilter() && !paint.getShader() && !style.applies()) { | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 279 | viewMatrix.preConcat(*prePathMatrix); | 
|  | 280 | } else { | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 281 | SkPath* result = pathIsMutable ? const_cast<SkPath*>(path) : tmpPath.init(); | 
|  | 282 | pathIsMutable = true; | 
|  | 283 | path->transform(*prePathMatrix, result); | 
|  | 284 | path = result; | 
|  | 285 | result->setIsVolatile(true); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 286 | } | 
|  | 287 | } | 
|  | 288 | // at this point we're done with prePathMatrix | 
|  | 289 | SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) | 
|  | 290 |  | 
|  | 291 | GrPaint grPaint; | 
| brianosman | 8fe485b | 2016-07-25 12:31:51 -0700 | [diff] [blame] | 292 | if (!SkPaintToGrPaint(context, drawContext, paint, viewMatrix, &grPaint)) { | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 293 | return; | 
|  | 294 | } | 
|  | 295 |  | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 296 | if (paint.getMaskFilter()) { | 
| robertphillips | 7bceedc | 2015-12-01 12:51:26 -0800 | [diff] [blame] | 297 | draw_path_with_mask_filter(context, drawContext, clip, &grPaint, viewMatrix, | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 298 | paint.getMaskFilter(), style, | 
|  | 299 | path, pathIsMutable); | 
| bsalomon | c55271f | 2015-11-09 11:55:57 -0800 | [diff] [blame] | 300 | } else { | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 301 | drawContext->drawPath(clip, grPaint, viewMatrix, *path, style); | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 302 | } | 
| robertphillips | ccb1b57 | 2015-05-27 11:02:55 -0700 | [diff] [blame] | 303 | } |