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

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

Issue 1116123003: Improve caching of dashed paths in GrStencilAndCoverPathRenderer (Closed) Base URL: https://skia.googlesource.com/skia.git@dashing-nvpr-01
Patch Set: Created 5 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
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | src/gpu/GrStrokeInfo.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 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 "GrStencilAndCoverTextContext.h" 8 #include "GrStencilAndCoverTextContext.h"
9 #include "GrAtlasTextContext.h" 9 #include "GrAtlasTextContext.h"
10 #include "GrDrawTarget.h" 10 #include "GrDrawTarget.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 const GrClip& clip, 48 const GrClip& clip,
49 const GrPaint& paint, 49 const GrPaint& paint,
50 const SkPaint& skPaint, 50 const SkPaint& skPaint,
51 const SkMatrix& viewMatrix) { 51 const SkMatrix& viewMatrix) {
52 if (skPaint.getRasterizer()) { 52 if (skPaint.getRasterizer()) {
53 return false; 53 return false;
54 } 54 }
55 if (skPaint.getMaskFilter()) { 55 if (skPaint.getMaskFilter()) {
56 return false; 56 return false;
57 } 57 }
58 if (skPaint.getPathEffect()) { 58 if (SkPathEffect* pe = skPaint.getPathEffect()) {
59 return false; 59 if (pe->asADash(NULL) != SkPathEffect::kDash_DashType) {
60 return false;
61 }
60 } 62 }
61 63
62 // No hairlines unless we can map the 1 px width to the object space. 64 // No hairlines unless we can map the 1 px width to the object space.
63 if (skPaint.getStyle() == SkPaint::kStroke_Style 65 if (skPaint.getStyle() == SkPaint::kStroke_Style
64 && skPaint.getStrokeWidth() == 0 66 && skPaint.getStrokeWidth() == 0
65 && viewMatrix.hasPerspective()) { 67 && viewMatrix.hasPerspective()) {
66 return false; 68 return false;
67 } 69 }
68 70
69 // No color bitmap fonts. 71 // No color bitmap fonts.
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 215 }
214 pos += scalarsPerPosition; 216 pos += scalarsPerPosition;
215 } 217 }
216 218
217 this->finish(); 219 this->finish();
218 } 220 }
219 221
220 static GrPathRange* get_gr_glyphs(GrContext* ctx, 222 static GrPathRange* get_gr_glyphs(GrContext* ctx,
221 const SkTypeface* typeface, 223 const SkTypeface* typeface,
222 const SkDescriptor* desc, 224 const SkDescriptor* desc,
223 const SkStrokeRec& stroke) { 225 const GrStrokeInfo& stroke) {
224 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 226
225 GrUniqueKey key; 227 static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::GenerateDom ain();
226 GrUniqueKey::Builder builder(&key, kDomain, 4); 228 int strokeDataCount = stroke.computeUniqueKeyFragmentData32Cnt();
227 struct GlyphKey { 229 GrUniqueKey glyphKey;
228 uint32_t fChecksum; 230 GrUniqueKey::Builder builder(&glyphKey, kPathGlyphDomain, 2 + strokeDataCoun t);
229 uint32_t fTypeface; 231 reinterpret_cast<uint32_t&>(builder[0]) = desc ? desc->getChecksum() : 0;
230 uint64_t fStroke; 232 reinterpret_cast<uint32_t&>(builder[1]) = typeface ? typeface->uniqueID() : 0;
231 }; 233 if (strokeDataCount > 0) {
232 GlyphKey* glyphKey = reinterpret_cast<GlyphKey*>(&builder[0]); 234 stroke.asUniqueKeyFragment(&builder[2]);
233 glyphKey->fChecksum = desc ? desc->getChecksum() : 0; 235 }
234 glyphKey->fTypeface = typeface ? typeface->uniqueID() : 0;
235 glyphKey->fStroke = GrPath::ComputeStrokeKey(stroke);
236 builder.finish(); 236 builder.finish();
237 237
238 SkAutoTUnref<GrPathRange> glyphs( 238 SkAutoTUnref<GrPathRange> glyphs(
239 static_cast<GrPathRange*>(ctx->resourceProvider()->findAndRefResourceByU niqueKey(key))); 239 static_cast<GrPathRange*>(
240 if (NULL == glyphs || (NULL != desc && !glyphs->isEqualTo(*desc))) { 240 ctx->resourceProvider()->findAndRefResourceByUniqueKey(glyphKey)));
241 if (NULL == glyphs) {
241 glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc , stroke)); 242 glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc , stroke));
242 ctx->resourceProvider()->assignUniqueKeyToResource(key, glyphs); 243 ctx->resourceProvider()->assignUniqueKeyToResource(glyphKey, glyphs);
244 } else {
245 SkASSERT(NULL == desc || glyphs->isEqualTo(*desc));
243 } 246 }
244 247
245 return glyphs.detach(); 248 return glyphs.detach();
246 } 249 }
247 250
248 void GrStencilAndCoverTextContext::init(GrRenderTarget* rt, 251 void GrStencilAndCoverTextContext::init(GrRenderTarget* rt,
249 const GrClip& clip, 252 const GrClip& clip,
250 const GrPaint& paint, 253 const GrPaint& paint,
251 const SkPaint& skPaint, 254 const SkPaint& skPaint,
252 size_t textByteLength, 255 size_t textByteLength,
(...skipping 13 matching lines...) Expand all
266 kMaxAccuracy_RenderMode == renderMode && 269 kMaxAccuracy_RenderMode == renderMode &&
267 SkToBool(fContextInitialMatrix.getType() & 270 SkToBool(fContextInitialMatrix.getType() &
268 (SkMatrix::kScale_Mask | SkMatrix::kAffin e_Mask)); 271 (SkMatrix::kScale_Mask | SkMatrix::kAffin e_Mask));
269 272
270 if (fUsingDeviceSpaceGlyphs) { 273 if (fUsingDeviceSpaceGlyphs) {
271 // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms. 274 // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms.
272 SkASSERT(!fContextInitialMatrix.hasPerspective()); 275 SkASSERT(!fContextInitialMatrix.hasPerspective());
273 276
274 // The whole shape (including stroke) will be baked into the glyph outli nes. Make 277 // The whole shape (including stroke) will be baked into the glyph outli nes. Make
275 // NVPR just fill the baked shapes. 278 // NVPR just fill the baked shapes.
276 fStroke = SkStrokeRec(SkStrokeRec::kFill_InitStyle); 279 fStroke = GrStrokeInfo(SkStrokeRec::kFill_InitStyle);
277 280
278 fTextRatio = fTextInverseRatio = 1.0f; 281 fTextRatio = fTextInverseRatio = 1.0f;
279 282
280 // Glyphs loaded by GPU path rendering have an inverted y-direction. 283 // Glyphs loaded by GPU path rendering have an inverted y-direction.
281 SkMatrix m; 284 SkMatrix m;
282 m.setScale(1, -1); 285 m.setScale(1, -1);
283 fViewMatrix = m; 286 fViewMatrix = m;
284 287
285 // Post-flip the initial matrix so we're left with just the flip after 288 // Post-flip the initial matrix so we're left with just the flip after
286 // the paint preConcats the inverse. 289 // the paint preConcats the inverse.
287 m = fContextInitialMatrix; 290 m = fContextInitialMatrix;
288 m.postScale(1, -1); 291 m.postScale(1, -1);
289 if (!m.invert(&fLocalMatrix)) { 292 if (!m.invert(&fLocalMatrix)) {
290 SkDebugf("Not invertible!\n"); 293 SkDebugf("Not invertible!\n");
291 return; 294 return;
292 } 295 }
293 296
294 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, &fContextInitialM atrix, 297 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, &fContextInitialM atrix,
295 true /*ignoreGamma*/); 298 true /*ignoreGamma*/);
296 fGlyphs = get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTy peface(), 299 fGlyphs = get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTy peface(),
297 &fGlyphCache->getDescriptor(), fStroke); 300 &fGlyphCache->getDescriptor(), fStroke);
298 } else { 301 } else {
299 // Don't bake strokes into the glyph outlines. We will stroke the glyphs 302 // Don't bake strokes into the glyph outlines. We will stroke the glyphs
300 // using the GPU instead. This is the fast path. 303 // using the GPU instead. This is the fast path.
301 fStroke = SkStrokeRec(fSkPaint); 304 fStroke = GrStrokeInfo(fSkPaint);
302 fSkPaint.setStyle(SkPaint::kFill_Style); 305 fSkPaint.setStyle(SkPaint::kFill_Style);
303 306
304 if (fStroke.isHairlineStyle()) { 307 if (fStroke.isHairlineStyle()) {
305 // Approximate hairline stroke. 308 // Approximate hairline stroke.
306 SkScalar strokeWidth = SK_Scalar1 / 309 SkScalar strokeWidth = SK_Scalar1 /
307 (SkVector::Make(fContextInitialMatrix.getScaleX(), 310 (SkVector::Make(fContextInitialMatrix.getScaleX(),
308 fContextInitialMatrix.getSkewY()).length()); 311 fContextInitialMatrix.getSkewY()).length());
309 fStroke.setStrokeStyle(strokeWidth, false /*strokeAndFill*/); 312 fStroke.setStrokeStyle(strokeWidth, false /*strokeAndFill*/);
310 313
311 } else if (fSkPaint.isFakeBoldText() && 314 } else if (fSkPaint.isFakeBoldText() &&
312 #ifdef SK_USE_FREETYPE_EMBOLDEN 315 #ifdef SK_USE_FREETYPE_EMBOLDEN
313 kMaxPerformance_RenderMode == renderMode && 316 kMaxPerformance_RenderMode == renderMode &&
314 #endif 317 #endif
315 SkStrokeRec::kStroke_Style != fStroke.getStyle()) { 318 SkStrokeRec::kStroke_Style != fStroke.getStyle()) {
316 319
317 // Instead of baking fake bold into the glyph outlines, do it with t he GPU stroke. 320 // Instead of baking fake bold into the glyph outlines, do it with t he GPU stroke.
318 SkScalar fakeBoldScale = SkScalarInterpFunc(fSkPaint.getTextSize(), 321 SkScalar fakeBoldScale = SkScalarInterpFunc(fSkPaint.getTextSize(),
319 kStdFakeBoldInterpKeys, 322 kStdFakeBoldInterpKeys,
320 kStdFakeBoldInterpValues , 323 kStdFakeBoldInterpValues ,
321 kStdFakeBoldInterpLength ); 324 kStdFakeBoldInterpLength );
322 SkScalar extra = SkScalarMul(fSkPaint.getTextSize(), fakeBoldScale); 325 SkScalar extra = SkScalarMul(fSkPaint.getTextSize(), fakeBoldScale);
323 fStroke.setStrokeStyle(fStroke.needToApply() ? fStroke.getWidth() + extra : extra, 326 fStroke.setStrokeStyle(fStroke.needToApply() ? fStroke.getWidth() + extra : extra,
324 true /*strokeAndFill*/); 327 true /*strokeAndFill*/);
325 328
326 fSkPaint.setFakeBoldText(false); 329 fSkPaint.setFakeBoldText(false);
327 } 330 }
328 331
329 bool canUseRawPaths; 332 bool canUseRawPaths;
330 333 if (!fStroke.isDashed() && (otherBackendsWillDrawAsPaths ||
331 if (otherBackendsWillDrawAsPaths || kMaxPerformance_RenderMode == render Mode) { 334 kMaxPerformance_RenderMode == renderMode)) {
332 // We can draw the glyphs from canonically sized paths. 335 // We can draw the glyphs from canonically sized paths.
333 fTextRatio = fSkPaint.getTextSize() / SkPaint::kCanonicalTextSizeFor Paths; 336 fTextRatio = fSkPaint.getTextSize() / SkPaint::kCanonicalTextSizeFor Paths;
334 fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fSkPaint.g etTextSize(); 337 fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fSkPaint.g etTextSize();
335 338
336 // Compensate for the glyphs being scaled by fTextRatio. 339 // Compensate for the glyphs being scaled by fTextRatio.
337 if (!fStroke.isFillStyle()) { 340 if (!fStroke.isFillStyle()) {
338 fStroke.setStrokeStyle(fStroke.getWidth() / fTextRatio, 341 fStroke.setStrokeStyle(fStroke.getWidth() / fTextRatio,
339 SkStrokeRec::kStrokeAndFill_Style == fStr oke.getStyle()); 342 SkStrokeRec::kStrokeAndFill_Style == fStr oke.getStyle());
340 } 343 }
341 344
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 479
477 SkGlyphCache::AttachCache(fGlyphCache); 480 SkGlyphCache::AttachCache(fGlyphCache);
478 fGlyphCache = NULL; 481 fGlyphCache = NULL;
479 482
480 fPipelineBuilder.stencil()->setDisabled(); 483 fPipelineBuilder.stencil()->setDisabled();
481 fStateRestore.set(NULL); 484 fStateRestore.set(NULL);
482 fViewMatrix = fContextInitialMatrix; 485 fViewMatrix = fContextInitialMatrix;
483 GrTextContext::finish(); 486 GrTextContext::finish();
484 } 487 }
485 488
OLDNEW
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | src/gpu/GrStrokeInfo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698