Index: src/gpu/GrAtlasTextContext.cpp |
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp |
index b95c446532d9273c48536f8a15972e53e8fd661e..e20ca4bb7ffd07c84d3cdf689dce05aeab32494e 100644 |
--- a/src/gpu/GrAtlasTextContext.cpp |
+++ b/src/gpu/GrAtlasTextContext.cpp |
@@ -1444,7 +1444,7 @@ inline void GrAtlasTextContext::appendGlyphCommon(GrAtlasTextBlob* blob, Run* ru |
subRun->fVertexEndIndex += vertexStride * kVerticesPerGlyph; |
} |
-class BitmapTextBatch : public GrBatch { |
+class TextBatch : public GrBatch { |
public: |
typedef GrAtlasTextContext::DistanceAdjustTable DistanceAdjustTable; |
typedef GrAtlasTextBlob Blob; |
@@ -1459,24 +1459,53 @@ public: |
SkScalar fTransY; |
}; |
- static BitmapTextBatch* Create(GrMaskFormat maskFormat, int glyphCount, |
+ static TextBatch* CreateBitmap(GrMaskFormat maskFormat, int glyphCount, |
GrBatchFontCache* fontCache) { |
- return SkNEW_ARGS(BitmapTextBatch, (maskFormat, glyphCount, fontCache)); |
- } |
- |
- static BitmapTextBatch* Create(GrMaskFormat maskFormat, int glyphCount, |
- GrBatchFontCache* fontCache, |
- DistanceAdjustTable* distanceAdjustTable, |
- SkColor filteredColor, bool useLCDText, |
- bool useBGR) { |
- return SkNEW_ARGS(BitmapTextBatch, (maskFormat, glyphCount, fontCache, distanceAdjustTable, |
- filteredColor, useLCDText, useBGR)); |
- } |
+ TextBatch* batch = SkNEW(TextBatch); |
- const char* name() const override { return "BitmapTextBatch"; } |
+ batch->initClassID<TextBatch>(); |
+ batch->fFontCache = fontCache; |
+ switch (maskFormat) { |
+ case kA8_GrMaskFormat: |
+ batch->fMaskType = kGrayscaleCoverageMask_MaskType; |
+ break; |
+ case kA565_GrMaskFormat: |
+ batch->fMaskType = kLCDCoverageMask_MaskType; |
+ break; |
+ case kARGB_GrMaskFormat: |
+ batch->fMaskType = kColorBitmapMask_MaskType; |
+ break; |
+ } |
+ batch->fBatch.fNumGlyphs = glyphCount; |
+ batch->fInstanceCount = 1; |
+ batch->fAllocatedCount = kMinAllocated; |
+ batch->fFilteredColor = 0; |
+ batch->fFontCache = fontCache; |
+ batch->fUseBGR = false; |
+ return batch; |
+ } |
+ |
+ static TextBatch* CreateDistanceField(int glyphCount, GrBatchFontCache* fontCache, |
+ DistanceAdjustTable* distanceAdjustTable, |
+ SkColor filteredColor, bool isLCD, |
+ bool useBGR) { |
+ TextBatch* batch = SkNEW(TextBatch); |
+ batch->initClassID<TextBatch>(); |
+ batch->fFontCache = fontCache; |
+ batch->fMaskType = isLCD ? kLCDDistanceField_MaskType : kGrayscaleDistanceField_MaskType; |
+ batch->fDistanceAdjustTable.reset(SkRef(distanceAdjustTable)); |
+ batch->fFilteredColor = filteredColor; |
+ batch->fUseBGR = useBGR; |
+ batch->fBatch.fNumGlyphs = glyphCount; |
+ batch->fInstanceCount = 1; |
+ batch->fAllocatedCount = kMinAllocated; |
+ return batch; |
+ } |
+ |
+ const char* name() const override { return "TextBatch"; } |
void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
- if (kARGB_GrMaskFormat == fMaskFormat) { |
+ if (kColorBitmapMask_MaskType == fMaskType) { |
out->setUnknownFourComponents(); |
} else { |
out->setKnownFourComponents(fBatch.fColor); |
@@ -1484,29 +1513,18 @@ public: |
} |
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
- if (!fUseDistanceFields) { |
- // Bitmap Text |
- if (kARGB_GrMaskFormat != fMaskFormat) { |
- if (GrPixelConfigIsAlphaOnly(fPixelConfig)) { |
- out->setUnknownSingleComponent(); |
- } else if (GrPixelConfigIsOpaque(fPixelConfig)) { |
- out->setUnknownOpaqueFourComponents(); |
- out->setUsingLCDCoverage(); |
- } else { |
- out->setUnknownFourComponents(); |
- out->setUsingLCDCoverage(); |
- } |
- } else { |
- out->setKnownSingleComponent(0xff); |
- } |
- } else { |
- // Distance fields |
- if (!fUseLCDText) { |
+ switch (fMaskType) { |
+ case kGrayscaleDistanceField_MaskType: |
+ case kGrayscaleCoverageMask_MaskType: |
out->setUnknownSingleComponent(); |
- } else { |
- out->setUnknownFourComponents(); |
+ break; |
+ case kLCDCoverageMask_MaskType: |
+ case kLCDDistanceField_MaskType: |
+ out->setUnknownOpaqueFourComponents(); |
out->setUsingLCDCoverage(); |
- } |
+ break; |
+ case kColorBitmapMask_MaskType: |
+ out->setKnownSingleComponent(0xff); |
} |
} |
@@ -1540,14 +1558,18 @@ public: |
return; |
} |
- GrTexture* texture = fFontCache->getTexture(fMaskFormat); |
+ GrTexture* texture = fFontCache->getTexture(this->maskFormat()); |
if (!texture) { |
SkDebugf("Could not allocate backing texture for atlas\n"); |
return; |
} |
+ bool usesDistanceFields = this->usesDistanceFields(); |
+ GrMaskFormat maskFormat = this->maskFormat(); |
+ bool isLCD = this->isLCD(); |
+ |
SkAutoTUnref<const GrGeometryProcessor> gp; |
- if (fUseDistanceFields) { |
+ if (usesDistanceFields) { |
gp.reset(this->setupDfProcessor(this->viewMatrix(), fFilteredColor, this->color(), |
texture)); |
} else { |
@@ -1555,7 +1577,7 @@ public: |
gp.reset(GrBitmapTextGeoProc::Create(this->color(), |
texture, |
params, |
- fMaskFormat, |
+ maskFormat, |
localMatrix, |
this->usesLocalCoords())); |
} |
@@ -1563,9 +1585,9 @@ public: |
FlushInfo flushInfo; |
flushInfo.fGlyphsToFlush = 0; |
size_t vertexStride = gp->getVertexStride(); |
- SkASSERT(vertexStride == (fUseDistanceFields ? |
- get_vertex_stride_df(fMaskFormat, fUseLCDText) : |
- get_vertex_stride(fMaskFormat))); |
+ SkASSERT(vertexStride == (usesDistanceFields ? |
+ get_vertex_stride_df(maskFormat, isLCD) : |
+ get_vertex_stride(maskFormat))); |
batchTarget->initDraw(gp, pipeline); |
@@ -1599,14 +1621,14 @@ public: |
Run& run = blob->fRuns[args.fRun]; |
TextInfo& info = run.fSubRunInfo[args.fSubRun]; |
- uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); |
+ uint64_t currentAtlasGen = fFontCache->atlasGeneration(maskFormat); |
bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen || |
run.fStrike->isAbandoned(); |
bool regenerateColors; |
- if (fUseDistanceFields) { |
- regenerateColors = !fUseLCDText && run.fColor != args.fColor; |
+ if (usesDistanceFields) { |
+ regenerateColors = !isLCD && run.fColor != args.fColor; |
} else { |
- regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColor != args.fColor; |
+ regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != args.fColor; |
} |
bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f; |
int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; |
@@ -1674,7 +1696,7 @@ public: |
} |
glyph = blob->fGlyphs[glyphOffset]; |
SkASSERT(glyph); |
- SkASSERT(glyph->fMaskFormat == fMaskFormat); |
+ SkASSERT(glyph->fMaskFormat == this->maskFormat()); |
if (!fFontCache->hasGlyph(glyph) && |
!strike->addGlyphToAtlas(batchTarget, glyph, scaler)) { |
@@ -1725,7 +1747,7 @@ public: |
run.fStrike.reset(SkRef(strike)); |
} |
info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAtlasGeneration : |
- fFontCache->atlasGeneration(fMaskFormat); |
+ fFontCache->atlasGeneration(maskFormat); |
} |
} else { |
flushInfo.fGlyphsToFlush += glyphCount; |
@@ -1734,7 +1756,7 @@ public: |
// have a valid atlas generation |
fFontCache->setUseTokenBulk(info.fBulkUseToken, |
batchTarget->currentToken(), |
- fMaskFormat); |
+ maskFormat); |
} |
// now copy all vertices |
@@ -1779,47 +1801,44 @@ public: |
} |
private: |
- BitmapTextBatch(GrMaskFormat maskFormat, int glyphCount, GrBatchFontCache* fontCache) |
- : fMaskFormat(maskFormat) |
- , fPixelConfig(fontCache->getPixelConfig(maskFormat)) |
- , fFontCache(fontCache) |
- , fUseDistanceFields(false) { |
- this->initClassID<BitmapTextBatch>(); |
- fBatch.fNumGlyphs = glyphCount; |
- fInstanceCount = 1; |
- fAllocatedCount = kMinAllocated; |
- } |
- |
- BitmapTextBatch(GrMaskFormat maskFormat, int glyphCount, GrBatchFontCache* fontCache, |
- DistanceAdjustTable* distanceAdjustTable, SkColor filteredColor, |
- bool useLCDText, bool useBGR) |
- : fMaskFormat(maskFormat) |
- , fPixelConfig(fontCache->getPixelConfig(maskFormat)) |
- , fFontCache(fontCache) |
- , fDistanceAdjustTable(SkRef(distanceAdjustTable)) |
- , fFilteredColor(filteredColor) |
- , fUseDistanceFields(true) |
- , fUseLCDText(useLCDText) |
- , fUseBGR(useBGR) { |
- this->initClassID<BitmapTextBatch>(); |
- fBatch.fNumGlyphs = glyphCount; |
- fInstanceCount = 1; |
- fAllocatedCount = kMinAllocated; |
- SkASSERT(fMaskFormat == kA8_GrMaskFormat); |
- } |
- |
- ~BitmapTextBatch() { |
+ TextBatch() {} // initialized in factory functions. |
+ |
+ ~TextBatch() { |
for (int i = 0; i < fInstanceCount; i++) { |
fGeoData[i].fBlob->unref(); |
} |
} |
+ GrMaskFormat maskFormat() const { |
+ switch (fMaskType) { |
+ case kLCDCoverageMask_MaskType: |
+ return kA565_GrMaskFormat; |
+ case kColorBitmapMask_MaskType: |
+ return kARGB_GrMaskFormat; |
+ case kGrayscaleCoverageMask_MaskType: |
+ case kGrayscaleDistanceField_MaskType: |
+ case kLCDDistanceField_MaskType: |
+ return kA8_GrMaskFormat; |
+ } |
+ return kA8_GrMaskFormat; // suppress warning |
+ } |
+ |
+ bool usesDistanceFields() const { |
+ return kGrayscaleDistanceField_MaskType == fMaskType || |
+ kLCDDistanceField_MaskType == fMaskType; |
+ } |
+ |
+ bool isLCD() const { |
+ return kLCDCoverageMask_MaskType == fMaskType || |
+ kLCDDistanceField_MaskType == fMaskType; |
+ } |
+ |
void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexStride) { |
int width = glyph->fBounds.width(); |
int height = glyph->fBounds.height(); |
int u0, v0, u1, v1; |
- if (fUseDistanceFields) { |
+ if (this->usesDistanceFields()) { |
u0 = glyph->fAtlasLocation.fX + SK_DistanceFieldInset; |
v0 = glyph->fAtlasLocation.fY + SK_DistanceFieldInset; |
u1 = u0 + width - 2 * SK_DistanceFieldInset; |
@@ -1892,32 +1911,22 @@ private: |
return false; |
} |
- BitmapTextBatch* that = t->cast<BitmapTextBatch>(); |
+ TextBatch* that = t->cast<TextBatch>(); |
- if (fUseDistanceFields != that->fUseDistanceFields) { |
+ if (fMaskType != that->fMaskType) { |
return false; |
} |
- if (!fUseDistanceFields) { |
- // Bitmap Text |
- if (fMaskFormat != that->fMaskFormat) { |
- return false; |
- } |
- |
+ if (!this->usesDistanceFields()) { |
// TODO we can often batch across LCD text if we have dual source blending and don't |
// have to use the blend constant |
- if (fMaskFormat != kA8_GrMaskFormat && this->color() != that->color()) { |
+ if (kGrayscaleCoverageMask_MaskType != fMaskType && this->color() != that->color()) { |
return false; |
} |
- |
if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
return false; |
} |
} else { |
- // Distance Fields |
- SkASSERT(this->fMaskFormat == that->fMaskFormat && |
- this->fMaskFormat == kA8_GrMaskFormat); |
- |
if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
return false; |
} |
@@ -1926,17 +1935,12 @@ private: |
return false; |
} |
- if (fUseLCDText != that->fUseLCDText) { |
- return false; |
- } |
- |
if (fUseBGR != that->fUseBGR) { |
return false; |
} |
// TODO see note above |
- if (fUseLCDText && this->color() != that->color()) { |
- return false; |
+ if (kLCDDistanceField_MaskType == fMaskType && this->color() != that->color()) { |
} |
} |
@@ -1970,17 +1974,16 @@ private: |
GrGeometryProcessor* setupDfProcessor(const SkMatrix& viewMatrix, SkColor filteredColor, |
GrColor color, GrTexture* texture) { |
GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode); |
- |
+ bool isLCD = this->isLCD(); |
// set up any flags |
- uint32_t flags = 0; |
- flags |= viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; |
- flags |= fUseLCDText ? kUseLCD_DistanceFieldEffectFlag : 0; |
- flags |= fUseLCDText && viewMatrix.rectStaysRect() ? |
- kRectToRect_DistanceFieldEffectFlag : 0; |
- flags |= fUseLCDText && fUseBGR ? kBGR_DistanceFieldEffectFlag : 0; |
+ uint32_t flags = viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; |
// see if we need to create a new effect |
- if (fUseLCDText) { |
+ if (isLCD) { |
+ flags |= kUseLCD_DistanceFieldEffectFlag; |
+ flags |= viewMatrix.rectStaysRect() ? kRectToRect_DistanceFieldEffectFlag : 0; |
+ flags |= fUseBGR ? kBGR_DistanceFieldEffectFlag : 0; |
+ |
GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor); |
float redCorrection = |
@@ -2038,16 +2041,21 @@ private: |
SkAutoSTMalloc<kMinAllocated, Geometry> fGeoData; |
int fInstanceCount; |
int fAllocatedCount; |
- GrMaskFormat fMaskFormat; |
- GrPixelConfig fPixelConfig; |
+ |
+ enum MaskType { |
+ kGrayscaleCoverageMask_MaskType, |
+ kLCDCoverageMask_MaskType, |
+ kColorBitmapMask_MaskType, |
+ kGrayscaleDistanceField_MaskType, |
+ kLCDDistanceField_MaskType, |
+ } fMaskType; |
+ bool fUseBGR; // fold this into the enum? |
+ |
GrBatchFontCache* fFontCache; |
// Distance field properties |
SkAutoTUnref<const DistanceAdjustTable> fDistanceAdjustTable; |
SkColor fFilteredColor; |
- bool fUseDistanceFields; |
- bool fUseLCDText; |
- bool fUseBGR; |
}; |
void GrAtlasTextContext::flushRunAsPaths(GrRenderTarget* rt, const SkTextBlob::RunIterator& it, |
@@ -2087,8 +2095,7 @@ void GrAtlasTextContext::flushRunAsPaths(GrRenderTarget* rt, const SkTextBlob::R |
} |
} |
- |
-inline BitmapTextBatch* |
+inline GrBatch* |
GrAtlasTextContext::createBatch(GrAtlasTextBlob* cacheBlob, const PerSubRunInfo& info, |
int glyphCount, int run, int subRun, |
GrColor color, SkScalar transX, SkScalar transY, |
@@ -2102,7 +2109,7 @@ GrAtlasTextContext::createBatch(GrAtlasTextBlob* cacheBlob, const PerSubRunInfo& |
subRunColor = color; |
} |
- BitmapTextBatch* batch; |
+ TextBatch* batch; |
if (info.fDrawAsDistanceFields) { |
SkColor filteredColor; |
SkColorFilter* colorFilter = skPaint.getColorFilter(); |
@@ -2112,13 +2119,13 @@ GrAtlasTextContext::createBatch(GrAtlasTextBlob* cacheBlob, const PerSubRunInfo& |
filteredColor = skPaint.getColor(); |
} |
bool useBGR = SkPixelGeometryIsBGR(fSurfaceProps.pixelGeometry()); |
- batch = BitmapTextBatch::Create(format, glyphCount, fContext->getBatchFontCache(), |
- fDistanceAdjustTable, filteredColor, |
- info.fUseLCDText, useBGR); |
+ batch = TextBatch::CreateDistanceField(glyphCount, fContext->getBatchFontCache(), |
+ fDistanceAdjustTable, filteredColor, |
+ info.fUseLCDText, useBGR); |
} else { |
- batch = BitmapTextBatch::Create(format, glyphCount, fContext->getBatchFontCache()); |
+ batch = TextBatch::CreateBitmap(format, glyphCount, fContext->getBatchFontCache()); |
} |
- BitmapTextBatch::Geometry& geometry = batch->geometry(); |
+ TextBatch::Geometry& geometry = batch->geometry(); |
geometry.fBlob = SkRef(cacheBlob); |
geometry.fRun = run; |
geometry.fSubRun = subRun; |
@@ -2141,9 +2148,9 @@ inline void GrAtlasTextContext::flushRun(GrPipelineBuilder* pipelineBuilder, |
continue; |
} |
- SkAutoTUnref<BitmapTextBatch> batch(this->createBatch(cacheBlob, info, glyphCount, run, |
- subRun, color, transX, transY, |
- skPaint)); |
+ SkAutoTUnref<GrBatch> batch(this->createBatch(cacheBlob, info, glyphCount, run, |
+ subRun, color, transX, transY, |
+ skPaint)); |
fDrawContext->drawBatch(pipelineBuilder, batch); |
} |
} |