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,
fEnableDFRendering = enable;
#endif
fStrike = NULL;
- fGammaTexture = NULL;
+ fDistanceAdjustTable = NULL;
fEffectTextureUniqueID = SK_InvalidUniqueID;
fEffectColor = GrColor_ILLEGAL;
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
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,
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,
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;
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;
#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
#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 {
const GrBatchTracker&)
: fColor(GrColor_ILLEGAL)
#ifdef SK_GAMMA_APPLY_TO_A8
- , fLuminance(-1.0f)
+ , fDistanceAdjust(-1.0f)
#endif
{}
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,
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()));
}
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);
}
#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
GrColor fColor;
UniformHandle fColorUniform;
#ifdef SK_GAMMA_APPLY_TO_A8
- UniformHandle fLuminanceUni;
- float fLuminance;
+ float fDistanceAdjust;
+ UniformHandle fDistanceAdjustUni;
#endif
typedef GrGLGeometryProcessor INHERITED;
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) {
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;
}
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));
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,
};
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() ?
return fFlags == cte.fFlags;
}
-void GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out) const{
+void GrDistanceFieldNoGammaTextureEffect::onGetInvariantOutputCoverage(GrInitInvariantOutput* out)
+ const {
out->setUnknownSingleComponent();
}
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 =
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
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);
}
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());
}
private:
- GrColor fColor;
- UniformHandle fColorUniform;
- UniformHandle fTextColorUni;
- SkColor fTextColor;
+ GrColor fColor;
+ UniformHandle fColorUniform;
+ GrDistanceFieldLCDTextureEffect::DistanceAdjust fDistanceAdjust;
+ UniformHandle fDistanceAdjustUni;
typedef GrGLGeometryProcessor INHERITED;
};
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>();
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();
}
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,
};
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);
}
#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
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; }
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);
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;
*/
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() {}
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,
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;