Emulate distance field gamma fix by making glyphs thicker or thinner
The idea here is that we determine the 0.5 crossover for each
row in the gamma table, then invert the mapping to determine
which point that maps to in the original range [-.65,
.65]. That gives us a change in the apparent width of the
glyph that closely corresponds to the change produced by the gamma fix.
BUG=skia:2933
Review URL: https://codereview.chromium.org/1042373002
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index 12aa1bf..90d6d76 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -43,6 +43,11 @@
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 @@
fEnableDFRendering = enable;
#endif
fStrike = NULL;
- fGammaTexture = NULL;
+ fDistanceAdjustTable = NULL;
fEffectTextureUniqueID = SK_InvalidUniqueID;
fEffectColor = GrColor_ILLEGAL;
@@ -75,6 +80,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
#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 b76be3d..1524a94 100644
--- a/src/gpu/GrDistanceFieldTextContext.h
+++ b/src/gpu/GrDistanceFieldTextContext.h
@@ -36,11 +36,11 @@
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 @@
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 0acf1f3..d44c193 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 @@
const GrBatchTracker&)
: fColor(GrColor_ILLEGAL)
#ifdef SK_GAMMA_APPLY_TO_A8
- , fLuminance(-1.0f)
+ , fDistanceAdjust(-1.0f)
#endif
{}
@@ -59,6 +61,14 @@
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 @@
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 @@
}
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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
};
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 @@
return fFlags == cte.fFlags;
}
-void GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const{
+void GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out)
+ const {
out->setUnknownSingleComponent();
}
@@ -563,8 +549,9 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
};
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 e05af76..6be7f9e 100644
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.h
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h
@@ -49,10 +49,8 @@
#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 @@
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 @@
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 @@
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 @@
*/
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 @@
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 @@
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;