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

Side by Side Diff: src/gpu/text/GrStencilAndCoverTextContext.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 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 "GrContext.h" 10 #include "GrContext.h"
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip); 228 GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip);
229 229
230 TextBlob::Iter iter(blob); 230 TextBlob::Iter iter(blob);
231 for (TextRun* run = iter.get(); run; run = iter.next()) { 231 for (TextRun* run = iter.get(); run; run = iter.next()) {
232 run->draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, p rops, x, y, 232 run->draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, p rops, x, y,
233 clipBounds, fFallbackTextContext, skPaint); 233 clipBounds, fFallbackTextContext, skPaint);
234 run->releaseGlyphCache(); 234 run->releaseGlyphCache();
235 } 235 }
236 } 236 }
237 237
238 static inline int style_key_cnt(const GrStyle& style) {
239 int cnt = GrStyle::KeySize(style, GrStyle::Apply::kPathEffectAndStrokeRec);
240 // We should be able to make a key because we filtered out arbitrary path ef fects.
241 SkASSERT(cnt > 0);
242 return cnt;
243 }
244
245 static inline void write_style_key(uint32_t* dst, const GrStyle& style) {
246 // Pass 1 for the scale since the GPU will apply the style not GrStyle::appl yToPath().
247 GrStyle::WriteKey(dst, style, GrStyle::Apply::kPathEffectAndStrokeRec, SK_Sc alar1);
248 }
249
238 const GrStencilAndCoverTextContext::TextBlob& 250 const GrStencilAndCoverTextContext::TextBlob&
239 GrStencilAndCoverTextContext::findOrCreateTextBlob(const SkTextBlob* skBlob, 251 GrStencilAndCoverTextContext::findOrCreateTextBlob(const SkTextBlob* skBlob,
240 const SkPaint& skPaint) { 252 const SkPaint& skPaint) {
241 // The font-related parameters are baked into the text blob and will overrid e this skPaint, so 253 // The font-related parameters are baked into the text blob and will overrid e this skPaint, so
242 // the only remaining properties that can affect a TextBlob are the ones rel ated to stroke. 254 // the only remaining properties that can affect a TextBlob are the ones rel ated to stroke.
243 if (SkPaint::kFill_Style == skPaint.getStyle()) { // Fast path. 255 if (SkPaint::kFill_Style == skPaint.getStyle()) { // Fast path.
244 if (TextBlob** found = fBlobIdCache.find(skBlob->uniqueID())) { 256 if (TextBlob** found = fBlobIdCache.find(skBlob->uniqueID())) {
245 fLRUList.remove(*found); 257 fLRUList.remove(*found);
246 fLRUList.addToTail(*found); 258 fLRUList.addToTail(*found);
247 return **found; 259 return **found;
248 } 260 }
249 TextBlob* blob = new TextBlob(skBlob->uniqueID(), skBlob, skPaint); 261 TextBlob* blob = new TextBlob(skBlob->uniqueID(), skBlob, skPaint);
250 this->purgeToFit(*blob); 262 this->purgeToFit(*blob);
251 fBlobIdCache.set(skBlob->uniqueID(), blob); 263 fBlobIdCache.set(skBlob->uniqueID(), blob);
252 fLRUList.addToTail(blob); 264 fLRUList.addToTail(blob);
253 fCacheSize += blob->cpuMemorySize(); 265 fCacheSize += blob->cpuMemorySize();
254 return *blob; 266 return *blob;
255 } else { 267 } else {
256 GrStrokeInfo stroke(skPaint); 268 GrStyle style(skPaint);
257 SkSTArray<4, uint32_t, true> key; 269 SkSTArray<4, uint32_t, true> key;
258 key.reset(1 + stroke.computeUniqueKeyFragmentData32Cnt()); 270 key.reset(1 + style_key_cnt(style));
259 key[0] = skBlob->uniqueID(); 271 key[0] = skBlob->uniqueID();
260 stroke.asUniqueKeyFragment(&key[1]); 272 write_style_key(&key[1], style);
261 if (TextBlob** found = fBlobKeyCache.find(key)) { 273 if (TextBlob** found = fBlobKeyCache.find(key)) {
262 fLRUList.remove(*found); 274 fLRUList.remove(*found);
263 fLRUList.addToTail(*found); 275 fLRUList.addToTail(*found);
264 return **found; 276 return **found;
265 } 277 }
266 TextBlob* blob = new TextBlob(key, skBlob, skPaint); 278 TextBlob* blob = new TextBlob(key, skBlob, skPaint);
267 this->purgeToFit(*blob); 279 this->purgeToFit(*blob);
268 fBlobKeyCache.set(blob); 280 fBlobKeyCache.set(blob);
269 fLRUList.addToTail(blob); 281 fLRUList.addToTail(blob);
270 fCacheSize += blob->cpuMemorySize(); 282 fCacheSize += blob->cpuMemorySize();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 SkPaint fFont; 358 SkPaint fFont;
347 int fBuffIdx; 359 int fBuffIdx;
348 int fCount; 360 int fCount;
349 uint16_t fGlyphIds[kWriteBufferSize]; 361 uint16_t fGlyphIds[kWriteBufferSize];
350 SkPoint fPositions[kWriteBufferSize]; 362 SkPoint fPositions[kWriteBufferSize];
351 }; 363 };
352 364
353 //////////////////////////////////////////////////////////////////////////////// //////////////////// 365 //////////////////////////////////////////////////////////////////////////////// ////////////////////
354 366
355 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke) 367 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
356 : fStroke(fontAndStroke), 368 : fStyle(fontAndStroke),
357 fFont(fontAndStroke), 369 fFont(fontAndStroke),
358 fTotalGlyphCount(0), 370 fTotalGlyphCount(0),
359 fFallbackGlyphCount(0), 371 fFallbackGlyphCount(0),
360 fDetachedGlyphCache(nullptr), 372 fDetachedGlyphCache(nullptr),
361 fLastDrawnGlyphsID(SK_InvalidUniqueID) { 373 fLastDrawnGlyphsID(SK_InvalidUniqueID) {
362 SkASSERT(fFont.getTextSize() > 0); 374 SkASSERT(fFont.getTextSize() > 0);
363 SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported. 375 SkASSERT(!fStyle.hasNonDashPathEffect()); // Arbitrary path effects not supp orted.
376 SkASSERT(!fStyle.isSimpleHairline()); // Hairlines are not supported.
364 377
365 // Setting to "fill" ensures that no strokes get baked into font outlines. ( We use the GPU path 378 // Setting to "fill" ensures that no strokes get baked into font outlines. ( We use the GPU path
366 // rendering API for stroking). 379 // rendering API for stroking).
367 fFont.setStyle(SkPaint::kFill_Style); 380 fFont.setStyle(SkPaint::kFill_Style);
368 381
369 if (fFont.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle ()) { 382 if (fFont.isFakeBoldText() && fStyle.isSimpleFill()) {
383 const SkStrokeRec& stroke = fStyle.strokeRec();
370 // Instead of letting fake bold get baked into the glyph outlines, do it with GPU stroke. 384 // Instead of letting fake bold get baked into the glyph outlines, do it with GPU stroke.
371 SkScalar fakeBoldScale = SkScalarInterpFunc(fFont.getTextSize(), 385 SkScalar fakeBoldScale = SkScalarInterpFunc(fFont.getTextSize(),
372 kStdFakeBoldInterpKeys, 386 kStdFakeBoldInterpKeys,
373 kStdFakeBoldInterpValues, 387 kStdFakeBoldInterpValues,
374 kStdFakeBoldInterpLength); 388 kStdFakeBoldInterpLength);
375 SkScalar extra = SkScalarMul(fFont.getTextSize(), fakeBoldScale); 389 SkScalar extra = SkScalarMul(fFont.getTextSize(), fakeBoldScale);
376 fStroke.setStrokeStyle(fStroke.needToApply() ? fStroke.getWidth() + extr a : extra,
377 true /*strokeAndFill*/);
378 390
391 SkStrokeRec strokeRec(SkStrokeRec::kFill_InitStyle);
392 strokeRec.setStrokeStyle(stroke.needToApply() ? stroke.getWidth() + extr a : extra,
393 true /*strokeAndFill*/);
394 fStyle = GrStyle(strokeRec, fStyle.pathEffect());
379 fFont.setFakeBoldText(false); 395 fFont.setFakeBoldText(false);
380 } 396 }
381 397
382 if (!fFont.getPathEffect() && !fStroke.isDashed()) { 398 if (!fFont.getPathEffect() && !fStyle.isDashed()) {
399 const SkStrokeRec& stroke = fStyle.strokeRec();
383 // We can draw the glyphs from canonically sized paths. 400 // We can draw the glyphs from canonically sized paths.
384 fTextRatio = fFont.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; 401 fTextRatio = fFont.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
385 fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fFont.getTextS ize(); 402 fTextInverseRatio = SkPaint::kCanonicalTextSizeForPaths / fFont.getTextS ize();
386 403
387 // Compensate for the glyphs being scaled by fTextRatio. 404 // Compensate for the glyphs being scaled by fTextRatio.
388 if (!fStroke.isFillStyle()) { 405 if (!fStyle.isSimpleFill()) {
389 fStroke.setStrokeStyle(fStroke.getWidth() / fTextRatio, 406 SkStrokeRec strokeRec(SkStrokeRec::kFill_InitStyle);
390 SkStrokeRec::kStrokeAndFill_Style == fStroke. getStyle()); 407 strokeRec.setStrokeStyle(stroke.getWidth() / fTextRatio,
408 SkStrokeRec::kStrokeAndFill_Style == stroke .getStyle());
409 fStyle = GrStyle(strokeRec, fStyle.pathEffect());
391 } 410 }
392 411
393 fFont.setLinearText(true); 412 fFont.setLinearText(true);
394 fFont.setLCDRenderText(false); 413 fFont.setLCDRenderText(false);
395 fFont.setAutohinted(false); 414 fFont.setAutohinted(false);
396 fFont.setHinting(SkPaint::kNo_Hinting); 415 fFont.setHinting(SkPaint::kNo_Hinting);
397 fFont.setSubpixelText(true); 416 fFont.setSubpixelText(true);
398 fFont.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); 417 fFont.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
399 418
400 fUsingRawGlyphPaths = SK_Scalar1 == fFont.getTextScaleX() && 419 fUsingRawGlyphPaths = SK_Scalar1 == fFont.getTextScaleX() &&
401 0 == fFont.getTextSkewX() && 420 0 == fFont.getTextSkewX() &&
402 !fFont.isFakeBoldText() && 421 !fFont.isFakeBoldText() &&
403 !fFont.isVerticalText(); 422 !fFont.isVerticalText();
404 } else { 423 } else {
405 fTextRatio = fTextInverseRatio = 1.0f; 424 fTextRatio = fTextInverseRatio = 1.0f;
406 fUsingRawGlyphPaths = false; 425 fUsingRawGlyphPaths = false;
407 } 426 }
408 427
409 // Generate the key that will be used to cache the GPU glyph path objects. 428 // Generate the key that will be used to cache the GPU glyph path objects.
410 if (fUsingRawGlyphPaths && fStroke.isFillStyle()) { 429 if (fUsingRawGlyphPaths && fStyle.isSimpleFill()) {
411 static const GrUniqueKey::Domain kRawFillPathGlyphDomain = GrUniqueKey:: GenerateDomain(); 430 static const GrUniqueKey::Domain kRawFillPathGlyphDomain = GrUniqueKey:: GenerateDomain();
412 431
413 const SkTypeface* typeface = fFont.getTypeface(); 432 const SkTypeface* typeface = fFont.getTypeface();
414 GrUniqueKey::Builder builder(&fGlyphPathsKey, kRawFillPathGlyphDomain, 1 ); 433 GrUniqueKey::Builder builder(&fGlyphPathsKey, kRawFillPathGlyphDomain, 1 );
415 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqueID( ) : 0; 434 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqueID( ) : 0;
416 } else { 435 } else {
417 static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::Generat eDomain(); 436 static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::Generat eDomain();
418 437
419 int strokeDataCount = fStroke.computeUniqueKeyFragmentData32Cnt(); 438 int styleDataCount = GrStyle::KeySize(fStyle, GrStyle::Apply::kPathEffec tAndStrokeRec);
439 // Key should be valid since we opted out of drawing arbitrary path effe cts.
440 SkASSERT(styleDataCount >= 0);
420 if (fUsingRawGlyphPaths) { 441 if (fUsingRawGlyphPaths) {
421 const SkTypeface* typeface = fFont.getTypeface(); 442 const SkTypeface* typeface = fFont.getTypeface();
422 GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain, 2 + strokeDataCount); 443 GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain, 2 + styleDataCount);
423 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqu eID() : 0; 444 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqu eID() : 0;
424 reinterpret_cast<uint32_t&>(builder[1]) = strokeDataCount; 445 reinterpret_cast<uint32_t&>(builder[1]) = styleDataCount;
425 fStroke.asUniqueKeyFragment(&builder[2]); 446 if (styleDataCount) {
447 write_style_key(&builder[2], fStyle);
448 }
426 } else { 449 } else {
427 SkGlyphCache* glyphCache = this->getGlyphCache(); 450 SkGlyphCache* glyphCache = this->getGlyphCache();
428 const SkTypeface* typeface = glyphCache->getScalerContext()->getType face(); 451 const SkTypeface* typeface = glyphCache->getScalerContext()->getType face();
429 const SkDescriptor* desc = &glyphCache->getDescriptor(); 452 const SkDescriptor* desc = &glyphCache->getDescriptor();
430 int descDataCount = (desc->getLength() + 3) / 4; 453 int descDataCount = (desc->getLength() + 3) / 4;
431 GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain, 454 GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain,
432 2 + strokeDataCount + descDataCount); 455 2 + styleDataCount + descDataCount);
433 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqu eID() : 0; 456 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqu eID() : 0;
434 reinterpret_cast<uint32_t&>(builder[1]) = strokeDataCount | (descDat aCount << 16); 457 reinterpret_cast<uint32_t&>(builder[1]) = styleDataCount | (descData Count << 16);
435 fStroke.asUniqueKeyFragment(&builder[2]); 458 if (styleDataCount) {
436 memcpy(&builder[2 + strokeDataCount], desc, desc->getLength()); 459 write_style_key(&builder[2], fStyle);
460 }
461 memcpy(&builder[2 + styleDataCount], desc, desc->getLength());
437 } 462 }
438 } 463 }
439 } 464 }
440 465
441 GrStencilAndCoverTextContext::TextRun::~TextRun() { 466 GrStencilAndCoverTextContext::TextRun::~TextRun() {
442 this->releaseGlyphCache(); 467 this->releaseGlyphCache();
443 } 468 }
444 469
445 void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by teLength, 470 void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by teLength,
446 SkScalar x, SkScalar y) { 471 SkScalar x, SkScalar y) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 fFallbackTextBlob.reset(fallback.buildIfNeeded(&fFallbackGlyphCount)); 559 fFallbackTextBlob.reset(fallback.buildIfNeeded(&fFallbackGlyphCount));
535 } 560 }
536 561
537 GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx) const { 562 GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx) const {
538 GrPathRange* glyphs = static_cast<GrPathRange*>( 563 GrPathRange* glyphs = static_cast<GrPathRange*>(
539 ctx->resourceProvider()->findAndRefResourceByUniqueKey(fGlyphPathsKe y)); 564 ctx->resourceProvider()->findAndRefResourceByUniqueKey(fGlyphPathsKe y));
540 if (nullptr == glyphs) { 565 if (nullptr == glyphs) {
541 if (fUsingRawGlyphPaths) { 566 if (fUsingRawGlyphPaths) {
542 SkScalerContextEffects noeffects; 567 SkScalerContextEffects noeffects;
543 glyphs = ctx->resourceProvider()->createGlyphs(fFont.getTypeface(), noeffects, 568 glyphs = ctx->resourceProvider()->createGlyphs(fFont.getTypeface(), noeffects,
544 nullptr, fStroke); 569 nullptr, fStyle);
545 } else { 570 } else {
546 SkGlyphCache* cache = this->getGlyphCache(); 571 SkGlyphCache* cache = this->getGlyphCache();
547 glyphs = ctx->resourceProvider()->createGlyphs(cache->getScalerConte xt()->getTypeface(), 572 glyphs = ctx->resourceProvider()->createGlyphs(cache->getScalerConte xt()->getTypeface(),
548 cache->getScalerConte xt()->getEffects(), 573 cache->getScalerConte xt()->getEffects(),
549 &cache->getDescriptor (), 574 &cache->getDescriptor (),
550 fStroke); 575 fStyle);
551 } 576 }
552 ctx->resourceProvider()->assignUniqueKeyToResource(fGlyphPathsKey, glyph s); 577 ctx->resourceProvider()->assignUniqueKeyToResource(fGlyphPathsKey, glyph s);
553 } 578 }
554 return glyphs; 579 return glyphs;
555 } 580 }
556 581
557 inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl yph, 582 inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl yph,
558 const SkPoint& po s, 583 const SkPoint& po s,
559 FallbackBlobBuild er* fallback) { 584 FallbackBlobBuild er* fallback) {
560 // Stick the glyphs we can't draw into the fallback text blob. 585 // Stick the glyphs we can't draw into the fallback text blob.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 GrDrawPathRangeBatch::Create(viewMatrix, fTextRatio, fTextInverseRat io * x, 639 GrDrawPathRangeBatch::Create(viewMatrix, fTextRatio, fTextInverseRat io * x,
615 fTextInverseRatio * y, color, 640 fTextInverseRatio * y, color,
616 GrPathRendering::kWinding_FillType, gly phs, fInstanceData, 641 GrPathRendering::kWinding_FillType, gly phs, fInstanceData,
617 bounds)); 642 bounds));
618 643
619 dc->drawPathBatch(*pipelineBuilder, batch); 644 dc->drawPathBatch(*pipelineBuilder, batch);
620 } 645 }
621 646
622 if (fFallbackTextBlob) { 647 if (fFallbackTextBlob) {
623 SkPaint fallbackSkPaint(originalSkPaint); 648 SkPaint fallbackSkPaint(originalSkPaint);
624 fStroke.applyToPaint(&fallbackSkPaint); 649 fStyle.strokeRec().applyToPaint(&fallbackSkPaint);
625 if (!fStroke.isFillStyle()) { 650 if (!fStyle.isSimpleFill()) {
626 fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio); 651 fallbackSkPaint.setStrokeWidth(fStyle.strokeRec().getWidth() * fText Ratio);
627 } 652 }
628 653
629 fallbackTextContext->drawTextBlob(ctx, dc, pipelineBuilder->clip(), fall backSkPaint, 654 fallbackTextContext->drawTextBlob(ctx, dc, pipelineBuilder->clip(), fall backSkPaint,
630 viewMatrix, props, fFallbackTextBlob, x, y, nullptr, 655 viewMatrix, props, fFallbackTextBlob, x, y, nullptr,
631 clipBounds); 656 clipBounds);
632 } 657 }
633 } 658 }
634 659
635 SkGlyphCache* GrStencilAndCoverTextContext::TextRun::getGlyphCache() const { 660 SkGlyphCache* GrStencilAndCoverTextContext::TextRun::getGlyphCache() const {
636 if (!fDetachedGlyphCache) { 661 if (!fDetachedGlyphCache) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 } 728 }
704 729
705 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfNeed ed(int *count) { 730 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfNeed ed(int *count) {
706 *count = fCount; 731 *count = fCount;
707 if (fCount) { 732 if (fCount) {
708 this->flush(); 733 this->flush();
709 return fBuilder->build(); 734 return fBuilder->build();
710 } 735 }
711 return nullptr; 736 return nullptr;
712 } 737 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698