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

Side by Side Diff: src/gpu/batches/GrAtlasTextBatch.cpp

Issue 1466333003: Move GrAtlasTextBatch blob regeneration to template (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add inline qualifier Created 5 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/batches/GrAtlasTextBatch.h ('k') | no next file » | 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 2015 Google Inc. 2 * Copyright 2015 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 "GrAtlasTextBatch.h" 8 #include "GrAtlasTextBatch.h"
9 9
10 #include "GrBatchFontCache.h" 10 #include "GrBatchFontCache.h"
11 #include "GrBatchFlushState.h" 11 #include "GrBatchFlushState.h"
12 #include "GrBatchTest.h" 12 #include "GrBatchTest.h"
13 #include "GrResourceProvider.h" 13 #include "GrResourceProvider.h"
14 14
15 #include "SkDistanceFieldGen.h" 15 #include "SkDistanceFieldGen.h"
16 #include "SkGlyphCache.h" 16 #include "SkGlyphCache.h"
17 17
18 #include "effects/GrBitmapTextGeoProc.h" 18 #include "effects/GrBitmapTextGeoProc.h"
19 #include "effects/GrDistanceFieldGeoProc.h" 19 #include "effects/GrDistanceFieldGeoProc.h"
20 20
21 //////////////////////////////////////////////////////////////////////////////// ////////////////////
22 // A large template to handle regenerating the vertices of a textblob with as fe w branches as
23 // possible
24 template <bool regenPos, bool regenCol, bool regenTexCoords>
25 inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS tride,
26 bool useDistanceFields, SkScalar transX, SkScalar tra nsY,
27 GrColor color) {
28 int u0, v0, u1, v1;
29 if (regenTexCoords) {
30 SkASSERT(glyph);
31 int width = glyph->fBounds.width();
32 int height = glyph->fBounds.height();
33
34 if (useDistanceFields) {
35 u0 = glyph->fAtlasLocation.fX + SK_DistanceFieldInset;
36 v0 = glyph->fAtlasLocation.fY + SK_DistanceFieldInset;
37 u1 = u0 + width - 2 * SK_DistanceFieldInset;
38 v1 = v0 + height - 2 * SK_DistanceFieldInset;
39 } else {
40 u0 = glyph->fAtlasLocation.fX;
41 v0 = glyph->fAtlasLocation.fY;
42 u1 = u0 + width;
43 v1 = v0 + height;
44 }
45 }
46
47 // This is a bit wonky, but sometimes we have LCD text, in which case we won 't have color
48 // vertices, hence vertexStride - sizeof(SkIPoint16)
49 intptr_t colorOffset = sizeof(SkPoint);
50 intptr_t texCoordOffset = vertexStride - sizeof(SkIPoint16);
51
52 // V0
53 if (regenPos) {
54 SkPoint* point = reinterpret_cast<SkPoint*>(vertex);
55 point->fX += transX;
56 point->fY += transY;
57 }
58
59 if (regenCol) {
60 SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset);
61 *vcolor = color;
62 }
63
64 if (regenTexCoords) {
65 SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCo ordOffset);
66 textureCoords->set(u0, v0);
67 }
68 vertex += vertexStride;
69
70 // V1
71 if (regenPos) {
72 SkPoint* point = reinterpret_cast<SkPoint*>(vertex);
73 point->fX += transX;
74 point->fY += transY;
75 }
76
77 if (regenCol) {
78 SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset);
79 *vcolor = color;
80 }
81
82 if (regenTexCoords) {
83 SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCo ordOffset);
84 textureCoords->set(u0, v1);
85 }
86 vertex += vertexStride;
87
88 // V2
89 if (regenPos) {
90 SkPoint* point = reinterpret_cast<SkPoint*>(vertex);
91 point->fX += transX;
92 point->fY += transY;
93 }
94
95 if (regenCol) {
96 SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset);
97 *vcolor = color;
98 }
99
100 if (regenTexCoords) {
101 SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCo ordOffset);
102 textureCoords->set(u1, v1);
103 }
104 vertex += vertexStride;
105
106 // V3
107 if (regenPos) {
108 SkPoint* point = reinterpret_cast<SkPoint*>(vertex);
109 point->fX += transX;
110 point->fY += transY;
111 }
112
113 if (regenCol) {
114 SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset);
115 *vcolor = color;
116 }
117
118 if (regenTexCoords) {
119 SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCo ordOffset);
120 textureCoords->set(u1, v0);
121 }
122 }
123
124 typedef GrAtlasTextBlob Blob;
125 typedef Blob::Run Run;
126 typedef Run::SubRunInfo TextInfo;
127
128 template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs>
129 inline void GrAtlasTextBatch::regenBlob(Target* target, FlushInfo* flushInfo, Bl ob* blob, Run* run,
130 TextInfo* info, SkGlyphCache** cache,
131 SkTypeface** typeface, GrFontScaler** sc aler,
132 const SkDescriptor** desc, const GrGeome tryProcessor* gp,
133 int glyphCount, size_t vertexStride,
134 GrColor color, SkScalar transX, SkScalar transY) {
135 static_assert(!regenGlyphs || regenTexCoords, "must regenTexCoords along reg enGlyphs");
136 GrBatchTextStrike* strike = nullptr;
137 if (regenTexCoords) {
138 info->fBulkUseToken.reset();
139
140 // We can reuse if we have a valid strike and our descriptors / typeface are the
141 // same. The override descriptor is only for the non distance field tex t within
142 // a run
143 const SkDescriptor* newDesc = (run->fOverrideDescriptor && !this->usesDi stanceFields()) ?
144 run->fOverrideDescriptor->getDesc() :
145 run->fDescriptor.getDesc();
146 if (!*cache || !SkTypeface::Equal(*typeface, run->fTypeface) ||
147 !((*desc)->equals(*newDesc))) {
148 if (*cache) {
149 SkGlyphCache::AttachCache(*cache);
150 }
151 *desc = newDesc;
152 *cache = SkGlyphCache::DetachCache(run->fTypeface, *desc);
153 *scaler = GrTextContext::GetGrFontScaler(*cache);
154 strike = info->fStrike;
155 *typeface = run->fTypeface;
156 }
157
158 if (regenGlyphs) {
159 strike = fFontCache->getStrike(*scaler);
160 } else {
161 strike = info->fStrike;
162 }
163 }
164
165 bool brokenRun = false;
166 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
167 GrGlyph* glyph = nullptr;
168 if (regenTexCoords) {
169 size_t glyphOffset = glyphIdx + info->fGlyphStartIndex;
170
171 glyph = blob->fGlyphs[glyphOffset];
172 GrGlyph::PackedID id = glyph->fPackedID;
173 const SkGlyph& skGlyph = (*scaler)->grToSkGlyph(id);
174 if (regenGlyphs) {
175 // Get the id from the old glyph, and use the new strike to look up
176 // the glyph.
177 blob->fGlyphs[glyphOffset] = strike->getGlyph(skGlyph, id, this- >maskFormat(),
178 *scaler);
179 }
180 glyph = blob->fGlyphs[glyphOffset];
181 SkASSERT(glyph);
182 SkASSERT(id == glyph->fPackedID);
183 // We want to be able to assert this but cannot for testing purposes .
184 // once skbug:4143 has landed we can revist this assert
185 //SkASSERT(glyph->fMaskFormat == this->maskFormat());
186
187 if (!fFontCache->hasGlyph(glyph) &&
188 !strike->addGlyphToAtlas(target, glyph, *scaler, skGlyph, this-> maskFormat())) {
189 this->flush(target, flushInfo);
190 target->initDraw(gp, this->pipeline());
191 brokenRun = glyphIdx > 0;
192
193 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(target,
194 glyph,
195 *scaler,
196 skGlyph,
197 this->maskFo rmat());
198 SkASSERT(success);
199 }
200 fFontCache->addGlyphToBulkAndSetUseToken(&info->fBulkUseToken, glyph ,
201 target->currentToken());
202 }
203
204 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices);
205 vertex += info->fVertexStartIndex;
206 vertex += vertexStride * glyphIdx * GrAtlasTextBatch::kVerticesPerGlyph;
207 regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertex Stride,
208 this->usesDistanceFie lds(), transX,
209 transY, color);
210 flushInfo->fGlyphsToFlush++;
211 }
212
213 // We my have changed the color so update it here
214 run->fColor = color;
215 if (regenTexCoords) {
216 if (regenGlyphs) {
217 info->fStrike.reset(SkRef(strike));
218 }
219 info->fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAtlasGenerati on :
220 fFontCache->atlasGeneration(this->m askFormat());
221 }
222 }
223 //////////////////////////////////////////////////////////////////////////////// ///////////////////
224
21 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { 225 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
22 unsigned r = SkColorGetR(c); 226 unsigned r = SkColorGetR(c);
23 unsigned g = SkColorGetG(c); 227 unsigned g = SkColorGetG(c);
24 unsigned b = SkColorGetB(c); 228 unsigned b = SkColorGetB(c);
25 return GrColorPackRGBA(r, g, b, 0xff); 229 return GrColorPackRGBA(r, g, b, 0xff);
26 } 230 }
27 231
28 static const int kDistanceAdjustLumShift = 5; 232 static const int kDistanceAdjustLumShift = 5;
29 233
30 SkString GrAtlasTextBatch::dumpInfo() const { 234 SkString GrAtlasTextBatch::dumpInfo() const {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 } 278 }
75 opt.getOverrideColorIfSet(&fGeoData[0].fColor); 279 opt.getOverrideColorIfSet(&fGeoData[0].fColor);
76 280
77 // setup batch properties 281 // setup batch properties
78 fBatch.fColorIgnored = !opt.readsColor(); 282 fBatch.fColorIgnored = !opt.readsColor();
79 fBatch.fColor = fGeoData[0].fColor; 283 fBatch.fColor = fGeoData[0].fColor;
80 fBatch.fUsesLocalCoords = opt.readsLocalCoords(); 284 fBatch.fUsesLocalCoords = opt.readsLocalCoords();
81 fBatch.fCoverageIgnored = !opt.readsCoverage(); 285 fBatch.fCoverageIgnored = !opt.readsCoverage();
82 } 286 }
83 287
288 enum RegenMask {
289 kNoRegen = 0x0,
290 kRegenPos = 0x1,
291 kRegenCol = 0x2,
292 kRegenTex = 0x4,
293 kRegenGlyph = 0x8 | kRegenTex, // we have to regenerate the texture coords w hen we regen glyphs
294
295 // combinations
296 kRegenPosCol = kRegenPos | kRegenCol,
297 kRegenPosTex = kRegenPos | kRegenTex,
298 kRegenPosTexGlyph = kRegenPos | kRegenGlyph,
299 kRegenPosColTex = kRegenPos | kRegenCol | kRegenTex,
300 kRegenPosColTexGlyph = kRegenPos | kRegenCol | kRegenGlyph,
301 kRegenColTex = kRegenCol | kRegenTex,
302 kRegenColTexGlyph = kRegenCol | kRegenGlyph,
303 };
304
305 #define REGEN_ARGS target, &flushInfo, blob, &run, &info, &cache, &typeface, &sc aler, &desc, gp, \
306 glyphCount, vertexStride, args.fColor, args.fTransX, args.fTr ansY
307
84 void GrAtlasTextBatch::onPrepareDraws(Target* target) { 308 void GrAtlasTextBatch::onPrepareDraws(Target* target) {
85 // if we have RGB, then we won't have any SkShaders so no need to use a loca lmatrix. 309 // if we have RGB, then we won't have any SkShaders so no need to use a loca lmatrix.
86 // TODO actually only invert if we don't have RGBA 310 // TODO actually only invert if we don't have RGBA
87 SkMatrix localMatrix; 311 SkMatrix localMatrix;
88 if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix)) { 312 if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix)) {
89 SkDebugf("Cannot invert viewmatrix\n"); 313 SkDebugf("Cannot invert viewmatrix\n");
90 return; 314 return;
91 } 315 }
92 316
93 GrTexture* texture = fFontCache->getTexture(this->maskFormat()); 317 GrTexture* texture = fFontCache->getTexture(this->maskFormat());
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 GrFontScaler* scaler = nullptr; 370 GrFontScaler* scaler = nullptr;
147 SkTypeface* typeface = nullptr; 371 SkTypeface* typeface = nullptr;
148 372
149 for (int i = 0; i < fGeoCount; i++) { 373 for (int i = 0; i < fGeoCount; i++) {
150 Geometry& args = fGeoData[i]; 374 Geometry& args = fGeoData[i];
151 Blob* blob = args.fBlob; 375 Blob* blob = args.fBlob;
152 Run& run = blob->fRuns[args.fRun]; 376 Run& run = blob->fRuns[args.fRun];
153 TextInfo& info = run.fSubRunInfo[args.fSubRun]; 377 TextInfo& info = run.fSubRunInfo[args.fSubRun];
154 378
155 uint64_t currentAtlasGen = fFontCache->atlasGeneration(maskFormat); 379 uint64_t currentAtlasGen = fFontCache->atlasGeneration(maskFormat);
380
381 // Because the GrBatchFontCache may evict the strike a blob depends on u sing for
382 // generating its texture coords, we have to track whether or not the st rike has
383 // been abandoned. If it hasn't been abandoned, then we can use the GrG lyph*s as is
384 // otherwise we have to get the new strike, and use that to get the corr ect glyphs.
385 // Because we do not have the packed ids, and thus can't look up our gly phs in the
386 // new strike, we instead keep our ref to the old strike and use the pac ked ids from
387 // it. These ids will still be valid as long as we hold the ref. When we are done
388 // updating our cache of the GrGlyph*s, we drop our ref on the old strik e
389 bool regenerateGlyphs = info.fStrike->isAbandoned();
156 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen || 390 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen ||
157 info.fStrike->isAbandoned(); 391 regenerateGlyphs;
158 bool regenerateColors; 392 bool regenerateColors;
159 if (usesDistanceFields) { 393 if (usesDistanceFields) {
160 regenerateColors = !isLCD && run.fColor != args.fColor; 394 regenerateColors = !isLCD && run.fColor != args.fColor;
161 } else { 395 } else {
162 regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != a rgs.fColor; 396 regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != a rgs.fColor;
163 } 397 }
164 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f; 398 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f;
165 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; 399 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex;
166 400
167 // We regenerate both texture coords and colors in the blob itself, and update the 401 uint32_t regenMaskBits = kNoRegen;
168 // atlas generation. If we don't end up purging any unused plots, we ca n avoid 402 regenMaskBits |= regeneratePositions ? kRegenPos : 0;
169 // regenerating the coords. We could take a finer grained approach to u pdating texture 403 regenMaskBits |= regenerateColors ? kRegenCol : 0;
170 // coords but its not clear if the extra bookkeeping would offset any ga ins. 404 regenMaskBits |= regenerateTextureCoords ? kRegenTex : 0;
171 // To avoid looping over the glyphs twice, we do one loop and conditiona lly update color 405 regenMaskBits |= regenerateGlyphs ? kRegenGlyph : 0;
172 // or coords as needed. One final note, if we have to break a run for a n atlas eviction 406 RegenMask regenMask = (RegenMask)regenMaskBits;
173 // then we can't really trust the atlas has all of the correct data. At las evictions
174 // should be pretty rare, so we just always regenerate in those cases
175 if (regenerateTextureCoords || regenerateColors || regeneratePositions) {
176 // first regenerate texture coordinates / colors if need be
177 bool brokenRun = false;
178 407
179 // Because the GrBatchFontCache may evict the strike a blob depends on using for 408 switch (regenMask) {
180 // generating its texture coords, we have to track whether or not th e strike has 409 case kRegenPos: this->regenBlob<true, false, false, false>(REGEN_ARG S); break;
181 // been abandoned. If it hasn't been abandoned, then we can use the GrGlyph*s as is 410 case kRegenCol: this->regenBlob<false, true, false, false>(REGEN_ARG S); break;
182 // otherwise we have to get the new strike, and use that to get the correct glyphs. 411 case kRegenTex: this->regenBlob<false, false, true, false>(REGEN_ARG S); break;
183 // Because we do not have the packed ids, and thus can't look up our glyphs in the 412 case kRegenGlyph: this->regenBlob<false, false, true, true>(REGEN_AR GS); break;
184 // new strike, we instead keep our ref to the old strike and use the packed ids from
185 // it. These ids will still be valid as long as we hold the ref. W hen we are done
186 // updating our cache of the GrGlyph*s, we drop our ref on the old s trike
187 bool regenerateGlyphs = false;
188 GrBatchTextStrike* strike = nullptr;
189 if (regenerateTextureCoords) {
190 info.fBulkUseToken.reset();
191 413
192 // We can reuse if we have a valid strike and our descriptors / typeface are the 414 // combinations
193 // same. The override descriptor is only for the non distance f ield text within 415 case kRegenPosCol: this->regenBlob<true, true, false, false>(REGEN_A RGS); break;
194 // a run 416 case kRegenPosTex: this->regenBlob<true, false, true, false>(REGEN_A RGS); break;
195 const SkDescriptor* newDesc = (run.fOverrideDescriptor && !usesD istanceFields) ? 417 case kRegenPosTexGlyph: this->regenBlob<true, false, true, true>(REG EN_ARGS); break;
196 run.fOverrideDescriptor->getDesc() : 418 case kRegenPosColTex: this->regenBlob<true, true, true, false>(REGEN _ARGS); break;
197 run.fDescriptor.getDesc(); 419 case kRegenPosColTexGlyph: this->regenBlob<true, true, true, true>(R EGEN_ARGS); break;
198 if (!cache || !SkTypeface::Equal(typeface, run.fTypeface) || 420 case kRegenColTex: this->regenBlob<false, true, true, false>(REGEN_A RGS); break;
199 !(desc->equals(*newDesc))) { 421 case kRegenColTexGlyph: this->regenBlob<false, true, true, true>(REG EN_ARGS); break;
200 if (cache) { 422 case kNoRegen:
201 SkGlyphCache::AttachCache(cache); 423 flushInfo.fGlyphsToFlush += glyphCount;
202 }
203 desc = newDesc;
204 cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
205 scaler = GrTextContext::GetGrFontScaler(cache);
206 strike = info.fStrike;
207 typeface = run.fTypeface;
208 }
209 424
210 if (info.fStrike->isAbandoned()) { 425 // set use tokens for all of the glyphs in our subrun. This is only valid if we
211 regenerateGlyphs = true; 426 // have a valid atlas generation
212 strike = fFontCache->getStrike(scaler); 427 fFontCache->setUseTokenBulk(info.fBulkUseToken, target->currentT oken(), maskFormat);
213 } else { 428 break;
214 strike = info.fStrike;
215 }
216 }
217
218 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
219 if (regenerateTextureCoords) {
220 size_t glyphOffset = glyphIdx + info.fGlyphStartIndex;
221
222 GrGlyph* glyph = blob->fGlyphs[glyphOffset];
223 GrGlyph::PackedID id = glyph->fPackedID;
224 const SkGlyph& skGlyph = scaler->grToSkGlyph(id);
225 if (regenerateGlyphs) {
226 // Get the id from the old glyph, and use the new strike to lookup
227 // the glyph.
228 blob->fGlyphs[glyphOffset] = strike->getGlyph(skGlyph, i d, maskFormat,
229 scaler);
230 }
231 glyph = blob->fGlyphs[glyphOffset];
232 SkASSERT(glyph);
233 SkASSERT(id == glyph->fPackedID);
234 // We want to be able to assert this but cannot for testing purposes.
235 // once skbug:4143 has landed we can revist this assert
236 //SkASSERT(glyph->fMaskFormat == this->maskFormat());
237
238 if (!fFontCache->hasGlyph(glyph) &&
239 !strike->addGlyphToAtlas(target, glyph, scaler, skGlyph, maskFormat)) {
240 this->flush(target, &flushInfo);
241 target->initDraw(gp, this->pipeline());
242 brokenRun = glyphIdx > 0;
243
244 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(targ et,
245 glyp h,
246 scal er,
247 skGl yph,
248 mask Format);
249 SkASSERT(success);
250 }
251 fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseToken , glyph,
252 target->currentToke n());
253
254 // Texture coords are the last vertex attribute so we get a pointer to the
255 // first one and then map with stride in regenerateTextureCo ords
256 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices );
257 vertex += info.fVertexStartIndex;
258 vertex += vertexStride * glyphIdx * kVerticesPerGlyph;
259 vertex += vertexStride - sizeof(SkIPoint16);
260
261 this->regenerateTextureCoords(glyph, vertex, vertexStride);
262 }
263
264 if (regenerateColors) {
265 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices );
266 vertex += info.fVertexStartIndex;
267 vertex += vertexStride * glyphIdx * kVerticesPerGlyph + size of(SkPoint);
268 this->regenerateColors(vertex, vertexStride, args.fColor);
269 }
270
271 if (regeneratePositions) {
272 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices );
273 vertex += info.fVertexStartIndex;
274 vertex += vertexStride * glyphIdx * kVerticesPerGlyph;
275 SkScalar transX = args.fTransX;
276 SkScalar transY = args.fTransY;
277 this->regeneratePositions(vertex, vertexStride, transX, tran sY);
278 }
279 flushInfo.fGlyphsToFlush++;
280 }
281
282 // We my have changed the color so update it here
283 run.fColor = args.fColor;
284 if (regenerateTextureCoords) {
285 if (regenerateGlyphs) {
286 info.fStrike.reset(SkRef(strike));
287 }
288 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAtlasG eneration :
289 fFontCache->atlasGeneration( maskFormat);
290 }
291 } else {
292 flushInfo.fGlyphsToFlush += glyphCount;
293
294 // set use tokens for all of the glyphs in our subrun. This is only valid if we
295 // have a valid atlas generation
296 fFontCache->setUseTokenBulk(info.fBulkUseToken, target->currentToken (), maskFormat);
297 } 429 }
298 430
299 // now copy all vertices 431 // now copy all vertices
300 size_t byteCount = info.fVertexEndIndex - info.fVertexStartIndex; 432 size_t byteCount = info.fVertexEndIndex - info.fVertexStartIndex;
301 memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCount); 433 memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCount);
302 434
303 currVertex += byteCount; 435 currVertex += byteCount;
304 } 436 }
437
305 // Make sure to attach the last cache if applicable 438 // Make sure to attach the last cache if applicable
306 if (cache) { 439 if (cache) {
307 SkGlyphCache::AttachCache(cache); 440 SkGlyphCache::AttachCache(cache);
308 } 441 }
309 this->flush(target, &flushInfo); 442 this->flush(target, &flushInfo);
310 } 443 }
311 444
312 void GrAtlasTextBatch::regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex,
313 size_t vertexStride) {
314 int width = glyph->fBounds.width();
315 int height = glyph->fBounds.height();
316
317 int u0, v0, u1, v1;
318 if (this->usesDistanceFields()) {
319 u0 = glyph->fAtlasLocation.fX + SK_DistanceFieldInset;
320 v0 = glyph->fAtlasLocation.fY + SK_DistanceFieldInset;
321 u1 = u0 + width - 2 * SK_DistanceFieldInset;
322 v1 = v0 + height - 2 * SK_DistanceFieldInset;
323 } else {
324 u0 = glyph->fAtlasLocation.fX;
325 v0 = glyph->fAtlasLocation.fY;
326 u1 = u0 + width;
327 v1 = v0 + height;
328 }
329
330 SkIPoint16* textureCoords;
331 // V0
332 textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
333 textureCoords->set(u0, v0);
334 vertex += vertexStride;
335
336 // V1
337 textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
338 textureCoords->set(u0, v1);
339 vertex += vertexStride;
340
341 // V2
342 textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
343 textureCoords->set(u1, v1);
344 vertex += vertexStride;
345
346 // V3
347 textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
348 textureCoords->set(u1, v0);
349 }
350
351 void GrAtlasTextBatch::regenerateColors(intptr_t vertex, size_t vertexStride, Gr Color color) {
352 for (int i = 0; i < kVerticesPerGlyph; i++) {
353 SkColor* vcolor = reinterpret_cast<SkColor*>(vertex);
354 *vcolor = color;
355 vertex += vertexStride;
356 }
357 }
358
359 void GrAtlasTextBatch::regeneratePositions(intptr_t vertex, size_t vertexStride, SkScalar transX,
360 SkScalar transY) {
361 for (int i = 0; i < kVerticesPerGlyph; i++) {
362 SkPoint* point = reinterpret_cast<SkPoint*>(vertex);
363 point->fX += transX;
364 point->fY += transY;
365 vertex += vertexStride;
366 }
367 }
368
369 void GrAtlasTextBatch::flush(GrVertexBatch::Target* target, FlushInfo* flushInfo ) { 445 void GrAtlasTextBatch::flush(GrVertexBatch::Target* target, FlushInfo* flushInfo ) {
370 GrVertices vertices; 446 GrVertices vertices;
371 int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads(); 447 int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads();
372 vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer, 448 vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
373 flushInfo->fIndexBuffer, flushInfo->fVertexOffset, 449 flushInfo->fIndexBuffer, flushInfo->fVertexOffset,
374 kVerticesPerGlyph, kIndicesPerGlyph, flushInfo->fGlyp hsToFlush, 450 kVerticesPerGlyph, kIndicesPerGlyph, flushInfo->fGlyp hsToFlush,
375 maxGlyphsPerDraw); 451 maxGlyphsPerDraw);
376 target->draw(vertices); 452 target->draw(vertices);
377 flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush; 453 flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
378 flushInfo->fGlyphsToFlush = 0; 454 flushInfo->fGlyphsToFlush = 0;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 return GrDistanceFieldA8TextGeoProc::Create(color, 574 return GrDistanceFieldA8TextGeoProc::Create(color,
499 viewMatrix, 575 viewMatrix,
500 texture, 576 texture,
501 params, 577 params,
502 flags, 578 flags,
503 this->usesLocalCoords()); 579 this->usesLocalCoords());
504 #endif 580 #endif
505 } 581 }
506 582
507 } 583 }
OLDNEW
« no previous file with comments | « src/gpu/batches/GrAtlasTextBatch.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698