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

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

Issue 141863005: Add standalone drawText for GrTextContext. (Closed) Base URL: https://skia.googlesource.com/skia.git@issue2018-factory
Patch Set: Some clean-up work. Created 6 years, 10 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 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 "GrDrawTarget.h" 10 #include "GrDrawTarget.h"
11 #include "GrFontScaler.h" 11 #include "GrFontScaler.h"
12 #include "SkGlyphCache.h" 12 #include "SkGlyphCache.h"
13 #include "GrIndexBuffer.h" 13 #include "GrIndexBuffer.h"
14 #include "GrTextStrike.h" 14 #include "GrTextStrike.h"
15 #include "GrTextStrike_impl.h" 15 #include "GrTextStrike_impl.h"
16 #include "SkGpuDevice.h"
16 #include "SkPath.h" 17 #include "SkPath.h"
17 #include "SkRTConf.h" 18 #include "SkRTConf.h"
18 #include "SkStrokeRec.h" 19 #include "SkStrokeRec.h"
19 #include "effects/GrDistanceFieldTextureEffect.h" 20 #include "effects/GrDistanceFieldTextureEffect.h"
20 21
21 static const int kGlyphCoordsAttributeIndex = 1; 22 static const int kGlyphCoordsAttributeIndex = 1;
22 23
23 static const int kBaseDFFontSize = 32; 24 static const int kBaseDFFontSize = 32;
24 25
25 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, 26 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
26 "Dump the contents of the font cache before every purge."); 27 "Dump the contents of the font cache before every purge.");
27 28
28 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, 29 GrDistanceFieldTextContext::GrDistanceFieldTextContext(SkGpuDevice* device,
29 const GrPaint& grPaint, 30 const GrPaint& grPaint,
30 const SkPaint& skPaint) 31 const SkPaint& skPaint)
31 : GrTextContext(context, gr Paint, skPaint) { 32 : GrTextContext(device, grP aint, skPaint) {
32 fStrike = NULL; 33 fStrike = NULL;
33 34
34 fCurrTexture = NULL; 35 fCurrTexture = NULL;
35 fCurrVertex = 0; 36 fCurrVertex = 0;
36 37
37 fVertices = NULL; 38 fVertices = NULL;
38 fMaxVertices = 0; 39 fMaxVertices = 0;
39 40
40 fTextRatio = fSkPaint.getTextSize()/kBaseDFFontSize; 41 fTextRatio = fSkPaint.getTextSize()/kBaseDFFontSize;
41 42
(...skipping 12 matching lines...) Expand all
54 unsigned g = SkColorGetG(c); 55 unsigned g = SkColorGetG(c);
55 unsigned b = SkColorGetB(c); 56 unsigned b = SkColorGetB(c);
56 return GrColorPackRGBA(r, g, b, 0xff); 57 return GrColorPackRGBA(r, g, b, 0xff);
57 } 58 }
58 59
59 void GrDistanceFieldTextContext::flushGlyphs() { 60 void GrDistanceFieldTextContext::flushGlyphs() {
60 if (NULL == fDrawTarget) { 61 if (NULL == fDrawTarget) {
61 return; 62 return;
62 } 63 }
63 64
65 GrContext* context = fDevice->context();
64 GrDrawState* drawState = fDrawTarget->drawState(); 66 GrDrawState* drawState = fDrawTarget->drawState();
65 GrDrawState::AutoRestoreEffects are(drawState); 67 GrDrawState::AutoRestoreEffects are(drawState);
66 drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTa rget()); 68 drawState->setFromPaint(fPaint, context->getMatrix(), context->getRenderTarg et());
67 69
68 if (fCurrVertex > 0) { 70 if (fCurrVertex > 0) {
69 // setup our sampler state for our text texture/atlas 71 // setup our sampler state for our text texture/atlas
70 SkASSERT(GrIsALIGN4(fCurrVertex)); 72 SkASSERT(GrIsALIGN4(fCurrVertex));
71 SkASSERT(fCurrTexture); 73 SkASSERT(fCurrTexture);
72 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil erp_FilterMode); 74 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil erp_FilterMode);
73 75
74 // This effect could be stored with one of the cache objects (atlas?) 76 // This effect could be stored with one of the cache objects (atlas?)
75 drawState->addCoverageEffect( 77 drawState->addCoverageEffect(
76 GrDistanceFieldTextureEffect::Create(fCurrTextur e, params), 78 GrDistanceFieldTextureEffect::Create(fCurrTextur e, params),
(...skipping 15 matching lines...) Expand all
92 // paintColor 94 // paintColor
93 drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPain t.getColor())); 95 drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPain t.getColor()));
94 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); 96 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
95 } else { 97 } else {
96 // set back to normal in case we took LCD path previously. 98 // set back to normal in case we took LCD path previously.
97 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen dCoeff()); 99 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen dCoeff());
98 drawState->setColor(fPaint.getColor()); 100 drawState->setColor(fPaint.getColor());
99 } 101 }
100 102
101 int nGlyphs = fCurrVertex / 4; 103 int nGlyphs = fCurrVertex / 4;
102 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); 104 fDrawTarget->setIndexSourceToBuffer(context->getQuadIndexBuffer());
103 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, 105 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
104 nGlyphs, 106 nGlyphs,
105 4, 6); 107 4, 6);
106 fDrawTarget->resetVertexSource(); 108 fDrawTarget->resetVertexSource();
107 fVertices = NULL; 109 fVertices = NULL;
108 fMaxVertices = 0; 110 fMaxVertices = 0;
109 fCurrVertex = 0; 111 fCurrVertex = 0;
110 SkSafeSetNull(fCurrTexture); 112 SkSafeSetNull(fCurrTexture);
111 } 113 }
112 } 114 }
113 115
114 namespace { 116 namespace {
115 117
116 // position + texture coord 118 // position + texture coord
117 extern const GrVertexAttrib gTextVertexAttribs[] = { 119 extern const GrVertexAttrib gTextVertexAttribs[] = {
118 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 120 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
119 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} 121 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
120 }; 122 };
121 123
122 }; 124 };
123 125
124 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, 126 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
125 GrFixed vx, GrFixed vy, 127 GrFixed vx, GrFixed vy,
126 GrFontScaler* scaler) { 128 GrFontScaler* scaler) {
127 if (NULL == fDrawTarget) { 129 if (NULL == fDrawTarget) {
128 return; 130 return;
129 } 131 }
132 GrContext* context = fDevice->context();
130 if (NULL == fStrike) { 133 if (NULL == fStrike) {
131 fStrike = fContext->getFontCache()->getStrike(scaler, true); 134 fStrike = context->getFontCache()->getStrike(scaler, true);
132 } 135 }
133 136
134 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); 137 GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
135 if (NULL == glyph || glyph->fBounds.isEmpty()) { 138 if (NULL == glyph || glyph->fBounds.isEmpty()) {
136 return; 139 return;
137 } 140 }
138 141
139 SkScalar sx = SkFixedToScalar(vx); 142 SkScalar sx = SkFixedToScalar(vx);
140 SkScalar sy = SkFixedToScalar(vy); 143 SkScalar sy = SkFixedToScalar(vy);
141 /* 144 /*
(...skipping 14 matching lines...) Expand all
156 return; 159 return;
157 } 160 }
158 } 161 }
159 */ 162 */
160 if (NULL == glyph->fPlot) { 163 if (NULL == glyph->fPlot) {
161 if (fStrike->getGlyphAtlas(glyph, scaler)) { 164 if (fStrike->getGlyphAtlas(glyph, scaler)) {
162 goto HAS_ATLAS; 165 goto HAS_ATLAS;
163 } 166 }
164 167
165 // try to clear out an unused plot before we flush 168 // try to clear out an unused plot before we flush
166 fContext->getFontCache()->freePlotExceptFor(fStrike); 169 context->getFontCache()->freePlotExceptFor(fStrike);
167 if (fStrike->getGlyphAtlas(glyph, scaler)) { 170 if (fStrike->getGlyphAtlas(glyph, scaler)) {
168 goto HAS_ATLAS; 171 goto HAS_ATLAS;
169 } 172 }
170 173
171 if (c_DumpFontCache) { 174 if (c_DumpFontCache) {
172 #ifdef SK_DEVELOPER 175 #ifdef SK_DEVELOPER
173 fContext->getFontCache()->dump(); 176 context->getFontCache()->dump();
174 #endif 177 #endif
175 } 178 }
176 179
177 // before we purge the cache, we must flush any accumulated draws 180 // before we purge the cache, we must flush any accumulated draws
178 this->flushGlyphs(); 181 this->flushGlyphs();
179 fContext->flush(); 182 context->flush();
180 183
181 // try to purge 184 // try to purge
182 fContext->getFontCache()->purgeExceptFor(fStrike); 185 context->getFontCache()->purgeExceptFor(fStrike);
183 // need to use new flush count here 186 // need to use new flush count here
184 if (fStrike->getGlyphAtlas(glyph, scaler)) { 187 if (fStrike->getGlyphAtlas(glyph, scaler)) {
185 goto HAS_ATLAS; 188 goto HAS_ATLAS;
186 } 189 }
187 190
188 if (NULL == glyph->fPath) { 191 if (NULL == glyph->fPath) {
189 SkPath* path = SkNEW(SkPath); 192 SkPath* path = SkNEW(SkPath);
190 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { 193 if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
191 // flag the glyph as being dead? 194 // flag the glyph as being dead?
192 delete path; 195 delete path;
193 return; 196 return;
194 } 197 }
195 glyph->fPath = path; 198 glyph->fPath = path;
196 } 199 }
197 200
198 GrContext::AutoMatrix am; 201 GrContext::AutoMatrix am;
199 SkMatrix translate; 202 SkMatrix translate;
200 translate.setTranslate(sx, sy); 203 translate.setTranslate(sx, sy);
201 GrPaint tmpPaint(fPaint); 204 GrPaint tmpPaint(fPaint);
202 am.setPreConcat(fContext, translate, &tmpPaint); 205 am.setPreConcat(context, translate, &tmpPaint);
203 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 206 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
204 fContext->drawPath(tmpPaint, *glyph->fPath, stroke); 207 context->drawPath(tmpPaint, *glyph->fPath, stroke);
205 return; 208 return;
206 } 209 }
207 210
208 HAS_ATLAS: 211 HAS_ATLAS:
209 SkASSERT(glyph->fPlot); 212 SkASSERT(glyph->fPlot);
210 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken(); 213 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
211 glyph->fPlot->setDrawToken(drawToken); 214 glyph->fPlot->setDrawToken(drawToken);
212 215
213 GrTexture* texture = glyph->fPlot->texture(); 216 GrTexture* texture = glyph->fPlot->texture();
214 SkASSERT(texture); 217 SkASSERT(texture);
215 218
216 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { 219 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
217 this->flushGlyphs(); 220 this->flushGlyphs();
218 fCurrTexture = texture; 221 fCurrTexture = texture;
219 fCurrTexture->ref(); 222 fCurrTexture->ref();
220 } 223 }
221 224
222 if (NULL == fVertices) { 225 if (NULL == fVertices) {
223 // If we need to reserve vertices allow the draw target to suggest 226 // If we need to reserve vertices allow the draw target to suggest
224 // a number of verts to reserve and whether to perform a flush. 227 // a number of verts to reserve and whether to perform a flush.
225 fMaxVertices = kMinRequestedVerts; 228 fMaxVertices = kMinRequestedVerts;
226 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( 229 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
227 SK_ARRAY_COUNT(gTextVertexAttribs)); 230 SK_ARRAY_COUNT(gTextVertexAttribs));
228 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); 231 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
229 if (flush) { 232 if (flush) {
230 this->flushGlyphs(); 233 this->flushGlyphs();
231 fContext->flush(); 234 context->flush();
232 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>( 235 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
233 SK_ARRAY_COUNT(gTextVertexAttribs)); 236 SK_ARRAY_COUNT(gTextVertexAttribs));
234 } 237 }
235 fMaxVertices = kDefaultRequestedVerts; 238 fMaxVertices = kDefaultRequestedVerts;
236 // ignore return, no point in flushing again. 239 // ignore return, no point in flushing again.
237 fDrawTarget->geometryHints(&fMaxVertices, NULL); 240 fDrawTarget->geometryHints(&fMaxVertices, NULL);
238 241
239 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); 242 int maxQuadVertices = 4 * context->getQuadIndexBuffer()->maxQuads();
240 if (fMaxVertices < kMinRequestedVerts) { 243 if (fMaxVertices < kMinRequestedVerts) {
241 fMaxVertices = kDefaultRequestedVerts; 244 fMaxVertices = kDefaultRequestedVerts;
242 } else if (fMaxVertices > maxQuadVertices) { 245 } else if (fMaxVertices > maxQuadVertices) {
243 // don't exceed the limit of the index buffer 246 // don't exceed the limit of the index buffer
244 fMaxVertices = maxQuadVertices; 247 fMaxVertices = maxQuadVertices;
245 } 248 }
246 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, 249 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
247 0, 250 0,
248 GrTCast<void**>(& fVertices), 251 GrTCast<void**>(& fVertices),
249 NULL); 252 NULL);
(...skipping 26 matching lines...) Expand all
276 2 * sizeof(SkPoint)); 279 2 * sizeof(SkPoint));
277 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)), 280 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)),
278 SkFixedToFloat(texture->normalizeFixed Y(ty)), 281 SkFixedToFloat(texture->normalizeFixed Y(ty)),
279 SkFixedToFloat(texture->normalizeFixed X(tx + tw)), 282 SkFixedToFloat(texture->normalizeFixed X(tx + tw)),
280 SkFixedToFloat(texture->normalizeFixed Y(ty + th)), 283 SkFixedToFloat(texture->normalizeFixed Y(ty + th)),
281 2 * sizeof(SkPoint)); 284 2 * sizeof(SkPoint));
282 fCurrVertex += 4; 285 fCurrVertex += 4;
283 } 286 }
284 287
285 void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength, 288 void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength,
286 SkScalar x, SkScalar y, SkGlyphCache* cache, 289 SkScalar x, SkScalar y) {
287 GrFontScaler* fontScaler) {
288 SkASSERT(byteLength == 0 || text != NULL); 290 SkASSERT(byteLength == 0 || text != NULL);
289 291
290 // nothing to draw 292 // nothing to draw or can't draw
291 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) { 293 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/
294 || fSkPaint.getRasterizer()) {
292 return; 295 return;
293 } 296 }
294 297
295 SkScalar sizeRatio = fTextRatio; 298 SkScalar sizeRatio = fTextRatio;
296 299
297 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 300 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
298 301
302 SkAutoGlyphCache autoCache(fSkPaint, &fDevice->getDeviceProperties(), NUL L);
303 SkGlyphCache* cache = autoCache.getCache();
304 GrFontScaler* fontScaler = GetGrFontScaler(cache);
305
299 // need to measure first 306 // need to measure first
300 // TODO - generate positions and pre-load cache as well? 307 // TODO - generate positions and pre-load cache as well?
301 const char* stop = text + byteLength; 308 const char* stop = text + byteLength;
302 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { 309 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) {
303 SkFixed stopX = 0; 310 SkFixed stopX = 0;
304 SkFixed stopY = 0; 311 SkFixed stopY = 0;
305 312
306 const char* textPtr = text; 313 const char* textPtr = text;
307 while (textPtr < stop) { 314 while (textPtr < stop) {
308 // don't need x, y here, since all subpixel variants will have the 315 // don't need x, y here, since all subpixel variants will have the
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 fontScaler); 348 fontScaler);
342 } 349 }
343 350
344 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale); 351 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale);
345 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale); 352 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale);
346 } 353 }
347 } 354 }
348 355
349 void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLengt h, 356 void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLengt h,
350 const SkScalar pos[], SkScalar cons tY, 357 const SkScalar pos[], SkScalar cons tY,
351 int scalarsPerPosition, 358 int scalarsPerPosition) {
352 SkGlyphCache* cache, GrFontScaler* fontScaler) {
353 359
354 SkASSERT(byteLength == 0 || text != NULL); 360 SkASSERT(byteLength == 0 || text != NULL);
355 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); 361 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
356 362
357 // nothing to draw 363 // nothing to draw
358 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) { 364 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/
365 || fSkPaint.getRasterizer()) {
359 return; 366 return;
360 } 367 }
361 368
362 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 369 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
363 370
371 SkAutoGlyphCache autoCache(fSkPaint, &fDevice->getDeviceProperties(), NUL L);
372 SkGlyphCache* cache = autoCache.getCache();
373 GrFontScaler* fontScaler = GetGrFontScaler(cache);
374
364 const char* stop = text + byteLength; 375 const char* stop = text + byteLength;
365 376
366 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { 377 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
367 while (text < stop) { 378 while (text < stop) {
368 // the last 2 parameters are ignored 379 // the last 2 parameters are ignored
369 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 380 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
370 381
371 if (glyph.fWidth) { 382 if (glyph.fWidth) {
372 SkScalar x = pos[0]; 383 SkScalar x = pos[0];
373 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1]; 384 SkScalar y = scalarsPerPosition == 1 ? constY : pos[1];
(...skipping 23 matching lines...) Expand all
397 SkScalarToFixed(x) - (glyph.fAdvanceX >> a lignShift) 408 SkScalarToFixed(x) - (glyph.fAdvanceX >> a lignShift)
398 + SK_FixedHalf, //d1g.fHalfSampleX, 409 + SK_FixedHalf, //d1g.fHalfSampleX,
399 SkScalarToFixed(y) - (glyph.fAdvanceY >> a lignShift) 410 SkScalarToFixed(y) - (glyph.fAdvanceY >> a lignShift)
400 + SK_FixedHalf, //d1g.fHalfSampleY, 411 + SK_FixedHalf, //d1g.fHalfSampleY,
401 fontScaler); 412 fontScaler);
402 } 413 }
403 pos += scalarsPerPosition; 414 pos += scalarsPerPosition;
404 } 415 }
405 } 416 }
406 } 417 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698