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

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

Issue 149853002: Improved distance field sampling (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: More clean up 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 "GrDrawTargetCaps.h"
11 #include "GrFontScaler.h" 12 #include "GrFontScaler.h"
12 #include "SkGlyphCache.h" 13 #include "SkGlyphCache.h"
13 #include "GrIndexBuffer.h" 14 #include "GrIndexBuffer.h"
14 #include "GrTextStrike.h" 15 #include "GrTextStrike.h"
15 #include "GrTextStrike_impl.h" 16 #include "GrTextStrike_impl.h"
16 #include "SkDraw.h" 17 #include "SkDraw.h"
17 #include "SkGpuDevice.h" 18 #include "SkGpuDevice.h"
18 #include "SkPath.h" 19 #include "SkPath.h"
19 #include "SkRTConf.h" 20 #include "SkRTConf.h"
20 #include "SkStrokeRec.h" 21 #include "SkStrokeRec.h"
21 #include "effects/GrDistanceFieldTextureEffect.h" 22 #include "effects/GrDistanceFieldTextureEffect.h"
22 23
23 static const int kGlyphCoordsAttributeIndex = 1; 24 static const int kGlyphCoordsAttributeIndex = 1;
25 static const int kGlyphOffsetAttributeIndex = 2;
24 26
25 static const int kBaseDFFontSize = 32; 27 static const int kBaseDFFontSize = 32;
26 28
27 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, 29 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
28 "Dump the contents of the font cache before every purge."); 30 "Dump the contents of the font cache before every purge.");
29 31
30 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, 32 GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
31 const SkDeviceProperties& properties) 33 const SkDeviceProperties& properties)
32 : GrTextContext(context, pro perties) { 34 : GrTextContext(context, pro perties) {
33 fStrike = NULL; 35 fStrike = NULL;
34 36
35 fCurrTexture = NULL; 37 fCurrTexture = NULL;
36 fCurrVertex = 0; 38 fCurrVertex = 0;
37 39
38 fVertices = NULL; 40 fVertices = NULL;
39 fMaxVertices = 0; 41 fMaxVertices = 0;
40 } 42 }
41 43
42 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { 44 GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
43 this->flushGlyphs(); 45 this->flushGlyphs();
44 } 46 }
45 47
46 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { 48 bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) {
47 return !paint.getRasterizer() && !paint.getMaskFilter() && 49 return !paint.getRasterizer() && !paint.getMaskFilter() &&
48 paint.getStyle() == SkPaint::kFill_Style && 50 paint.getStyle() == SkPaint::kFill_Style &&
51 fContext->getTextTarget()->caps()->shaderDerivativeSupport() &&
49 !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix()); 52 !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix());
50 } 53 }
51 54
52 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { 55 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
53 unsigned r = SkColorGetR(c); 56 unsigned r = SkColorGetR(c);
54 unsigned g = SkColorGetG(c); 57 unsigned g = SkColorGetG(c);
55 unsigned b = SkColorGetB(c); 58 unsigned b = SkColorGetB(c);
56 return GrColorPackRGBA(r, g, b, 0xff); 59 return GrColorPackRGBA(r, g, b, 0xff);
57 } 60 }
58 61
59 void GrDistanceFieldTextContext::flushGlyphs() { 62 void GrDistanceFieldTextContext::flushGlyphs() {
60 if (NULL == fDrawTarget) { 63 if (NULL == fDrawTarget) {
61 return; 64 return;
62 } 65 }
63 66
64 GrDrawState* drawState = fDrawTarget->drawState(); 67 GrDrawState* drawState = fDrawTarget->drawState();
65 GrDrawState::AutoRestoreEffects are(drawState); 68 GrDrawState::AutoRestoreEffects are(drawState);
66 drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTa rget()); 69 drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTa rget());
67 70
68 if (fCurrVertex > 0) { 71 if (fCurrVertex > 0) {
69 // setup our sampler state for our text texture/atlas 72 // setup our sampler state for our text texture/atlas
70 SkASSERT(GrIsALIGN4(fCurrVertex)); 73 SkASSERT(fCurrVertex % 6 == 0);
71 SkASSERT(fCurrTexture); 74 SkASSERT(fCurrTexture);
72 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil erp_FilterMode); 75 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil erp_FilterMode);
73 76
74 // This effect could be stored with one of the cache objects (atlas?) 77 // This effect could be stored with one of the cache objects (atlas?)
75 drawState->addCoverageEffect( 78 drawState->addCoverageEffect(
76 GrDistanceFieldTextureEffect::Create(fCurrTextur e, params), 79 GrDistanceFieldTextureEffect::Create(fCurrTextur e, params),
77 kGlyphCoordsAttributeIndex)->unref(); 80 kGlyphCoordsAttributeIndex, kGlyphOffsetAttribut eIndex)->unref();
78 81
79 if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) { 82 if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
80 if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() || 83 if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
81 kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() || 84 kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
82 fPaint.numColorStages()) { 85 fPaint.numColorStages()) {
83 GrPrintf("LCD Text will not draw correctly.\n"); 86 GrPrintf("LCD Text will not draw correctly.\n");
84 } 87 }
85 // We don't use the GrPaint's color in this case because it's been p remultiplied by 88 // We don't use the GrPaint's color in this case because it's been p remultiplied by
86 // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by 89 // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by
87 // the mask texture color. The end result is that we get 90 // the mask texture color. The end result is that we get
88 // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstCo lor 91 // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstCo lor
89 int a = SkColorGetA(fSkPaint.getColor()); 92 int a = SkColorGetA(fSkPaint.getColor());
90 // paintAlpha 93 // paintAlpha
91 drawState->setColor(SkColorSetARGB(a, a, a, a)); 94 drawState->setColor(SkColorSetARGB(a, a, a, a));
92 // paintColor 95 // paintColor
93 drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPain t.getColor())); 96 drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPain t.getColor()));
94 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); 97 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
95 } else { 98 } else {
96 // set back to normal in case we took LCD path previously. 99 // set back to normal in case we took LCD path previously.
97 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen dCoeff()); 100 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen dCoeff());
98 drawState->setColor(fPaint.getColor()); 101 drawState->setColor(fPaint.getColor());
99 } 102 }
100 103
101 int nGlyphs = fCurrVertex / 4; 104 int nGlyphs = fCurrVertex / 6;
102 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); 105 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
103 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, 106 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
104 nGlyphs, 107 nGlyphs,
105 4, 6); 108 4, 6);
106 fDrawTarget->resetVertexSource(); 109 fDrawTarget->resetVertexSource();
107 fVertices = NULL; 110 fVertices = NULL;
108 fMaxVertices = 0; 111 fMaxVertices = 0;
109 fCurrVertex = 0; 112 fCurrVertex = 0;
110 SkSafeSetNull(fCurrTexture); 113 SkSafeSetNull(fCurrTexture);
111 } 114 }
112 } 115 }
113 116
114 namespace { 117 namespace {
115 118
116 // position + texture coord 119 // position + texture coord
117 extern const GrVertexAttrib gTextVertexAttribs[] = { 120 extern const GrVertexAttrib gTextVertexAttribs[] = {
118 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 121 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBindi ng},
119 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} 122 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding },
123 {kVec2f_GrVertexAttribType, 2*sizeof(GrPoint), kEffect_GrVertexAttribBinding }
120 }; 124 };
121 125
122 }; 126 };
123 127
124 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, 128 void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
125 GrFixed vx, GrFixed vy, 129 GrFixed vx, GrFixed vy,
126 GrFontScaler* scaler) { 130 GrFontScaler* scaler) {
127 if (NULL == fDrawTarget) { 131 if (NULL == fDrawTarget) {
128 return; 132 return;
129 } 133 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 fMaxVertices = kDefaultRequestedVerts; 245 fMaxVertices = kDefaultRequestedVerts;
242 } else if (fMaxVertices > maxQuadVertices) { 246 } else if (fMaxVertices > maxQuadVertices) {
243 // don't exceed the limit of the index buffer 247 // don't exceed the limit of the index buffer
244 fMaxVertices = maxQuadVertices; 248 fMaxVertices = maxQuadVertices;
245 } 249 }
246 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, 250 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
247 0, 251 0,
248 GrTCast<void**>(& fVertices), 252 GrTCast<void**>(& fVertices),
249 NULL); 253 NULL);
250 GrAlwaysAssert(success); 254 GrAlwaysAssert(success);
251 SkASSERT(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize( )); 255 SkASSERT(3*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize( ));
252 } 256 }
253 257
254 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft); 258 SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft);
255 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop); 259 SkScalar dy = SkIntToScalar(glyph->fBounds.fTop);
256 SkScalar width = SkIntToScalar(glyph->fBounds.width()); 260 SkScalar width = SkIntToScalar(glyph->fBounds.width());
257 SkScalar height = SkIntToScalar(glyph->fBounds.height()); 261 SkScalar height = SkIntToScalar(glyph->fBounds.height());
258 262
259 SkScalar scale = fTextRatio; 263 SkScalar scale = fTextRatio;
260 dx *= scale; 264 dx *= scale;
261 dy *= scale; 265 dy *= scale;
262 sx += dx; 266 sx += dx;
263 sy += dy; 267 sy += dy;
264 width *= scale; 268 width *= scale;
265 height *= scale; 269 height *= scale;
266 270
267 GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX); 271 GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX);
268 GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY); 272 GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY);
269 GrFixed tw = SkIntToFixed(glyph->fBounds.width()); 273 GrFixed tw = SkIntToFixed(glyph->fBounds.width());
270 GrFixed th = SkIntToFixed(glyph->fBounds.height()); 274 GrFixed th = SkIntToFixed(glyph->fBounds.height());
271 275
276 SkISize texSize = fStrike->getAtlasSize();
bsalomon 2014/02/05 20:19:10 AFAICT this is the same for the lifetime of the pr
jvanverth1 2014/02/10 18:34:02 Done.
277
272 fVertices[2*fCurrVertex].setRectFan(sx, 278 fVertices[2*fCurrVertex].setRectFan(sx,
273 sy, 279 sy,
274 sx + width, 280 sx + width,
275 sy + height, 281 sy + height,
276 2 * sizeof(SkPoint)); 282 3 * sizeof(SkPoint));
bsalomon 2014/02/05 20:19:10 this 3 * sizeof(SkPoint) is repeated here three ti
jvanverth1 2014/02/10 18:34:02 Done.
277 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)), 283 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)),
278 SkFixedToFloat(texture->normalizeFixed Y(ty)), 284 SkFixedToFloat(texture->normalizeFixed Y(ty)),
279 SkFixedToFloat(texture->normalizeFixed X(tx + tw)), 285 SkFixedToFloat(texture->normalizeFixed X(tx + tw)),
280 SkFixedToFloat(texture->normalizeFixed Y(ty + th)), 286 SkFixedToFloat(texture->normalizeFixed Y(ty + th)),
281 2 * sizeof(SkPoint)); 287 3 * sizeof(SkPoint));
282 fCurrVertex += 4; 288 fVertices[2*fCurrVertex+2].setRectFan(SkIntToScalar(texSize.fWidth),
289 SkIntToScalar(texSize.fHeight),
290 SkIntToScalar(texSize.fWidth),
291 SkIntToScalar(texSize.fHeight),
292 3 * sizeof(SkPoint));
293 fCurrVertex += 6;
283 } 294 }
284 295
285 inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint & skPaint) { 296 inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint & skPaint) {
286 GrTextContext::init(paint, skPaint); 297 GrTextContext::init(paint, skPaint);
287 298
288 fStrike = NULL; 299 fStrike = NULL;
289 300
290 fCurrTexture = NULL; 301 fCurrTexture = NULL;
291 fCurrVertex = 0; 302 fCurrVertex = 0;
292 303
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 SkScalarToFixed(y) - (glyph.fAdvanceY >> a lignShift) 450 SkScalarToFixed(y) - (glyph.fAdvanceY >> a lignShift)
440 + SK_FixedHalf, //d1g.fHalfSampleY, 451 + SK_FixedHalf, //d1g.fHalfSampleY,
441 fontScaler); 452 fontScaler);
442 } 453 }
443 pos += scalarsPerPosition; 454 pos += scalarsPerPosition;
444 } 455 }
445 } 456 }
446 457
447 this->finish(); 458 this->finish();
448 } 459 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698