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 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 SkDebugf("Cannot invert viewmatrix\n"); | 305 SkDebugf("Cannot invert viewmatrix\n"); |
306 return; | 306 return; |
307 } | 307 } |
308 | 308 |
309 GrTexture* texture = fFontCache->getTexture(this->maskFormat()); | 309 GrTexture* texture = fFontCache->getTexture(this->maskFormat()); |
310 if (!texture) { | 310 if (!texture) { |
311 SkDebugf("Could not allocate backing texture for atlas\n"); | 311 SkDebugf("Could not allocate backing texture for atlas\n"); |
312 return; | 312 return; |
313 } | 313 } |
314 | 314 |
315 bool usesDistanceFields = this->usesDistanceFields(); | |
316 GrMaskFormat maskFormat = this->maskFormat(); | 315 GrMaskFormat maskFormat = this->maskFormat(); |
317 bool isLCD = this->isLCD(); | 316 bool isLCD = this->isLCD(); |
318 | 317 |
319 SkAutoTUnref<const GrGeometryProcessor> gp; | 318 SkAutoTUnref<const GrGeometryProcessor> gp; |
320 if (usesDistanceFields) { | 319 if (this->usesDistanceFields()) { |
321 gp.reset(this->setupDfProcessor(this->viewMatrix(), fFilteredColor, this
->color(), | 320 gp.reset(this->setupDfProcessor(this->viewMatrix(), fFilteredColor, this
->color(), |
322 texture)); | 321 texture)); |
323 } else { | 322 } else { |
324 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone
_FilterMode); | 323 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone
_FilterMode); |
325 gp.reset(GrBitmapTextGeoProc::Create(this->color(), | 324 gp.reset(GrBitmapTextGeoProc::Create(this->color(), |
326 texture, | 325 texture, |
327 params, | 326 params, |
328 maskFormat, | 327 maskFormat, |
329 localMatrix, | 328 localMatrix, |
330 this->usesLocalCoords())); | 329 this->usesLocalCoords())); |
331 } | 330 } |
332 | 331 |
333 FlushInfo flushInfo; | 332 FlushInfo flushInfo; |
334 flushInfo.fGlyphsToFlush = 0; | 333 flushInfo.fGlyphsToFlush = 0; |
335 size_t vertexStride = gp->getVertexStride(); | 334 size_t vertexStride = gp->getVertexStride(); |
336 SkASSERT(vertexStride == (usesDistanceFields ? | 335 SkASSERT(vertexStride == GetVertexStride(maskFormat)); |
337 GetVertexStrideDf(maskFormat, isLCD) : | |
338 GetVertexStride(maskFormat))); | |
339 | 336 |
340 target->initDraw(gp, this->pipeline()); | 337 target->initDraw(gp, this->pipeline()); |
341 | 338 |
342 int glyphCount = this->numGlyphs(); | 339 int glyphCount = this->numGlyphs(); |
343 const GrVertexBuffer* vertexBuffer; | 340 const GrVertexBuffer* vertexBuffer; |
344 | 341 |
345 void* vertices = target->makeVertexSpace(vertexStride, | 342 void* vertices = target->makeVertexSpace(vertexStride, |
346 glyphCount * kVerticesPerGlyph, | 343 glyphCount * kVerticesPerGlyph, |
347 &vertexBuffer, | 344 &vertexBuffer, |
348 &flushInfo.fVertexOffset); | 345 &flushInfo.fVertexOffset); |
(...skipping 25 matching lines...) Expand all Loading... |
374 // generating its texture coords, we have to track whether or not the st
rike has | 371 // generating its texture coords, we have to track whether or not the st
rike has |
375 // been abandoned. If it hasn't been abandoned, then we can use the GrG
lyph*s as is | 372 // been abandoned. If it hasn't been abandoned, then we can use the GrG
lyph*s as is |
376 // otherwise we have to get the new strike, and use that to get the corr
ect glyphs. | 373 // otherwise we have to get the new strike, and use that to get the corr
ect glyphs. |
377 // Because we do not have the packed ids, and thus can't look up our gly
phs in the | 374 // Because we do not have the packed ids, and thus can't look up our gly
phs in the |
378 // new strike, we instead keep our ref to the old strike and use the pac
ked ids from | 375 // new strike, we instead keep our ref to the old strike and use the pac
ked ids from |
379 // it. These ids will still be valid as long as we hold the ref. When
we are done | 376 // it. These ids will still be valid as long as we hold the ref. When
we are done |
380 // updating our cache of the GrGlyph*s, we drop our ref on the old strik
e | 377 // updating our cache of the GrGlyph*s, we drop our ref on the old strik
e |
381 bool regenerateGlyphs = info.strike()->isAbandoned(); | 378 bool regenerateGlyphs = info.strike()->isAbandoned(); |
382 bool regenerateTextureCoords = info.atlasGeneration() != currentAtlasGen
|| | 379 bool regenerateTextureCoords = info.atlasGeneration() != currentAtlasGen
|| |
383 regenerateGlyphs; | 380 regenerateGlyphs; |
384 bool regenerateColors; | 381 bool regenerateColors = kARGB_GrMaskFormat != maskFormat && |
385 if (usesDistanceFields) { | 382 run.fColor != args.fColor; |
386 regenerateColors = !isLCD && run.fColor != args.fColor; | |
387 } else { | |
388 regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != a
rgs.fColor; | |
389 } | |
390 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f; | 383 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f; |
391 int glyphCount = info.glyphCount(); | 384 int glyphCount = info.glyphCount(); |
392 | 385 |
393 uint32_t regenMaskBits = kNoRegen; | 386 uint32_t regenMaskBits = kNoRegen; |
394 regenMaskBits |= regeneratePositions ? kRegenPos : 0; | 387 regenMaskBits |= regeneratePositions ? kRegenPos : 0; |
395 regenMaskBits |= regenerateColors ? kRegenCol : 0; | 388 regenMaskBits |= regenerateColors ? kRegenCol : 0; |
396 regenMaskBits |= regenerateTextureCoords ? kRegenTex : 0; | 389 regenMaskBits |= regenerateTextureCoords ? kRegenTex : 0; |
397 regenMaskBits |= regenerateGlyphs ? kRegenGlyph : 0; | 390 regenMaskBits |= regenerateGlyphs ? kRegenGlyph : 0; |
398 RegenMask regenMask = (RegenMask)regenMaskBits; | 391 RegenMask regenMask = (RegenMask)regenMaskBits; |
399 | 392 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeli
ne(), | 445 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeli
ne(), |
453 that->bounds(), caps)) { | 446 that->bounds(), caps)) { |
454 return false; | 447 return false; |
455 } | 448 } |
456 | 449 |
457 if (fMaskType != that->fMaskType) { | 450 if (fMaskType != that->fMaskType) { |
458 return false; | 451 return false; |
459 } | 452 } |
460 | 453 |
461 if (!this->usesDistanceFields()) { | 454 if (!this->usesDistanceFields()) { |
462 // TODO we can often batch across LCD text if we have dual source blendi
ng and don't | 455 if (kColorBitmapMask_MaskType == fMaskType && this->color() != that->col
or()) { |
463 // have to use the blend constant | |
464 if (kGrayscaleCoverageMask_MaskType != fMaskType && this->color() != tha
t->color()) { | |
465 return false; | 456 return false; |
466 } | 457 } |
467 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { | 458 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { |
468 return false; | 459 return false; |
469 } | 460 } |
470 } else { | 461 } else { |
471 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { | 462 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
472 return false; | 463 return false; |
473 } | 464 } |
474 | 465 |
475 if (fFilteredColor != that->fFilteredColor) { | 466 if (fFilteredColor != that->fFilteredColor) { |
476 return false; | 467 return false; |
477 } | 468 } |
478 | 469 |
479 if (fUseBGR != that->fUseBGR) { | 470 if (fUseBGR != that->fUseBGR) { |
480 return false; | 471 return false; |
481 } | 472 } |
482 | |
483 // TODO see note above | |
484 if (kLCDDistanceField_MaskType == fMaskType && this->color() != that->co
lor()) { | |
485 return false; | |
486 } | |
487 } | 473 } |
488 | 474 |
489 fBatch.fNumGlyphs += that->numGlyphs(); | 475 fBatch.fNumGlyphs += that->numGlyphs(); |
490 | 476 |
491 // Reallocate space for geo data if necessary and then import that's geo dat
a. | 477 // Reallocate space for geo data if necessary and then import that's geo dat
a. |
492 int newGeoCount = that->fGeoCount + fGeoCount; | 478 int newGeoCount = that->fGeoCount + fGeoCount; |
493 // We assume (and here enforce) that the allocation size is the smallest pow
er of two that | 479 // We assume (and here enforce) that the allocation size is the smallest pow
er of two that |
494 // is greater than or equal to the number of geometries (and at least | 480 // is greater than or equal to the number of geometries (and at least |
495 // kMinGeometryAllocated). | 481 // kMinGeometryAllocated). |
496 int newAllocSize = GrNextPow2(newGeoCount); | 482 int newAllocSize = GrNextPow2(newGeoCount); |
(...skipping 26 matching lines...) Expand all Loading... |
523 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_F
ilterMode); | 509 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_F
ilterMode); |
524 bool isLCD = this->isLCD(); | 510 bool isLCD = this->isLCD(); |
525 // set up any flags | 511 // set up any flags |
526 uint32_t flags = viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffect
Flag : 0; | 512 uint32_t flags = viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffect
Flag : 0; |
527 | 513 |
528 // see if we need to create a new effect | 514 // see if we need to create a new effect |
529 if (isLCD) { | 515 if (isLCD) { |
530 flags |= kUseLCD_DistanceFieldEffectFlag; | 516 flags |= kUseLCD_DistanceFieldEffectFlag; |
531 flags |= viewMatrix.rectStaysRect() ? kRectToRect_DistanceFieldEffectFla
g : 0; | 517 flags |= viewMatrix.rectStaysRect() ? kRectToRect_DistanceFieldEffectFla
g : 0; |
532 flags |= fUseBGR ? kBGR_DistanceFieldEffectFlag : 0; | 518 flags |= fUseBGR ? kBGR_DistanceFieldEffectFlag : 0; |
| 519 flags |= kColorAttr_DistanceFieldEffectFlag; |
533 | 520 |
534 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor); | 521 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor); |
535 | 522 |
536 float redCorrection = | 523 float redCorrection = |
537 (*fDistanceAdjustTable)[GrColorUnpackR(colorNoPreMul) >> kDistanceAd
justLumShift]; | 524 (*fDistanceAdjustTable)[GrColorUnpackR(colorNoPreMul) >> kDistanceAd
justLumShift]; |
538 float greenCorrection = | 525 float greenCorrection = |
539 (*fDistanceAdjustTable)[GrColorUnpackG(colorNoPreMul) >> kDistanceAd
justLumShift]; | 526 (*fDistanceAdjustTable)[GrColorUnpackG(colorNoPreMul) >> kDistanceAd
justLumShift]; |
540 float blueCorrection = | 527 float blueCorrection = |
541 (*fDistanceAdjustTable)[GrColorUnpackB(colorNoPreMul) >> kDistanceAd
justLumShift]; | 528 (*fDistanceAdjustTable)[GrColorUnpackB(colorNoPreMul) >> kDistanceAd
justLumShift]; |
542 GrDistanceFieldLCDTextGeoProc::DistanceAdjust widthAdjust = | 529 GrDistanceFieldLCDTextGeoProc::DistanceAdjust widthAdjust = |
(...skipping 24 matching lines...) Expand all Loading... |
567 return GrDistanceFieldA8TextGeoProc::Create(color, | 554 return GrDistanceFieldA8TextGeoProc::Create(color, |
568 viewMatrix, | 555 viewMatrix, |
569 texture, | 556 texture, |
570 params, | 557 params, |
571 flags, | 558 flags, |
572 this->usesLocalCoords()); | 559 this->usesLocalCoords()); |
573 #endif | 560 #endif |
574 } | 561 } |
575 | 562 |
576 } | 563 } |
OLD | NEW |