Adjust atlas sizes to fix Mali400 precision issues
The previous change to atlas sizes introduced an issue where texture coordinates for glyphs stored on the right side of the atlas were being computed in an imprecise manner on Mali400 chips. The only reasonable fix appears to be to use power-of-two texture sizes. This widens the glyph atlas to the next power of 2 (or 2048) for A8 glyphs only, and widens each GrPlot by 2x as well. By doing this, we can fit 3-4 large distance field glyphs into a single GrPlot, which gives us 100-128 total large glyphs at one time. The 565 and 8888 glyph atlases are kept in their original size to preserve space. BUG=skia:3523 Review URL: https://codereview.chromium.org/994303003
This commit is contained in:
parent
6ba791f661
commit
cb251f1d0a
@ -34,10 +34,9 @@ SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
|
||||
|
||||
static const int kSmallDFFontSize = 32;
|
||||
static const int kSmallDFFontLimit = 32;
|
||||
static const int kMediumDFFontSize = 70;
|
||||
static const int kMediumDFFontLimit = 70;
|
||||
static const int kLargeDFFontSize = 156;
|
||||
SK_COMPILE_ASSERT(GR_SDF_MAX_SIZE >= kLargeDFFontSize, sdf_too_big);
|
||||
static const int kMediumDFFontSize = 72;
|
||||
static const int kMediumDFFontLimit = 72;
|
||||
static const int kLargeDFFontSize = 162;
|
||||
|
||||
static const int kVerticesPerGlyph = 4;
|
||||
static const int kIndicesPerGlyph = 6;
|
||||
|
@ -9,27 +9,25 @@
|
||||
#ifndef GrFontAtlasSizes_DEFINED
|
||||
#define GrFontAtlasSizes_DEFINED
|
||||
|
||||
#include "SkDistanceFieldGen.h"
|
||||
#define GR_FONT_ATLAS_TEXTURE_WIDTH 1024
|
||||
#define GR_FONT_ATLAS_A8_TEXTURE_WIDTH 2048
|
||||
#define GR_FONT_ATLAS_TEXTURE_HEIGHT 2048
|
||||
|
||||
#define GR_SDF_MAX_SIZE 156
|
||||
#define GR_FONT_ATLAS_PLOT_WIDTH 256
|
||||
#define GR_FONT_ATLAS_A8_PLOT_WIDTH 512
|
||||
#define GR_FONT_ATLAS_PLOT_HEIGHT 256
|
||||
|
||||
// allows us to fit four of the largest distance field glyphs
|
||||
#define GR_FONT_ATLAS_PLOT_WIDTH (2*(GR_SDF_MAX_SIZE+2*SK_DistanceFieldPad))
|
||||
#define GR_FONT_ATLAS_PLOT_HEIGHT (2*(GR_SDF_MAX_SIZE+2*SK_DistanceFieldPad))
|
||||
|
||||
#define GR_FONT_ATLAS_NUM_PLOTS_X 5
|
||||
#define GR_FONT_ATLAS_NUM_PLOTS_Y 6
|
||||
|
||||
#define GR_FONT_ATLAS_TEXTURE_WIDTH (GR_FONT_ATLAS_PLOT_WIDTH*GR_FONT_ATLAS_NUM_PLOTS_X)
|
||||
SK_COMPILE_ASSERT(GR_FONT_ATLAS_TEXTURE_WIDTH == 1640, font_atlas_unexpected_size);
|
||||
#define GR_FONT_ATLAS_TEXTURE_HEIGHT (GR_FONT_ATLAS_PLOT_HEIGHT*GR_FONT_ATLAS_NUM_PLOTS_Y)
|
||||
SK_COMPILE_ASSERT(GR_FONT_ATLAS_TEXTURE_HEIGHT == 1968, font_atlas_unexpected_size);
|
||||
#define GR_FONT_ATLAS_NUM_PLOTS_X (GR_FONT_ATLAS_TEXTURE_WIDTH / GR_FONT_ATLAS_PLOT_WIDTH)
|
||||
#define GR_FONT_ATLAS_A8_NUM_PLOTS_X (GR_FONT_ATLAS_A8_TEXTURE_WIDTH / GR_FONT_ATLAS_A8_PLOT_WIDTH)
|
||||
#define GR_FONT_ATLAS_NUM_PLOTS_Y (GR_FONT_ATLAS_TEXTURE_HEIGHT / GR_FONT_ATLAS_PLOT_HEIGHT)
|
||||
|
||||
// one over width and height
|
||||
#define GR_FONT_ATLAS_RECIP_WIDTH "0.00060975609"
|
||||
#define GR_FONT_ATLAS_RECIP_HEIGHT "0.00050813008"
|
||||
#define GR_FONT_ATLAS_RECIP_WIDTH "0.0009765625"
|
||||
#define GR_FONT_ATLAS_A8_RECIP_WIDTH "0.00048828125"
|
||||
#define GR_FONT_ATLAS_RECIP_HEIGHT "0.00048828125"
|
||||
|
||||
// 1/(3*width)
|
||||
#define GR_FONT_ATLAS_LCD_DELTA "0.00020325203"
|
||||
// only used for distance fields, which are A8
|
||||
#define GR_FONT_ATLAS_LCD_DELTA "0.000162760417"
|
||||
|
||||
#endif
|
||||
|
@ -113,13 +113,23 @@ GrPlot* GrFontCache::addToAtlas(GrMaskFormat format, GrAtlas::ClientPlotUsage* u
|
||||
GrPixelConfig config = mask_format_to_pixel_config(format);
|
||||
int atlasIndex = mask_format_to_atlas_index(format);
|
||||
if (NULL == fAtlases[atlasIndex]) {
|
||||
SkISize textureSize = SkISize::Make(GR_FONT_ATLAS_TEXTURE_WIDTH,
|
||||
GR_FONT_ATLAS_TEXTURE_HEIGHT);
|
||||
fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrSurfaceFlags,
|
||||
textureSize,
|
||||
GR_FONT_ATLAS_NUM_PLOTS_X,
|
||||
GR_FONT_ATLAS_NUM_PLOTS_Y,
|
||||
true));
|
||||
if (kA8_GrMaskFormat == format) {
|
||||
SkISize textureSize = SkISize::Make(GR_FONT_ATLAS_A8_TEXTURE_WIDTH,
|
||||
GR_FONT_ATLAS_TEXTURE_HEIGHT);
|
||||
fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrSurfaceFlags,
|
||||
textureSize,
|
||||
GR_FONT_ATLAS_A8_NUM_PLOTS_X,
|
||||
GR_FONT_ATLAS_NUM_PLOTS_Y,
|
||||
true));
|
||||
} else {
|
||||
SkISize textureSize = SkISize::Make(GR_FONT_ATLAS_TEXTURE_WIDTH,
|
||||
GR_FONT_ATLAS_TEXTURE_HEIGHT);
|
||||
fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrSurfaceFlags,
|
||||
textureSize,
|
||||
GR_FONT_ATLAS_NUM_PLOTS_X,
|
||||
GR_FONT_ATLAS_NUM_PLOTS_Y,
|
||||
true));
|
||||
}
|
||||
}
|
||||
return fAtlases[atlasIndex]->addToAtlas(usage, width, height, image, loc);
|
||||
}
|
||||
@ -281,7 +291,9 @@ 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_FONT_ATLAS_PLOT_WIDTH) {
|
||||
int plotWidth = (kA8_GrMaskFormat == glyph->fMaskFormat) ? GR_FONT_ATLAS_A8_PLOT_WIDTH
|
||||
: GR_FONT_ATLAS_PLOT_WIDTH;
|
||||
if (width + pad > plotWidth) {
|
||||
return true;
|
||||
}
|
||||
if (height + pad > GR_FONT_ATLAS_PLOT_HEIGHT) {
|
||||
|
@ -39,9 +39,15 @@ public:
|
||||
GrGLVertToFrag v(kVec2f_GrSLType);
|
||||
pb->addVarying("TextureCoords", &v);
|
||||
// this is only used with text, so our texture bounds always match the glyph atlas
|
||||
vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", "
|
||||
GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", v.vsOut(),
|
||||
cte.inTextureCoords()->fName);
|
||||
if (cte.maskFormat() == kA8_GrMaskFormat) {
|
||||
vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
|
||||
GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", v.vsOut(),
|
||||
cte.inTextureCoords()->fName);
|
||||
} else {
|
||||
vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", "
|
||||
GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", v.vsOut(),
|
||||
cte.inTextureCoords()->fName);
|
||||
}
|
||||
|
||||
// Setup pass through color
|
||||
this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, cte.inColor(),
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
GrGLVertToFrag uv(kVec2f_GrSLType);
|
||||
args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
|
||||
// this is only used with text, so our texture bounds always match the glyph atlas
|
||||
vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", "
|
||||
vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
|
||||
GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
|
||||
dfTexEffect.inTextureCoords()->fName);
|
||||
|
||||
@ -582,7 +582,7 @@ public:
|
||||
GrGLVertToFrag uv(kVec2f_GrSLType);
|
||||
args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
|
||||
// this is only used with text, so our texture bounds always match the glyph atlas
|
||||
vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_RECIP_WIDTH ", "
|
||||
vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
|
||||
GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
|
||||
dfTexEffect.inTextureCoords()->fName);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user