Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1183)

Side by Side Diff: src/gpu/GrBlurUtils.cpp

Issue 1957363002: Replace GrStrokeInfo with GrStyle. (Closed) Base URL: https://chromium.googlesource.com/skia.git@resscale
Patch Set: Fix issue where hairlines were going to MSAAPathRenderer Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "GrContext.h" 11 #include "GrContext.h"
12 #include "effects/GrSimpleTextureEffect.h" 12 #include "effects/GrSimpleTextureEffect.h"
13 #include "GrStrokeInfo.h" 13 #include "GrStyle.h"
14 #include "GrTexture.h" 14 #include "GrTexture.h"
15 #include "GrTextureProvider.h" 15 #include "GrTextureProvider.h"
16 #include "SkDraw.h" 16 #include "SkDraw.h"
17 #include "SkGrPriv.h" 17 #include "SkGrPriv.h"
18 #include "SkMaskFilter.h" 18 #include "SkMaskFilter.h"
19 #include "SkPaint.h" 19 #include "SkPaint.h"
20 20
21 static bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& r ect) { 21 static bool clip_bounds_quick_reject(const SkIRect& clipBounds, const SkIRect& r ect) {
22 return clipBounds.isEmpty() || rect.isEmpty() || !SkIRect::Intersects(clipBo unds, rect); 22 return clipBounds.isEmpty() || rect.isEmpty() || !SkIRect::Intersects(clipBo unds, rect);
23 } 23 }
(...skipping 23 matching lines...) Expand all
47 } 47 }
48 48
49 static bool sw_draw_with_mask_filter(GrDrawContext* drawContext, 49 static bool sw_draw_with_mask_filter(GrDrawContext* drawContext,
50 GrTextureProvider* textureProvider, 50 GrTextureProvider* textureProvider,
51 const GrClip& clipData, 51 const GrClip& clipData,
52 const SkMatrix& viewMatrix, 52 const SkMatrix& viewMatrix,
53 const SkPath& devPath, 53 const SkPath& devPath,
54 const SkMaskFilter* filter, 54 const SkMaskFilter* filter,
55 const SkIRect& clipBounds, 55 const SkIRect& clipBounds,
56 GrPaint* grp, 56 GrPaint* grp,
57 SkStrokeRec::InitStyle style) { 57 SkStrokeRec::InitStyle fillOrHairline) {
58 SkMask srcM, dstM; 58 SkMask srcM, dstM;
59
60 if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM, 59 if (!SkDraw::DrawToMask(devPath, &clipBounds, filter, &viewMatrix, &srcM,
61 SkMask::kComputeBoundsAndRenderImage_CreateMode, sty le)) { 60 SkMask::kComputeBoundsAndRenderImage_CreateMode, fil lOrHairline)) {
62 return false; 61 return false;
63 } 62 }
64 SkAutoMaskFreeImage autoSrc(srcM.fImage); 63 SkAutoMaskFreeImage autoSrc(srcM.fImage);
65 64
66 if (!filter->filterMask(&dstM, srcM, viewMatrix, nullptr)) { 65 if (!filter->filterMask(&dstM, srcM, viewMatrix, nullptr)) {
67 return false; 66 return false;
68 } 67 }
69 // this will free-up dstM when we're done (allocated in filterMask()) 68 // this will free-up dstM when we're done (allocated in filterMask())
70 SkAutoMaskFreeImage autoDst(dstM.fImage); 69 SkAutoMaskFreeImage autoDst(dstM.fImage);
71 70
(...skipping 17 matching lines...) Expand all
89 88
90 SkRect maskRect = SkRect::Make(dstM.fBounds); 89 SkRect maskRect = SkRect::Make(dstM.fBounds);
91 90
92 return draw_mask(drawContext, clipData, viewMatrix, maskRect, grp, texture); 91 return draw_mask(drawContext, clipData, viewMatrix, maskRect, grp, texture);
93 } 92 }
94 93
95 // Create a mask of 'devPath' and place the result in 'mask'. 94 // Create a mask of 'devPath' and place the result in 'mask'.
96 static sk_sp<GrTexture> create_mask_GPU(GrContext* context, 95 static sk_sp<GrTexture> create_mask_GPU(GrContext* context,
97 SkRect* maskRect, 96 SkRect* maskRect,
98 const SkPath& devPath, 97 const SkPath& devPath,
99 SkStrokeRec::InitStyle style, 98 SkStrokeRec::InitStyle fillOrHairline,
100 bool doAA, 99 bool doAA,
101 int sampleCnt) { 100 int sampleCnt) {
102 // This mask will ultimately be drawn as a non-AA rect (see draw_mask). 101 // 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 102 // Non-AA rects have a bad habit of snapping arbitrarily. Integerize here
104 // so the mask draws in a reproducible manner. 103 // so the mask draws in a reproducible manner.
105 *maskRect = SkRect::Make(maskRect->roundOut()); 104 *maskRect = SkRect::Make(maskRect->roundOut());
106 105
107 if (!doAA) { 106 if (!doAA) {
108 // Don't need MSAA if mask isn't AA 107 // Don't need MSAA if mask isn't AA
109 sampleCnt = 0; 108 sampleCnt = 0;
(...skipping 22 matching lines...) Expand all
132 tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op); 131 tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
133 132
134 // setup new clip 133 // setup new clip
135 const SkRect clipRect = SkRect::MakeWH(maskRect->width(), maskRect->height() ); 134 const SkRect clipRect = SkRect::MakeWH(maskRect->width(), maskRect->height() );
136 GrClip clip(clipRect); 135 GrClip clip(clipRect);
137 136
138 // Draw the mask into maskTexture with the path's integerized top-left at 137 // Draw the mask into maskTexture with the path's integerized top-left at
139 // the origin using tempPaint. 138 // the origin using tempPaint.
140 SkMatrix translate; 139 SkMatrix translate;
141 translate.setTranslate(-maskRect->fLeft, -maskRect->fTop); 140 translate.setTranslate(-maskRect->fLeft, -maskRect->fTop);
142 drawContext->drawPath(clip, tempPaint, translate, devPath, GrStrokeInfo(styl e)); 141 drawContext->drawPath(clip, tempPaint, translate, devPath, GrStyle(fillOrHai rline));
143 return drawContext->asTexture();; 142 return drawContext->asTexture();;
144 } 143 }
145 144
146 static void draw_path_with_mask_filter(GrContext* context, 145 static void draw_path_with_mask_filter(GrContext* context,
147 GrDrawContext* drawContext, 146 GrDrawContext* drawContext,
148 const GrClip& clip, 147 const GrClip& clip,
149 GrPaint* paint, 148 GrPaint* paint,
150 const SkMatrix& viewMatrix, 149 const SkMatrix& viewMatrix,
151 const SkMaskFilter* maskFilter, 150 const SkMaskFilter* maskFilter,
152 const SkPathEffect* pathEffect, 151 const GrStyle& style,
153 const GrStrokeInfo& strokeInfo, 152 const SkPath* path,
154 SkPath* pathPtr,
155 bool pathIsMutable) { 153 bool pathIsMutable) {
156 SkASSERT(maskFilter); 154 SkASSERT(maskFilter);
157 155
158 SkIRect clipBounds; 156 SkIRect clipBounds;
159 clip.getConservativeBounds(drawContext->width(), drawContext->height(), &cli pBounds); 157 clip.getConservativeBounds(drawContext->width(), drawContext->height(), &cli pBounds);
160 SkTLazy<SkPath> tmpPath; 158 SkTLazy<SkPath> tmpPath;
159 SkStrokeRec::InitStyle fillOrHairline;
161 160
162 static const SkRect* cullRect = nullptr; // TODO: what is our bounds? 161 // We just fully apply the style here.
163 162 if (style.applies()) {
164 SkASSERT(strokeInfo.isDashed() || !pathEffect); 163 if (!style.applyToPath(tmpPath.init(), &fillOrHairline, *path,
165 SkStrokeRec::InitStyle maskStyle; 164 GrStyle::MatrixToScaleFactor(viewMatrix))) {
166 if (strokeInfo.isHairlineStyle()) { 165 return;
167 maskStyle = SkStrokeRec::kHairline_InitStyle; 166 }
167 pathIsMutable = true;
168 path = tmpPath.get();
169 } else if (style.isSimpleHairline()) {
170 fillOrHairline = SkStrokeRec::kHairline_InitStyle;
168 } else { 171 } else {
169 SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init(); 172 SkASSERT(style.isSimpleFill());
170 SkStrokeRec rec = strokeInfo; 173 fillOrHairline = SkStrokeRec::kFill_InitStyle;
171 if (strokeInfo.isDashed()) {
172 if (pathEffect->filterPath(strokedPath, *pathPtr, &rec, cullRect)) {
173 pathPtr = strokedPath;
174 pathPtr->setIsVolatile(true);
175 pathIsMutable = true;
176 }
177 }
178 if (rec.applyToPath(strokedPath, *pathPtr)) {
179 // Apply the stroke to the path if there is one
180 pathPtr = strokedPath;
181 pathPtr->setIsVolatile(true);
182 pathIsMutable = true;
183 }
184 maskStyle = SkStrokeRec::kFill_InitStyle;
185 }
186
187 // avoid possibly allocating a new path in transform if we can
188 SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init();
189 if (!pathIsMutable) {
190 devPathPtr->setIsVolatile(true);
191 } 174 }
192 175
193 // transform the path into device space 176 // transform the path into device space
194 pathPtr->transform(viewMatrix, devPathPtr); 177 if (!viewMatrix.isIdentity()) {
178 SkPath* result;
179 if (pathIsMutable) {
180 result = const_cast<SkPath*>(path);
181 } else {
182 if (!tmpPath.isValid()) {
183 tmpPath.init();
184 }
185 result = tmpPath.get();
186 }
187 path->transform(viewMatrix, result);
188 path = result;
189 result->setIsVolatile(true);
190 pathIsMutable = true;
191 }
195 192
196 SkRect maskRect; 193 SkRect maskRect;
197 if (maskFilter->canFilterMaskGPU(SkRRect::MakeRect(devPathPtr->getBounds()), 194 if (maskFilter->canFilterMaskGPU(SkRRect::MakeRect(path->getBounds()),
198 clipBounds, 195 clipBounds,
199 viewMatrix, 196 viewMatrix,
200 &maskRect)) { 197 &maskRect)) {
201 SkIRect finalIRect; 198 SkIRect finalIRect;
202 maskRect.roundOut(&finalIRect); 199 maskRect.roundOut(&finalIRect);
203 if (clip_bounds_quick_reject(clipBounds, finalIRect)) { 200 if (clip_bounds_quick_reject(clipBounds, finalIRect)) {
204 // clipped out 201 // clipped out
205 return; 202 return;
206 } 203 }
207 204
208 if (maskFilter->directFilterMaskGPU(context->textureProvider(), 205 if (maskFilter->directFilterMaskGPU(context->textureProvider(),
209 drawContext, 206 drawContext,
210 paint, 207 paint,
211 clip, 208 clip,
212 viewMatrix, 209 viewMatrix,
213 SkStrokeRec(maskStyle), 210 SkStrokeRec(fillOrHairline),
214 *devPathPtr)) { 211 *path)) {
215 // the mask filter was able to draw itself directly, so there's noth ing 212 // the mask filter was able to draw itself directly, so there's noth ing
216 // left to do. 213 // left to do.
217 return; 214 return;
218 } 215 }
219 216
220 sk_sp<GrTexture> mask(create_mask_GPU(context, 217 sk_sp<GrTexture> mask(create_mask_GPU(context,
221 &maskRect, 218 &maskRect,
222 *devPathPtr, 219 *path,
223 maskStyle, 220 fillOrHairline,
224 paint->isAntiAlias(), 221 paint->isAntiAlias(),
225 drawContext->numColorSamples())); 222 drawContext->numColorSamples()));
226 if (mask) { 223 if (mask) {
227 GrTexture* filtered; 224 GrTexture* filtered;
228 225
229 if (maskFilter->filterMaskGPU(mask.get(), viewMatrix, maskRect, &fil tered, true)) { 226 if (maskFilter->filterMaskGPU(mask.get(), viewMatrix, maskRect, &fil tered, true)) {
230 // filterMaskGPU gives us ownership of a ref to the result 227 // filterMaskGPU gives us ownership of a ref to the result
231 SkAutoTUnref<GrTexture> atu(filtered); 228 SkAutoTUnref<GrTexture> atu(filtered);
232 if (draw_mask(drawContext, clip, viewMatrix, maskRect, paint, fi ltered)) { 229 if (draw_mask(drawContext, clip, viewMatrix, maskRect, paint, fi ltered)) {
233 // This path is completely drawn 230 // This path is completely drawn
234 return; 231 return;
235 } 232 }
236 } 233 }
237 } 234 }
238 } 235 }
239 236
240 sw_draw_with_mask_filter(drawContext, context->textureProvider(), 237 sw_draw_with_mask_filter(drawContext, context->textureProvider(),
241 clip, viewMatrix, *devPathPtr, 238 clip, viewMatrix, *path,
242 maskFilter, clipBounds, paint, maskStyle); 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);
243 } 253 }
244 254
245 void GrBlurUtils::drawPathWithMaskFilter(GrContext* context, 255 void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
246 GrDrawContext* drawContext, 256 GrDrawContext* drawContext,
247 const GrClip& clip, 257 const GrClip& clip,
248 const SkPath& origPath, 258 const SkPath& origPath,
249 GrPaint* paint,
250 const SkMatrix& viewMatrix,
251 const SkMaskFilter* mf,
252 const SkPathEffect* pathEffect,
253 const GrStrokeInfo& origStrokeInfo,
254 bool pathIsMutable) {
255 SkPath* pathPtr = const_cast<SkPath*>(&origPath);
256
257 SkTLazy<SkPath> tmpPath;
258 GrStrokeInfo strokeInfo(origStrokeInfo);
259
260 if (!strokeInfo.isDashed() && pathEffect && pathEffect->filterPath(tmpPath.i nit(), *pathPtr,
261 &strokeIn fo, nullptr)) {
262 pathPtr = tmpPath.get();
263 pathPtr->setIsVolatile(true);
264 pathIsMutable = true;
265 pathEffect = nullptr;
266 }
267
268 draw_path_with_mask_filter(context, drawContext, clip, paint, viewMatrix, mf , pathEffect,
269 strokeInfo, pathPtr, pathIsMutable);
270 }
271
272 void GrBlurUtils::drawPathWithMaskFilter(GrContext* context,
273 GrDrawContext* drawContext,
274 const GrClip& clip,
275 const SkPath& origSrcPath,
276 const SkPaint& paint, 259 const SkPaint& paint,
277 const SkMatrix& origViewMatrix, 260 const SkMatrix& origViewMatrix,
278 const SkMatrix* prePathMatrix, 261 const SkMatrix* prePathMatrix,
279 const SkIRect& clipBounds, 262 const SkIRect& clipBounds,
280 bool pathIsMutable) { 263 bool pathIsMutable) {
281 SkASSERT(!pathIsMutable || origSrcPath.isVolatile()); 264 SkASSERT(!pathIsMutable || origPath.isVolatile());
282 265
283 GrStrokeInfo strokeInfo(paint); 266 GrStyle style(paint);
284 // comment out the line below to determine if it is the reason that the chro me mac perf bot
285 // has begun crashing
286 // strokeInfo.setResScale(SkDraw::ComputeResScaleForStroking(origViewMatrix) );
287
288 // If we have a prematrix, apply it to the path, optimizing for the case 267 // If we have a prematrix, apply it to the path, optimizing for the case
289 // where the original path can in fact be modified in place (even though 268 // where the original path can in fact be modified in place (even though
290 // its parameter type is const). 269 // its parameter type is const).
291 SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath); 270
271 const SkPath* path = &origPath;
292 SkTLazy<SkPath> tmpPath; 272 SkTLazy<SkPath> tmpPath;
293 SkTLazy<SkPath> effectPath;
294 SkPathEffect* pathEffect = paint.getPathEffect();
295 273
296 SkMatrix viewMatrix = origViewMatrix; 274 SkMatrix viewMatrix = origViewMatrix;
297 275
298 if (prePathMatrix) { 276 if (prePathMatrix) {
299 // stroking, path effects, and blurs are supposed to be applied *after* the prePathMatrix. 277 // Styling, blurs, and shading are supposed to be applied *after* the pr ePathMatrix.
300 // The pre-path-matrix also should not affect shading. 278 if (!paint.getMaskFilter() && !paint.getShader() && !style.applies()) {
301 if (!paint.getMaskFilter() && !pathEffect && !paint.getShader() &&
302 (strokeInfo.isFillStyle() || strokeInfo.isHairlineStyle())) {
303 viewMatrix.preConcat(*prePathMatrix); 279 viewMatrix.preConcat(*prePathMatrix);
304 } else { 280 } else {
305 SkPath* result = pathPtr; 281 SkPath* result = pathIsMutable ? const_cast<SkPath*>(path) : tmpPath .init();
306 282 pathIsMutable = true;
307 if (!pathIsMutable) { 283 path->transform(*prePathMatrix, result);
308 result = tmpPath.init(); 284 path = result;
309 result->setIsVolatile(true); 285 result->setIsVolatile(true);
310 pathIsMutable = true;
311 }
312 // should I push prePathMatrix on our MV stack temporarily, instead
313 // of applying it here? See SkDraw.cpp
314 pathPtr->transform(*prePathMatrix, result);
315 pathPtr = result;
316 } 286 }
317 } 287 }
318 // at this point we're done with prePathMatrix 288 // at this point we're done with prePathMatrix
319 SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) 289 SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
320 290
321 SkTLazy<SkPath> tmpPath2;
322
323 if (!strokeInfo.isDashed() && pathEffect &&
324 pathEffect->filterPath(tmpPath2.init(), *pathPtr, &strokeInfo, nullptr)) {
325 pathPtr = tmpPath2.get();
326 pathPtr->setIsVolatile(true);
327 pathIsMutable = true;
328 pathEffect = nullptr;
329 }
330
331 GrPaint grPaint; 291 GrPaint grPaint;
332 if (!SkPaintToGrPaint(context, paint, viewMatrix, drawContext->isGammaCorrec t(), 292 if (!SkPaintToGrPaint(context, paint, viewMatrix, drawContext->isGammaCorrec t(),
333 &grPaint)) { 293 &grPaint)) {
334 return; 294 return;
335 } 295 }
336 296
337 if (paint.getMaskFilter()) { 297 if (paint.getMaskFilter()) {
338 draw_path_with_mask_filter(context, drawContext, clip, &grPaint, viewMat rix, 298 draw_path_with_mask_filter(context, drawContext, clip, &grPaint, viewMat rix,
339 paint.getMaskFilter(), pathEffect, strokeInfo , 299 paint.getMaskFilter(), style,
340 pathPtr, pathIsMutable); 300 path, pathIsMutable);
341 } else { 301 } else {
342 drawContext->drawPath(clip, grPaint, viewMatrix, *pathPtr, strokeInfo); 302 drawContext->drawPath(clip, grPaint, viewMatrix, *path, style);
343 } 303 }
344 } 304 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698