OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 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 | 8 |
9 | 9 |
10 #include "GrTextContext.h" | 10 #include "GrTextContext.h" |
11 #include "GrAtlas.h" | 11 #include "GrAtlas.h" |
12 #include "GrContext.h" | 12 #include "GrContext.h" |
13 #include "GrDrawTarget.h" | 13 #include "GrDrawTarget.h" |
14 #include "GrFontScaler.h" | 14 #include "GrFontScaler.h" |
15 #include "GrIndexBuffer.h" | 15 #include "GrIndexBuffer.h" |
16 #include "GrTextStrike.h" | 16 #include "GrTextStrike.h" |
17 #include "GrTextStrike_impl.h" | 17 #include "GrTextStrike_impl.h" |
18 #include "SkPath.h" | 18 #include "SkPath.h" |
19 #include "SkStrokeRec.h" | 19 #include "SkStrokeRec.h" |
20 | 20 |
21 // glyph rendering shares this stage with edge rendering (kEdgeEffectStage in Gr Context) && SW path | 21 // glyph rendering shares this stage with edge rendering (kEdgeEffectStage in Gr Context) && SW path |
22 // rendering (kPathMaskStage in GrSWMaskHelper) | 22 // rendering (kPathMaskStage in GrSWMaskHelper) |
23 static const int kGlyphMaskStage = GrPaint::kTotalStages; | 23 static const int kGlyphMaskStage = GrPaint::kTotalStages; |
24 static const int kGlyphCoordsAttributeIndex = 1; | 24 static const int kGlyphCoordsAttributeIndex = 1; |
25 | 25 |
26 void GrTextContext::flushGlyphs() { | 26 void GrTextContext::flushGlyphs() { |
27 if (NULL == fDrawTarget) { | 27 if (NULL == fDrawTarget) { |
28 return; | 28 return; |
29 } | 29 } |
30 GrDrawTarget::AutoStateRestore asr(fDrawTarget, GrDrawTarget::kPreserve_ASRI nit); | |
bsalomon
2013/06/13 14:20:53
This will be replaced by a lighter weight auto-res
| |
30 GrDrawState* drawState = fDrawTarget->drawState(); | 31 GrDrawState* drawState = fDrawTarget->drawState(); |
32 drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget()); | |
33 | |
31 if (fCurrVertex > 0) { | 34 if (fCurrVertex > 0) { |
32 // setup our sampler state for our text texture/atlas | 35 // setup our sampler state for our text texture/atlas |
33 GrAssert(GrIsALIGN4(fCurrVertex)); | 36 GrAssert(GrIsALIGN4(fCurrVertex)); |
34 GrAssert(fCurrTexture); | 37 GrAssert(fCurrTexture); |
35 GrTextureParams params(SkShader::kRepeat_TileMode, false); | 38 GrTextureParams params(SkShader::kRepeat_TileMode, false); |
36 | 39 |
37 // This effect could be stored with one of the cache objects (atlas?) | 40 // This effect could be stored with one of the cache objects (atlas?) |
38 drawState->setEffect(kGlyphMaskStage, | 41 drawState->setEffect(kGlyphMaskStage, |
39 GrSimpleTextureEffect::CreateWithCustomCoords(fCurr Texture, params), | 42 GrSimpleTextureEffect::CreateWithCustomCoords(fCurr Texture, params), |
40 kGlyphCoordsAttributeIndex)->unref(); | 43 kGlyphCoordsAttributeIndex)->unref(); |
(...skipping 20 matching lines...) Expand all Loading... | |
61 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); | 64 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); |
62 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, | 65 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType, |
63 nGlyphs, | 66 nGlyphs, |
64 4, 6); | 67 4, 6); |
65 fDrawTarget->resetVertexSource(); | 68 fDrawTarget->resetVertexSource(); |
66 fVertices = NULL; | 69 fVertices = NULL; |
67 fMaxVertices = 0; | 70 fMaxVertices = 0; |
68 fCurrVertex = 0; | 71 fCurrVertex = 0; |
69 GrSafeSetNull(fCurrTexture); | 72 GrSafeSetNull(fCurrTexture); |
70 } | 73 } |
71 drawState->disableStages(); | |
72 fDrawTarget = NULL; | |
73 } | 74 } |
74 | 75 |
75 GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint( paint) { | 76 GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint( paint) { |
76 fContext = context; | 77 fContext = context; |
77 fStrike = NULL; | 78 fStrike = NULL; |
78 | 79 |
79 fCurrTexture = NULL; | 80 fCurrTexture = NULL; |
80 fCurrVertex = 0; | 81 fCurrVertex = 0; |
81 | 82 |
82 const GrClipData* clipData = context->getClip(); | 83 const GrClipData* clipData = context->getClip(); |
83 | 84 |
84 GrRect devConservativeBound; | 85 GrRect devConservativeBound; |
85 clipData->fClipStack->getConservativeBounds( | 86 clipData->fClipStack->getConservativeBounds( |
86 -clipData->fOrigin.fX, | 87 -clipData->fOrigin.fX, |
87 -clipData->fOrigin.fY, | 88 -clipData->fOrigin.fY, |
88 context->getRenderTarget()->width(), | 89 context->getRenderTarget()->width(), |
89 context->getRenderTarget()->height(), | 90 context->getRenderTarget()->height(), |
90 &devConservativeBound); | 91 &devConservativeBound); |
91 | 92 |
92 devConservativeBound.roundOut(&fClipRect); | 93 devConservativeBound.roundOut(&fClipRect); |
93 | 94 |
94 fAutoMatrix.setIdentity(fContext, &fPaint); | 95 fAutoMatrix.setIdentity(fContext, &fPaint); |
95 | 96 |
96 fDrawTarget = NULL; | 97 fDrawTarget = fContext->getTextTarget(); |
97 | 98 |
98 fVertices = NULL; | 99 fVertices = NULL; |
99 fMaxVertices = 0; | 100 fMaxVertices = 0; |
100 } | 101 } |
101 | 102 |
102 GrTextContext::~GrTextContext() { | 103 GrTextContext::~GrTextContext() { |
103 this->flushGlyphs(); | 104 this->flushGlyphs(); |
104 if (fDrawTarget) { | |
105 fDrawTarget->drawState()->disableStages(); | |
106 } | |
107 } | 105 } |
108 | 106 |
109 void GrTextContext::flush() { | 107 void GrTextContext::flush() { |
110 this->flushGlyphs(); | 108 this->flushGlyphs(); |
111 } | 109 } |
112 | 110 |
113 namespace { | 111 namespace { |
114 | 112 |
115 // position + texture coord | 113 // position + texture coord |
116 extern const GrVertexAttrib gTextVertexAttribs[] = { | 114 extern const GrVertexAttrib gTextVertexAttribs[] = { |
117 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, | 115 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, |
118 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} | 116 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} |
119 }; | 117 }; |
120 | 118 |
121 }; | 119 }; |
122 | 120 |
123 void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed, | 121 void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed, |
124 GrFixed vx, GrFixed vy, | 122 GrFixed vx, GrFixed vy, |
125 GrFontScaler* scaler) { | 123 GrFontScaler* scaler) { |
124 if (NULL == fDrawTarget) { | |
125 return; | |
126 } | |
126 if (NULL == fStrike) { | 127 if (NULL == fStrike) { |
127 fStrike = fContext->getFontCache()->getStrike(scaler); | 128 fStrike = fContext->getFontCache()->getStrike(scaler); |
128 } | 129 } |
129 | 130 |
130 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); | 131 GrGlyph* glyph = fStrike->getGlyph(packed, scaler); |
131 if (NULL == glyph || glyph->fBounds.isEmpty()) { | 132 if (NULL == glyph || glyph->fBounds.isEmpty()) { |
132 return; | 133 return; |
133 } | 134 } |
134 | 135 |
135 vx += SkIntToFixed(glyph->fBounds.fLeft); | 136 vx += SkIntToFixed(glyph->fBounds.fLeft); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 | 198 |
198 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { | 199 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) { |
199 this->flushGlyphs(); | 200 this->flushGlyphs(); |
200 fCurrTexture = texture; | 201 fCurrTexture = texture; |
201 fCurrTexture->ref(); | 202 fCurrTexture->ref(); |
202 } | 203 } |
203 | 204 |
204 if (NULL == fVertices) { | 205 if (NULL == fVertices) { |
205 // If we need to reserve vertices allow the draw target to suggest | 206 // If we need to reserve vertices allow the draw target to suggest |
206 // a number of verts to reserve and whether to perform a flush. | 207 // a number of verts to reserve and whether to perform a flush. |
207 fMaxVertices = kMinRequestedVerts; | 208 fMaxVertices = kMinRequestedVerts; |
robertphillips
2013/06/13 16:26:08
overlength
| |
208 bool flush = false; | 209 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(SK_ARRAY_ COUNT(gTextVertexAttribs)); |
209 fDrawTarget = fContext->getTextTarget(fPaint); | 210 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); |
210 if (NULL != fDrawTarget) { | |
211 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(SK_AR RAY_COUNT(gTextVertexAttribs)); | |
212 flush = fDrawTarget->geometryHints(&fMaxVertices, NULL); | |
213 } | |
214 if (flush) { | 211 if (flush) { |
215 this->flushGlyphs(); | 212 this->flushGlyphs(); |
216 fContext->flush(); | 213 fContext->flush(); |
217 // flushGlyphs() will reset fDrawTarget to NULL. | |
218 fDrawTarget = fContext->getTextTarget(fPaint); | |
219 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(SK_AR RAY_COUNT(gTextVertexAttribs)); | 214 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(SK_AR RAY_COUNT(gTextVertexAttribs)); |
220 } | 215 } |
221 fMaxVertices = kDefaultRequestedVerts; | 216 fMaxVertices = kDefaultRequestedVerts; |
222 // ignore return, no point in flushing again. | 217 // ignore return, no point in flushing again. |
223 fDrawTarget->geometryHints(&fMaxVertices, NULL); | 218 fDrawTarget->geometryHints(&fMaxVertices, NULL); |
224 | 219 |
225 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); | 220 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads(); |
226 if (fMaxVertices < kMinRequestedVerts) { | 221 if (fMaxVertices < kMinRequestedVerts) { |
227 fMaxVertices = kDefaultRequestedVerts; | 222 fMaxVertices = kDefaultRequestedVerts; |
228 } else if (fMaxVertices > maxQuadVertices) { | 223 } else if (fMaxVertices > maxQuadVertices) { |
229 // don't exceed the limit of the index buffer | 224 // don't exceed the limit of the index buffer |
230 fMaxVertices = maxQuadVertices; | 225 fMaxVertices = maxQuadVertices; |
231 } | 226 } |
232 bool success = fDrawTarget->reserveVertexAndIndexSpace( | 227 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices, |
233 fMaxVertices, | 228 0, |
234 0, | 229 GrTCast<void**>(& fVertices), |
235 GrTCast<void**>(&fVertices), | 230 NULL); |
236 NULL); | |
237 GrAlwaysAssert(success); | 231 GrAlwaysAssert(success); |
238 GrAssert(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize( )); | 232 GrAssert(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize( )); |
239 } | 233 } |
240 | 234 |
241 GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX); | 235 GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX); |
242 GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY); | 236 GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY); |
243 | 237 |
244 fVertices[2*fCurrVertex].setRectFan(SkFixedToFloat(vx), | 238 fVertices[2*fCurrVertex].setRectFan(SkFixedToFloat(vx), |
245 SkFixedToFloat(vy), | 239 SkFixedToFloat(vy), |
246 SkFixedToFloat(vx + width), | 240 SkFixedToFloat(vx + width), |
247 SkFixedToFloat(vy + height), | 241 SkFixedToFloat(vy + height), |
248 2 * sizeof(SkPoint)); | 242 2 * sizeof(SkPoint)); |
249 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)), | 243 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)), |
250 SkFixedToFloat(texture->normalizeFixed Y(ty)), | 244 SkFixedToFloat(texture->normalizeFixed Y(ty)), |
251 SkFixedToFloat(texture->normalizeFixed X(tx + width)), | 245 SkFixedToFloat(texture->normalizeFixed X(tx + width)), |
252 SkFixedToFloat(texture->normalizeFixed Y(ty + height)), | 246 SkFixedToFloat(texture->normalizeFixed Y(ty + height)), |
253 2 * sizeof(SkPoint)); | 247 2 * sizeof(SkPoint)); |
254 fCurrVertex += 4; | 248 fCurrVertex += 4; |
255 } | 249 } |
OLD | NEW |