aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp155
-rw-r--r--src/gpu/GrDistanceFieldTextContext.h3
-rwxr-xr-xsrc/gpu/effects/GrDistanceFieldTextureEffect.cpp160
-rw-r--r--src/gpu/effects/GrDistanceFieldTextureEffect.h49
4 files changed, 197 insertions, 170 deletions
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index 12aa1bf0a9..90d6d7619a 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -43,6 +43,11 @@ static const int kLargeDFFontSize = 162;
static const int kVerticesPerGlyph = 4;
static const int kIndicesPerGlyph = 6;
+#ifdef SK_DEBUG
+static const int kExpectedDistanceAdjustTableSize = 8;
+#endif
+static const int kDistanceAdjustLumShift = 5;
+
GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
SkGpuDevice* gpuDevice,
const SkDeviceProperties& properties,
@@ -54,7 +59,7 @@ GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
fEnableDFRendering = enable;
#endif
fStrike = NULL;
- fGammaTexture = NULL;
+ fDistanceAdjustTable = NULL;
fEffectTextureUniqueID = SK_InvalidUniqueID;
fEffectColor = GrColor_ILLEGAL;
@@ -75,6 +80,7 @@ GrDistanceFieldTextContext* GrDistanceFieldTextContext::Create(GrContext* contex
bool enable) {
GrDistanceFieldTextContext* textContext = SkNEW_ARGS(GrDistanceFieldTextContext,
(context, gpuDevice, props, enable));
+ textContext->buildDistanceAdjustTable();
#ifdef USE_BITMAP_TEXTBLOBS
textContext->fFallbackTextContext = GrBitmapTextContextB::Create(context, gpuDevice, props);
#else
@@ -84,8 +90,92 @@ GrDistanceFieldTextContext* GrDistanceFieldTextContext::Create(GrContext* contex
return textContext;
}
+void GrDistanceFieldTextContext::buildDistanceAdjustTable() {
+
+ // This is used for an approximation of the mask gamma hack, used by raster and bitmap
+ // text. The mask gamma hack is based off of guessing what the blend color is going to
+ // be, and adjusting the mask so that when run through the linear blend will
+ // produce the value closest to the desired result. However, in practice this means
+ // that the 'adjusted' mask is just increasing or decreasing the coverage of
+ // the mask depending on what it is thought it will blit against. For black (on
+ // assumed white) this means that coverages are decreased (on a curve). For white (on
+ // assumed black) this means that coverages are increased (on a a curve). At
+ // middle (perceptual) gray (which could be blit against anything) the coverages
+ // remain the same.
+ //
+ // The idea here is that instead of determining the initial (real) coverage and
+ // then adjusting that coverage, we determine an adjusted coverage directly by
+ // essentially manipulating the geometry (in this case, the distance to the glyph
+ // edge). So for black (on assumed white) this thins a bit; for white (on
+ // assumed black) this fake bolds the geometry a bit.
+ //
+ // The distance adjustment is calculated by determining the actual coverage value which
+ // when fed into in the mask gamma table gives us an 'adjusted coverage' value of 0.5. This
+ // actual coverage value (assuming it's between 0 and 1) corresponds to a distance from the
+ // actual edge. So by subtracting this distance adjustment and computing without the
+ // the coverage adjustment we should get 0.5 coverage at the same point.
+ //
+ // This has several implications:
+ // For non-gray lcd smoothed text, each subpixel essentially is using a
+ // slightly different geometry.
+ //
+ // For black (on assumed white) this may not cover some pixels which were
+ // previously covered; however those pixels would have been only slightly
+ // covered and that slight coverage would have been decreased anyway. Also, some pixels
+ // which were previously fully covered may no longer be fully covered.
+ //
+ // For white (on assumed black) this may cover some pixels which weren't
+ // previously covered at all.
+
+ int width, height;
+ size_t size;
+
+#ifdef SK_GAMMA_CONTRAST
+ SkScalar contrast = SK_GAMMA_CONTRAST;
+#else
+ SkScalar contrast = 0.5f;
+#endif
+ SkScalar paintGamma = fDeviceProperties.gamma();
+ SkScalar deviceGamma = fDeviceProperties.gamma();
+
+ size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma,
+ &width, &height);
+
+ SkASSERT(kExpectedDistanceAdjustTableSize == height);
+ fDistanceAdjustTable = SkNEW_ARRAY(SkScalar, height);
+
+ SkAutoTArray<uint8_t> data((int)size);
+ SkScalerContext::GetGammaLUTData(contrast, paintGamma, deviceGamma, data.get());
+
+ // find the inverse points where we cross 0.5
+ // binsearch might be better, but we only need to do this once on creation
+ for (int row = 0; row < height; ++row) {
+ uint8_t* rowPtr = data.get() + row*width;
+ for (int col = 0; col < width - 1; ++col) {
+ if (rowPtr[col] <= 127 && rowPtr[col + 1] >= 128) {
+ // compute point where a mask value will give us a result of 0.5
+ float interp = (127.5f - rowPtr[col]) / (rowPtr[col + 1] - rowPtr[col]);
+ float borderAlpha = (col + interp) / 255.f;
+
+ // compute t value for that alpha
+ // this is an approximate inverse for smoothstep()
+ float t = borderAlpha*(borderAlpha*(4.0f*borderAlpha - 6.0f) + 5.0f) / 3.0f;
+
+ // compute distance which gives us that t value
+ const float kDistanceFieldAAFactor = 0.65f; // should match SK_DistanceFieldAAFactor
+ float d = 2.0f*kDistanceFieldAAFactor*t - kDistanceFieldAAFactor;
+
+ fDistanceAdjustTable[row] = d;
+ break;
+ }
+ }
+ }
+}
+
+
GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
- SkSafeSetNull(fGammaTexture);
+ SkDELETE_ARRAY(fDistanceAdjustTable);
+ fDistanceAdjustTable = NULL;
}
bool GrDistanceFieldTextContext::canDraw(const GrRenderTarget* rt,
@@ -183,45 +273,6 @@ inline void GrDistanceFieldTextContext::init(GrRenderTarget* rt, const GrClip& c
fSkPaint.setSubpixelText(true);
}
-static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache,
- const SkDeviceProperties& deviceProperties,
- GrTexture** gammaTexture) {
- if (NULL == *gammaTexture) {
- int width, height;
- size_t size;
-
-#ifdef SK_GAMMA_CONTRAST
- SkScalar contrast = SK_GAMMA_CONTRAST;
-#else
- SkScalar contrast = 0.5f;
-#endif
- SkScalar paintGamma = deviceProperties.gamma();
- SkScalar deviceGamma = deviceProperties.gamma();
-
- size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma,
- &width, &height);
-
- SkAutoTArray<uint8_t> data((int)size);
- SkScalerContext::GetGammaLUTData(contrast, paintGamma, deviceGamma, data.get());
-
- // TODO: Update this to use the cache rather than directly creating a texture.
- GrSurfaceDesc desc;
- desc.fFlags = kNone_GrSurfaceFlags;
- desc.fWidth = width;
- desc.fHeight = height;
- desc.fConfig = kAlpha_8_GrPixelConfig;
-
- *gammaTexture = context->getGpu()->createTexture(desc, true, NULL, 0);
- if (NULL == *gammaTexture) {
- return;
- }
-
- (*gammaTexture)->writePixels(0, 0, width, height,
- (*gammaTexture)->config(), data.get(), 0,
- GrContext::kDontFlush_PixelOpsFlag);
- }
-}
-
void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
const GrPaint& paint,
const SkPaint& skPaint, const SkMatrix& viewMatrix,
@@ -314,8 +365,6 @@ void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip&
SkGlyphCache* cache = autoCache.getCache();
GrFontScaler* fontScaler = GetGrFontScaler(cache);
- setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
-
int numGlyphs = fSkPaint.textToGlyphs(text, byteLength, NULL);
fTotalVertexCount = kVerticesPerGlyph*numGlyphs;
@@ -443,13 +492,22 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
GrColor color = fPaint.getColor();
if (fUseLCDText) {
GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
+
+ float redCorrection =
+ fDistanceAdjustTable[GrColorUnpackR(colorNoPreMul) >> kDistanceAdjustLumShift];
+ float greenCorrection =
+ fDistanceAdjustTable[GrColorUnpackG(colorNoPreMul) >> kDistanceAdjustLumShift];
+ float blueCorrection =
+ fDistanceAdjustTable[GrColorUnpackB(colorNoPreMul) >> kDistanceAdjustLumShift];
+ GrDistanceFieldLCDTextureEffect::DistanceAdjust widthAdjust =
+ GrDistanceFieldLCDTextureEffect::DistanceAdjust::Make(redCorrection,
+ greenCorrection,
+ blueCorrection);
fCachedGeometryProcessor.reset(GrDistanceFieldLCDTextureEffect::Create(color,
fViewMatrix,
fCurrTexture,
params,
- fGammaTexture,
- gammaParams,
- colorNoPreMul,
+ widthAdjust,
flags));
} else {
flags |= kColorAttr_DistanceFieldEffectFlag;
@@ -457,13 +515,12 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo
#ifdef SK_GAMMA_APPLY_TO_A8
U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.gamma(),
filteredColor);
+ float correction = fDistanceAdjustTable[lum >> kDistanceAdjustLumShift];
fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(color,
fViewMatrix,
fCurrTexture,
params,
- fGammaTexture,
- gammaParams,
- lum/255.f,
+ correction,
flags,
opaque));
#else
diff --git a/src/gpu/GrDistanceFieldTextContext.h b/src/gpu/GrDistanceFieldTextContext.h
index b76be3d1ec..1524a9495e 100644
--- a/src/gpu/GrDistanceFieldTextContext.h
+++ b/src/gpu/GrDistanceFieldTextContext.h
@@ -36,11 +36,11 @@ private:
bool fUseLCDText;
bool fEnableDFRendering;
SkAutoTUnref<GrGeometryProcessor> fCachedGeometryProcessor;
+ SkScalar* fDistanceAdjustTable;
// Used to check whether fCachedEffect is still valid.
uint32_t fEffectTextureUniqueID;
SkColor fEffectColor;
uint32_t fEffectFlags;
- GrTexture* fGammaTexture;
void* fVertices;
int fCurrVertex;
int fAllocVertexCount;
@@ -50,6 +50,7 @@ private:
SkMatrix fViewMatrix;
GrDistanceFieldTextContext(GrContext*, SkGpuDevice*, const SkDeviceProperties&, bool enable);
+ void buildDistanceAdjustTable();
bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&,
const SkPaint&, const SkMatrix& viewMatrix) override;
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index 0acf1f324a..d44c193260 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -9,14 +9,16 @@
#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 the diagonal of the fragment, hence a factor of sqrt(2)/2
+// Assuming a radius of a little less than the diagonal of the fragment
#define SK_DistanceFieldAAFactor "0.65"
struct DistanceFieldBatchTracker {
@@ -31,7 +33,7 @@ public:
const GrBatchTracker&)
: fColor(GrColor_ILLEGAL)
#ifdef SK_GAMMA_APPLY_TO_A8
- , fLuminance(-1.0f)
+ , fDistanceAdjust(-1.0f)
#endif
{}
@@ -59,6 +61,14 @@ public:
vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
dfTexEffect.inTextureCoords()->fName);
+#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,
@@ -83,6 +93,10 @@ public:
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(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
pb->ctxInfo().standard()));
@@ -119,21 +133,6 @@ public:
}
fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
-#ifdef SK_GAMMA_APPLY_TO_A8
- // adjust based on gamma
- const char* luminanceUniName = NULL;
- // width, height, 1/(3*width)
- fLuminanceUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
- kFloat_GrSLType, kDefault_GrSLPrecision,
- "Luminance", &luminanceUniName);
-
- fsBuilder->codeAppendf("\tuv = vec2(val, %s);\n", luminanceUniName);
- fsBuilder->codeAppend("\tvec4 gammaColor = ");
- fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
- fsBuilder->codeAppend(";\n");
- fsBuilder->codeAppend("\tval = gammaColor.r;\n");
-#endif
-
fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
}
@@ -143,10 +142,10 @@ public:
#ifdef SK_GAMMA_APPLY_TO_A8
const GrDistanceFieldTextureEffect& dfTexEffect =
proc.cast<GrDistanceFieldTextureEffect>();
- float luminance = dfTexEffect.getLuminance();
- if (luminance != fLuminance) {
- pdman.set1f(fLuminanceUni, luminance);
- fLuminance = luminance;
+ float distanceAdjust = dfTexEffect.getDistanceAdjust();
+ if (distanceAdjust != fDistanceAdjust) {
+ pdman.set1f(fDistanceAdjustUni, distanceAdjust);
+ fDistanceAdjust = distanceAdjust;
}
#endif
@@ -178,8 +177,8 @@ private:
GrColor fColor;
UniformHandle fColorUniform;
#ifdef SK_GAMMA_APPLY_TO_A8
- UniformHandle fLuminanceUni;
- float fLuminance;
+ float fDistanceAdjust;
+ UniformHandle fDistanceAdjustUni;
#endif
typedef GrGLGeometryProcessor INHERITED;
@@ -192,16 +191,13 @@ GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color,
GrTexture* texture,
const GrTextureParams& params,
#ifdef SK_GAMMA_APPLY_TO_A8
- GrTexture* gamma,
- const GrTextureParams& gammaParams,
- float luminance,
+ float distanceAdjust,
#endif
uint32_t flags, bool opaqueVertexColors)
: INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors)
, fTextureAccess(texture, params)
#ifdef SK_GAMMA_APPLY_TO_A8
- , fGammaTextureAccess(gamma, gammaParams)
- , fLuminance(luminance)
+ , fDistanceAdjust(distanceAdjust)
#endif
, fFlags(flags & kNonLCD_DistanceFieldEffectMask)
, fInColor(NULL) {
@@ -215,16 +211,13 @@ GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color,
fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
kVec2s_GrVertexAttribType));
this->addTextureAccess(&fTextureAccess);
-#ifdef SK_GAMMA_APPLY_TO_A8
- this->addTextureAccess(&fGammaTextureAccess);
-#endif
}
bool GrDistanceFieldTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
const GrDistanceFieldTextureEffect& cte = other.cast<GrDistanceFieldTextureEffect>();
return
#ifdef SK_GAMMA_APPLY_TO_A8
- fLuminance == cte.fLuminance &&
+ fDistanceAdjust == cte.fDistanceAdjust &&
#endif
fFlags == cte.fFlags;
}
@@ -245,7 +238,8 @@ GrDistanceFieldTextureEffect::createGLInstance(const GrBatchTracker& bt,
return SkNEW_ARGS(GrGLDistanceFieldTextureEffect, (*this, bt));
}
-void GrDistanceFieldTextureEffect::initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const {
+void GrDistanceFieldTextureEffect::initBatchTracker(GrBatchTracker* bt,
+ const GrPipelineInfo& init) const {
DistanceFieldBatchTracker* local = bt->cast<DistanceFieldBatchTracker>();
local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init,
SkToBool(fInColor));
@@ -273,10 +267,6 @@ GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
GrTexture* textures[]) {
int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
GrProcessorUnitTest::kAlphaTextureIdx;
-#ifdef SK_GAMMA_APPLY_TO_A8
- int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
- GrProcessorUnitTest::kAlphaTextureIdx;
-#endif
static const SkShader::TileMode kTileModes[] = {
SkShader::kClamp_TileMode,
SkShader::kRepeat_TileMode,
@@ -288,16 +278,11 @@ GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random,
};
GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
GrTextureParams::kNone_FilterMode);
-#ifdef SK_GAMMA_APPLY_TO_A8
- GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
- GrTextureParams::kNone_FilterMode);
-#endif
return GrDistanceFieldTextureEffect::Create(GrRandomColor(random),
GrProcessorUnitTest::TestMatrix(random),
textures[texIdx], params,
#ifdef SK_GAMMA_APPLY_TO_A8
- textures[texIdx2], params2,
random->nextF(),
#endif
random->nextBool() ?
@@ -487,7 +472,8 @@ bool GrDistanceFieldNoGammaTextureEffect::onIsEqual(const GrGeometryProcessor& o
return fFlags == cte.fFlags;
}
-void GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const{
+void GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out)
+ const {
out->setUnknownSingleComponent();
}
@@ -563,8 +549,9 @@ class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor {
public:
GrGLDistanceFieldLCDTextureEffect(const GrGeometryProcessor&,
const GrBatchTracker&)
- : fColor(GrColor_ILLEGAL)
- , fTextColor(GrColor_ILLEGAL) {}
+ : fColor(GrColor_ILLEGAL) {
+ fDistanceAdjust = GrDistanceFieldLCDTextureEffect::DistanceAdjust::Make(1.0f, 1.0f, 1.0f);
+ }
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrDistanceFieldLCDTextureEffect& dfTexEffect =
@@ -650,6 +637,13 @@ public:
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
@@ -682,31 +676,8 @@ public:
fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
}
- fsBuilder->codeAppend("vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);");
-
- // adjust based on gamma
- const char* textColorUniName = NULL;
- fTextColorUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
- kVec3f_GrSLType, kDefault_GrSLPrecision,
- "TextColor", &textColorUniName);
-
- fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName);
- fsBuilder->codeAppend("float gammaColor = ");
- fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
- fsBuilder->codeAppend(".r;\n");
- fsBuilder->codeAppend("\tval.x = gammaColor;\n");
-
- fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName);
- fsBuilder->codeAppend("\tgammaColor = ");
- fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
- fsBuilder->codeAppend(".r;\n");
- fsBuilder->codeAppend("\tval.y = gammaColor;\n");
-
- fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName);
- fsBuilder->codeAppend("\tgammaColor = ");
- fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType);
- fsBuilder->codeAppend(".r;\n");
- fsBuilder->codeAppend("\tval.z = gammaColor;\n");
+ fsBuilder->codeAppend(
+ "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);");
fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
}
@@ -714,18 +685,17 @@ public:
virtual void setData(const GrGLProgramDataManager& pdman,
const GrPrimitiveProcessor& processor,
const GrBatchTracker& bt) override {
- SkASSERT(fTextColorUni.isValid());
+ SkASSERT(fDistanceAdjustUni.isValid());
const GrDistanceFieldLCDTextureEffect& dfTexEffect =
processor.cast<GrDistanceFieldLCDTextureEffect>();
- GrColor textColor = dfTexEffect.getTextColor();
- if (textColor != fTextColor) {
- static const float ONE_OVER_255 = 1.f / 255.f;
- pdman.set3f(fTextColorUni,
- GrColorUnpackR(textColor) * ONE_OVER_255,
- GrColorUnpackG(textColor) * ONE_OVER_255,
- GrColorUnpackB(textColor) * ONE_OVER_255);
- fTextColor = textColor;
+ GrDistanceFieldLCDTextureEffect::DistanceAdjust wa = dfTexEffect.getDistanceAdjust();
+ if (wa != fDistanceAdjust) {
+ pdman.set3f(fDistanceAdjustUni,
+ wa.fR,
+ wa.fG,
+ wa.fB);
+ fDistanceAdjust = wa;
}
this->setUniformViewMatrix(pdman, processor.viewMatrix());
@@ -755,10 +725,10 @@ public:
}
private:
- GrColor fColor;
- UniformHandle fColorUniform;
- UniformHandle fTextColorUni;
- SkColor fTextColor;
+ GrColor fColor;
+ UniformHandle fColorUniform;
+ GrDistanceFieldLCDTextureEffect::DistanceAdjust fDistanceAdjust;
+ UniformHandle fDistanceAdjustUni;
typedef GrGLGeometryProcessor INHERITED;
};
@@ -768,13 +738,11 @@ private:
GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(
GrColor color, const SkMatrix& viewMatrix,
GrTexture* texture, const GrTextureParams& params,
- GrTexture* gamma, const GrTextureParams& gParams,
- SkColor textColor,
+ DistanceAdjust distanceAdjust,
uint32_t flags)
: INHERITED(color, viewMatrix, SkMatrix::I())
, fTextureAccess(texture, params)
- , fGammaTextureAccess(gamma, gParams)
- , fTextColor(textColor)
+ , fDistanceAdjust(distanceAdjust)
, fFlags(flags & kLCD_DistanceFieldEffectMask){
SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_DistanceFieldEffectFlag));
this->initClassID<GrDistanceFieldLCDTextureEffect>();
@@ -782,16 +750,16 @@ GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect(
fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords",
kVec2s_GrVertexAttribType));
this->addTextureAccess(&fTextureAccess);
- this->addTextureAccess(&fGammaTextureAccess);
}
bool GrDistanceFieldLCDTextureEffect::onIsEqual(const GrGeometryProcessor& other) const {
const GrDistanceFieldLCDTextureEffect& cte = other.cast<GrDistanceFieldLCDTextureEffect>();
- return (fTextColor == cte.fTextColor &&
+ return (fDistanceAdjust == cte.fDistanceAdjust &&
fFlags == cte.fFlags);
}
-void GrDistanceFieldLCDTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const {
+void GrDistanceFieldLCDTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out)
+ const {
out->setUnknownFourComponents();
out->setUsingLCDCoverage();
}
@@ -836,8 +804,6 @@ GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* rando
GrTexture* textures[]) {
int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
GrProcessorUnitTest::kAlphaTextureIdx;
- int texIdx2 = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx :
- GrProcessorUnitTest::kAlphaTextureIdx;
static const SkShader::TileMode kTileModes[] = {
SkShader::kClamp_TileMode,
SkShader::kRepeat_TileMode,
@@ -849,19 +815,13 @@ GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* rando
};
GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
GrTextureParams::kNone_FilterMode);
- GrTextureParams params2(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode :
- GrTextureParams::kNone_FilterMode);
- GrColor textColor = GrColorPackRGBA(random->nextULessThan(256),
- random->nextULessThan(256),
- random->nextULessThan(256),
- random->nextULessThan(256));
+ 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 GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random),
GrProcessorUnitTest::TestMatrix(random),
textures[texIdx], params,
- textures[texIdx2], params2,
- textColor,
+ wa,
flags);
}
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.h b/src/gpu/effects/GrDistanceFieldTextureEffect.h
index e05af7684c..6be7f9eef3 100644
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.h
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h
@@ -49,10 +49,8 @@ public:
#ifdef SK_GAMMA_APPLY_TO_A8
static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex,
const GrTextureParams& params,
- GrTexture* gamma, const GrTextureParams& gammaParams,
float lum, uint32_t flags, bool opaqueVertexColors) {
- return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, viewMatrix, tex, params, gamma,
- gammaParams, lum,
+ return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, viewMatrix, tex, params, lum,
flags, opaqueVertexColors));
}
#else
@@ -72,7 +70,7 @@ public:
const Attribute* inColor() const { return fInColor; }
const Attribute* inTextureCoords() const { return fInTextureCoords; }
#ifdef SK_GAMMA_APPLY_TO_A8
- float getLuminance() const { return fLuminance; }
+ float getDistanceAdjust() const { return fDistanceAdjust; }
#endif
uint32_t getFlags() const { return fFlags; }
@@ -93,7 +91,7 @@ private:
GrDistanceFieldTextureEffect(GrColor, const SkMatrix& viewMatrix, GrTexture* texture,
const GrTextureParams& params,
#ifdef SK_GAMMA_APPLY_TO_A8
- GrTexture* gamma, const GrTextureParams& gammaParams, float lum,
+ float distanceAdjust,
#endif
uint32_t flags, bool opaqueVertexColors);
@@ -101,12 +99,11 @@ private:
void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const override;
- GrTextureAccess fTextureAccess;
+ GrTextureAccess fTextureAccess;
#ifdef SK_GAMMA_APPLY_TO_A8
- GrTextureAccess fGammaTextureAccess;
- float fLuminance;
+ float fDistanceAdjust;
#endif
- uint32_t fFlags;
+ uint32_t fFlags;
const Attribute* fInPosition;
const Attribute* fInColor;
const Attribute* fInTextureCoords;
@@ -182,12 +179,26 @@ private:
*/
class GrDistanceFieldLCDTextureEffect : public GrGeometryProcessor {
public:
+ struct DistanceAdjust {
+ SkScalar fR, fG, fB;
+ static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) {
+ DistanceAdjust result;
+ result.fR = r; result.fG = g; result.fB = b;
+ return result;
+ }
+ bool operator==(const DistanceAdjust& wa) const {
+ return (fR == wa.fR && fG == wa.fG && fB == wa.fB);
+ }
+ bool operator!=(const DistanceAdjust& wa) const {
+ return !(*this == wa);
+ }
+ };
+
static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex,
- const GrTextureParams& params, GrTexture* gamma,
- const GrTextureParams& gammaParams,
- SkColor textColor, uint32_t flags) {
+ const GrTextureParams& params,
+ DistanceAdjust distanceAdjust, uint32_t flags) {
return SkNEW_ARGS(GrDistanceFieldLCDTextureEffect,
- (color, viewMatrix, tex, params, gamma, gammaParams, textColor, flags));
+ (color, viewMatrix, tex, params, distanceAdjust, flags));
}
virtual ~GrDistanceFieldLCDTextureEffect() {}
@@ -196,7 +207,7 @@ public:
const Attribute* inPosition() const { return fInPosition; }
const Attribute* inTextureCoords() const { return fInTextureCoords; }
- GrColor getTextColor() const { return fTextColor; }
+ DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; }
uint32_t getFlags() const { return fFlags; }
virtual void getGLProcessorKey(const GrBatchTracker& bt,
@@ -215,17 +226,15 @@ public:
private:
GrDistanceFieldLCDTextureEffect(GrColor, const SkMatrix& viewMatrix, GrTexture* texture,
const GrTextureParams& params,
- GrTexture* gamma, const GrTextureParams& gammaParams,
- SkColor textColor, uint32_t flags);
+ DistanceAdjust wa, uint32_t flags);
bool onIsEqual(const GrGeometryProcessor& other) const override;
void onGetInvariantOutputCoverage(GrInitInvariantOutput*) const override;
- GrTextureAccess fTextureAccess;
- GrTextureAccess fGammaTextureAccess;
- GrColor fTextColor;
- uint32_t fFlags;
+ GrTextureAccess fTextureAccess;
+ DistanceAdjust fDistanceAdjust;
+ uint32_t fFlags;
const Attribute* fInPosition;
const Attribute* fInTextureCoords;