diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/ccpr/GrCCPRPathProcessor.cpp | 1 | ||||
-rw-r--r-- | src/gpu/effects/GrBitmapTextGeoProc.cpp | 64 | ||||
-rw-r--r-- | src/gpu/effects/GrDistanceFieldGeoProc.cpp | 249 | ||||
-rw-r--r-- | src/gpu/gl/GrGLVertexArray.cpp | 4 | ||||
-rw-r--r-- | src/gpu/ops/GrSmallPathRenderer.cpp | 31 | ||||
-rw-r--r-- | src/gpu/text/GrAtlasTextBlob_regenInOp.cpp | 38 | ||||
-rw-r--r-- | src/gpu/vk/GrVkPipeline.cpp | 4 | ||||
-rw-r--r-- | src/gpu/vk/GrVkUniformHandler.cpp | 4 | ||||
-rw-r--r-- | src/gpu/vk/GrVkVaryingHandler.cpp | 2 |
9 files changed, 205 insertions, 192 deletions
diff --git a/src/gpu/ccpr/GrCCPRPathProcessor.cpp b/src/gpu/ccpr/GrCCPRPathProcessor.cpp index 1292553824..54ffb9b5ca 100644 --- a/src/gpu/ccpr/GrCCPRPathProcessor.cpp +++ b/src/gpu/ccpr/GrCCPRPathProcessor.cpp @@ -56,6 +56,7 @@ GrCCPRPathProcessor::GrCCPRPathProcessor(GrResourceProvider* rp, sk_sp<GrTexture this->addInstanceAttrib("view_matrix", kVec4f_GrVertexAttribType, kHigh_GrSLPrecision); this->addInstanceAttrib("view_translate", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision); // FIXME: this could be a vector of two shorts if it were supported by Ganesh. + // Note: this should be doable now with kVec2us_uint_GrVertexAttribType this->addInstanceAttrib("atlas_offset", kVec2i_GrVertexAttribType, kHigh_GrSLPrecision); this->addInstanceAttrib("color", kVec4ub_GrVertexAttribType, kLow_GrSLPrecision); diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index a934ff10f7..d24ddf8b8f 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -17,50 +17,53 @@ class GrGLBitmapTextGeoProc : public GrGLSLGeometryProcessor { public: - GrGLBitmapTextGeoProc() : fColor(GrColor_ILLEGAL) {} + GrGLBitmapTextGeoProc() : fColor(GrColor_ILLEGAL), fAtlasSize({0,0}) {} void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { - const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>(); + const GrBitmapTextGeoProc& btgp = args.fGP.cast<GrBitmapTextGeoProc>(); GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; // emit attributes - varyingHandler->emitAttributes(cte); + varyingHandler->emitAttributes(btgp); - // compute numbers to be hardcoded to convert texture coordinates from int to float - SkASSERT(cte.numTextureSamplers() == 1); - SkDEBUGCODE(GrTexture* atlas = cte.textureSampler(0).peekTexture()); - SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); + const char* atlasSizeInvName; + fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, + kVec2f_GrSLType, + kHigh_GrSLPrecision, + "AtlasSizeInv", + &atlasSizeInvName); GrGLSLVertToFrag v(kVec2f_GrSLType); varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = %s;", v.vsOut(), - cte.inTextureCoords()->fName); + vertBuilder->codeAppendf("%s = %s * %s;", v.vsOut(), + btgp.inTextureCoords()->fName, + atlasSizeInvName); GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; // Setup pass through color - if (cte.hasVertexColor()) { - varyingHandler->addPassThroughAttribute(cte.inColor(), args.fOutputColor); + if (btgp.hasVertexColor()) { + varyingHandler->addPassThroughAttribute(btgp.inColor(), args.fOutputColor); } else { this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform); } // Setup position - this->writeOutputPosition(vertBuilder, gpArgs, cte.inPosition()->fName); + this->writeOutputPosition(vertBuilder, gpArgs, btgp.inPosition()->fName); // emit transforms this->emitTransforms(vertBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar, - cte.inPosition()->fName, - cte.localMatrix(), + btgp.inPosition()->fName, + btgp.localMatrix(), args.fFPCoordTransformHandler); - if (cte.maskFormat() == kARGB_GrMaskFormat) { + if (btgp.maskFormat() == kARGB_GrMaskFormat) { fragBuilder->codeAppendf("%s = ", args.fOutputColor); fragBuilder->appendTextureLookupAndModulate(args.fOutputColor, args.fTexSamplers[0], @@ -84,31 +87,35 @@ public: pdman.set4fv(fColorUniform, 1, c); fColor = btgp.color(); } + + SkASSERT(btgp.numTextureSamplers() == 1); + GrTexture* atlas = btgp.textureSampler(0).peekTexture(); + SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); + + if (fAtlasSize.fWidth != atlas->width() || fAtlasSize.fHeight != atlas->height()) { + pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlas->width(), 1.0f / atlas->height()); + fAtlasSize.set(atlas->width(), atlas->height()); + } this->setTransformDataHelper(btgp.localMatrix(), pdman, &transformIter); } static inline void GenKey(const GrGeometryProcessor& proc, const GrShaderCaps&, GrProcessorKeyBuilder* b) { - const GrBitmapTextGeoProc& gp = proc.cast<GrBitmapTextGeoProc>(); + const GrBitmapTextGeoProc& btgp = proc.cast<GrBitmapTextGeoProc>(); uint32_t key = 0; - key |= (gp.usesLocalCoords() && gp.localMatrix().hasPerspective()) ? 0x1 : 0x0; - key |= gp.maskFormat() << 1; + key |= (btgp.usesLocalCoords() && btgp.localMatrix().hasPerspective()) ? 0x1 : 0x0; + key |= btgp.maskFormat() << 1; b->add32(key); - - // Currently we hardcode numbers to convert atlas coordinates to normalized floating point - SkASSERT(gp.numTextureSamplers() == 1); - GrTextureProxy* atlas = gp.textureSampler(0).proxy(); - if (atlas) { - b->add32(atlas->width()); - b->add32(atlas->height()); - } } private: - GrColor fColor; + GrColor fColor; UniformHandle fColorUniform; + SkISize fAtlasSize; + UniformHandle fAtlasSizeInvUniform; + typedef GrGLSLGeometryProcessor INHERITED; }; @@ -133,7 +140,8 @@ GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, if (hasVertexColor) { fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType); } - fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_GrVertexAttribType, + + fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType, kHigh_GrSLPrecision); this->addTextureSampler(&fTextureSampler); } diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index 8dd2fa617a..37b1113a5a 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -23,11 +23,12 @@ class GrGLDistanceFieldA8TextGeoProc : public GrGLSLGeometryProcessor { public: GrGLDistanceFieldA8TextGeoProc() - : fViewMatrix(SkMatrix::InvalidMatrix()) -#ifdef SK_GAMMA_APPLY_TO_A8 - , fDistanceAdjust(-1.0f) -#endif - {} + : fViewMatrix(SkMatrix::InvalidMatrix()) + #ifdef SK_GAMMA_APPLY_TO_A8 + , fDistanceAdjust(-1.0f) + #endif + , fAtlasSize({0,0}) { + } void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrDistanceFieldA8TextGeoProc& dfTexEffect = @@ -41,6 +42,12 @@ public: // emit attributes varyingHandler->emitAttributes(dfTexEffect); + const char* atlasSizeInvName; + fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, + kVec2f_GrSLType, + kHigh_GrSLPrecision, + "AtlasSizeInv", + &atlasSizeInvName); #ifdef SK_GAMMA_APPLY_TO_A8 // adjust based on gamma const char* distanceAdjustUniName = nullptr; @@ -70,8 +77,17 @@ public: args.fFPCoordTransformHandler); // add varyings - GrGLSLVertToFrag recipScale(kFloat_GrSLType); GrGLSLVertToFrag uv(kVec2f_GrSLType); + varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); + vertBuilder->codeAppendf("%s = %s * %s;", uv.vsOut(), + dfTexEffect.inTextureCoords()->fName, + atlasSizeInvName); + + GrGLSLVertToFrag st(kVec2f_GrSLType); + varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); + vertBuilder->codeAppendf("%s = %s;", st.vsOut(), + dfTexEffect.inTextureCoords()->fName); + bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) == kUniformScale_DistanceFieldEffectMask; bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag); @@ -79,29 +95,14 @@ public: SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectFlag); bool isAliased = SkToBool(dfTexEffect.getFlags() & kAliased_DistanceFieldEffectFlag); - 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 float to int - SkASSERT(dfTexEffect.numTextureSamplers() == 1); - GrTexture* atlas = dfTexEffect.textureSampler(0).peekTexture(); - SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); - - GrGLSLVertToFrag st(kVec2f_GrSLType); - varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = float2(%d, %d) * %s;", st.vsOut(), - atlas->width(), atlas->height(), - dfTexEffect.inTextureCoords()->fName); // Use highp to work around aliasing issues fragBuilder->codeAppendf("highp float2 uv = %s;\n", uv.fsIn()); - fragBuilder->codeAppend("\tfloat texColor = "); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], - "uv", - kVec2f_GrSLType); - fragBuilder->codeAppend(".r;\n"); - fragBuilder->codeAppend("\tfloat distance = " + fragBuilder->codeAppend("float texColor = "); + fragBuilder->appendTextureLookup(args.fTexSamplers[0], "uv", kVec2f_GrSLType); + fragBuilder->codeAppend(".r;"); + fragBuilder->codeAppend("float distance = " SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");"); #ifdef SK_GAMMA_APPLY_TO_A8 // adjust width based on gamma @@ -177,15 +178,15 @@ public: void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc, FPCoordTransformIter&& transformIter) override { + const GrDistanceFieldA8TextGeoProc& dfa8gp = proc.cast<GrDistanceFieldA8TextGeoProc>(); + #ifdef SK_GAMMA_APPLY_TO_A8 - const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFieldA8TextGeoProc>(); - float distanceAdjust = dfTexEffect.getDistanceAdjust(); + float distanceAdjust = dfa8gp.getDistanceAdjust(); if (distanceAdjust != fDistanceAdjust) { - pdman.set1f(fDistanceAdjustUni, distanceAdjust); fDistanceAdjust = distanceAdjust; + pdman.set1f(fDistanceAdjustUni, distanceAdjust); } #endif - const GrDistanceFieldA8TextGeoProc& dfa8gp = proc.cast<GrDistanceFieldA8TextGeoProc>(); if (!dfa8gp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfa8gp.viewMatrix())) { fViewMatrix = dfa8gp.viewMatrix(); @@ -193,6 +194,16 @@ public: GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } + + SkASSERT(dfa8gp.numTextureSamplers() == 1); + GrTexture* atlas = dfa8gp.textureSampler(0).peekTexture(); + SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); + + if (fAtlasSize.fWidth != atlas->width() || fAtlasSize.fHeight != atlas->height()) { + fAtlasSize.set(atlas->width(), atlas->height()); + pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlas->width(), 1.0f / atlas->height()); + } + this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); } @@ -203,14 +214,6 @@ public: uint32_t key = dfTexEffect.getFlags(); key |= ComputePosKey(dfTexEffect.viewMatrix()) << 16; b->add32(key); - - // Currently we hardcode numbers to convert atlas coordinates to normalized floating point - SkASSERT(gp.numTextureSamplers() == 1); - GrTextureProxy* atlas = gp.textureSampler(0).proxy(); - if (atlas) { - b->add32(atlas->width()); - b->add32(atlas->height()); - } } private: @@ -220,6 +223,8 @@ private: float fDistanceAdjust; UniformHandle fDistanceAdjustUni; #endif + SkISize fAtlasSize; + UniformHandle fAtlasSizeInvUniform; typedef GrGLSLGeometryProcessor INHERITED; }; @@ -249,7 +254,7 @@ GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color, fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision); fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType); - fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_GrVertexAttribType, + fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType, kHigh_GrSLPrecision); this->addTextureSampler(&fTextureSampler); } @@ -308,8 +313,9 @@ sk_sp<GrGeometryProcessor> GrDistanceFieldA8TextGeoProc::TestCreate(GrProcessorT class GrGLDistanceFieldPathGeoProc : public GrGLSLGeometryProcessor { public: GrGLDistanceFieldPathGeoProc() - : fViewMatrix(SkMatrix::InvalidMatrix()) - , fTextureSize(SkISize::Make(-1, -1)) {} + : fViewMatrix(SkMatrix::InvalidMatrix()) + , fAtlasSize({0,0}) { + } void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>(); @@ -323,12 +329,26 @@ public: // emit attributes varyingHandler->emitAttributes(dfTexEffect); - GrGLSLVertToFrag v(kVec2f_GrSLType); - varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); + const char* atlasSizeInvName; + fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, + kVec2f_GrSLType, + kHigh_GrSLPrecision, + "AtlasSizeInv", + &atlasSizeInvName); + + GrGLSLVertToFrag uv(kVec2f_GrSLType); + varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); + vertBuilder->codeAppendf("%s = %s * %s;", uv.vsOut(), + dfTexEffect.inTextureCoords()->fName, + atlasSizeInvName); + + GrGLSLVertToFrag st(kVec2f_GrSLType); + varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); + vertBuilder->codeAppendf("%s = %s;", st.vsOut(), + dfTexEffect.inTextureCoords()->fName); // setup pass through color varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor); - vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName); // Setup position this->writeOutputPosition(vertBuilder, @@ -346,23 +366,15 @@ public: dfTexEffect.inPosition()->fName, args.fFPCoordTransformHandler); - const char* textureSizeUniName = nullptr; - fTextureSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec2f_GrSLType, kDefault_GrSLPrecision, - "TextureSize", &textureSizeUniName); - // Use highp to work around aliasing issues - fragBuilder->codeAppendf("highp float2 uv = %s;", v.fsIn()); + fragBuilder->codeAppendf("highp float2 uv = %s;", uv.fsIn()); fragBuilder->codeAppend("float texColor = "); - fragBuilder->appendTextureLookup(args.fTexSamplers[0], - "uv", - kVec2f_GrSLType); + fragBuilder->appendTextureLookup(args.fTexSamplers[0], "uv", kVec2f_GrSLType); fragBuilder->codeAppend(".r;"); fragBuilder->codeAppend("float distance = " SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");"); - fragBuilder->codeAppendf("highp float2 st = uv*%s;", textureSizeUniName); fragBuilder->codeAppend("float afwidth;"); bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) == kUniformScale_DistanceFieldEffectMask; @@ -376,10 +388,12 @@ public: // this gives us a smooth step across approximately one fragment #ifdef SK_VULKAN - fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));"); + fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(%s.x));", + st.fsIn()); #else // We use the y gradient because there is a bug in the Mali 400 in the x direction. - fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));"); + fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));", + st.fsIn()); #endif } else if (isSimilarity) { // For similarity transform, we adjust the effect of the transformation on the distance @@ -388,10 +402,10 @@ public: // this gives us a smooth step across approximately one fragment #ifdef SK_VULKAN - fragBuilder->codeAppend("float st_grad_len = length(dFdx(st));"); + fragBuilder->codeAppendf("float st_grad_len = length(dFdx(%s));", st.fsIn()); #else // We use the y gradient because there is a bug in the Mali 400 in the x direction. - fragBuilder->codeAppend("float st_grad_len = length(dFdy(st));"); + fragBuilder->codeAppendf("float st_grad_len = length(dFdy(%s));", st.fsIn()); #endif fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);"); } else { @@ -408,8 +422,8 @@ public: fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);"); fragBuilder->codeAppend("}"); - fragBuilder->codeAppend("float2 Jdx = dFdx(st);"); - fragBuilder->codeAppend("float2 Jdy = dFdy(st);"); + fragBuilder->codeAppendf("float2 Jdx = dFdx(%s);", st.fsIn()); + fragBuilder->codeAppendf("float2 Jdy = dFdy(%s);", st.fsIn()); fragBuilder->codeAppend("float2 grad = float2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,"); fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);"); @@ -431,17 +445,6 @@ public: void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc, FPCoordTransformIter&& transformIter) override { - SkASSERT(fTextureSizeUni.isValid()); - - GrTexture* texture = proc.textureSampler(0).peekTexture(); - - if (texture->width() != fTextureSize.width() || - texture->height() != fTextureSize.height()) { - fTextureSize = SkISize::Make(texture->width(), texture->height()); - pdman.set2f(fTextureSizeUni, - SkIntToScalar(fTextureSize.width()), - SkIntToScalar(fTextureSize.height())); - } const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathGeoProc>(); @@ -451,6 +454,16 @@ public: GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } + + SkASSERT(dfpgp.numTextureSamplers() == 1); + GrTexture* atlas = dfpgp.textureSampler(0).peekTexture(); + SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); + + if (fAtlasSize.fWidth != atlas->width() || fAtlasSize.fHeight != atlas->height()) { + fAtlasSize.set(atlas->width(), atlas->height()); + pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlas->width(), 1.0f / atlas->height()); + } + this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); } @@ -465,10 +478,11 @@ public: } private: - UniformHandle fTextureSizeUni; - UniformHandle fViewMatrixUniform; SkMatrix fViewMatrix; - SkISize fTextureSize; + UniformHandle fViewMatrixUniform; + + SkISize fAtlasSize; + UniformHandle fAtlasSizeInvUniform; typedef GrGLSLGeometryProcessor INHERITED; }; @@ -491,7 +505,7 @@ GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(GrColor color, fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision); fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType); - fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_GrVertexAttribType); + fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType); this->addTextureSampler(&fTextureSampler); } @@ -547,7 +561,8 @@ sk_sp<GrGeometryProcessor> GrDistanceFieldPathGeoProc::TestCreate(GrProcessorTes class GrGLDistanceFieldLCDTextGeoProc : public GrGLSLGeometryProcessor { public: GrGLDistanceFieldLCDTextGeoProc() - : fViewMatrix(SkMatrix::InvalidMatrix()) { + : fViewMatrix(SkMatrix::InvalidMatrix()) + , fAtlasSize({0,0}) { fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.0f, 1.0f, 1.0f); } @@ -562,6 +577,13 @@ public: // emit attributes varyingHandler->emitAttributes(dfTexEffect); + const char* atlasSizeInvName; + fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, + kVec2f_GrSLType, + kHigh_GrSLPrecision, + "AtlasSizeInv", + &atlasSizeInvName); + GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; // setup pass through color @@ -584,39 +606,36 @@ public: args.fFPCoordTransformHandler); // set up varyings - bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) == - kUniformScale_DistanceFieldEffectMask; - bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag); - bool isGammaCorrect = - SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectFlag); - GrGLSLVertToFrag recipScale(kFloat_GrSLType); 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 float to int - SkASSERT(dfTexEffect.numTextureSamplers() == 1); - GrTexture* atlas = dfTexEffect.textureSampler(0).peekTexture(); - SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); + vertBuilder->codeAppendf("%s = %s * %s;", uv.vsOut(), + dfTexEffect.inTextureCoords()->fName, + atlasSizeInvName); GrGLSLVertToFrag st(kVec2f_GrSLType); varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = float2(%d, %d) * %s;", st.vsOut(), - atlas->width(), atlas->height(), + vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); + GrGLSLVertToFrag delta(kFloat_GrSLType); + varyingHandler->addVarying("Delta", &delta, kHigh_GrSLPrecision); + if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { + vertBuilder->codeAppendf("%s = -%s.x/3.0;", delta.vsOut(), atlasSizeInvName); + } else { + vertBuilder->codeAppendf("%s = %s.x/3.0;", delta.vsOut(), atlasSizeInvName); + } + // add frag shader code + bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) == + kUniformScale_DistanceFieldEffectMask; + bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag); + bool isGammaCorrect = + SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectFlag); // create LCD offset adjusted by inverse of transform // Use highp to work around aliasing issues fragBuilder->codeAppendf("highp float2 uv = %s;\n", uv.fsIn()); - SkScalar lcdDelta = 1.0f / (3.0f * atlas->width()); - if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { - fragBuilder->codeAppendf("highp float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta); - } else { - fragBuilder->codeAppendf("highp float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta); - } if (isUniformScale) { #ifdef SK_VULKAN fragBuilder->codeAppendf("float st_grad_len = abs(dFdx(%s.x));", st.fsIn()); @@ -624,18 +643,19 @@ public: // We use the y gradient because there is a bug in the Mali 400 in the x direction. fragBuilder->codeAppendf("float st_grad_len = abs(dFdy(%s.y));", st.fsIn()); #endif - fragBuilder->codeAppend("float2 offset = float2(st_grad_len*delta, 0.0);"); + fragBuilder->codeAppendf("float2 offset = float2(st_grad_len*%s, 0.0);", delta.fsIn()); } else if (isSimilarity) { // For a similarity matrix with rotation, the gradient will not be aligned // with the texel coordinate axes, so we need to calculate it. #ifdef SK_VULKAN fragBuilder->codeAppendf("float2 st_grad = dFdx(%s);", st.fsIn()); - fragBuilder->codeAppend("float2 offset = delta*st_grad;"); + fragBuilder->codeAppendf("float2 offset = %s*st_grad;", delta.fsIn()); #else // We use dFdy because of a Mali 400 bug, and rotate -90 degrees to // get the gradient in the x direction. fragBuilder->codeAppendf("float2 st_grad = dFdy(%s);", st.fsIn()); - fragBuilder->codeAppend("float2 offset = delta*float2(st_grad.y, -st_grad.x);"); + fragBuilder->codeAppendf("float2 offset = %s*float2(st_grad.y, -st_grad.x);", + delta.fsIn()); #endif fragBuilder->codeAppend("float st_grad_len = length(st_grad);"); } else { @@ -643,7 +663,7 @@ public: fragBuilder->codeAppend("float2 Jdx = dFdx(st);"); fragBuilder->codeAppend("float2 Jdy = dFdy(st);"); - fragBuilder->codeAppend("float2 offset = delta*Jdx;"); + fragBuilder->codeAppendf("float2 offset = %s*Jdx;", delta.fsIn()); } // green is distance to uv center @@ -742,6 +762,16 @@ public: GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } + + SkASSERT(dflcd.numTextureSamplers() == 1); + GrTexture* atlas = dflcd.textureSampler(0).peekTexture(); + SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())); + + if (fAtlasSize.fWidth != atlas->width() || fAtlasSize.fHeight != atlas->height()) { + fAtlasSize.set(atlas->width(), atlas->height()); + pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlas->width(), 1.0f / atlas->height()); + } + this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); } @@ -753,22 +783,17 @@ public: uint32_t key = dfTexEffect.getFlags(); key |= ComputePosKey(dfTexEffect.viewMatrix()) << 16; b->add32(key); - - // Currently we hardcode numbers to convert atlas coordinates to normalized floating point - SkASSERT(gp.numTextureSamplers() == 1); - GrTextureProxy* atlas = gp.textureSampler(0).proxy(); - if (atlas) { - b->add32(atlas->width()); - b->add32(atlas->height()); - } } private: - SkMatrix fViewMatrix; - UniformHandle fViewMatrixUniform; - UniformHandle fColorUniform; + SkMatrix fViewMatrix; + UniformHandle fViewMatrixUniform; + GrDistanceFieldLCDTextGeoProc::DistanceAdjust fDistanceAdjust; - UniformHandle fDistanceAdjustUni; + UniformHandle fDistanceAdjustUni; + + SkISize fAtlasSize; + UniformHandle fAtlasSizeInvUniform; typedef GrGLSLGeometryProcessor INHERITED; }; @@ -791,7 +816,7 @@ GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc( fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision); fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType); - fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_GrVertexAttribType, + fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_uint_GrVertexAttribType, kHigh_GrSLPrecision); this->addTextureSampler(&fTextureSampler); } diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp index 745e532645..b4df8b8434 100644 --- a/src/gpu/gl/GrGLVertexArray.cpp +++ b/src/gpu/gl/GrGLVertexArray.cpp @@ -37,8 +37,10 @@ static AttribLayout attrib_layout(GrVertexAttribType type) { return {true, 1, GR_GL_UNSIGNED_BYTE}; case kVec4ub_GrVertexAttribType: return {true, 4, GR_GL_UNSIGNED_BYTE}; - case kVec2us_GrVertexAttribType: + case kVec2us_norm_GrVertexAttribType: return {true, 2, GR_GL_UNSIGNED_SHORT}; + case kVec2us_uint_GrVertexAttribType: + return {false, 2, GR_GL_UNSIGNED_SHORT}; case kInt_GrVertexAttribType: return {false, 1, GR_GL_INT}; case kUint_GrVertexAttribType: diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp index 69cd669abb..7e7a496af6 100644 --- a/src/gpu/ops/GrSmallPathRenderer.cpp +++ b/src/gpu/ops/GrSmallPathRenderer.cpp @@ -351,11 +351,11 @@ private: shapeData = new ShapeData; if (!this->addBMPathToAtlas(target, - &flushInfo, - atlas, - shapeData, - args.fShape, - this->viewMatrix())) { + &flushInfo, + atlas, + shapeData, + args.fShape, + this->viewMatrix())) { delete shapeData; continue; } @@ -479,7 +479,6 @@ private: shapeData->fKey.set(shape, dimension); shapeData->fID = id; - // set the bounds rect to the original bounds shapeData->fBounds = SkRect::Make(devPathBounds); shapeData->fBounds.offset(-translateX, -translateY); shapeData->fBounds.fLeft /= scale; @@ -615,22 +614,10 @@ private: } // set up texture coordinates - SkScalar texLeft = shapeData->fTextureCoords.fLeft; - SkScalar texTop = shapeData->fTextureCoords.fTop; - SkScalar texRight = shapeData->fTextureCoords.fRight; - SkScalar texBottom = shapeData->fTextureCoords.fBottom; - - // convert texcoords to unsigned short format - sk_sp<GrTextureProxy> proxy = atlas->getProxy(); - - // The proxy must be functionally exact for this normalization to work correctly - SkASSERT(GrResourceProvider::IsFunctionallyExact(proxy.get())); - SkScalar uFactor = 65535.f / proxy->width(); - SkScalar vFactor = 65535.f / proxy->height(); - uint16_t l = (uint16_t)(texLeft*uFactor); - uint16_t t = (uint16_t)(texTop*vFactor); - uint16_t r = (uint16_t)(texRight*uFactor); - uint16_t b = (uint16_t)(texBottom*vFactor); + uint16_t l = shapeData->fTextureCoords.fLeft; + uint16_t t = shapeData->fTextureCoords.fTop; + uint16_t r = shapeData->fTextureCoords.fRight; + uint16_t b = shapeData->fTextureCoords.fBottom; // set vertex texture coords intptr_t textureCoordOffset = offset + sizeof(SkPoint) + sizeof(GrColor); diff --git a/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp b/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp index 3150988fdb..96f0080ec2 100644 --- a/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp +++ b/src/gpu/text/GrAtlasTextBlob_regenInOp.cpp @@ -21,9 +21,8 @@ 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; + uint16_t u0, v0, u1, v1; if (regenTexCoords) { SkASSERT(glyph); int width = glyph->fBounds.width(); @@ -40,20 +39,6 @@ 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 @@ -75,8 +60,8 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS if (regenTexCoords) { uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); - textureCoords[0] = (uint16_t) u0; - textureCoords[1] = (uint16_t) v0; + textureCoords[0] = u0; + textureCoords[1] = v0; } vertex += vertexStride; @@ -94,8 +79,8 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS if (regenTexCoords) { uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); - textureCoords[0] = (uint16_t)u0; - textureCoords[1] = (uint16_t)v1; + textureCoords[0] = u0; + textureCoords[1] = v1; } vertex += vertexStride; @@ -113,8 +98,8 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS if (regenTexCoords) { uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); - textureCoords[0] = (uint16_t)u1; - textureCoords[1] = (uint16_t)v1; + textureCoords[0] = u1; + textureCoords[1] = v1; } vertex += vertexStride; @@ -132,8 +117,8 @@ inline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexS if (regenTexCoords) { uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); - textureCoords[0] = (uint16_t)u1; - textureCoords[1] = (uint16_t)v0; + textureCoords[0] = u1; + textureCoords[1] = v0; } } @@ -170,7 +155,6 @@ void GrAtlasTextBlob::regenInOp(GrDrawOp::Target* target, GrAtlasGlyphCache* fon 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(); @@ -197,8 +181,6 @@ void GrAtlasTextBlob::regenInOp(GrDrawOp::Target* target, GrAtlasGlyphCache* fon } fontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph, target->nextDrawToken()); - log2Width = fontCache->log2Width(info->maskFormat()); - log2Height = fontCache->log2Height(info->maskFormat()); } intptr_t vertex = reinterpret_cast<intptr_t>(fVertices); @@ -206,7 +188,7 @@ void GrAtlasTextBlob::regenInOp(GrDrawOp::Target* target, GrAtlasGlyphCache* fon vertex += vertexStride * glyphIdx * GrAtlasTextOp::kVerticesPerGlyph; regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertexStride, info->drawAsDistanceFields(), transX, - transY, log2Width, log2Height, color); + transY, color); helper->incGlyphCount(); } diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp index 1a616054ba..22777df94a 100644 --- a/src/gpu/vk/GrVkPipeline.cpp +++ b/src/gpu/vk/GrVkPipeline.cpp @@ -34,8 +34,10 @@ static inline VkFormat attrib_type_to_vkformat(GrVertexAttribType type) { return VK_FORMAT_R8_UNORM; case kVec4ub_GrVertexAttribType: return VK_FORMAT_R8G8B8A8_UNORM; - case kVec2us_GrVertexAttribType: + case kVec2us_norm_GrVertexAttribType: return VK_FORMAT_R16G16_UNORM; + case kVec2us_uint_GrVertexAttribType: + return VK_FORMAT_R16G16_UINT; case kInt_GrVertexAttribType: return VK_FORMAT_R32_SINT; case kUint_GrVertexAttribType: diff --git a/src/gpu/vk/GrVkUniformHandler.cpp b/src/gpu/vk/GrVkUniformHandler.cpp index be746cd653..98a27518a3 100644 --- a/src/gpu/vk/GrVkUniformHandler.cpp +++ b/src/gpu/vk/GrVkUniformHandler.cpp @@ -28,6 +28,8 @@ uint32_t grsltype_to_alignment_mask(GrSLType type) { return 0xF; case kVec4f_GrSLType: return 0xF; + case kVec2us_GrSLType: + return 0x3; case kVec2i_GrSLType: return 0x7; case kVec3i_GrSLType: @@ -76,6 +78,8 @@ static inline uint32_t grsltype_to_vk_size(GrSLType type) { return 3 * sizeof(float); case kVec4f_GrSLType: return 4 * sizeof(float); + case kVec2us_GrSLType: + return 2 * sizeof(uint16_t); case kVec2i_GrSLType: return 2 * sizeof(int32_t); case kVec3i_GrSLType: diff --git a/src/gpu/vk/GrVkVaryingHandler.cpp b/src/gpu/vk/GrVkVaryingHandler.cpp index 8e43b76341..59120980c1 100644 --- a/src/gpu/vk/GrVkVaryingHandler.cpp +++ b/src/gpu/vk/GrVkVaryingHandler.cpp @@ -21,6 +21,8 @@ static inline int grsltype_to_location_size(GrSLType type) { return 1; case kVec4f_GrSLType: return 1; + case kVec2us_GrSLType: + return 1; case kVec2i_GrSLType: return 1; case kVec3i_GrSLType: |