| Index: src/gpu/effects/GrDistanceFieldTextureEffect.cpp
|
| diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
|
| deleted file mode 100755
|
| index ad3be5fc045b0be9cd4cc3830d177ff664f781f4..0000000000000000000000000000000000000000
|
| --- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
|
| +++ /dev/null
|
| @@ -1,862 +0,0 @@
|
| -/*
|
| - * Copyright 2013 Google Inc.
|
| - *
|
| - * Use of this source code is governed by a BSD-style license that can be
|
| - * found in the LICENSE file.
|
| - */
|
| -
|
| -#include "GrDistanceFieldTextureEffect.h"
|
| -#include "GrFontAtlasSizes.h"
|
| -#include "GrInvariantOutput.h"
|
| -#include "GrTexture.h"
|
| -
|
| -#include "SkDistanceFieldGen.h"
|
| -
|
| -#include "gl/GrGLProcessor.h"
|
| -#include "gl/GrGLSL.h"
|
| -#include "gl/GrGLTexture.h"
|
| -#include "gl/GrGLGeometryProcessor.h"
|
| -#include "gl/builders/GrGLProgramBuilder.h"
|
| -
|
| -// Assuming a radius of a little less than the diagonal of the fragment
|
| -#define SK_DistanceFieldAAFactor "0.65"
|
| -
|
| -struct DistanceFieldBatchTracker {
|
| - GrGPInput fInputColorType;
|
| - GrColor fColor;
|
| - bool fUsesLocalCoords;
|
| -};
|
| -
|
| -class GrGLDistanceFieldA8TextGeoProc : public GrGLGeometryProcessor {
|
| -public:
|
| - GrGLDistanceFieldA8TextGeoProc(const GrGeometryProcessor&,
|
| - const GrBatchTracker&)
|
| - : fColor(GrColor_ILLEGAL)
|
| -#ifdef SK_GAMMA_APPLY_TO_A8
|
| - , fDistanceAdjust(-1.0f)
|
| -#endif
|
| - {}
|
| -
|
| - void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
|
| - const GrDistanceFieldA8TextGeoProc& dfTexEffect =
|
| - args.fGP.cast<GrDistanceFieldA8TextGeoProc>();
|
| - const DistanceFieldBatchTracker& local = args.fBT.cast<DistanceFieldBatchTracker>();
|
| - GrGLGPBuilder* pb = args.fPB;
|
| - GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
| - SkAssertResult(fsBuilder->enableFeature(
|
| - GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
| -
|
| - GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
| -
|
| - // emit attributes
|
| - vsBuilder->emitAttributes(dfTexEffect);
|
| -
|
| -#ifdef SK_GAMMA_APPLY_TO_A8
|
| - // adjust based on gamma
|
| - const char* distanceAdjustUniName = NULL;
|
| - // width, height, 1/(3*width)
|
| - fDistanceAdjustUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
| - kFloat_GrSLType, kDefault_GrSLPrecision,
|
| - "DistanceAdjust", &distanceAdjustUniName);
|
| -#endif
|
| -
|
| - // Setup pass through color
|
| - this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor,
|
| - dfTexEffect.inColor(), &fColorUniform);
|
| -
|
| - // Setup position
|
| - this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
|
| -
|
| - // emit transforms
|
| - const SkMatrix& localMatrix = dfTexEffect.localMatrix();
|
| - this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
|
| - localMatrix, args.fTransformsIn, args.fTransformsOut);
|
| -
|
| - // add varyings
|
| - GrGLVertToFrag recipScale(kFloat_GrSLType);
|
| - GrGLVertToFrag st(kVec2f_GrSLType);
|
| - bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
|
| - const char* viewMatrixName = this->uViewM();
|
| - // view matrix name is NULL if identity matrix
|
| - bool useInverseScale = !localMatrix.isIdentity() && viewMatrixName;
|
| - if (isSimilarity && useInverseScale) {
|
| - args.fPB->addVarying("RecipScale", &recipScale, kHigh_GrSLPrecision);
|
| - vsBuilder->codeAppendf("vec2 tx = vec2(%s[0][0], %s[1][0]);",
|
| - viewMatrixName, viewMatrixName);
|
| - vsBuilder->codeAppend("float tx2 = dot(tx, tx);");
|
| - vsBuilder->codeAppendf("%s = inversesqrt(tx2);", recipScale.vsOut());
|
| - } else {
|
| - args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
|
| - vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
| - }
|
| -
|
| - 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_A8_RECIP_WIDTH ", "
|
| - GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
|
| - dfTexEffect.inTextureCoords()->fName);
|
| -
|
| - // Use highp to work around aliasing issues
|
| - fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
|
| - pb->ctxInfo().standard()));
|
| - fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
|
| -
|
| - fsBuilder->codeAppend("\tfloat texColor = ");
|
| - fsBuilder->appendTextureLookup(args.fSamplers[0],
|
| - "uv",
|
| - kVec2f_GrSLType);
|
| - fsBuilder->codeAppend(".r;\n");
|
| - fsBuilder->codeAppend("\tfloat distance = "
|
| - SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
|
| -#ifdef SK_GAMMA_APPLY_TO_A8
|
| - // adjust width based on gamma
|
| - fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
|
| -#endif
|
| -
|
| - fsBuilder->codeAppend("float afwidth;");
|
| - if (isSimilarity) {
|
| - // For uniform scale, we adjust for the effect of the transformation on the distance
|
| - // either by using the inverse scale in the view matrix, or (if there is no view matrix)
|
| - // by using the length of the gradient of the texture coordinates. We use st coordinates
|
| - // with the latter to ensure we're mapping 1:1 from texel space to pixel space.
|
| -
|
| - // this gives us a smooth step across approximately one fragment
|
| - if (useInverseScale) {
|
| - fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*%s);",
|
| - recipScale.fsIn());
|
| - } else {
|
| - fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(%s.x));",
|
| - st.fsIn());
|
| - }
|
| - } else {
|
| - // For general transforms, to determine the amount of correction we multiply a unit
|
| - // vector pointing along the SDF gradient direction by the Jacobian of the st coords
|
| - // (which is the inverse transform for this fragment) and take the length of the result.
|
| - fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
|
| - // the length of the gradient may be 0, so we need to check for this
|
| - // this also compensates for the Adreno, which likes to drop tiles on division by 0
|
| - fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
| - fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
| - fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
| - fsBuilder->codeAppend("} else {");
|
| - fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
| - fsBuilder->codeAppend("}");
|
| -
|
| - fsBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn());
|
| - fsBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn());
|
| - fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
| - fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
| -
|
| - // this gives us a smooth step across approximately one fragment
|
| - fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
| - }
|
| - fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
|
| -
|
| - fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
| - }
|
| -
|
| - virtual void setData(const GrGLProgramDataManager& pdman,
|
| - const GrPrimitiveProcessor& proc,
|
| - const GrBatchTracker& bt) override {
|
| -#ifdef SK_GAMMA_APPLY_TO_A8
|
| - const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFieldA8TextGeoProc>();
|
| - float distanceAdjust = dfTexEffect.getDistanceAdjust();
|
| - if (distanceAdjust != fDistanceAdjust) {
|
| - pdman.set1f(fDistanceAdjustUni, distanceAdjust);
|
| - fDistanceAdjust = distanceAdjust;
|
| - }
|
| -#endif
|
| -
|
| - this->setUniformViewMatrix(pdman, proc.viewMatrix());
|
| -
|
| - const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
|
| - if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
|
| - GrGLfloat c[4];
|
| - GrColorToRGBAFloat(local.fColor, c);
|
| - pdman.set4fv(fColorUniform, 1, c);
|
| - fColor = local.fColor;
|
| - }
|
| - }
|
| -
|
| - static inline void GenKey(const GrGeometryProcessor& gp,
|
| - const GrBatchTracker& bt,
|
| - const GrGLCaps&,
|
| - GrProcessorKeyBuilder* b) {
|
| - const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldA8TextGeoProc>();
|
| - const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTracker>();
|
| - uint32_t key = dfTexEffect.getFlags();
|
| - key |= local.fInputColorType << 16;
|
| - key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
|
| - key |= ComputePosKey(gp.viewMatrix()) << 25;
|
| - key |= (!gp.viewMatrix().isIdentity() && !gp.localMatrix().isIdentity()) ? 0x1 << 27 : 0x0;
|
| - b->add32(key);
|
| - }
|
| -
|
| -private:
|
| - GrColor fColor;
|
| - UniformHandle fColorUniform;
|
| -#ifdef SK_GAMMA_APPLY_TO_A8
|
| - float fDistanceAdjust;
|
| - UniformHandle fDistanceAdjustUni;
|
| -#endif
|
| -
|
| - typedef GrGLGeometryProcessor INHERITED;
|
| -};
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color,
|
| - const SkMatrix& viewMatrix,
|
| - const SkMatrix& localMatrix,
|
| - GrTexture* texture,
|
| - const GrTextureParams& params,
|
| -#ifdef SK_GAMMA_APPLY_TO_A8
|
| - float distanceAdjust,
|
| -#endif
|
| - uint32_t flags, bool opaqueVertexColors)
|
| - : INHERITED(color, viewMatrix, localMatrix, opaqueVertexColors)
|
| - , fTextureAccess(texture, params)
|
| -#ifdef SK_GAMMA_APPLY_TO_A8
|
| - , fDistanceAdjust(distanceAdjust)
|
| -#endif
|
| - , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
|
| - , fInColor(NULL) {
|
| - SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
|
| - this->initClassID<GrDistanceFieldA8TextGeoProc>();
|
| - fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
|
| - if (flags & kColorAttr_DistanceFieldEffectFlag) {
|
| - fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
|
| - this->setHasVertexColor();
|
| - }
|
| - fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
|
| - kVec2s_GrVertexAttribType));
|
| - this->addTextureAccess(&fTextureAccess);
|
| -}
|
| -
|
| -bool GrDistanceFieldA8TextGeoProc::onIsEqual(const GrGeometryProcessor& other) const {
|
| - const GrDistanceFieldA8TextGeoProc& cte = other.cast<GrDistanceFieldA8TextGeoProc>();
|
| - return
|
| -#ifdef SK_GAMMA_APPLY_TO_A8
|
| - fDistanceAdjust == cte.fDistanceAdjust &&
|
| -#endif
|
| - fFlags == cte.fFlags;
|
| -}
|
| -
|
| -void GrDistanceFieldA8TextGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
|
| - out->setUnknownSingleComponent();
|
| -}
|
| -
|
| -void GrDistanceFieldA8TextGeoProc::getGLProcessorKey(const GrBatchTracker& bt,
|
| - const GrGLCaps& caps,
|
| - GrProcessorKeyBuilder* b) const {
|
| - GrGLDistanceFieldA8TextGeoProc::GenKey(*this, bt, caps, b);
|
| -}
|
| -
|
| -GrGLPrimitiveProcessor*
|
| -GrDistanceFieldA8TextGeoProc::createGLInstance(const GrBatchTracker& bt,
|
| - const GrGLCaps&) const {
|
| - return SkNEW_ARGS(GrGLDistanceFieldA8TextGeoProc, (*this, bt));
|
| -}
|
| -
|
| -void GrDistanceFieldA8TextGeoProc::initBatchTracker(GrBatchTracker* bt,
|
| - const GrPipelineInfo& init) const {
|
| - DistanceFieldBatchTracker* local = bt->cast<DistanceFieldBatchTracker>();
|
| - local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
|
| - SkToBool(fInColor));
|
| - local->fUsesLocalCoords = init.fUsesLocalCoords;
|
| -}
|
| -
|
| -bool GrDistanceFieldA8TextGeoProc::onCanMakeEqual(const GrBatchTracker& m,
|
| - const GrGeometryProcessor& that,
|
| - const GrBatchTracker& t) const {
|
| - const DistanceFieldBatchTracker& mine = m.cast<DistanceFieldBatchTracker>();
|
| - const DistanceFieldBatchTracker& theirs = t.cast<DistanceFieldBatchTracker>();
|
| - return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
|
| - that, theirs.fUsesLocalCoords) &&
|
| - CanCombineOutput(mine.fInputColorType, mine.fColor,
|
| - theirs.fInputColorType, theirs.fColor);
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldA8TextGeoProc);
|
| -
|
| -GrGeometryProcessor* GrDistanceFieldA8TextGeoProc::TestCreate(SkRandom* random,
|
| - GrContext*,
|
| - const GrDrawTargetCaps&,
|
| - GrTexture* textures[]) {
|
| - int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
|
| - GrProcessorUnitTest::kAlphaTextureIdx;
|
| - static const SkShader::TileMode kTileModes[] = {
|
| - SkShader::kClamp_TileMode,
|
| - SkShader::kRepeat_TileMode,
|
| - SkShader::kMirror_TileMode,
|
| - };
|
| - SkShader::TileMode tileModes[] = {
|
| - kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
| - kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
| - };
|
| - GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
|
| - GrTextureParams::kNone_FilterMode);
|
| -
|
| - return GrDistanceFieldA8TextGeoProc::Create(GrRandomColor(random),
|
| - GrProcessorUnitTest::TestMatrix(random),
|
| - GrProcessorUnitTest::TestMatrix(random),
|
| - textures[texIdx], params,
|
| -#ifdef SK_GAMMA_APPLY_TO_A8
|
| - random->nextF(),
|
| -#endif
|
| - random->nextBool() ?
|
| - kSimilarity_DistanceFieldEffectFlag : 0,
|
| - random->nextBool());
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -struct DistanceFieldPathBatchTracker {
|
| - GrGPInput fInputColorType;
|
| - GrColor fColor;
|
| - bool fUsesLocalCoords;
|
| -};
|
| -
|
| -class GrGLDistanceFieldPathGeoProc : public GrGLGeometryProcessor {
|
| -public:
|
| - GrGLDistanceFieldPathGeoProc(const GrGeometryProcessor&,
|
| - const GrBatchTracker&)
|
| - : fColor(GrColor_ILLEGAL), fTextureSize(SkISize::Make(-1, -1)) {}
|
| -
|
| - void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
|
| - const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>();
|
| -
|
| - const DistanceFieldPathBatchTracker& local = args.fBT.cast<DistanceFieldPathBatchTracker>();
|
| - GrGLGPBuilder* pb = args.fPB;
|
| - GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
| - SkAssertResult(fsBuilder->enableFeature(
|
| - GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
| -
|
| - GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
| -
|
| - // emit attributes
|
| - vsBuilder->emitAttributes(dfTexEffect);
|
| -
|
| - GrGLVertToFrag v(kVec2f_GrSLType);
|
| - args.fPB->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
|
| -
|
| - // setup pass through color
|
| - this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor,
|
| - dfTexEffect.inColor(), &fColorUniform);
|
| -
|
| - vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
| -
|
| - // Setup position
|
| - this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
|
| -
|
| - // emit transforms
|
| - this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
|
| - dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut);
|
| -
|
| - const char* textureSizeUniName = NULL;
|
| - fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
| - kVec2f_GrSLType, kDefault_GrSLPrecision,
|
| - "TextureSize", &textureSizeUniName);
|
| -
|
| - // Use highp to work around aliasing issues
|
| - fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
|
| - pb->ctxInfo().standard()));
|
| - fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
|
| -
|
| - fsBuilder->codeAppend("float texColor = ");
|
| - fsBuilder->appendTextureLookup(args.fSamplers[0],
|
| - "uv",
|
| - kVec2f_GrSLType);
|
| - fsBuilder->codeAppend(".r;");
|
| - fsBuilder->codeAppend("float distance = "
|
| - SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
|
| -
|
| - fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
|
| - pb->ctxInfo().standard()));
|
| - fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
|
| - fsBuilder->codeAppend("float afwidth;");
|
| - if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
|
| - // For uniform scale, we adjust for the effect of the transformation on the distance
|
| - // by using the length of the gradient of the texture coordinates. We use st coordinates
|
| - // to ensure we're mapping 1:1 from texel space to pixel space.
|
| -
|
| - // this gives us a smooth step across approximately one fragment
|
| - fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));");
|
| - } else {
|
| - // For general transforms, to determine the amount of correction we multiply a unit
|
| - // vector pointing along the SDF gradient direction by the Jacobian of the st coords
|
| - // (which is the inverse transform for this fragment) and take the length of the result.
|
| - fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
|
| - // the length of the gradient may be 0, so we need to check for this
|
| - // this also compensates for the Adreno, which likes to drop tiles on division by 0
|
| - fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
| - fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
| - fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
| - fsBuilder->codeAppend("} else {");
|
| - fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
| - fsBuilder->codeAppend("}");
|
| -
|
| - fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
|
| - fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
|
| - fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
| - fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
| -
|
| - // this gives us a smooth step across approximately one fragment
|
| - fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
| - }
|
| - fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
|
| -
|
| - fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
| - }
|
| -
|
| - virtual void setData(const GrGLProgramDataManager& pdman,
|
| - const GrPrimitiveProcessor& proc,
|
| - const GrBatchTracker& bt) override {
|
| - SkASSERT(fTextureSizeUni.isValid());
|
| -
|
| - GrTexture* texture = proc.texture(0);
|
| - 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()));
|
| - }
|
| -
|
| - this->setUniformViewMatrix(pdman, proc.viewMatrix());
|
| -
|
| - const DistanceFieldPathBatchTracker& local = bt.cast<DistanceFieldPathBatchTracker>();
|
| - if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
|
| - GrGLfloat c[4];
|
| - GrColorToRGBAFloat(local.fColor, c);
|
| - pdman.set4fv(fColorUniform, 1, c);
|
| - fColor = local.fColor;
|
| - }
|
| - }
|
| -
|
| - static inline void GenKey(const GrGeometryProcessor& gp,
|
| - const GrBatchTracker& bt,
|
| - const GrGLCaps&,
|
| - GrProcessorKeyBuilder* b) {
|
| - const GrDistanceFieldPathGeoProc& dfTexEffect = gp.cast<GrDistanceFieldPathGeoProc>();
|
| -
|
| - const DistanceFieldPathBatchTracker& local = bt.cast<DistanceFieldPathBatchTracker>();
|
| - uint32_t key = dfTexEffect.getFlags();
|
| - key |= local.fInputColorType << 16;
|
| - key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
|
| - key |= ComputePosKey(gp.viewMatrix()) << 25;
|
| - b->add32(key);
|
| - }
|
| -
|
| -private:
|
| - UniformHandle fColorUniform;
|
| - UniformHandle fTextureSizeUni;
|
| - GrColor fColor;
|
| - SkISize fTextureSize;
|
| -
|
| - typedef GrGLGeometryProcessor INHERITED;
|
| -};
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(
|
| - GrColor color,
|
| - const SkMatrix& viewMatrix,
|
| - GrTexture* texture,
|
| - const GrTextureParams& params,
|
| - uint32_t flags,
|
| - bool opaqueVertexColors)
|
| - : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
|
| - , fTextureAccess(texture, params)
|
| - , fFlags(flags & kNonLCD_DistanceFieldEffectMask)
|
| - , fInColor(NULL) {
|
| - SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
|
| - this->initClassID<GrDistanceFieldPathGeoProc>();
|
| - fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
|
| - if (flags & kColorAttr_DistanceFieldEffectFlag) {
|
| - fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType));
|
| - this->setHasVertexColor();
|
| - }
|
| - fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
|
| - kVec2f_GrVertexAttribType));
|
| - this->addTextureAccess(&fTextureAccess);
|
| -}
|
| -
|
| -bool GrDistanceFieldPathGeoProc::onIsEqual(const GrGeometryProcessor& other) const {
|
| - const GrDistanceFieldPathGeoProc& cte = other.cast<GrDistanceFieldPathGeoProc>();
|
| - return fFlags == cte.fFlags;
|
| -}
|
| -
|
| -void GrDistanceFieldPathGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
|
| - out->setUnknownSingleComponent();
|
| -}
|
| -
|
| -void GrDistanceFieldPathGeoProc::getGLProcessorKey(const GrBatchTracker& bt,
|
| - const GrGLCaps& caps,
|
| - GrProcessorKeyBuilder* b) const {
|
| - GrGLDistanceFieldPathGeoProc::GenKey(*this, bt, caps, b);
|
| -}
|
| -
|
| -GrGLPrimitiveProcessor*
|
| -GrDistanceFieldPathGeoProc::createGLInstance(const GrBatchTracker& bt, const GrGLCaps&) const {
|
| - return SkNEW_ARGS(GrGLDistanceFieldPathGeoProc, (*this, bt));
|
| -}
|
| -
|
| -void GrDistanceFieldPathGeoProc::initBatchTracker(GrBatchTracker* bt,
|
| - const GrPipelineInfo& init) const {
|
| - DistanceFieldPathBatchTracker* local = bt->cast<DistanceFieldPathBatchTracker>();
|
| - local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
|
| - SkToBool(fInColor));
|
| - local->fUsesLocalCoords = init.fUsesLocalCoords;
|
| -}
|
| -
|
| -bool GrDistanceFieldPathGeoProc::onCanMakeEqual(const GrBatchTracker& m,
|
| - const GrGeometryProcessor& that,
|
| - const GrBatchTracker& t) const {
|
| - const DistanceFieldPathBatchTracker& mine = m.cast<DistanceFieldPathBatchTracker>();
|
| - const DistanceFieldPathBatchTracker& theirs = t.cast<DistanceFieldPathBatchTracker>();
|
| - return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
|
| - that, theirs.fUsesLocalCoords) &&
|
| - CanCombineOutput(mine.fInputColorType, mine.fColor,
|
| - theirs.fInputColorType, theirs.fColor);
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldPathGeoProc);
|
| -
|
| -GrGeometryProcessor* GrDistanceFieldPathGeoProc::TestCreate(SkRandom* random,
|
| - GrContext*,
|
| - const GrDrawTargetCaps&,
|
| - GrTexture* textures[]) {
|
| - int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
|
| - : GrProcessorUnitTest::kAlphaTextureIdx;
|
| - static const SkShader::TileMode kTileModes[] = {
|
| - SkShader::kClamp_TileMode,
|
| - SkShader::kRepeat_TileMode,
|
| - SkShader::kMirror_TileMode,
|
| - };
|
| - SkShader::TileMode tileModes[] = {
|
| - kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
| - kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
| - };
|
| - GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode
|
| - : GrTextureParams::kNone_FilterMode);
|
| -
|
| - return GrDistanceFieldPathGeoProc::Create(GrRandomColor(random),
|
| - GrProcessorUnitTest::TestMatrix(random),
|
| - textures[texIdx],
|
| - params,
|
| - random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0, random->nextBool());
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -struct DistanceFieldLCDBatchTracker {
|
| - GrGPInput fInputColorType;
|
| - GrColor fColor;
|
| - bool fUsesLocalCoords;
|
| -};
|
| -
|
| -class GrGLDistanceFieldLCDTextGeoProc : public GrGLGeometryProcessor {
|
| -public:
|
| - GrGLDistanceFieldLCDTextGeoProc(const GrGeometryProcessor&, const GrBatchTracker&)
|
| - : fColor(GrColor_ILLEGAL) {
|
| - fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.0f, 1.0f, 1.0f);
|
| - }
|
| -
|
| - void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
|
| - const GrDistanceFieldLCDTextGeoProc& dfTexEffect =
|
| - args.fGP.cast<GrDistanceFieldLCDTextGeoProc>();
|
| - const DistanceFieldLCDBatchTracker& local = args.fBT.cast<DistanceFieldLCDBatchTracker>();
|
| - GrGLGPBuilder* pb = args.fPB;
|
| -
|
| - GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
| -
|
| - // emit attributes
|
| - vsBuilder->emitAttributes(dfTexEffect);
|
| -
|
| - // setup pass through color
|
| - this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL,
|
| - &fColorUniform);
|
| -
|
| - // Setup position
|
| - this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix());
|
| -
|
| - // emit transforms
|
| - const SkMatrix& localMatrix = dfTexEffect.localMatrix();
|
| - this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
|
| - localMatrix, args.fTransformsIn, args.fTransformsOut);
|
| -
|
| - // set up varyings
|
| - bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
|
| - GrGLVertToFrag recipScale(kFloat_GrSLType);
|
| - GrGLVertToFrag st(kVec2f_GrSLType);
|
| - const char* viewMatrixName = this->uViewM();
|
| - // view matrix name is NULL if identity matrix
|
| - bool useInverseScale = !localMatrix.isIdentity() && viewMatrixName;
|
| - if (isUniformScale && useInverseScale) {
|
| - args.fPB->addVarying("RecipScale", &recipScale, kHigh_GrSLPrecision);
|
| - vsBuilder->codeAppendf("vec2 tx = vec2(%s[0][0], %s[1][0]);",
|
| - viewMatrixName, viewMatrixName);
|
| - vsBuilder->codeAppend("float tx2 = dot(tx, tx);");
|
| - vsBuilder->codeAppendf("%s = inversesqrt(tx2);", recipScale.vsOut());
|
| - } else {
|
| - args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
|
| - vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
| - }
|
| -
|
| - 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_A8_RECIP_WIDTH ", "
|
| - GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
|
| - dfTexEffect.inTextureCoords()->fName);
|
| -
|
| - // add frag shader code
|
| - GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
| -
|
| - SkAssertResult(fsBuilder->enableFeature(
|
| - GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
| -
|
| - // create LCD offset adjusted by inverse of transform
|
| - // Use highp to work around aliasing issues
|
| - fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
|
| - pb->ctxInfo().standard()));
|
| - fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
|
| - fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
|
| - pb->ctxInfo().standard()));
|
| - if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
|
| - fsBuilder->codeAppend("float delta = -" GR_FONT_ATLAS_LCD_DELTA ";\n");
|
| - } else {
|
| - fsBuilder->codeAppend("float delta = " GR_FONT_ATLAS_LCD_DELTA ";\n");
|
| - }
|
| - if (isUniformScale) {
|
| - if (useInverseScale) {
|
| - fsBuilder->codeAppendf("float dx = %s;", recipScale.fsIn());
|
| - } else {
|
| - fsBuilder->codeAppendf("float dx = dFdx(%s.x);", st.fsIn());
|
| - }
|
| - fsBuilder->codeAppend("vec2 offset = vec2(dx*delta, 0.0);");
|
| - } else {
|
| - fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
|
| -
|
| - fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
|
| - fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
|
| - fsBuilder->codeAppend("vec2 offset = delta*Jdx;");
|
| - }
|
| -
|
| - // green is distance to uv center
|
| - fsBuilder->codeAppend("\tvec4 texColor = ");
|
| - fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType);
|
| - fsBuilder->codeAppend(";\n");
|
| - fsBuilder->codeAppend("\tvec3 distance;\n");
|
| - fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
|
| - // red is distance to left offset
|
| - fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
|
| - fsBuilder->codeAppend("\ttexColor = ");
|
| - fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
|
| - fsBuilder->codeAppend(";\n");
|
| - fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
|
| - // blue is distance to right offset
|
| - fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
|
| - fsBuilder->codeAppend("\ttexColor = ");
|
| - fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
|
| - fsBuilder->codeAppend(";\n");
|
| - fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
|
| -
|
| - fsBuilder->codeAppend("\tdistance = "
|
| - "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));");
|
| -
|
| - // adjust width based on gamma
|
| - const char* distanceAdjustUniName = NULL;
|
| - fDistanceAdjustUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
| - kVec3f_GrSLType, kDefault_GrSLPrecision,
|
| - "DistanceAdjust", &distanceAdjustUniName);
|
| - fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
|
| -
|
| - // To be strictly correct, we should compute the anti-aliasing factor separately
|
| - // for each color component. However, this is only important when using perspective
|
| - // transformations, and even then using a single factor seems like a reasonable
|
| - // trade-off between quality and speed.
|
| - fsBuilder->codeAppend("float afwidth;");
|
| - if (isUniformScale) {
|
| - // For uniform scale, we adjust for the effect of the transformation on the distance
|
| - // by using the length of the gradient of the texture coordinates. We use st coordinates
|
| - // to ensure we're mapping 1:1 from texel space to pixel space.
|
| -
|
| - // this gives us a smooth step across approximately one fragment
|
| - fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dx);");
|
| - } else {
|
| - // For general transforms, to determine the amount of correction we multiply a unit
|
| - // vector pointing along the SDF gradient direction by the Jacobian of the st coords
|
| - // (which is the inverse transform for this fragment) and take the length of the result.
|
| - fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(distance.r));");
|
| - // the length of the gradient may be 0, so we need to check for this
|
| - // this also compensates for the Adreno, which likes to drop tiles on division by 0
|
| - fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
| - fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
| - fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
| - fsBuilder->codeAppend("} else {");
|
| - fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
| - fsBuilder->codeAppend("}");
|
| - fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
| - fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
| -
|
| - // this gives us a smooth step across approximately one fragment
|
| - fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
| - }
|
| -
|
| - fsBuilder->codeAppend(
|
| - "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);");
|
| -
|
| - fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
| - }
|
| -
|
| - virtual void setData(const GrGLProgramDataManager& pdman,
|
| - const GrPrimitiveProcessor& processor,
|
| - const GrBatchTracker& bt) override {
|
| - SkASSERT(fDistanceAdjustUni.isValid());
|
| -
|
| - const GrDistanceFieldLCDTextGeoProc& dfTexEffect =
|
| - processor.cast<GrDistanceFieldLCDTextGeoProc>();
|
| - GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dfTexEffect.getDistanceAdjust();
|
| - if (wa != fDistanceAdjust) {
|
| - pdman.set3f(fDistanceAdjustUni,
|
| - wa.fR,
|
| - wa.fG,
|
| - wa.fB);
|
| - fDistanceAdjust = wa;
|
| - }
|
| -
|
| - this->setUniformViewMatrix(pdman, processor.viewMatrix());
|
| -
|
| - const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
|
| - if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
|
| - GrGLfloat c[4];
|
| - GrColorToRGBAFloat(local.fColor, c);
|
| - pdman.set4fv(fColorUniform, 1, c);
|
| - fColor = local.fColor;
|
| - }
|
| - }
|
| -
|
| - static inline void GenKey(const GrGeometryProcessor& gp,
|
| - const GrBatchTracker& bt,
|
| - const GrGLCaps&,
|
| - GrProcessorKeyBuilder* b) {
|
| - const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast<GrDistanceFieldLCDTextGeoProc>();
|
| -
|
| - const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatchTracker>();
|
| - uint32_t key = dfTexEffect.getFlags();
|
| - key |= local.fInputColorType << 16;
|
| - key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1 << 24: 0x0;
|
| - key |= ComputePosKey(gp.viewMatrix()) << 25;
|
| - key |= (!gp.viewMatrix().isIdentity() && !gp.localMatrix().isIdentity()) ? 0x1 << 27 : 0x0;
|
| - b->add32(key);
|
| - }
|
| -
|
| -private:
|
| - GrColor fColor;
|
| - UniformHandle fColorUniform;
|
| - GrDistanceFieldLCDTextGeoProc::DistanceAdjust fDistanceAdjust;
|
| - UniformHandle fDistanceAdjustUni;
|
| -
|
| - typedef GrGLGeometryProcessor INHERITED;
|
| -};
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc(
|
| - GrColor color, const SkMatrix& viewMatrix,
|
| - const SkMatrix& localMatrix,
|
| - GrTexture* texture, const GrTextureParams& params,
|
| - DistanceAdjust distanceAdjust,
|
| - uint32_t flags)
|
| - : INHERITED(color, viewMatrix, localMatrix)
|
| - , fTextureAccess(texture, params)
|
| - , fDistanceAdjust(distanceAdjust)
|
| - , fFlags(flags & kLCD_DistanceFieldEffectMask){
|
| - SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag));
|
| - this->initClassID<GrDistanceFieldLCDTextGeoProc>();
|
| - fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType));
|
| - fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
|
| - kVec2s_GrVertexAttribType));
|
| - this->addTextureAccess(&fTextureAccess);
|
| -}
|
| -
|
| -bool GrDistanceFieldLCDTextGeoProc::onIsEqual(const GrGeometryProcessor& other) const {
|
| - const GrDistanceFieldLCDTextGeoProc& cte = other.cast<GrDistanceFieldLCDTextGeoProc>();
|
| - return (fDistanceAdjust == cte.fDistanceAdjust &&
|
| - fFlags == cte.fFlags);
|
| -}
|
| -
|
| -void GrDistanceFieldLCDTextGeoProc::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
|
| - out->setUnknownFourComponents();
|
| - out->setUsingLCDCoverage();
|
| -}
|
| -
|
| -void GrDistanceFieldLCDTextGeoProc::getGLProcessorKey(const GrBatchTracker& bt,
|
| - const GrGLCaps& caps,
|
| - GrProcessorKeyBuilder* b) const {
|
| - GrGLDistanceFieldLCDTextGeoProc::GenKey(*this, bt, caps, b);
|
| -}
|
| -
|
| -GrGLPrimitiveProcessor*
|
| -GrDistanceFieldLCDTextGeoProc::createGLInstance(const GrBatchTracker& bt,
|
| - const GrGLCaps&) const {
|
| - return SkNEW_ARGS(GrGLDistanceFieldLCDTextGeoProc, (*this, bt));
|
| -}
|
| -
|
| -void GrDistanceFieldLCDTextGeoProc::initBatchTracker(GrBatchTracker* bt,
|
| - const GrPipelineInfo& init) const {
|
| - DistanceFieldLCDBatchTracker* local = bt->cast<DistanceFieldLCDBatchTracker>();
|
| - local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
|
| - local->fUsesLocalCoords = init.fUsesLocalCoords;
|
| -}
|
| -
|
| -bool GrDistanceFieldLCDTextGeoProc::onCanMakeEqual(const GrBatchTracker& m,
|
| - const GrGeometryProcessor& that,
|
| - const GrBatchTracker& t) const {
|
| - const DistanceFieldLCDBatchTracker& mine = m.cast<DistanceFieldLCDBatchTracker>();
|
| - const DistanceFieldLCDBatchTracker& theirs = t.cast<DistanceFieldLCDBatchTracker>();
|
| - return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
|
| - that, theirs.fUsesLocalCoords) &&
|
| - CanCombineOutput(mine.fInputColorType, mine.fColor,
|
| - theirs.fInputColorType, theirs.fColor);
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldLCDTextGeoProc);
|
| -
|
| -GrGeometryProcessor* GrDistanceFieldLCDTextGeoProc::TestCreate(SkRandom* random,
|
| - GrContext*,
|
| - const GrDrawTargetCaps&,
|
| - GrTexture* textures[]) {
|
| - int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
|
| - GrProcessorUnitTest::kAlphaTextureIdx;
|
| - static const SkShader::TileMode kTileModes[] = {
|
| - SkShader::kClamp_TileMode,
|
| - SkShader::kRepeat_TileMode,
|
| - SkShader::kMirror_TileMode,
|
| - };
|
| - SkShader::TileMode tileModes[] = {
|
| - kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
| - kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
| - };
|
| - GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
|
| - GrTextureParams::kNone_FilterMode);
|
| - DistanceAdjust wa = { 0.0f, 0.1f, -0.1f };
|
| - uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
|
| - flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
|
| - flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
|
| - return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(random),
|
| - GrProcessorUnitTest::TestMatrix(random),
|
| - GrProcessorUnitTest::TestMatrix(random),
|
| - textures[texIdx], params,
|
| - wa,
|
| - flags);
|
| -}
|
|
|