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

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
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 GrUniqueKey glyphKey;
227 struct GlyphKey { 229 GrUniqueKey::Builder builder(&glyphKey, kPathGlyphDomain,
228 uint32_t fChecksum; 230 2 + stroke.computeUniqueKeyFragmentData32Cnt()) ;
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 stroke.asUniqueKeyFragment(&builder[2]);
egdaniel 2015/05/15 15:28:53 Same with asserting computeUKFD32C is not zero
Kimmo Kinnunen 2015/05/18 06:48:40 Done.
232 GlyphKey* glyphKey = reinterpret_cast<GlyphKey*>(&builder[0]);
233 glyphKey->fChecksum = desc ? desc->getChecksum() : 0;
234 glyphKey->fTypeface = typeface ? typeface->uniqueID() : 0;
235 glyphKey->fStroke = GrPath::ComputeStrokeKey(stroke);
236 builder.finish(); 234 builder.finish();
237 235
238 SkAutoTUnref<GrPathRange> glyphs( 236 SkAutoTUnref<GrPathRange> glyphs(
239 static_cast<GrPathRange*>(ctx->resourceProvider()->findAndRefResourceByU niqueKey(key))); 237 static_cast<GrPathRange*>(
240 if (NULL == glyphs || (NULL != desc && !glyphs->isEqualTo(*desc))) { 238 ctx->resourceProvider()->findAndRefResourceByUniqueKey(glyphKey)));
239 if (NULL == glyphs) {
241 glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc , stroke)); 240 glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc , stroke));
242 ctx->resourceProvider()->assignUniqueKeyToResource(key, glyphs); 241 ctx->resourceProvider()->assignUniqueKeyToResource(glyphKey, glyphs);
242 } else {
243 SkASSERT(NULL == desc || glyphs->isEqualTo(*desc));
243 } 244 }
244 245
245 return glyphs.detach(); 246 return glyphs.detach();
246 } 247 }
247 248
248 void GrStencilAndCoverTextContext::init(GrRenderTarget* rt, 249 void GrStencilAndCoverTextContext::init(GrRenderTarget* rt,
249 const GrClip& clip, 250 const GrClip& clip,
250 const GrPaint& paint, 251 const GrPaint& paint,
251 const SkPaint& skPaint, 252 const SkPaint& skPaint,
252 size_t textByteLength, 253 size_t textByteLength,
(...skipping 13 matching lines...) Expand all
266 kMaxAccuracy_RenderMode == renderMode && 267 kMaxAccuracy_RenderMode == renderMode &&
267 SkToBool(fContextInitialMatrix.getType() & 268 SkToBool(fContextInitialMatrix.getType() &
268 (SkMatrix::kScale_Mask | SkMatrix::kAffin e_Mask)); 269 (SkMatrix::kScale_Mask | SkMatrix::kAffin e_Mask));
269 270
270 if (fUsingDeviceSpaceGlyphs) { 271 if (fUsingDeviceSpaceGlyphs) {
271 // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms. 272 // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms.
272 SkASSERT(!fContextInitialMatrix.hasPerspective()); 273 SkASSERT(!fContextInitialMatrix.hasPerspective());
273 274
274 // The whole shape (including stroke) will be baked into the glyph outli nes. Make 275 // The whole shape (including stroke) will be baked into the glyph outli nes. Make
275 // NVPR just fill the baked shapes. 276 // NVPR just fill the baked shapes.
276 fStroke = SkStrokeRec(SkStrokeRec::kFill_InitStyle); 277 fStroke = GrStrokeInfo(SkStrokeRec::kFill_InitStyle);
277 278
278 fTextRatio = fTextInverseRatio = 1.0f; 279 fTextRatio = fTextInverseRatio = 1.0f;
279 280
280 // Glyphs loaded by GPU path rendering have an inverted y-direction. 281 // Glyphs loaded by GPU path rendering have an inverted y-direction.
281 SkMatrix m; 282 SkMatrix m;
282 m.setScale(1, -1); 283 m.setScale(1, -1);
283 fViewMatrix = m; 284 fViewMatrix = m;
284 285
285 // Post-flip the initial matrix so we're left with just the flip after 286 // Post-flip the initial matrix so we're left with just the flip after
286 // the paint preConcats the inverse. 287 // the paint preConcats the inverse.
287 m = fContextInitialMatrix; 288 m = fContextInitialMatrix;
288 m.postScale(1, -1); 289 m.postScale(1, -1);
289 if (!m.invert(&fLocalMatrix)) { 290 if (!m.invert(&fLocalMatrix)) {
290 SkDebugf("Not invertible!\n"); 291 SkDebugf("Not invertible!\n");
291 return; 292 return;
292 } 293 }
293 294
294 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, &fContextInitialM atrix, 295 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, &fContextInitialM atrix,
295 true /*ignoreGamma*/); 296 true /*ignoreGamma*/);
296 fGlyphs = get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTy peface(), 297 fGlyphs = get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTy peface(),
297 &fGlyphCache->getDescriptor(), fStroke); 298 &fGlyphCache->getDescriptor(), fStroke);
298 } else { 299 } else {
299 // Don't bake strokes into the glyph outlines. We will stroke the glyphs 300 // Don't bake strokes into the glyph outlines. We will stroke the glyphs
300 // using the GPU instead. This is the fast path. 301 // using the GPU instead. This is the fast path.
301 fStroke = SkStrokeRec(fSkPaint); 302 fStroke = GrStrokeInfo(fSkPaint);
302 fSkPaint.setStyle(SkPaint::kFill_Style); 303 fSkPaint.setStyle(SkPaint::kFill_Style);
303 304
304 if (fStroke.isHairlineStyle()) { 305 if (fStroke.isHairlineStyle()) {
305 // Approximate hairline stroke. 306 // Approximate hairline stroke.
306 SkScalar strokeWidth = SK_Scalar1 / 307 SkScalar strokeWidth = SK_Scalar1 /
307 (SkVector::Make(fContextInitialMatrix.getScaleX(), 308 (SkVector::Make(fContextInitialMatrix.getScaleX(),
308 fContextInitialMatrix.getSkewY()).length()); 309 fContextInitialMatrix.getSkewY()).length());
309 fStroke.setStrokeStyle(strokeWidth, false /*strokeAndFill*/); 310 fStroke.setStrokeStyle(strokeWidth, false /*strokeAndFill*/);
310 311
311 } else if (fSkPaint.isFakeBoldText() && 312 } else if (fSkPaint.isFakeBoldText() &&
312 #ifdef SK_USE_FREETYPE_EMBOLDEN 313 #ifdef SK_USE_FREETYPE_EMBOLDEN
313 kMaxPerformance_RenderMode == renderMode && 314 kMaxPerformance_RenderMode == renderMode &&
314 #endif 315 #endif
315 SkStrokeRec::kStroke_Style != fStroke.getStyle()) { 316 SkStrokeRec::kStroke_Style != fStroke.getStyle()) {
316 317
317 // Instead of baking fake bold into the glyph outlines, do it with t he GPU stroke. 318 // Instead of baking fake bold into the glyph outlines, do it with t he GPU stroke.
318 SkScalar fakeBoldScale = SkScalarInterpFunc(fSkPaint.getTextSize(), 319 SkScalar fakeBoldScale = SkScalarInterpFunc(fSkPaint.getTextSize(),
319 kStdFakeBoldInterpKeys, 320 kStdFakeBoldInterpKeys,
320 kStdFakeBoldInterpValues , 321 kStdFakeBoldInterpValues ,
321 kStdFakeBoldInterpLength ); 322 kStdFakeBoldInterpLength );
322 SkScalar extra = SkScalarMul(fSkPaint.getTextSize(), fakeBoldScale); 323 SkScalar extra = SkScalarMul(fSkPaint.getTextSize(), fakeBoldScale);
323 fStroke.setStrokeStyle(fStroke.needToApply() ? fStroke.getWidth() + extra : extra, 324 fStroke.setStrokeStyle(fStroke.needToApply() ? fStroke.getWidth() + extra : extra,
324 true /*strokeAndFill*/); 325 true /*strokeAndFill*/);
325 326
326 fSkPaint.setFakeBoldText(false); 327 fSkPaint.setFakeBoldText(false);
327 } 328 }
328 329
329 bool canUseRawPaths; 330 bool canUseRawPaths;
330 331 if (!fStroke.isDashed() && (otherBackendsWillDrawAsPaths ||
331 if (otherBackendsWillDrawAsPaths || kMaxPerformance_RenderMode == render Mode) { 332 kMaxPerformance_RenderMode == renderMode)) {
332 // We can draw the glyphs from canonically sized paths. 333 // We can draw the glyphs from canonically sized paths.
333 fTextRatio = fSkPaint.getTextSize() / SkPaint::kCanonicalTextSizeFor Paths; 334 fTextRatio = fSkPaint.getTextSize() / SkPaint::kCanonicalTextSizeFor Paths;
334 fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fSkPaint.g etTextSize(); 335 fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fSkPaint.g etTextSize();
335 336
336 // Compensate for the glyphs being scaled by fTextRatio. 337 // Compensate for the glyphs being scaled by fTextRatio.
337 if (!fStroke.isFillStyle()) { 338 if (!fStroke.isFillStyle()) {
338 fStroke.setStrokeStyle(fStroke.getWidth() / fTextRatio, 339 fStroke.setStrokeStyle(fStroke.getWidth() / fTextRatio,
339 SkStrokeRec::kStrokeAndFill_Style == fStr oke.getStyle()); 340 SkStrokeRec::kStrokeAndFill_Style == fStr oke.getStyle());
340 } 341 }
341 342
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 477
477 SkGlyphCache::AttachCache(fGlyphCache); 478 SkGlyphCache::AttachCache(fGlyphCache);
478 fGlyphCache = NULL; 479 fGlyphCache = NULL;
479 480
480 fPipelineBuilder.stencil()->setDisabled(); 481 fPipelineBuilder.stencil()->setDisabled();
481 fStateRestore.set(NULL); 482 fStateRestore.set(NULL);
482 fViewMatrix = fContextInitialMatrix; 483 fViewMatrix = fContextInitialMatrix;
483 GrTextContext::finish(); 484 GrTextContext::finish();
484 } 485 }
485 486
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698