Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 SkDebugf("Cannot invert viewmatrix\n"); | 89 SkDebugf("Cannot invert viewmatrix\n"); |
| 90 return; | 90 return; |
| 91 } | 91 } |
| 92 | 92 |
| 93 GrTexture* texture = fFontCache->getTexture(this->maskFormat()); | 93 GrTexture* texture = fFontCache->getTexture(this->maskFormat()); |
| 94 if (!texture) { | 94 if (!texture) { |
| 95 SkDebugf("Could not allocate backing texture for atlas\n"); | 95 SkDebugf("Could not allocate backing texture for atlas\n"); |
| 96 return; | 96 return; |
| 97 } | 97 } |
| 98 | 98 |
| 99 bool usesDistanceFields = this->usesDistanceFields(); | |
| 100 GrMaskFormat maskFormat = this->maskFormat(); | 99 GrMaskFormat maskFormat = this->maskFormat(); |
| 101 bool isLCD = this->isLCD(); | 100 bool isLCD = this->isLCD(); |
| 102 | 101 |
| 103 SkAutoTUnref<const GrGeometryProcessor> gp; | 102 SkAutoTUnref<const GrGeometryProcessor> gp; |
| 104 if (usesDistanceFields) { | 103 if (this->usesDistanceFields()) { |
| 105 gp.reset(this->setupDfProcessor(this->viewMatrix(), fFilteredColor, this ->color(), | 104 gp.reset(this->setupDfProcessor(this->viewMatrix(), fFilteredColor, this ->color(), |
| 106 texture)); | 105 texture)); |
| 107 } else { | 106 } else { |
| 108 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone _FilterMode); | 107 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone _FilterMode); |
| 109 gp.reset(GrBitmapTextGeoProc::Create(this->color(), | 108 gp.reset(GrBitmapTextGeoProc::Create(this->color(), |
| 110 texture, | 109 texture, |
| 111 params, | 110 params, |
| 112 maskFormat, | 111 maskFormat, |
| 113 localMatrix, | 112 localMatrix, |
| 114 this->usesLocalCoords())); | 113 this->usesLocalCoords())); |
| 115 } | 114 } |
| 116 | 115 |
| 117 FlushInfo flushInfo; | 116 FlushInfo flushInfo; |
| 118 flushInfo.fGlyphsToFlush = 0; | 117 flushInfo.fGlyphsToFlush = 0; |
| 119 size_t vertexStride = gp->getVertexStride(); | 118 size_t vertexStride = gp->getVertexStride(); |
| 120 SkASSERT(vertexStride == (usesDistanceFields ? | 119 SkASSERT(vertexStride == (this->usesDistanceFields() ? |
| 121 GetVertexStrideDf(maskFormat, isLCD) : | 120 GetVertexStrideDf(maskFormat, isLCD) : |
| 122 GetVertexStride(maskFormat))); | 121 GetVertexStride(maskFormat))); |
| 123 | 122 |
| 124 target->initDraw(gp, this->pipeline()); | 123 target->initDraw(gp, this->pipeline()); |
| 125 | 124 |
| 126 int glyphCount = this->numGlyphs(); | 125 int glyphCount = this->numGlyphs(); |
| 127 const GrVertexBuffer* vertexBuffer; | 126 const GrVertexBuffer* vertexBuffer; |
| 128 | 127 |
| 129 void* vertices = target->makeVertexSpace(vertexStride, | 128 void* vertices = target->makeVertexSpace(vertexStride, |
| 130 glyphCount * kVerticesPerGlyph, | 129 glyphCount * kVerticesPerGlyph, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 146 GrFontScaler* scaler = nullptr; | 145 GrFontScaler* scaler = nullptr; |
| 147 SkTypeface* typeface = nullptr; | 146 SkTypeface* typeface = nullptr; |
| 148 | 147 |
| 149 for (int i = 0; i < fGeoCount; i++) { | 148 for (int i = 0; i < fGeoCount; i++) { |
| 150 Geometry& args = fGeoData[i]; | 149 Geometry& args = fGeoData[i]; |
| 151 Blob* blob = args.fBlob; | 150 Blob* blob = args.fBlob; |
| 152 Run& run = blob->fRuns[args.fRun]; | 151 Run& run = blob->fRuns[args.fRun]; |
| 153 TextInfo& info = run.fSubRunInfo[args.fSubRun]; | 152 TextInfo& info = run.fSubRunInfo[args.fSubRun]; |
| 154 | 153 |
| 155 uint64_t currentAtlasGen = fFontCache->atlasGeneration(maskFormat); | 154 uint64_t currentAtlasGen = fFontCache->atlasGeneration(maskFormat); |
| 155 bool regenerateGlyphs = info.fStrike->isAbandoned(); | |
| 156 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen || | 156 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen || |
| 157 info.fStrike->isAbandoned(); | 157 regenerateGlyphs; |
| 158 bool regenerateColors; | 158 bool regenerateColors; |
| 159 if (usesDistanceFields) { | 159 if (usesDistanceFields) { |
| 160 regenerateColors = !isLCD && run.fColor != args.fColor; | 160 regenerateColors = !isLCD && run.fColor != args.fColor; |
| 161 } else { | 161 } else { |
| 162 regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != a rgs.fColor; | 162 regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != a rgs.fColor; |
| 163 } | 163 } |
| 164 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f; | 164 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f; |
| 165 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; | 165 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
| 166 | 166 |
| 167 // We regenerate both texture coords and colors in the blob itself, and update the | 167 // We regenerate both texture coords and colors in the blob itself, and update the |
| 168 // atlas generation. If we don't end up purging any unused plots, we ca n avoid | 168 // atlas generation. If we don't end up purging any unused plots, we ca n avoid |
| 169 // regenerating the coords. We could take a finer grained approach to u pdating texture | 169 // regenerating the coords. We could take a finer grained approach to u pdating texture |
| 170 // coords but its not clear if the extra bookkeeping would offset any ga ins. | 170 // coords but its not clear if the extra bookkeeping would offset any ga ins. |
| 171 // To avoid looping over the glyphs twice, we do one loop and conditiona lly update color | 171 // To avoid looping over the glyphs twice, we do one loop and conditiona lly update color |
| 172 // or coords as needed. One final note, if we have to break a run for a n atlas eviction | 172 // or coords as needed. One final note, if we have to break a run for a n atlas eviction |
| 173 // then we can't really trust the atlas has all of the correct data. At las evictions | 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 | 174 // should be pretty rare, so we just always regenerate in those cases |
| 175 if (regenerateTextureCoords || regenerateColors || regeneratePositions) { | 175 if (regenerateTextureCoords || regenerateColors || regeneratePositions) { |
| 176 // first regenerate texture coordinates / colors if need be | 176 // first regenerate texture coordinates / colors if need be |
| 177 bool brokenRun = false; | 177 bool brokenRun = false; |
| 178 | 178 |
| 179 // Because the GrBatchFontCache may evict the strike a blob depends on using for | 179 // Because the GrBatchFontCache may evict the strike a blob depends on using for |
| 180 // generating its texture coords, we have to track whether or not th e strike has | 180 // generating its texture coords, we have to track whether or not th e strike has |
| 181 // been abandoned. If it hasn't been abandoned, then we can use the GrGlyph*s as is | 181 // been abandoned. If it hasn't been abandoned, then we can use the GrGlyph*s as is |
| 182 // otherwise we have to get the new strike, and use that to get the correct glyphs. | 182 // otherwise we have to get the new strike, and use that to get the correct glyphs. |
| 183 // Because we do not have the packed ids, and thus can't look up our glyphs in the | 183 // Because we do not have the packed ids, and thus can't look up our glyphs in the |
| 184 // new strike, we instead keep our ref to the old strike and use the packed ids from | 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 | 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 | 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; | 187 GrBatchTextStrike* strike = nullptr; |
| 189 if (regenerateTextureCoords) { | 188 if (regenerateTextureCoords) { |
| 190 info.fBulkUseToken.reset(); | 189 info.fBulkUseToken.reset(); |
| 191 | 190 |
| 192 // We can reuse if we have a valid strike and our descriptors / typeface are the | 191 // We can reuse if we have a valid strike and our descriptors / typeface are the |
| 193 // same. The override descriptor is only for the non distance f ield text within | 192 // same. The override descriptor is only for the non distance f ield text within |
| 194 // a run | 193 // a run |
| 195 const SkDescriptor* newDesc = (run.fOverrideDescriptor && !usesD istanceFields) ? | 194 const SkDescriptor* newDesc = (run.fOverrideDescriptor && |
| 195 !this->usesDistanceFields()) ? | |
| 196 run.fOverrideDescriptor->getDesc() : | 196 run.fOverrideDescriptor->getDesc() : |
| 197 run.fDescriptor.getDesc(); | 197 run.fDescriptor.getDesc(); |
| 198 if (!cache || !SkTypeface::Equal(typeface, run.fTypeface) || | 198 if (!cache || !SkTypeface::Equal(typeface, run.fTypeface) || |
| 199 !(desc->equals(*newDesc))) { | 199 !(desc->equals(*newDesc))) { |
| 200 if (cache) { | 200 if (cache) { |
| 201 SkGlyphCache::AttachCache(cache); | 201 SkGlyphCache::AttachCache(cache); |
| 202 } | 202 } |
| 203 desc = newDesc; | 203 desc = newDesc; |
| 204 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); | 204 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); |
| 205 scaler = GrTextContext::GetGrFontScaler(cache); | 205 scaler = GrTextContext::GetGrFontScaler(cache); |
| 206 strike = info.fStrike; | 206 strike = info.fStrike; |
| 207 typeface = run.fTypeface; | 207 typeface = run.fTypeface; |
| 208 } | 208 } |
| 209 | 209 |
| 210 if (info.fStrike->isAbandoned()) { | 210 if (regenerateGlyphs) { |
| 211 regenerateGlyphs = true; | |
| 212 strike = fFontCache->getStrike(scaler); | 211 strike = fFontCache->getStrike(scaler); |
| 213 } else { | 212 } else { |
| 214 strike = info.fStrike; | 213 strike = info.fStrike; |
| 215 } | 214 } |
| 216 } | 215 } |
| 217 | 216 |
| 218 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { | 217 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { |
| 219 if (regenerateTextureCoords) { | 218 if (regenerateTextureCoords) { |
| 220 size_t glyphOffset = glyphIdx + info.fGlyphStartIndex; | 219 size_t glyphOffset = glyphIdx + info.fGlyphStartIndex; |
| 221 | 220 |
| 222 GrGlyph* glyph = blob->fGlyphs[glyphOffset]; | 221 GrGlyph* glyph = blob->fGlyphs[glyphOffset]; |
| 223 GrGlyph::PackedID id = glyph->fPackedID; | 222 GrGlyph::PackedID id = glyph->fPackedID; |
| 224 const SkGlyph& skGlyph = scaler->grToSkGlyph(id); | 223 const SkGlyph& skGlyph = scaler->grToSkGlyph(id); |
| 225 if (regenerateGlyphs) { | 224 if (regenerateGlyphs) { |
| 226 // Get the id from the old glyph, and use the new strike to lookup | 225 // Get the id from the old glyph, and use the new strike to lookup |
| 227 // the glyph. | 226 // the glyph. |
| 228 blob->fGlyphs[glyphOffset] = strike->getGlyph(skGlyph, i d, maskFormat, | 227 blob->fGlyphs[glyphOffset] = strike->getGlyph(skGlyph, i d, maskFormat, |
| 229 scaler); | 228 scaler); |
| 230 } | 229 } |
| 231 glyph = blob->fGlyphs[glyphOffset]; | 230 glyph = blob->fGlyphs[glyphOffset]; |
| 232 SkASSERT(glyph); | 231 SkASSERT(glyph); |
| 233 SkASSERT(id == glyph->fPackedID); | 232 SkASSERT(id == glyph->fPackedID); |
| 234 // We want to be able to assert this but cannot for testing purposes. | 233 SkASSERT(glyph->fMaskFormat == this->maskFormat()); |
| 235 // once skbug:4143 has landed we can revist this assert | |
| 236 //SkASSERT(glyph->fMaskFormat == this->maskFormat()); | |
| 237 | 234 |
| 238 if (!fFontCache->hasGlyph(glyph) && | 235 if (!fFontCache->hasGlyph(glyph) && |
| 239 !strike->addGlyphToAtlas(target, glyph, scaler, skGlyph, maskFormat)) { | 236 !strike->addGlyphToAtlas(target, glyph, scaler, skGlyph, maskFormat)) { |
| 240 this->flush(target, &flushInfo); | 237 this->flush(target, &flushInfo); |
| 241 target->initDraw(gp, this->pipeline()); | 238 target->initDraw(gp, this->pipeline()); |
| 242 brokenRun = glyphIdx > 0; | 239 brokenRun = glyphIdx > 0; |
| 243 | 240 |
| 244 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(targ et, | 241 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(targ et, |
| 245 glyp h, | 242 glyp h, |
| 246 scal er, | 243 scal er, |
| 247 skGl yph, | 244 skGl yph, |
| 248 mask Format); | 245 mask Format); |
| 249 SkASSERT(success); | 246 SkASSERT(success); |
| 250 } | 247 } |
| 251 fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseToken , glyph, | 248 fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseToken , glyph, |
| 252 target->currentToke n()); | 249 target->currentToke n()); |
| 253 | 250 |
| 254 // Texture coords are the last vertex attribute so we get a pointer to the | 251 this->regenerateTextureCoords(glyph, blob->fVertices, glyphI dx, |
| 255 // first one and then map with stride in regenerateTextureCo ords | 252 info.fVertexStartIndex, vertex Stride); |
| 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 } | 253 } |
| 263 | 254 |
| 264 if (regenerateColors) { | 255 if (regenerateColors) { |
| 265 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices ); | 256 this->regenerateColors(blob->fVertices, glyphIdx, info.fVert exStartIndex, |
| 266 vertex += info.fVertexStartIndex; | 257 vertexStride, args.fColor); |
| 267 vertex += vertexStride * glyphIdx * kVerticesPerGlyph + size of(SkPoint); | |
| 268 this->regenerateColors(vertex, vertexStride, args.fColor); | |
| 269 } | 258 } |
| 270 | 259 |
| 271 if (regeneratePositions) { | 260 if (regeneratePositions) { |
| 272 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices ); | 261 this->regeneratePositions(blob->fVertices, glyphIdx, info.fV ertexStartIndex, |
| 273 vertex += info.fVertexStartIndex; | 262 vertexStride, args.fTransX, args.f TransY); |
| 274 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; | |
| 275 SkScalar transX = args.fTransX; | |
| 276 SkScalar transY = args.fTransY; | |
| 277 this->regeneratePositions(vertex, vertexStride, transX, tran sY); | |
| 278 } | 263 } |
| 279 flushInfo.fGlyphsToFlush++; | 264 flushInfo.fGlyphsToFlush++; |
| 280 } | 265 } |
| 281 | 266 |
| 282 // We my have changed the color so update it here | 267 // We my have changed the color so update it here |
| 283 run.fColor = args.fColor; | 268 run.fColor = args.fColor; |
| 284 if (regenerateTextureCoords) { | 269 if (regenerateTextureCoords) { |
| 285 if (regenerateGlyphs) { | 270 if (regenerateGlyphs) { |
| 286 info.fStrike.reset(SkRef(strike)); | 271 info.fStrike.reset(SkRef(strike)); |
| 287 } | 272 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 302 | 287 |
| 303 currVertex += byteCount; | 288 currVertex += byteCount; |
| 304 } | 289 } |
| 305 // Make sure to attach the last cache if applicable | 290 // Make sure to attach the last cache if applicable |
| 306 if (cache) { | 291 if (cache) { |
| 307 SkGlyphCache::AttachCache(cache); | 292 SkGlyphCache::AttachCache(cache); |
| 308 } | 293 } |
| 309 this->flush(target, &flushInfo); | 294 this->flush(target, &flushInfo); |
| 310 } | 295 } |
| 311 | 296 |
| 312 void GrAtlasTextBatch::regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, | 297 void GrAtlasTextBatch::regenerateTextureCoords(const GrGlyph* glyph, void* verti ces, int glyphIdx, |
| 313 size_t vertexStride) { | 298 size_t vertexStartIndex, size_t v ertexStride) { |
| 314 int width = glyph->fBounds.width(); | 299 int width = glyph->fBounds.width(); |
| 315 int height = glyph->fBounds.height(); | 300 int height = glyph->fBounds.height(); |
| 316 | 301 |
| 317 int u0, v0, u1, v1; | 302 int u0, v0, u1, v1; |
| 318 if (this->usesDistanceFields()) { | 303 if (this->usesDistanceFields()) { |
| 319 u0 = glyph->fAtlasLocation.fX + SK_DistanceFieldInset; | 304 u0 = glyph->fAtlasLocation.fX + SK_DistanceFieldInset; |
| 320 v0 = glyph->fAtlasLocation.fY + SK_DistanceFieldInset; | 305 v0 = glyph->fAtlasLocation.fY + SK_DistanceFieldInset; |
| 321 u1 = u0 + width - 2 * SK_DistanceFieldInset; | 306 u1 = u0 + width - 2 * SK_DistanceFieldInset; |
| 322 v1 = v0 + height - 2 * SK_DistanceFieldInset; | 307 v1 = v0 + height - 2 * SK_DistanceFieldInset; |
| 323 } else { | 308 } else { |
| 324 u0 = glyph->fAtlasLocation.fX; | 309 u0 = glyph->fAtlasLocation.fX; |
| 325 v0 = glyph->fAtlasLocation.fY; | 310 v0 = glyph->fAtlasLocation.fY; |
| 326 u1 = u0 + width; | 311 u1 = u0 + width; |
| 327 v1 = v0 + height; | 312 v1 = v0 + height; |
| 328 } | 313 } |
| 329 | 314 |
| 315 // Texture coords are the last vertex attribute so we get a pointer to the | |
| 316 // first one and then map with stride in regenerateTextureCoords | |
| 317 intptr_t vertex = reinterpret_cast<intptr_t>(vertices); | |
| 318 vertex += vertexStartIndex; | |
| 319 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; | |
| 320 vertex += vertexStride - sizeof(SkIPoint16); | |
| 321 | |
| 330 SkIPoint16* textureCoords; | 322 SkIPoint16* textureCoords; |
| 331 // V0 | 323 // V0 |
| 332 textureCoords = reinterpret_cast<SkIPoint16*>(vertex); | 324 textureCoords = reinterpret_cast<SkIPoint16*>(vertex); |
| 333 textureCoords->set(u0, v0); | 325 textureCoords->set(u0, v0); |
| 334 vertex += vertexStride; | 326 vertex += vertexStride; |
| 335 | 327 |
| 336 // V1 | 328 // V1 |
| 337 textureCoords = reinterpret_cast<SkIPoint16*>(vertex); | 329 textureCoords = reinterpret_cast<SkIPoint16*>(vertex); |
| 338 textureCoords->set(u0, v1); | 330 textureCoords->set(u0, v1); |
| 339 vertex += vertexStride; | 331 vertex += vertexStride; |
| 340 | 332 |
| 341 // V2 | 333 // V2 |
| 342 textureCoords = reinterpret_cast<SkIPoint16*>(vertex); | 334 textureCoords = reinterpret_cast<SkIPoint16*>(vertex); |
| 343 textureCoords->set(u1, v1); | 335 textureCoords->set(u1, v1); |
| 344 vertex += vertexStride; | 336 vertex += vertexStride; |
| 345 | 337 |
| 346 // V3 | 338 // V3 |
| 347 textureCoords = reinterpret_cast<SkIPoint16*>(vertex); | 339 textureCoords = reinterpret_cast<SkIPoint16*>(vertex); |
| 348 textureCoords->set(u1, v0); | 340 textureCoords->set(u1, v0); |
| 349 } | 341 } |
| 350 | 342 |
|
robertphillips
2015/11/20 18:43:02
can this be static ?
| |
| 351 void GrAtlasTextBatch::regenerateColors(intptr_t vertex, size_t vertexStride, Gr Color color) { | 343 void GrAtlasTextBatch::regenerateColors(void* vertices, int glyphIdx, size_t ver texStartIndex, |
| 344 size_t vertexStride, GrColor color) { | |
| 345 intptr_t vertex = reinterpret_cast<intptr_t>(vertices); | |
| 346 vertex += vertexStartIndex; | |
| 347 vertex += vertexStride * glyphIdx * kVerticesPerGlyph + sizeof(SkPoint); | |
| 348 | |
| 352 for (int i = 0; i < kVerticesPerGlyph; i++) { | 349 for (int i = 0; i < kVerticesPerGlyph; i++) { |
| 353 SkColor* vcolor = reinterpret_cast<SkColor*>(vertex); | 350 SkColor* vcolor = reinterpret_cast<SkColor*>(vertex); |
| 354 *vcolor = color; | 351 *vcolor = color; |
| 355 vertex += vertexStride; | 352 vertex += vertexStride; |
| 356 } | 353 } |
| 357 } | 354 } |
| 358 | 355 |
|
robertphillips
2015/11/20 18:43:02
this guy too ?
| |
| 359 void GrAtlasTextBatch::regeneratePositions(intptr_t vertex, size_t vertexStride, SkScalar transX, | 356 void GrAtlasTextBatch::regeneratePositions(void* vertices, int glyphIdx, size_t vertexStartIndex, |
| 360 SkScalar transY) { | 357 size_t vertexStride, SkScalar transX, SkScalar transY) { |
| 358 intptr_t vertex = reinterpret_cast<intptr_t>(vertices); | |
| 359 vertex += vertexStartIndex; | |
| 360 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; | |
| 361 for (int i = 0; i < kVerticesPerGlyph; i++) { | 361 for (int i = 0; i < kVerticesPerGlyph; i++) { |
| 362 SkPoint* point = reinterpret_cast<SkPoint*>(vertex); | 362 SkPoint* point = reinterpret_cast<SkPoint*>(vertex); |
| 363 point->fX += transX; | 363 point->fX += transX; |
| 364 point->fY += transY; | 364 point->fY += transY; |
| 365 vertex += vertexStride; | 365 vertex += vertexStride; |
| 366 } | 366 } |
| 367 } | 367 } |
| 368 | 368 |
| 369 void GrAtlasTextBatch::flush(GrVertexBatch::Target* target, FlushInfo* flushInfo ) { | 369 void GrAtlasTextBatch::flush(GrVertexBatch::Target* target, FlushInfo* flushInfo ) { |
| 370 GrVertices vertices; | 370 GrVertices vertices; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 return GrDistanceFieldA8TextGeoProc::Create(color, | 498 return GrDistanceFieldA8TextGeoProc::Create(color, |
| 499 viewMatrix, | 499 viewMatrix, |
| 500 texture, | 500 texture, |
| 501 params, | 501 params, |
| 502 flags, | 502 flags, |
| 503 this->usesLocalCoords()); | 503 this->usesLocalCoords()); |
| 504 #endif | 504 #endif |
| 505 } | 505 } |
| 506 | 506 |
| 507 } | 507 } |
| OLD | NEW |