Don't try to add large glyphs to the font atlas.

When the glyph data is invalid we can try to allocate a ridiculous amount of memory. This adds a check to cover such cases.

BUG=414581
R=egdaniel@google.com

Author: jvanverth@google.com

Review URL: https://codereview.chromium.org/585853003
This commit is contained in:
jvanverth 2014-09-19 13:07:38 -07:00 committed by Commit bot
parent 5d9ab2816f
commit 681e65b199
4 changed files with 57 additions and 36 deletions

View File

@ -454,30 +454,32 @@ void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
}
if (NULL == glyph->fPlot) {
if (fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
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) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
// try to clear out an unused plot before we flush
if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
if (c_DumpFontCache) {
if (c_DumpFontCache) {
#ifdef SK_DEVELOPER
fContext->getFontCache()->dump();
fContext->getFontCache()->dump();
#endif
}
}
// flush any accumulated draws to allow us to free up a plot
this->flushGlyphs();
fContext->flush();
// flush any accumulated draws to allow us to free up a plot
this->flushGlyphs();
fContext->flush();
// we should have an unused plot now
if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
// we should have an unused plot now
if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
}
if (NULL == glyph->fPath) {

View File

@ -273,30 +273,32 @@ void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
}
*/
if (NULL == glyph->fPlot) {
if (fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
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) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
// try to clear out an unused plot before we flush
if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
if (c_DumpFontCache) {
if (c_DumpFontCache) {
#ifdef SK_DEVELOPER
fContext->getFontCache()->dump();
fContext->getFontCache()->dump();
#endif
}
}
// before we purge the cache, we must flush any accumulated draws
this->flushGlyphs();
fContext->flush();
// before we purge the cache, we must flush any accumulated draws
this->flushGlyphs();
fContext->flush();
// we should have an unused plot now
if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
// we should have an unused plot now
if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
fStrike->addGlyphToAtlas(glyph, scaler)) {
goto HAS_ATLAS;
}
}
if (NULL == glyph->fPath) {

View File

@ -289,6 +289,19 @@ void GrTextStrike::removePlot(const GrPlot* plot) {
GrAtlas::RemovePlot(&fPlotUsage, plot);
}
bool GrTextStrike::glyphTooLargeForAtlas(GrGlyph* glyph) {
int width = glyph->fBounds.width();
int height = glyph->fBounds.height();
int pad = fUseDistanceField ? 2 * SK_DistanceFieldPad : 0;
if (width + pad > GR_PLOT_WIDTH) {
return true;
}
if (height + pad > GR_PLOT_HEIGHT) {
return true;
}
return false;
}
bool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
#if 0 // testing hack to force us to flush our cache often

View File

@ -37,6 +37,10 @@ public:
GrTexture* getTexture() const { return fAtlas->getTexture(); }
inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
// returns true if glyph (or glyph+padding for distance field)
// is too large to ever fit in texture atlas subregions (GrPlots)
bool glyphTooLargeForAtlas(GrGlyph*);
// returns true if glyph successfully added to texture atlas, false otherwise
bool addGlyphToAtlas(GrGlyph*, GrFontScaler*);
// testing