diff options
-rwxr-xr-x | src/gpu/GrDistanceFieldTextContext.cpp | 155 | ||||
-rw-r--r-- | src/gpu/GrDistanceFieldTextContext.h | 3 | ||||
-rwxr-xr-x | src/gpu/effects/GrDistanceFieldTextureEffect.cpp | 160 | ||||
-rw-r--r-- | src/gpu/effects/GrDistanceFieldTextureEffect.h | 49 |
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; |