diff options
author | jvanverth <jvanverth@google.com> | 2016-02-22 11:25:32 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-22 11:25:32 -0800 |
commit | 7023a00c35d904e4ccff09c377e9ba26abba6181 (patch) | |
tree | 33a9241b646576bd5c66b88623c1db8d925d1274 /src | |
parent | 01e583807618038a578a3b07cfad3101d24115c7 (diff) |
Use unorm shorts for texture coordinates when rendering text.
There are a couple of reasons for this:
- Vulkan does not guarantee conversions from integral vertex attributes
to floating point shader variables
- This may be faster and more precise on some platforms, as it avoids
the aforementioned conversion and changes a multiply by a very small
value to a multiply by a medium-sized value.
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1713693002
TBR=bsalomon@google.com
Committed: https://skia.googlesource.com/skia/+/e507ff0460f4f878214b9454fb5b9ab8d64d8063
Review URL: https://codereview.chromium.org/1713693002
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrBatchAtlas.h | 2 | ||||
-rw-r--r-- | src/gpu/GrTest.cpp | 6 | ||||
-rw-r--r-- | src/gpu/effects/GrBitmapTextGeoProc.cpp | 13 | ||||
-rw-r--r-- | src/gpu/effects/GrDistanceFieldGeoProc.cpp | 40 | ||||
-rw-r--r-- | src/gpu/gl/GrGLVertexArray.cpp | 4 | ||||
-rw-r--r-- | src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp | 40 | ||||
-rw-r--r-- | src/gpu/text/GrBatchFontCache.cpp | 6 | ||||
-rw-r--r-- | src/gpu/text/GrBatchFontCache.h | 3 |
8 files changed, 73 insertions, 41 deletions
diff --git a/src/gpu/GrBatchAtlas.h b/src/gpu/GrBatchAtlas.h index 61fc7e1093..43dd692429 100644 --- a/src/gpu/GrBatchAtlas.h +++ b/src/gpu/GrBatchAtlas.h @@ -22,6 +22,8 @@ struct GrBatchAtlasConfig { int numPlotsY() const { return fHeight / fPlotWidth; } int fWidth; int fHeight; + int fLog2Width; + int fLog2Height; int fPlotWidth; int fPlotHeight; }; diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp index 04122e1319..b4fb27bcc5 100644 --- a/src/gpu/GrTest.cpp +++ b/src/gpu/GrTest.cpp @@ -29,16 +29,22 @@ void SetupAlwaysEvictAtlas(GrContext* context) { GrBatchAtlasConfig configs[3]; configs[kA8_GrMaskFormat].fWidth = dim; configs[kA8_GrMaskFormat].fHeight = dim; + configs[kA8_GrMaskFormat].fLog2Width = SkNextLog2(dim); + configs[kA8_GrMaskFormat].fLog2Height = SkNextLog2(dim); configs[kA8_GrMaskFormat].fPlotWidth = dim; configs[kA8_GrMaskFormat].fPlotHeight = dim; configs[kA565_GrMaskFormat].fWidth = dim; configs[kA565_GrMaskFormat].fHeight = dim; + configs[kA565_GrMaskFormat].fLog2Width = SkNextLog2(dim); + configs[kA565_GrMaskFormat].fLog2Height = SkNextLog2(dim); configs[kA565_GrMaskFormat].fPlotWidth = dim; configs[kA565_GrMaskFormat].fPlotHeight = dim; configs[kARGB_GrMaskFormat].fWidth = dim; configs[kARGB_GrMaskFormat].fHeight = dim; + configs[kARGB_GrMaskFormat].fLog2Width = SkNextLog2(dim); + configs[kARGB_GrMaskFormat].fLog2Height = SkNextLog2(dim); configs[kARGB_GrMaskFormat].fPlotWidth = dim; configs[kARGB_GrMaskFormat].fPlotHeight = dim; diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index 263676d353..18f12bdfa5 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -31,16 +31,12 @@ public: // compute numbers to be hardcoded to convert texture coordinates from int to float SkASSERT(cte.numTextures() == 1); - GrTexture* atlas = cte.textureAccess(0).getTexture(); + SkDEBUGCODE(GrTexture* atlas = cte.textureAccess(0).getTexture()); SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); - SkScalar recipWidth = 1.0f / atlas->width(); - SkScalar recipHeight = 1.0f / atlas->height(); GrGLSLVertToFrag v(kVec2f_GrSLType); - varyingHandler->addVarying("TextureCoords", &v); - vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", v.vsOut(), - GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, - GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, + varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); + vertBuilder->codeAppendf("%s = %s;", v.vsOut(), cte.inTextureCoords()->fName); GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; @@ -150,7 +146,8 @@ GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, GrTexture* texture, fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); } fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", - kVec2s_GrVertexAttribType)); + kVec2us_GrVertexAttribType, + kHigh_GrSLPrecision)); this->addTextureAccess(&fTextureAccess); } diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index 50e78ccb44..b77a1f5a5d 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -78,23 +78,20 @@ public: // add varyings GrGLSLVertToFrag recipScale(kFloat_GrSLType); - GrGLSLVertToFrag st(kVec2f_GrSLType); + GrGLSLVertToFrag uv(kVec2f_GrSLType); bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag); - varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); + varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); + vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCoords()->fName); // compute numbers to be hardcoded to convert texture coordinates from int to float SkASSERT(dfTexEffect.numTextures() == 1); GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); - SkScalar recipWidth = 1.0f / atlas->width(); - SkScalar recipHeight = 1.0f / atlas->height(); - GrGLSLVertToFrag uv(kVec2f_GrSLType); - varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), - GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, - GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, + GrGLSLVertToFrag st(kVec2f_GrSLType); + varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); + vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(), + atlas->width(), atlas->height(), dfTexEffect.inTextureCoords()->fName); // Use highp to work around aliasing issues @@ -224,7 +221,8 @@ GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color, kHigh_GrSLPrecision)); fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", - kVec2s_GrVertexAttribType)); + kVec2us_GrVertexAttribType, + kHigh_GrSLPrecision)); this->addTextureAccess(&fTextureAccess); } @@ -522,22 +520,19 @@ public: // set up varyings bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask); GrGLSLVertToFrag recipScale(kFloat_GrSLType); - GrGLSLVertToFrag st(kVec2f_GrSLType); - varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); + GrGLSLVertToFrag uv(kVec2f_GrSLType); + varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); + vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCoords()->fName); // compute numbers to be hardcoded to convert texture coordinates from int to float SkASSERT(dfTexEffect.numTextures() == 1); GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); - SkScalar recipWidth = 1.0f / atlas->width(); - SkScalar recipHeight = 1.0f / atlas->height(); - GrGLSLVertToFrag uv(kVec2f_GrSLType); - varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), - GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, - GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, + GrGLSLVertToFrag st(kVec2f_GrSLType); + varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); + vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(), + atlas->width(), atlas->height(), dfTexEffect.inTextureCoords()->fName); // add frag shader code @@ -708,7 +703,8 @@ GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc( kHigh_GrSLPrecision)); fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", - kVec2s_GrVertexAttribType)); + kVec2us_GrVertexAttribType, + kHigh_GrSLPrecision)); this->addTextureAccess(&fTextureAccess); } diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp index 2048e2c58f..d49846db55 100644 --- a/src/gpu/gl/GrGLVertexArray.cpp +++ b/src/gpu/gl/GrGLVertexArray.cpp @@ -21,7 +21,7 @@ static const AttribLayout gLayouts[kGrVertexAttribTypeCount] = { {4, GR_GL_FLOAT, false}, // kVec4f_GrVertexAttribType {1, GR_GL_UNSIGNED_BYTE, true}, // kUByte_GrVertexAttribType {4, GR_GL_UNSIGNED_BYTE, true}, // kVec4ub_GrVertexAttribType - {2, GR_GL_SHORT, false}, // kVec2s_GrVertexAttribType + {2, GR_GL_UNSIGNED_SHORT, true}, // kVec2s_GrVertexAttribType {1, GR_GL_INT, false}, // kInt_GrVertexAttribType {1, GR_GL_UNSIGNED_INT, false}, // kUint_GrVertexAttribType }; @@ -32,7 +32,7 @@ GR_STATIC_ASSERT(2 == kVec3f_GrVertexAttribType); GR_STATIC_ASSERT(3 == kVec4f_GrVertexAttribType); GR_STATIC_ASSERT(4 == kUByte_GrVertexAttribType); GR_STATIC_ASSERT(5 == kVec4ub_GrVertexAttribType); -GR_STATIC_ASSERT(6 == kVec2s_GrVertexAttribType); +GR_STATIC_ASSERT(6 == kVec2us_GrVertexAttribType); GR_STATIC_ASSERT(7 == kInt_GrVertexAttribType); GR_STATIC_ASSERT(8 == kUint_GrVertexAttribType); diff --git a/src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp b/src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp index 00a73641aa..c2f3f22d7e 100644 --- a/src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp +++ b/src/gpu/text/GrAtlasTextBlob_regenInBatch.cpp @@ -21,6 +21,7 @@ template <bool regenPos, bool regenCol, bool regenTexCoords> inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexStride, bool useDistanceFields, SkScalar transX, SkScalar transY, + int32_t log2Width, int32_t log2Height, GrColor color) { int u0, v0, u1, v1; if (regenTexCoords) { @@ -39,6 +40,20 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS u1 = u0 + width; v1 = v0 + height; } + + // normalize + u0 *= 65535; + u0 >>= log2Width; + u1 *= 65535; + u1 >>= log2Width; + v0 *= 65535; + v0 >>= log2Height; + v1 *= 65535; + v1 >>= log2Height; + SkASSERT(u0 >= 0 && u0 <= 65535); + SkASSERT(u1 >= 0 && u1 <= 65535); + SkASSERT(v0 >= 0 && v0 <= 65535); + SkASSERT(v1 >= 0 && v1 <= 65535); } // This is a bit wonky, but sometimes we have LCD text, in which case we won't have color @@ -59,8 +74,9 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS } if (regenTexCoords) { - SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCoordOffset); - textureCoords->set(u0, v0); + uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); + textureCoords[0] = (uint16_t) u0; + textureCoords[1] = (uint16_t) v0; } vertex += vertexStride; @@ -77,8 +93,9 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS } if (regenTexCoords) { - SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCoordOffset); - textureCoords->set(u0, v1); + uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); + textureCoords[0] = (uint16_t)u0; + textureCoords[1] = (uint16_t)v1; } vertex += vertexStride; @@ -95,8 +112,9 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS } if (regenTexCoords) { - SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCoordOffset); - textureCoords->set(u1, v1); + uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); + textureCoords[0] = (uint16_t)u1; + textureCoords[1] = (uint16_t)v1; } vertex += vertexStride; @@ -113,8 +131,9 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS } if (regenTexCoords) { - SkIPoint16* textureCoords = reinterpret_cast<SkIPoint16*>(vertex + texCoordOffset); - textureCoords->set(u1, v0); + uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); + textureCoords[0] = (uint16_t)u1; + textureCoords[1] = (uint16_t)v0; } } @@ -161,6 +180,7 @@ void GrAtlasTextBlob::regenInBatch(GrDrawBatch::Target* target, bool brokenRun = false; for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { GrGlyph* glyph = nullptr; + int log2Width = 0, log2Height = 0; if (regenTexCoords) { size_t glyphOffset = glyphIdx + info->glyphStartIndex(); @@ -187,6 +207,8 @@ void GrAtlasTextBlob::regenInBatch(GrDrawBatch::Target* target, } fontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph, target->currentToken()); + log2Width = fontCache->log2Width(info->maskFormat()); + log2Height = fontCache->log2Height(info->maskFormat()); } intptr_t vertex = reinterpret_cast<intptr_t>(fVertices); @@ -194,7 +216,7 @@ void GrAtlasTextBlob::regenInBatch(GrDrawBatch::Target* target, vertex += vertexStride * glyphIdx * GrAtlasTextBatch::kVerticesPerGlyph; regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertexStride, info->drawAsDistanceFields(), transX, - transY, color); + transY, log2Width, log2Height, color); helper->incGlyphCount(); } diff --git a/src/gpu/text/GrBatchFontCache.cpp b/src/gpu/text/GrBatchFontCache.cpp index ad76e4d71f..d99df1da03 100644 --- a/src/gpu/text/GrBatchFontCache.cpp +++ b/src/gpu/text/GrBatchFontCache.cpp @@ -48,16 +48,22 @@ GrBatchFontCache::GrBatchFontCache(GrContext* context) // setup default atlas configs fAtlasConfigs[kA8_GrMaskFormat].fWidth = 2048; fAtlasConfigs[kA8_GrMaskFormat].fHeight = 2048; + fAtlasConfigs[kA8_GrMaskFormat].fLog2Width = 11; + fAtlasConfigs[kA8_GrMaskFormat].fLog2Height = 11; fAtlasConfigs[kA8_GrMaskFormat].fPlotWidth = 512; fAtlasConfigs[kA8_GrMaskFormat].fPlotHeight = 256; fAtlasConfigs[kA565_GrMaskFormat].fWidth = 1024; fAtlasConfigs[kA565_GrMaskFormat].fHeight = 2048; + fAtlasConfigs[kA565_GrMaskFormat].fLog2Width = 10; + fAtlasConfigs[kA565_GrMaskFormat].fLog2Height = 11; fAtlasConfigs[kA565_GrMaskFormat].fPlotWidth = 256; fAtlasConfigs[kA565_GrMaskFormat].fPlotHeight = 256; fAtlasConfigs[kARGB_GrMaskFormat].fWidth = 1024; fAtlasConfigs[kARGB_GrMaskFormat].fHeight = 2048; + fAtlasConfigs[kARGB_GrMaskFormat].fLog2Width = 10; + fAtlasConfigs[kARGB_GrMaskFormat].fLog2Height = 11; fAtlasConfigs[kARGB_GrMaskFormat].fPlotWidth = 256; fAtlasConfigs[kARGB_GrMaskFormat].fPlotHeight = 256; } diff --git a/src/gpu/text/GrBatchFontCache.h b/src/gpu/text/GrBatchFontCache.h index 46ab1c8274..7ff1b9e77f 100644 --- a/src/gpu/text/GrBatchFontCache.h +++ b/src/gpu/text/GrBatchFontCache.h @@ -171,6 +171,9 @@ public: return this->getAtlas(format)->atlasGeneration(); } + int log2Width(GrMaskFormat format) { return fAtlasConfigs[format].fLog2Width; } + int log2Height(GrMaskFormat format) { return fAtlasConfigs[format].fLog2Height; } + /////////////////////////////////////////////////////////////////////////// // Functions intended debug only void dump() const; |