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

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

Issue 663423003: Allocate only the vertices we need for text. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments Created 6 years, 1 month 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/GrDistanceFieldTextContext.h ('k') | src/gpu/GrTextContext.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 2013 Google Inc. 2 * Copyright 2013 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 "GrDistanceFieldTextContext.h" 8 #include "GrDistanceFieldTextContext.h"
9 #include "GrAtlas.h" 9 #include "GrAtlas.h"
10 #include "GrBitmapTextContext.h" 10 #include "GrBitmapTextContext.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 49
50 // position + color + texture coord 50 // position + color + texture coord
51 extern const GrVertexAttrib gTextVertexWithColorAttribs[] = { 51 extern const GrVertexAttrib gTextVertexWithColorAttribs[] = {
52 {kVec2f_GrVertexAttribType, 0, kPosition_Gr VertexAttribBinding}, 52 {kVec2f_GrVertexAttribType, 0, kPosition_Gr VertexAttribBinding},
53 {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVer texAttribBinding}, 53 {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVer texAttribBinding},
54 {kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kGeometryPro cessor_GrVertexAttribBinding} 54 {kVec2f_GrVertexAttribType, sizeof(SkPoint) + sizeof(GrColor), kGeometryPro cessor_GrVertexAttribBinding}
55 }; 55 };
56 56
57 static const size_t kTextVAColorSize = 2 * sizeof(SkPoint) + sizeof(GrColor); 57 static const size_t kTextVAColorSize = 2 * sizeof(SkPoint) + sizeof(GrColor);
58 58
59 static const int kVerticesPerGlyph = 4;
60 static const int kIndicesPerGlyph = 6;
59 }; 61 };
60 62
61 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, 63 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
62 const SkDeviceProperties& properties, 64 const SkDeviceProperties& properties,
63 bool enable) 65 bool enable)
64 : GrTextContext(context, pro perties) { 66 : GrTextContext(context, pro perties) {
65 #if SK_FORCE_DISTANCEFIELD_FONTS 67 #if SK_FORCE_DISTANCEFIELD_FONTS
66 fEnableDFRendering = true; 68 fEnableDFRendering = true;
67 #else 69 #else
68 fEnableDFRendering = enable; 70 fEnableDFRendering = enable;
69 #endif 71 #endif
70 fStrike = NULL; 72 fStrike = NULL;
71 fGammaTexture = NULL; 73 fGammaTexture = NULL;
72 74
73 fCurrTexture = NULL;
74 fCurrVertex = 0;
75 fEffectTextureUniqueID = SK_InvalidUniqueID; 75 fEffectTextureUniqueID = SK_InvalidUniqueID;
76 fEffectColor = GrColor_ILLEGAL; 76 fEffectColor = GrColor_ILLEGAL;
77 fEffectFlags = 0; 77 fEffectFlags = 0;
78 78
79 fVertices = NULL; 79 fVertices = NULL;
80 fMaxVertices = 0; 80 fCurrVertex = 0;
81 fAllocVertexCount = 0;
82 fTotalVertexCount = 0;
83 fCurrTexture = NULL;
81 84
82 fVertexBounds.setLargestInverted(); 85 fVertexBounds.setLargestInverted();
83 } 86 }
84 87
85 GrDistanceFieldTextContext* GrDistanceFieldTextContext::Create(GrContext* contex t, 88 GrDistanceFieldTextContext* GrDistanceFieldTextContext::Create(GrContext* contex t,
86 const SkDevicePro perties& props, 89 const SkDevicePro perties& props,
87 bool enable) { 90 bool enable) {
88 GrDistanceFieldTextContext* textContext = SkNEW_ARGS(GrDistanceFieldTextCont ext, 91 GrDistanceFieldTextContext* textContext = SkNEW_ARGS(GrDistanceFieldTextCont ext,
89 (context, props, enable )); 92 (context, props, enable ));
90 textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, pro ps); 93 textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, pro ps);
91 94
92 return textContext; 95 return textContext;
93 } 96 }
94 97
95 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { 98 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
96 this->flush(); 99 this->finish();
97 SkSafeSetNull(fGammaTexture); 100 SkSafeSetNull(fGammaTexture);
98 } 101 }
99 102
100 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { 103 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) {
101 if (!fEnableDFRendering && !paint.isDistanceFieldTextTEMP()) { 104 if (!fEnableDFRendering && !paint.isDistanceFieldTextTEMP()) {
102 return false; 105 return false;
103 } 106 }
104 107
105 // rasterizers and mask filters modify alpha, which doesn't 108 // rasterizers and mask filters modify alpha, which doesn't
106 // translate well to distance 109 // translate well to distance
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 SkScalar maxScale = ctm.getMaxScale(); 141 SkScalar maxScale = ctm.getMaxScale();
139 SkScalar textSize = fSkPaint.getTextSize(); 142 SkScalar textSize = fSkPaint.getTextSize();
140 SkScalar scaledTextSize = textSize; 143 SkScalar scaledTextSize = textSize;
141 // if we have non-unity scale, we need to choose our base text size 144 // if we have non-unity scale, we need to choose our base text size
142 // based on the SkPaint's text size multiplied by the max scale factor 145 // based on the SkPaint's text size multiplied by the max scale factor
143 // TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)? 146 // TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)?
144 if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) { 147 if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) {
145 scaledTextSize *= maxScale; 148 scaledTextSize *= maxScale;
146 } 149 }
147 150
151 fVertices = NULL;
148 fCurrVertex = 0; 152 fCurrVertex = 0;
149 153 fAllocVertexCount = 0;
150 fVertices = NULL; 154 fTotalVertexCount = 0;
151 155
152 if (scaledTextSize <= kSmallDFFontLimit) { 156 if (scaledTextSize <= kSmallDFFontLimit) {
153 fTextRatio = textSize / kSmallDFFontSize; 157 fTextRatio = textSize / kSmallDFFontSize;
154 fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize)); 158 fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize));
155 } else if (scaledTextSize <= kMediumDFFontLimit) { 159 } else if (scaledTextSize <= kMediumDFFontLimit) {
156 fTextRatio = textSize / kMediumDFFontSize; 160 fTextRatio = textSize / kMediumDFFontSize;
157 fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize)); 161 fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize));
158 } else { 162 } else {
159 fTextRatio = textSize / kLargeDFFontSize; 163 fTextRatio = textSize / kLargeDFFontSize;
160 fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize)); 164 fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize));
161 } 165 }
162 166
163 fUseLCDText = fSkPaint.isLCDRenderText(); 167 fUseLCDText = fSkPaint.isLCDRenderText();
164 168
165 fSkPaint.setLCDRenderText(false); 169 fSkPaint.setLCDRenderText(false);
166 fSkPaint.setAutohinted(false); 170 fSkPaint.setAutohinted(false);
167 fSkPaint.setHinting(SkPaint::kNormal_Hinting); 171 fSkPaint.setHinting(SkPaint::kNormal_Hinting);
168 fSkPaint.setSubpixelText(true); 172 fSkPaint.setSubpixelText(true);
169
170 } 173 }
171 174
172 static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache, 175 static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache,
173 const SkDeviceProperties& deviceProperties, 176 const SkDeviceProperties& deviceProperties,
174 GrTexture** gammaTexture) { 177 GrTexture** gammaTexture) {
175 if (NULL == *gammaTexture) { 178 if (NULL == *gammaTexture) {
176 int width, height; 179 int width, height;
177 size_t size; 180 size_t size;
178 181
179 #ifdef SK_GAMMA_CONTRAST 182 #ifdef SK_GAMMA_CONTRAST
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 this->init(paint, skPaint); 289 this->init(paint, skPaint);
287 290
288 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 291 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
289 292
290 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); 293 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL);
291 SkGlyphCache* cache = autoCache.getCache(); 294 SkGlyphCache* cache = autoCache.getCache();
292 GrFontScaler* fontScaler = GetGrFontScaler(cache); 295 GrFontScaler* fontScaler = GetGrFontScaler(cache);
293 296
294 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); 297 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
295 298
299 int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL);
300 fTotalVertexCount = kVerticesPerGlyph*numGlyphs;
301
296 const char* stop = text + byteLength; 302 const char* stop = text + byteLength;
297 SkTArray<char> fallbackTxt; 303 SkTArray<char> fallbackTxt;
298 SkTArray<SkScalar> fallbackPos; 304 SkTArray<SkScalar> fallbackPos;
299 305
300 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { 306 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
301 while (text < stop) { 307 while (text < stop) {
302 const char* lastText = text; 308 const char* lastText = text;
303 // the last 2 parameters are ignored 309 // the last 2 parameters are ignored
304 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 310 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
305 311
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 } 370 }
365 } 371 }
366 372
367 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { 373 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
368 unsigned r = SkColorGetR(c); 374 unsigned r = SkColorGetR(c);
369 unsigned g = SkColorGetG(c); 375 unsigned g = SkColorGetG(c);
370 unsigned b = SkColorGetB(c); 376 unsigned b = SkColorGetB(c);
371 return GrColorPackRGBA(r, g, b, 0xff); 377 return GrColorPackRGBA(r, g, b, 0xff);
372 } 378 }
373 379
380 static void* alloc_vertices(GrDrawTarget* drawTarget, int numVertices, bool useC olorVerts) {
381 if (numVertices <= 0) {
382 return NULL;
383 }
384
385 // set up attributes
386 if (useColorVerts) {
387 drawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
388 SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSize);
389 } else {
390 drawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
391 SK_ARRAY_COUNT(gTextVertexAttribs), kTextVAS ize);
392 }
393 void* vertices = NULL;
394 bool success = drawTarget->reserveVertexAndIndexSpace(numVertices,
395 0,
396 &vertices,
397 NULL);
398 GrAlwaysAssert(success);
399 return vertices;
400 }
401
374 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo r) { 402 void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo r) {
375 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_ FilterMode); 403 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_ FilterMode);
376 GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNon e_FilterMode); 404 GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNon e_FilterMode);
377 405
378 uint32_t textureUniqueID = fCurrTexture->getUniqueID(); 406 uint32_t textureUniqueID = fCurrTexture->getUniqueID();
379 const SkMatrix& ctm = fContext->getMatrix(); 407 const SkMatrix& ctm = fContext->getMatrix();
380 408
381 // set up any flags 409 // set up any flags
382 uint32_t flags = 0; 410 uint32_t flags = 0;
383 flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; 411 flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 this->flush(); 536 this->flush();
509 537
510 GrContext::AutoMatrix am; 538 GrContext::AutoMatrix am;
511 SkMatrix ctm; 539 SkMatrix ctm;
512 ctm.setScale(fTextRatio, fTextRatio); 540 ctm.setScale(fTextRatio, fTextRatio);
513 ctm.postTranslate(sx, sy); 541 ctm.postTranslate(sx, sy);
514 GrPaint tmpPaint(fPaint); 542 GrPaint tmpPaint(fPaint);
515 am.setPreConcat(fContext, ctm, &tmpPaint); 543 am.setPreConcat(fContext, ctm, &tmpPaint);
516 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); 544 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
517 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo); 545 fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo);
546
547 // remove this glyph from the vertices we need to allocate
548 fTotalVertexCount -= kVerticesPerGlyph;
518 return true; 549 return true;
519 } 550 }
520 551
521 HAS_ATLAS: 552 HAS_ATLAS:
522 SkASSERT(glyph->fPlot); 553 SkASSERT(glyph->fPlot);
523 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); 554 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
524 glyph->fPlot->setDrawToken(drawToken); 555 glyph->fPlot->setDrawToken(drawToken);
525 556
526 GrTexture* texture = glyph->fPlot->texture(); 557 GrTexture* texture = glyph->fPlot->texture();
527 SkASSERT(texture); 558 SkASSERT(texture);
528 559
529 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { 560 if (fCurrTexture != texture || fCurrVertex + kVerticesPerGlyph > fTotalVerte xCount) {
530 this->flush(); 561 this->flush();
531 fCurrTexture = texture; 562 fCurrTexture = texture;
532 fCurrTexture->ref(); 563 fCurrTexture->ref();
533 } 564 }
534 565
535 bool useColorVerts = !fUseLCDText; 566 bool useColorVerts = !fUseLCDText;
536 567
537 if (NULL == fVertices) { 568 if (NULL == fVertices) {
538 // If we need to reserve vertices allow the draw target to suggest 569 int maxQuadVertices = kVerticesPerGlyph * fContext->getQuadIndexBuffer() ->maxQuads();
539 // a number of verts to reserve and whether to perform a flush. 570 fAllocVertexCount = SkMin32(fTotalVertexCount, maxQuadVertices);
540 fMaxVertices = kMinRequestedVerts; 571 fVertices = alloc_vertices(fDrawTarget, fAllocVertexCount, useColorVerts );
541 if (useColorVerts) {
542 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttri bs>(
543 SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSize);
544 } else {
545 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
546 SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize);
547 }
548 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
549 if (flush) {
550 this->flush();
551 fContext->flush();
552 if (useColorVerts) {
553 fDrawTarget->drawState()->setVertexAttribs<gTextVertexWithColorA ttribs>(
554 SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSiz e);
555 } else {
556 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
557 SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize);
558 }
559 }
560 fMaxVertices = kDefaultRequestedVerts;
561 // ignore return, no point in flushing again.
562 fDrawTarget->geometryHints(&fMaxVertices, NULL);
563
564 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
565 if (fMaxVertices < kMinRequestedVerts) {
566 fMaxVertices = kDefaultRequestedVerts;
567 } else if (fMaxVertices > maxQuadVertices) {
568 // don't exceed the limit of the index buffer
569 fMaxVertices = maxQuadVertices;
570 }
571 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
572 0,
573 &fVertices,
574 NULL);
575 GrAlwaysAssert(success);
576 } 572 }
577 573
578 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset); 574 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset);
579 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset); 575 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset);
580 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn set); 576 SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldIn set);
581 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField Inset); 577 SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceField Inset);
582 578
583 SkScalar scale = fTextRatio; 579 SkScalar scale = fTextRatio;
584 dx *= scale; 580 dx *= scale;
585 dy *= scale; 581 dy *= scale;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 drawState->setColor(SkColorSetARGB(a, a, a, a)); 676 drawState->setColor(SkColorSetARGB(a, a, a, a));
681 // paintColor 677 // paintColor
682 drawState->setBlendConstant(colorNoPreMul); 678 drawState->setBlendConstant(colorNoPreMul);
683 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); 679 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
684 } else { 680 } else {
685 // set back to normal in case we took LCD path previously. 681 // set back to normal in case we took LCD path previously.
686 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen dCoeff()); 682 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen dCoeff());
687 // We're using per-vertex color. 683 // We're using per-vertex color.
688 SkASSERT(drawState->hasColorVertexAttribute()); 684 SkASSERT(drawState->hasColorVertexAttribute());
689 } 685 }
690 int nGlyphs = fCurrVertex / 4; 686 int nGlyphs = fCurrVertex / kVerticesPerGlyph;
691 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); 687 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
692 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, 688 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
693 nGlyphs, 689 nGlyphs,
694 4, 6, &fVertexBounds); 690 kVerticesPerGlyph, kIndicesPerGlyph, & fVertexBounds);
695 fDrawTarget->resetVertexSource(); 691 fDrawTarget->resetVertexSource();
696 fVertices = NULL; 692 fVertices = NULL;
697 fMaxVertices = 0; 693 fTotalVertexCount -= fCurrVertex;
698 fCurrVertex = 0; 694 fCurrVertex = 0;
699 SkSafeSetNull(fCurrTexture); 695 SkSafeSetNull(fCurrTexture);
700 fVertexBounds.setLargestInverted(); 696 fVertexBounds.setLargestInverted();
701 } 697 }
702 } 698 }
703 699
704 inline void GrDistanceFieldTextContext::finish() { 700 inline void GrDistanceFieldTextContext::finish() {
705 this->flush(); 701 this->flush();
702 fTotalVertexCount = 0;
706 703
707 GrTextContext::finish(); 704 GrTextContext::finish();
708 } 705 }
709 706
OLDNEW
« no previous file with comments | « src/gpu/GrDistanceFieldTextContext.h ('k') | src/gpu/GrTextContext.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698