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