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

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

Issue 1698503002: Remove last bit of privacy violation for GrAtlasTextBlob (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase + nits Created 4 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
« no previous file with comments | « src/gpu/batches/GrAtlasTextBatch.h ('k') | src/gpu/text/GrAtlasTextBlob.h » ('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 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 "GrBatchFlushState.h" 10 #include "GrBatchFlushState.h"
11 #include "GrBatchTest.h"
12 #include "GrResourceProvider.h" 11 #include "GrResourceProvider.h"
13 12
14 #include "SkDistanceFieldGen.h"
15 #include "SkGlyphCache.h" 13 #include "SkGlyphCache.h"
16 14
17 #include "effects/GrBitmapTextGeoProc.h" 15 #include "effects/GrBitmapTextGeoProc.h"
18 #include "effects/GrDistanceFieldGeoProc.h" 16 #include "effects/GrDistanceFieldGeoProc.h"
19 #include "text/GrBatchFontCache.h" 17 #include "text/GrBatchFontCache.h"
20 18
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 template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs>
125 inline void GrAtlasTextBatch::regenBlob(Target* target, FlushInfo* flushInfo, Bl ob* blob, Run* run,
126 TextInfo* info, SkGlyphCache** cache,
127 SkTypeface** typeface, GrFontScaler** sc aler,
128 const SkDescriptor** desc, const GrGeome tryProcessor* gp,
129 int glyphCount, size_t vertexStride,
130 GrColor color, SkScalar transX, SkScalar transY) const {
131 static_assert(!regenGlyphs || regenTexCoords, "must regenTexCoords along reg enGlyphs");
132 GrBatchTextStrike* strike = nullptr;
133 if (regenTexCoords) {
134 info->resetBulkUseToken();
135
136 // We can reuse if we have a valid strike and our descriptors / typeface are the
137 // same. The override descriptor is only for the non distance field tex t within
138 // a run
139 const SkDescriptor* newDesc = (run->fOverrideDescriptor && !this->usesDi stanceFields()) ?
140 run->fOverrideDescriptor->getDesc() :
141 run->fDescriptor.getDesc();
142 if (!*cache || !SkTypeface::Equal(*typeface, run->fTypeface) ||
143 !((*desc)->equals(*newDesc))) {
144 if (*cache) {
145 SkGlyphCache::AttachCache(*cache);
146 }
147 *desc = newDesc;
148 *cache = SkGlyphCache::DetachCache(run->fTypeface, *desc);
149 *scaler = GrTextContext::GetGrFontScaler(*cache);
150 *typeface = run->fTypeface;
151 }
152
153 if (regenGlyphs) {
154 strike = fFontCache->getStrike(*scaler);
155 } else {
156 strike = info->strike();
157 }
158 }
159
160 bool brokenRun = false;
161 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
162 GrGlyph* glyph = nullptr;
163 if (regenTexCoords) {
164 size_t glyphOffset = glyphIdx + info->glyphStartIndex();
165
166 if (regenGlyphs) {
167 // Get the id from the old glyph, and use the new strike to look up
168 // the glyph.
169 GrGlyph::PackedID id = blob->fGlyphs[glyphOffset]->fPackedID;
170 blob->fGlyphs[glyphOffset] = strike->getGlyph(id, this->maskForm at(), *scaler);
171 SkASSERT(id == blob->fGlyphs[glyphOffset]->fPackedID);
172 }
173 glyph = blob->fGlyphs[glyphOffset];
174 SkASSERT(glyph && glyph->fMaskFormat == this->maskFormat());
175
176 if (!fFontCache->hasGlyph(glyph) &&
177 !strike->addGlyphToAtlas(target, glyph, *scaler, this->maskForma t())) {
178 this->flush(target, flushInfo);
179 target->initDraw(gp, this->pipeline());
180 brokenRun = glyphIdx > 0;
181
182 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(target,
183 glyph,
184 *scaler,
185 this->maskFo rmat());
186 SkASSERT(success);
187 }
188 fFontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph ,
189 target->currentToken());
190 }
191
192 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices);
193 vertex += info->vertexStartIndex();
194 vertex += vertexStride * glyphIdx * GrAtlasTextBatch::kVerticesPerGlyph;
195 regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertex Stride,
196 this->usesDistanceFie lds(), transX,
197 transY, color);
198 flushInfo->fGlyphsToFlush++;
199 }
200
201 // We may have changed the color so update it here
202 info->setColor(color);
203 if (regenTexCoords) {
204 if (regenGlyphs) {
205 info->setStrike(strike);
206 }
207 info->setAtlasGeneration(brokenRun ? GrBatchAtlas::kInvalidAtlasGenerati on :
208 fFontCache->atlasGeneration(this->m askFormat()));
209 }
210 }
211 //////////////////////////////////////////////////////////////////////////////// /////////////////// 19 //////////////////////////////////////////////////////////////////////////////// ///////////////////
212 20
213 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { 21 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
214 unsigned r = SkColorGetR(c); 22 unsigned r = SkColorGetR(c);
215 unsigned g = SkColorGetG(c); 23 unsigned g = SkColorGetG(c);
216 unsigned b = SkColorGetB(c); 24 unsigned b = SkColorGetB(c);
217 return GrColorPackRGBA(r, g, b, 0xff); 25 return GrColorPackRGBA(r, g, b, 0xff);
218 } 26 }
219 27
220 static const int kDistanceAdjustLumShift = 5; 28 static const int kDistanceAdjustLumShift = 5;
221 29
222 SkString GrAtlasTextBatch::dumpInfo() const { 30 SkString GrAtlasTextBatch::dumpInfo() const {
223 SkString str; 31 SkString str;
224 32
225 for (int i = 0; i < fGeoCount; ++i) { 33 for (int i = 0; i < fGeoCount; ++i) {
226 str.appendf("%d: Color: 0x%08x Trans: %.2f,%.2f Runs: %d\n", 34 str.appendf("%d: Color: 0x%08x Trans: %.2f,%.2f Runs: %d\n",
227 i, 35 i,
228 fGeoData[i].fColor, 36 fGeoData[i].fColor,
229 fGeoData[i].fTransX, 37 fGeoData[i].fTransX,
230 fGeoData[i].fTransY, 38 fGeoData[i].fTransY,
231 fGeoData[i].fBlob->fRunCount); 39 fGeoData[i].fBlob->runCount());
232 } 40 }
233 41
234 str.append(INHERITED::dumpInfo()); 42 str.append(INHERITED::dumpInfo());
235 return str; 43 return str;
236 } 44 }
237 45
238 void GrAtlasTextBatch::computePipelineOptimizations(GrInitInvariantOutput* color , 46 void GrAtlasTextBatch::computePipelineOptimizations(GrInitInvariantOutput* color ,
239 GrInitInvariantOutput* cover age, 47 GrInitInvariantOutput* cover age,
240 GrBatchToXPOverrides* overri des) const { 48 GrBatchToXPOverrides* overri des) const {
241 if (kColorBitmapMask_MaskType == fMaskType) { 49 if (kColorBitmapMask_MaskType == fMaskType) {
(...skipping 23 matching lines...) Expand all
265 } 73 }
266 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); 74 overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
267 75
268 // setup batch properties 76 // setup batch properties
269 fBatch.fColorIgnored = !overrides.readsColor(); 77 fBatch.fColorIgnored = !overrides.readsColor();
270 fBatch.fColor = fGeoData[0].fColor; 78 fBatch.fColor = fGeoData[0].fColor;
271 fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); 79 fBatch.fUsesLocalCoords = overrides.readsLocalCoords();
272 fBatch.fCoverageIgnored = !overrides.readsCoverage(); 80 fBatch.fCoverageIgnored = !overrides.readsCoverage();
273 } 81 }
274 82
275 enum RegenMask {
276 kNoRegen = 0x0,
277 kRegenPos = 0x1,
278 kRegenCol = 0x2,
279 kRegenTex = 0x4,
280 kRegenGlyph = 0x8 | kRegenTex, // we have to regenerate the texture coords w hen we regen glyphs
281
282 // combinations
283 kRegenPosCol = kRegenPos | kRegenCol,
284 kRegenPosTex = kRegenPos | kRegenTex,
285 kRegenPosTexGlyph = kRegenPos | kRegenGlyph,
286 kRegenPosColTex = kRegenPos | kRegenCol | kRegenTex,
287 kRegenPosColTexGlyph = kRegenPos | kRegenCol | kRegenGlyph,
288 kRegenColTex = kRegenCol | kRegenTex,
289 kRegenColTexGlyph = kRegenCol | kRegenGlyph,
290 };
291
292 #define REGEN_ARGS target, &flushInfo, blob, &run, &info, &cache, &typeface, &sc aler, &desc, gp, \
293 glyphCount, vertexStride, args.fColor, args.fTransX, args.fTr ansY
294
295 void GrAtlasTextBatch::onPrepareDraws(Target* target) const { 83 void GrAtlasTextBatch::onPrepareDraws(Target* target) const {
296 // if we have RGB, then we won't have any SkShaders so no need to use a loca lmatrix. 84 // if we have RGB, then we won't have any SkShaders so no need to use a loca lmatrix.
297 // TODO actually only invert if we don't have RGBA 85 // TODO actually only invert if we don't have RGBA
298 SkMatrix localMatrix; 86 SkMatrix localMatrix;
299 if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix)) { 87 if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix)) {
300 SkDebugf("Cannot invert viewmatrix\n"); 88 SkDebugf("Cannot invert viewmatrix\n");
301 return; 89 return;
302 } 90 }
303 91
304 GrTexture* texture = fFontCache->getTexture(this->maskFormat()); 92 GrTexture* texture = fFontCache->getTexture(this->maskFormat());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 134
347 unsigned char* currVertex = reinterpret_cast<unsigned char*>(vertices); 135 unsigned char* currVertex = reinterpret_cast<unsigned char*>(vertices);
348 136
349 // We cache some values to avoid going to the glyphcache for the same fontSc aler twice 137 // We cache some values to avoid going to the glyphcache for the same fontSc aler twice
350 // in a row 138 // in a row
351 const SkDescriptor* desc = nullptr; 139 const SkDescriptor* desc = nullptr;
352 SkGlyphCache* cache = nullptr; 140 SkGlyphCache* cache = nullptr;
353 GrFontScaler* scaler = nullptr; 141 GrFontScaler* scaler = nullptr;
354 SkTypeface* typeface = nullptr; 142 SkTypeface* typeface = nullptr;
355 143
144 GrBlobRegenHelper helper(this, target, &flushInfo, gp);
145
356 for (int i = 0; i < fGeoCount; i++) { 146 for (int i = 0; i < fGeoCount; i++) {
357 const Geometry& args = fGeoData[i]; 147 const Geometry& args = fGeoData[i];
358 Blob* blob = args.fBlob; 148 Blob* blob = args.fBlob;
359 Run& run = blob->fRuns[args.fRun]; 149 size_t byteCount;
360 TextInfo& info = run.fSubRunInfo[args.fSubRun]; 150 void* blobVertices;
361 151 int glyphCount;
362 uint64_t currentAtlasGen = fFontCache->atlasGeneration(maskFormat); 152 blob->regenInBatch(target, fFontCache, &helper, args.fRun, args.fSubRun, &cache,
363 153 &typeface, &scaler, &desc, vertexStride, args.fColor, args.fTransX,
364 // Because the GrBatchFontCache may evict the strike a blob depends on u sing for 154 args.fTransY, &blobVertices, &byteCount, &glyphCount) ;
365 // generating its texture coords, we have to track whether or not the st rike has
366 // been abandoned. If it hasn't been abandoned, then we can use the GrG lyph*s as is
367 // otherwise we have to get the new strike, and use that to get the corr ect glyphs.
368 // Because we do not have the packed ids, and thus can't look up our gly phs in the
369 // new strike, we instead keep our ref to the old strike and use the pac ked ids from
370 // it. These ids will still be valid as long as we hold the ref. When we are done
371 // updating our cache of the GrGlyph*s, we drop our ref on the old strik e
372 bool regenerateGlyphs = info.strike()->isAbandoned();
373 bool regenerateTextureCoords = info.atlasGeneration() != currentAtlasGen ||
374 regenerateGlyphs;
375 bool regenerateColors = kARGB_GrMaskFormat != maskFormat &&
376 info.color() != args.fColor;
377 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f;
378 int glyphCount = info.glyphCount();
379
380 uint32_t regenMaskBits = kNoRegen;
381 regenMaskBits |= regeneratePositions ? kRegenPos : 0;
382 regenMaskBits |= regenerateColors ? kRegenCol : 0;
383 regenMaskBits |= regenerateTextureCoords ? kRegenTex : 0;
384 regenMaskBits |= regenerateGlyphs ? kRegenGlyph : 0;
385 RegenMask regenMask = (RegenMask)regenMaskBits;
386
387 switch (regenMask) {
388 case kRegenPos: this->regenBlob<true, false, false, false>(REGEN_ARG S); break;
389 case kRegenCol: this->regenBlob<false, true, false, false>(REGEN_ARG S); break;
390 case kRegenTex: this->regenBlob<false, false, true, false>(REGEN_ARG S); break;
391 case kRegenGlyph: this->regenBlob<false, false, true, true>(REGEN_AR GS); break;
392
393 // combinations
394 case kRegenPosCol: this->regenBlob<true, true, false, false>(REGEN_A RGS); break;
395 case kRegenPosTex: this->regenBlob<true, false, true, false>(REGEN_A RGS); break;
396 case kRegenPosTexGlyph: this->regenBlob<true, false, true, true>(REG EN_ARGS); break;
397 case kRegenPosColTex: this->regenBlob<true, true, true, false>(REGEN _ARGS); break;
398 case kRegenPosColTexGlyph: this->regenBlob<true, true, true, true>(R EGEN_ARGS); break;
399 case kRegenColTex: this->regenBlob<false, true, true, false>(REGEN_A RGS); break;
400 case kRegenColTexGlyph: this->regenBlob<false, true, true, true>(REG EN_ARGS); break;
401 case kNoRegen:
402 flushInfo.fGlyphsToFlush += glyphCount;
403
404 // set use tokens for all of the glyphs in our subrun. This is only valid if we
405 // have a valid atlas generation
406 fFontCache->setUseTokenBulk(*info.bulkUseToken(), target->curren tToken(),
407 maskFormat);
408 break;
409 }
410 155
411 // now copy all vertices 156 // now copy all vertices
412 size_t byteCount = info.byteCount(); 157 memcpy(currVertex, blobVertices, byteCount);
413 memcpy(currVertex, blob->fVertices + info.vertexStartIndex(), byteCount) ;
414 158
415 #ifdef SK_DEBUG 159 #ifdef SK_DEBUG
416 // bounds sanity check 160 // bounds sanity check
417 SkRect rect; 161 SkRect rect;
418 rect.setLargestInverted(); 162 rect.setLargestInverted();
419 SkPoint* vertex = (SkPoint*) ((char*)blob->fVertices + info.vertexStartI ndex()); 163 SkPoint* vertex = (SkPoint*) ((char*)blobVertices);
420 rect.growToInclude(vertex, vertexStride, kVerticesPerGlyph * info.glyphC ount()); 164 rect.growToInclude(vertex, vertexStride, kVerticesPerGlyph * glyphCount) ;
421 165
422 if (this->usesDistanceFields()) { 166 if (this->usesDistanceFields()) {
423 fBatch.fViewMatrix.mapRect(&rect); 167 fBatch.fViewMatrix.mapRect(&rect);
424 } 168 }
425 SkASSERT(fBounds.contains(rect)); 169 SkASSERT(fBounds.contains(rect));
426 #endif 170 #endif
427 171
428 currVertex += byteCount; 172 currVertex += byteCount;
429 } 173 }
430 174
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 return GrDistanceFieldA8TextGeoProc::Create(color, 303 return GrDistanceFieldA8TextGeoProc::Create(color,
560 viewMatrix, 304 viewMatrix,
561 texture, 305 texture,
562 params, 306 params,
563 flags, 307 flags,
564 this->usesLocalCoords()); 308 this->usesLocalCoords());
565 #endif 309 #endif
566 } 310 }
567 311
568 } 312 }
313
314 void GrBlobRegenHelper::flush() {
315 fBatch->flush(fTarget, fFlushInfo);
316 fTarget->initDraw(fGP, fBatch->pipeline());
317 }
OLDNEW
« no previous file with comments | « src/gpu/batches/GrAtlasTextBatch.h ('k') | src/gpu/text/GrAtlasTextBlob.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698