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

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

Issue 27199002: Split out GrBitmapTextContext from GrTextContext. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Update based on comments Created 7 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « src/gpu/GrBitmapTextContext.cpp ('k') | src/gpu/SkGpuDevice.cpp » ('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 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
10 #include "GrTextContext.h" 9 #include "GrTextContext.h"
11 #include "GrAtlas.h"
12 #include "GrContext.h"
13 #include "GrDrawTarget.h"
14 #include "GrFontScaler.h"
15 #include "GrIndexBuffer.h"
16 #include "GrTextStrike.h"
17 #include "GrTextStrike_impl.h"
18 #include "SkPath.h"
19 #include "SkRTConf.h"
20 #include "SkStrokeRec.h"
21 #include "effects/GrCustomCoordsTextureEffect.h"
22
23 static const int kGlyphCoordsAttributeIndex = 1;
24
25 SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
26 "Dump the contents of the font cache before every purge.");
27
28 void GrTextContext::flushGlyphs() {
29 if (NULL == fDrawTarget) {
30 return;
31 }
32
33 GrDrawState* drawState = fDrawTarget->drawState();
34 GrDrawState::AutoRestoreEffects are(drawState);
35 drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget());
36
37 if (fCurrVertex > 0) {
38 // setup our sampler state for our text texture/atlas
39 SkASSERT(GrIsALIGN4(fCurrVertex));
40 SkASSERT(fCurrTexture);
41 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNon e_FilterMode);
42
43 // This effect could be stored with one of the cache objects (atlas?)
44 drawState->addCoverageEffect(
45 GrCustomCoordsTextureEffect::Create(fCurrTexture , params),
46 kGlyphCoordsAttributeIndex)->unref();
47
48 if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
49 if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
50 kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
51 fPaint.numColorStages()) {
52 GrPrintf("LCD Text will not draw correctly.\n");
53 }
54 // setup blend so that we get mask * paintColor + (1-mask)*dstColor
55 drawState->setBlendConstant(fPaint.getColor());
56 drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
57 // don't modulate by the paint's color in the frag since we're
58 // already doing it via the blend const.
59 drawState->setColor(0xffffffff);
60 } else {
61 // set back to normal in case we took LCD path previously.
62 drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlen dCoeff());
63 drawState->setColor(fPaint.getColor());
64 }
65
66 int nGlyphs = fCurrVertex / 4;
67 fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
68 fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
69 nGlyphs,
70 4, 6);
71 fDrawTarget->resetVertexSource();
72 fVertices = NULL;
73 fMaxVertices = 0;
74 fCurrVertex = 0;
75 SkSafeSetNull(fCurrTexture);
76 }
77 }
78 10
79 GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint( paint) { 11 GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint( paint) {
80 fContext = context; 12 fContext = context;
81 fStrike = NULL;
82
83 fCurrTexture = NULL;
84 fCurrVertex = 0;
85 13
86 const GrClipData* clipData = context->getClip(); 14 const GrClipData* clipData = context->getClip();
87 15
88 SkRect devConservativeBound; 16 SkRect devConservativeBound;
89 clipData->fClipStack->getConservativeBounds( 17 clipData->fClipStack->getConservativeBounds(
90 -clipData->fOrigin.fX, 18 -clipData->fOrigin.fX,
91 -clipData->fOrigin.fY, 19 -clipData->fOrigin.fY,
92 context->getRenderTarget()->width(), 20 context->getRenderTarget()->width(),
93 context->getRenderTarget()->height(), 21 context->getRenderTarget()->height(),
94 &devConservativeBound); 22 &devConservativeBound);
95 23
96 devConservativeBound.roundOut(&fClipRect); 24 devConservativeBound.roundOut(&fClipRect);
97 25
98 fAutoMatrix.setIdentity(fContext, &fPaint);
99
100 fDrawTarget = fContext->getTextTarget(); 26 fDrawTarget = fContext->getTextTarget();
101
102 fVertices = NULL;
103 fMaxVertices = 0;
104 } 27 }
105 28
106 GrTextContext::~GrTextContext() {
107 this->flushGlyphs();
108 }
109
110 void GrTextContext::flush() {
111 this->flushGlyphs();
112 }
113
114 namespace {
115
116 // position + texture coord
117 extern const GrVertexAttrib gTextVertexAttribs[] = {
118 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
119 {kVec2f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
120 };
121
122 };
123
124 void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
125 GrFixed vx, GrFixed vy,
126 GrFontScaler* scaler) {
127 if (NULL == fDrawTarget) {
128 return;
129 }
130 if (NULL == fStrike) {
131 fStrike = fContext->getFontCache()->getStrike(scaler);
132 }
133
134 GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
135 if (NULL == glyph || glyph->fBounds.isEmpty()) {
136 return;
137 }
138
139 vx += SkIntToFixed(glyph->fBounds.fLeft);
140 vy += SkIntToFixed(glyph->fBounds.fTop);
141
142 // keep them as ints until we've done the clip-test
143 GrFixed width = glyph->fBounds.width();
144 GrFixed height = glyph->fBounds.height();
145
146 // check if we clipped out
147 if (true || NULL == glyph->fPlot) {
148 int x = vx >> 16;
149 int y = vy >> 16;
150 if (fClipRect.quickReject(x, y, x + width, y + height)) {
151 // SkCLZ(3); // so we can set a break-point in the debugger
152 return;
153 }
154 }
155
156 if (NULL == glyph->fPlot) {
157 if (fStrike->getGlyphAtlas(glyph, scaler)) {
158 goto HAS_ATLAS;
159 }
160
161 // try to clear out an unused plot before we flush
162 fContext->getFontCache()->freePlotExceptFor(fStrike);
163 if (fStrike->getGlyphAtlas(glyph, scaler)) {
164 goto HAS_ATLAS;
165 }
166
167 if (c_DumpFontCache) {
168 #ifdef SK_DEVELOPER
169 fContext->getFontCache()->dump();
170 #endif
171 }
172
173 // before we purge the cache, we must flush any accumulated draws
174 this->flushGlyphs();
175 fContext->flush();
176
177 // try to purge
178 fContext->getFontCache()->purgeExceptFor(fStrike);
179 // need to use new flush count here
180 if (fStrike->getGlyphAtlas(glyph, scaler)) {
181 goto HAS_ATLAS;
182 }
183
184 if (NULL == glyph->fPath) {
185 SkPath* path = SkNEW(SkPath);
186 if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
187 // flag the glyph as being dead?
188 delete path;
189 return;
190 }
191 glyph->fPath = path;
192 }
193
194 GrContext::AutoMatrix am;
195 SkMatrix translate;
196 translate.setTranslate(SkFixedToScalar(vx - SkIntToFixed(glyph->fBounds. fLeft)),
197 SkFixedToScalar(vy - SkIntToFixed(glyph->fBounds. fTop)));
198 GrPaint tmpPaint(fPaint);
199 am.setPreConcat(fContext, translate, &tmpPaint);
200 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
201 fContext->drawPath(tmpPaint, *glyph->fPath, stroke);
202 return;
203 }
204
205 HAS_ATLAS:
206 SkASSERT(glyph->fPlot);
207 GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
208 glyph->fPlot->setDrawToken(drawToken);
209
210 // now promote them to fixed (TODO: Rethink using fixed pt).
211 width = SkIntToFixed(width);
212 height = SkIntToFixed(height);
213
214 GrTexture* texture = glyph->fPlot->texture();
215 SkASSERT(texture);
216
217 if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
218 this->flushGlyphs();
219 fCurrTexture = texture;
220 fCurrTexture->ref();
221 }
222
223 if (NULL == fVertices) {
224 // If we need to reserve vertices allow the draw target to suggest
225 // a number of verts to reserve and whether to perform a flush.
226 fMaxVertices = kMinRequestedVerts;
227 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
228 SK_ARRAY_COUNT(gTextVertexAttribs));
229 bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
230 if (flush) {
231 this->flushGlyphs();
232 fContext->flush();
233 fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
234 SK_ARRAY_COUNT(gTextVertexAttribs));
235 }
236 fMaxVertices = kDefaultRequestedVerts;
237 // ignore return, no point in flushing again.
238 fDrawTarget->geometryHints(&fMaxVertices, NULL);
239
240 int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
241 if (fMaxVertices < kMinRequestedVerts) {
242 fMaxVertices = kDefaultRequestedVerts;
243 } else if (fMaxVertices > maxQuadVertices) {
244 // don't exceed the limit of the index buffer
245 fMaxVertices = maxQuadVertices;
246 }
247 bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
248 0,
249 GrTCast<void**>(& fVertices),
250 NULL);
251 GrAlwaysAssert(success);
252 SkASSERT(2*sizeof(GrPoint) == fDrawTarget->getDrawState().getVertexSize( ));
253 }
254
255 GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX);
256 GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY);
257
258 fVertices[2*fCurrVertex].setRectFan(SkFixedToFloat(vx),
259 SkFixedToFloat(vy),
260 SkFixedToFloat(vx + width),
261 SkFixedToFloat(vy + height),
262 2 * sizeof(SkPoint));
263 fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixed X(tx)),
264 SkFixedToFloat(texture->normalizeFixed Y(ty)),
265 SkFixedToFloat(texture->normalizeFixed X(tx + width)),
266 SkFixedToFloat(texture->normalizeFixed Y(ty + height)),
267 2 * sizeof(SkPoint));
268 fCurrVertex += 4;
269 }
OLDNEW
« no previous file with comments | « src/gpu/GrBitmapTextContext.cpp ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698