Ganesh text rendering cleanup.

Rename GrTextStrike.{cpp.h} to GrFontCache.{cpp,h}
Move contents of GrTextStrike_impl.h to GrFontCache.h
Move glyph uploading to a separate function and remove harmful gotos
Add assert on glyph upload failure (shouldn't happen)

Review URL: https://codereview.chromium.org/780923002
This commit is contained in:
jvanverth 2014-12-04 10:46:50 -08:00 committed by Commit bot
parent 32fee2907e
commit 787cdf9ab0
11 changed files with 130 additions and 139 deletions

View File

@ -164,9 +164,8 @@
'<(skia_src_path)/gpu/GrTemplates.h',
'<(skia_src_path)/gpu/GrTextContext.cpp',
'<(skia_src_path)/gpu/GrTextContext.h',
'<(skia_src_path)/gpu/GrTextStrike.cpp',
'<(skia_src_path)/gpu/GrTextStrike.h',
'<(skia_src_path)/gpu/GrTextStrike_impl.h',
'<(skia_src_path)/gpu/GrFontCache.cpp',
'<(skia_src_path)/gpu/GrFontCache.h',
'<(skia_src_path)/gpu/GrTexture.cpp',
'<(skia_src_path)/gpu/GrTexturePriv.h',
'<(skia_src_path)/gpu/GrTextureAccess.cpp',

View File

@ -9,12 +9,11 @@
#include "GrAtlas.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrDrawTarget.h"
#include "GrFontCache.h"
#include "GrFontScaler.h"
#include "GrIndexBuffer.h"
#include "GrStrokeInfo.h"
#include "GrTexturePriv.h"
#include "GrTextStrike.h"
#include "GrTextStrike_impl.h"
#include "SkAutoKern.h"
#include "SkColorPriv.h"
@ -359,6 +358,41 @@ static void* alloc_vertices(GrDrawTarget* drawTarget,
return vertices;
}
inline bool GrBitmapTextContext::uploadGlyph(GrGlyph* glyph, GrFontScaler* scaler) {
if (!fStrike->glyphTooLargeForAtlas(glyph)) {
if (fStrike->addGlyphToAtlas(glyph, scaler)) {
return true;
}
// try to clear out an unused plot before we flush
if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
return true;
}
if (c_DumpFontCache) {
#ifdef SK_DEVELOPER
fContext->getFontCache()->dump();
#endif
}
// before we purge the cache, we must flush any accumulated draws
this->flush();
fContext->flush();
// we should have an unused plot now
if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
return true;
}
// we should never get here
SkASSERT(false);
}
return false;
}
void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed,
SkFixed vx, SkFixed vy,
GrFontScaler* scaler) {
@ -392,35 +426,7 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed,
}
}
if (NULL == glyph->fPlot) {
if (!fStrike->glyphTooLargeForAtlas(glyph)) {
if (fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
// try to clear out an unused plot before we flush
if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
if (c_DumpFontCache) {
#ifdef SK_DEVELOPER
fContext->getFontCache()->dump();
#endif
}
// flush any accumulated draws to allow us to free up a plot
this->flush();
fContext->flush();
// we should have an unused plot now
if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
}
if (NULL == glyph->fPlot && !uploadGlyph(glyph, scaler)) {
if (NULL == glyph->fPath) {
SkPath* path = SkNEW(SkPath);
if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
@ -448,7 +454,6 @@ void GrBitmapTextContext::appendGlyph(GrGlyph::PackedID packed,
return;
}
HAS_ATLAS:
SkASSERT(glyph->fPlot);
GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
glyph->fPlot->setDrawToken(drawToken);

View File

@ -48,6 +48,7 @@ private:
void init(const GrPaint&, const SkPaint&);
void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
bool uploadGlyph(GrGlyph*, GrFontScaler*);
void flush(); // automatically called by destructor
void finish();
};

View File

@ -11,6 +11,7 @@
#include "GrAARectRenderer.h"
#include "GrBufferAllocPool.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrFontCache.h"
#include "GrGpuResource.h"
#include "GrGpuResourceCacheAccess.h"
#include "GrDistanceFieldTextContext.h"
@ -27,7 +28,6 @@
#include "GrStencilAndCoverTextContext.h"
#include "GrStrokeInfo.h"
#include "GrSurfacePriv.h"
#include "GrTextStrike.h"
#include "GrTexturePriv.h"
#include "GrTraceMarker.h"
#include "GrTracing.h"

View File

@ -10,13 +10,12 @@
#include "GrBitmapTextContext.h"
#include "GrDrawTarget.h"
#include "GrDrawTargetCaps.h"
#include "GrFontCache.h"
#include "GrFontScaler.h"
#include "GrGpu.h"
#include "GrIndexBuffer.h"
#include "GrStrokeInfo.h"
#include "GrTexturePriv.h"
#include "GrTextStrike.h"
#include "GrTextStrike_impl.h"
#include "SkAutoKern.h"
#include "SkColorFilter.h"
@ -435,6 +434,42 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
}
inline bool GrDistanceFieldTextContext::uploadGlyph(GrGlyph* glyph, GrFontScaler* scaler) {
if (!fStrike->glyphTooLargeForAtlas(glyph)) {
if (fStrike->addGlyphToAtlas(glyph, scaler)) {
return true;
}
// try to clear out an unused plot before we flush
if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
return true;
}
if (c_DumpFontCache) {
#ifdef SK_DEVELOPER
fContext->getFontCache()->dump();
#endif
}
// before we purge the cache, we must flush any accumulated draws
this->flush();
fContext->flush();
// we should have an unused plot now
if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
return true;
}
// we should never get here
SkASSERT(false);
}
return false;
}
// Returns true if this method handled the glyph, false if needs to be passed to fallback
//
bool GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
@ -484,35 +519,7 @@ bool GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
return true;
}
if (NULL == glyph->fPlot) {
if (!fStrike->glyphTooLargeForAtlas(glyph)) {
if (fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
// try to clear out an unused plot before we flush
if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
if (c_DumpFontCache) {
#ifdef SK_DEVELOPER
fContext->getFontCache()->dump();
#endif
}
// before we purge the cache, we must flush any accumulated draws
this->flush();
fContext->flush();
// we should have an unused plot now
if (fContext->getFontCache()->freeUnusedPlot(fStrike, glyph) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
}
if (NULL == glyph->fPlot && !uploadGlyph(glyph, scaler)) {
if (NULL == glyph->fPath) {
SkPath* path = SkNEW(SkPath);
if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
@ -540,7 +547,6 @@ bool GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
return true;
}
HAS_ATLAS:
SkASSERT(glyph->fPlot);
GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
glyph->fPlot->setDrawToken(drawToken);

View File

@ -60,6 +60,7 @@ private:
void init(const GrPaint&, const SkPaint&);
bool appendGlyph(GrGlyph::PackedID, SkScalar left, SkScalar top, GrFontScaler*);
bool uploadGlyph(GrGlyph*, GrFontScaler*);
void setupCoverageEffect(const SkColor& filteredColor);
void flush(); // automatically called by destructor
void finish();

View File

@ -7,8 +7,8 @@
#include "GrFlushToGpuDrawTarget.h"
#include "GrContext.h"
#include "GrFontCache.h"
#include "GrGpu.h"
#include "GrTextStrike.h"
#include "GrBufferAllocPool.h"
GrFlushToGpuDrawTarget::GrFlushToGpuDrawTarget(GrGpu* gpu,

View File

@ -5,11 +5,10 @@
* found in the LICENSE file.
*/
#include "GrFontCache.h"
#include "GrGpu.h"
#include "GrRectanizer.h"
#include "GrSurfacePriv.h"
#include "GrTextStrike.h"
#include "GrTextStrike_impl.h"
#include "SkString.h"
#include "SkDistanceFieldGen.h"

View File

@ -34,7 +34,14 @@ public:
const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; }
GrFontCache* getFontCache() const { return fFontCache; }
inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
inline GrGlyph* getGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler) {
GrGlyph* glyph = fCache.find(packed);
if (NULL == glyph) {
glyph = this->generateGlyph(packed, scaler);
}
return glyph;
}
// returns true if glyph (or glyph+padding for distance field)
// is too large to ever fit in texture atlas subregions (GrPlots)
bool glyphTooLargeForAtlas(GrGlyph*);
@ -79,7 +86,26 @@ public:
GrFontCache(GrGpu*);
~GrFontCache();
inline GrTextStrike* getStrike(GrFontScaler*, bool useDistanceField);
inline GrTextStrike* getStrike(GrFontScaler* scaler, bool useDistanceField) {
this->validate();
GrTextStrike* strike = fCache.find(*(scaler->getKey()));
if (NULL == strike) {
strike = this->generateStrike(scaler);
} else if (strike->fPrev) {
// Need to put the strike at the head of its dllist, since that is how
// we age the strikes for purging (we purge from the back of the list)
this->detachStrikeFromList(strike);
// attach at the head
fHead->fPrev = strike;
strike->fNext = fHead;
strike->fPrev = NULL;
fHead = strike;
}
strike->fUseDistanceField = useDistanceField;
this->validate();
return strike;
}
// add to texture atlas that matches this format
GrPlot* addToAtlas(GrMaskFormat format, GrAtlas::ClientPlotUsage* usage,
@ -132,7 +158,25 @@ private:
GrAtlas* fAtlases[kAtlasCount];
GrTextStrike* generateStrike(GrFontScaler*);
inline void detachStrikeFromList(GrTextStrike*);
inline void detachStrikeFromList(GrTextStrike* strike) {
if (strike->fPrev) {
SkASSERT(fHead != strike);
strike->fPrev->fNext = strike->fNext;
} else {
SkASSERT(fHead == strike);
fHead = strike->fNext;
}
if (strike->fNext) {
SkASSERT(fTail != strike);
strike->fNext->fPrev = strike->fPrev;
} else {
SkASSERT(fTail == strike);
fTail = strike->fPrev;
}
}
void purgeStrike(GrTextStrike* strike);
};

View File

@ -11,7 +11,7 @@
#include "GrDrawTargetCaps.h"
#include "GrGpu.h"
#include "GrTemplates.h"
#include "GrTextStrike.h"
#include "GrFontCache.h"
#include "GrTexture.h"
GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,

View File

@ -1,64 +0,0 @@
/*
* Copyright 2010 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrTextStrike_impl_DEFINED
#define GrTextStrike_impl_DEFINED
void GrFontCache::detachStrikeFromList(GrTextStrike* strike) {
if (strike->fPrev) {
SkASSERT(fHead != strike);
strike->fPrev->fNext = strike->fNext;
} else {
SkASSERT(fHead == strike);
fHead = strike->fNext;
}
if (strike->fNext) {
SkASSERT(fTail != strike);
strike->fNext->fPrev = strike->fPrev;
} else {
SkASSERT(fTail == strike);
fTail = strike->fPrev;
}
}
GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler, bool useDistanceField) {
this->validate();
GrTextStrike* strike = fCache.find(*(scaler->getKey()));
if (NULL == strike) {
strike = this->generateStrike(scaler);
} else if (strike->fPrev) {
// Need to put the strike at the head of its dllist, since that is how
// we age the strikes for purging (we purge from the back of the list)
this->detachStrikeFromList(strike);
// attach at the head
fHead->fPrev = strike;
strike->fNext = fHead;
strike->fPrev = NULL;
fHead = strike;
}
strike->fUseDistanceField = useDistanceField;
this->validate();
return strike;
}
///////////////////////////////////////////////////////////////////////////////
GrGlyph* GrTextStrike::getGlyph(GrGlyph::PackedID packed,
GrFontScaler* scaler) {
GrGlyph* glyph = fCache.find(packed);
if (NULL == glyph) {
glyph = this->generateGlyph(packed, scaler);
}
return glyph;
}
#endif