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:
parent
5d9ab2816f
commit
681e65b199
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user