diff --git a/experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp b/experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp index 091a55b4c8..c0652bfa98 100644 --- a/experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp +++ b/experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp @@ -1334,13 +1334,17 @@ sk_sp SkPerlinNoiseShader2::asFragmentProcessor(const AsFPA if (0 == fNumOctaves) { if (kFractalNoise_Type == fType) { // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2) + // TODO: Either treat the output of this shader as sRGB or allow client to specify a + // color space of the noise. Either way, this case (and the GLSL) need to convert to + // the destination. sk_sp inner( - GrConstColorProcessor::Make(0x80404040, + GrConstColorProcessor::Make(GrColor4f::FromGrColor(0x80404040), GrConstColorProcessor::kModulateRGBA_InputMode)); return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)); } // Emit zero. - return GrConstColorProcessor::Make(0x0, GrConstColorProcessor::kIgnore_InputMode); + return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), + GrConstColorProcessor::kIgnore_InputMode); } SkAutoTUnref permutationsTexture( diff --git a/gm/constcolorprocessor.cpp b/gm/constcolorprocessor.cpp index ef23f7832e..b4983dc44c 100644 --- a/gm/constcolorprocessor.cpp +++ b/gm/constcolorprocessor.cpp @@ -103,7 +103,7 @@ protected: &grPaint)); GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m; - GrColor color = kColors[procColor]; + GrColor4f color = GrColor4f::FromGrColor(kColors[procColor]); sk_sp fp(GrConstColorProcessor::Make(color, mode)); grPaint.addColorFragmentProcessor(std::move(fp)); diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h index 485739842a..f265998e05 100644 --- a/include/core/SkColorFilter.h +++ b/include/core/SkColorFilter.h @@ -16,6 +16,7 @@ class GrContext; class GrFragmentProcessor; class SkBitmap; +class SkColorSpace; class SkRasterPipeline; /** @@ -144,7 +145,8 @@ public: * * A null return indicates that the color filter isn't implemented for the GPU backend. */ - virtual sk_sp asFragmentProcessor(GrContext*) const; + virtual sk_sp asFragmentProcessor(GrContext*, + SkColorSpace* dstColorSpace) const; #endif bool affectsTransparentBlack() const { diff --git a/include/effects/SkColorCubeFilter.h b/include/effects/SkColorCubeFilter.h index f30371de46..ea69d4d65d 100644 --- a/include/effects/SkColorCubeFilter.h +++ b/include/effects/SkColorCubeFilter.h @@ -26,7 +26,7 @@ public: uint32_t getFlags() const override; #if SK_SUPPORT_GPU - sk_sp asFragmentProcessor(GrContext*) const override; + sk_sp asFragmentProcessor(GrContext*, SkColorSpace*) const override; #endif SK_TO_STRING_OVERRIDE() diff --git a/include/effects/SkGammaColorFilter.h b/include/effects/SkGammaColorFilter.h index b98838eb8f..72c464e33b 100644 --- a/include/effects/SkGammaColorFilter.h +++ b/include/effects/SkGammaColorFilter.h @@ -25,7 +25,7 @@ public: void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override; #if SK_SUPPORT_GPU - sk_sp asFragmentProcessor(GrContext*) const override; + sk_sp asFragmentProcessor(GrContext*, SkColorSpace*) const override; #endif SK_TO_STRING_OVERRIDE() diff --git a/include/effects/SkLumaColorFilter.h b/include/effects/SkLumaColorFilter.h index ac4afa2bfc..9625435b25 100644 --- a/include/effects/SkLumaColorFilter.h +++ b/include/effects/SkLumaColorFilter.h @@ -29,7 +29,7 @@ public: void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override; #if SK_SUPPORT_GPU - sk_sp asFragmentProcessor(GrContext*) const override; + sk_sp asFragmentProcessor(GrContext*, SkColorSpace*) const override; #endif SK_TO_STRING_OVERRIDE() diff --git a/include/gpu/GrColor.h b/include/gpu/GrColor.h index f52671732a..cde9b74cb9 100644 --- a/include/gpu/GrColor.h +++ b/include/gpu/GrColor.h @@ -185,6 +185,24 @@ struct GrColor4f { fRGBA[3] = a; } + enum Illegal_Constructor { + kIllegalConstructor + }; + GrColor4f(Illegal_Constructor) { + fRGBA[0] = SK_FloatNaN; + fRGBA[1] = SK_FloatNaN; + fRGBA[2] = SK_FloatNaN; + fRGBA[3] = SK_FloatNaN; + } + + static GrColor4f OpaqueWhite() { + return GrColor4f(1.0f, 1.0f, 1.0f, 1.0f); + } + + static GrColor4f TransparentBlack() { + return GrColor4f(0.0f, 0.0f, 0.0f, 0.0f); + } + static GrColor4f FromGrColor(GrColor color) { GrColor4f result; GrColorToRGBAFloat(color, result.fRGBA); diff --git a/include/gpu/effects/GrConstColorProcessor.h b/include/gpu/effects/GrConstColorProcessor.h index e9781bb22a..1d23fc349e 100644 --- a/include/gpu/effects/GrConstColorProcessor.h +++ b/include/gpu/effects/GrConstColorProcessor.h @@ -26,7 +26,7 @@ public: }; static const int kInputModeCnt = kLastInputMode + 1; - static sk_sp Make(GrColor color, InputMode mode) { + static sk_sp Make(GrColor4f color, InputMode mode) { return sk_sp(new GrConstColorProcessor(color, mode)); } @@ -34,16 +34,16 @@ public: SkString dumpInfo() const override { SkString str; - str.appendf("Color: 0x%08x", fColor); + str.appendf("Color: 0x%08x", fColor.toGrColor()); return str; } - GrColor color() const { return fColor; } + GrColor4f color() const { return fColor; } InputMode inputMode() const { return fMode; } private: - GrConstColorProcessor(GrColor color, InputMode mode) : fColor(color), fMode(mode) { + GrConstColorProcessor(GrColor4f color, InputMode mode) : fColor(color), fMode(mode) { this->initClassID(); } @@ -57,7 +57,7 @@ private: GR_DECLARE_FRAGMENT_PROCESSOR_TEST; - GrColor fColor; + GrColor4f fColor; InputMode fMode; typedef GrFragmentProcessor INHERITED; diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp index 31c0ddb06b..b23b100e28 100644 --- a/src/core/SkColorFilter.cpp +++ b/src/core/SkColorFilter.cpp @@ -32,7 +32,7 @@ bool SkColorFilter::asComponentTable(SkBitmap*) const { } #if SK_SUPPORT_GPU -sk_sp SkColorFilter::asFragmentProcessor(GrContext*) const { +sk_sp SkColorFilter::asFragmentProcessor(GrContext*, SkColorSpace*) const { return nullptr; } #endif @@ -114,9 +114,10 @@ public: #endif #if SK_SUPPORT_GPU - sk_sp asFragmentProcessor(GrContext* context) const override { - sk_sp innerFP(fInner->asFragmentProcessor(context)); - sk_sp outerFP(fOuter->asFragmentProcessor(context)); + sk_sp asFragmentProcessor(GrContext* context, + SkColorSpace* dstColorSpace) const override { + sk_sp innerFP(fInner->asFragmentProcessor(context, dstColorSpace)); + sk_sp outerFP(fOuter->asFragmentProcessor(context, dstColorSpace)); if (!innerFP || !outerFP) { return nullptr; } diff --git a/src/core/SkColorFilterShader.cpp b/src/core/SkColorFilterShader.cpp index 8bf82b8b18..4090a18b45 100644 --- a/src/core/SkColorFilterShader.cpp +++ b/src/core/SkColorFilterShader.cpp @@ -104,7 +104,8 @@ sk_sp SkColorFilterShader::asFragmentProcessor(const AsFPAr return nullptr; } - sk_sp fp2(fFilter->asFragmentProcessor(args.fContext)); + sk_sp fp2(fFilter->asFragmentProcessor(args.fContext, + args.fDstColorSpace)); if (!fp2) { return fp1; } diff --git a/src/core/SkColorMatrixFilterRowMajor255.cpp b/src/core/SkColorMatrixFilterRowMajor255.cpp index 29a3f107b8..9517704076 100644 --- a/src/core/SkColorMatrixFilterRowMajor255.cpp +++ b/src/core/SkColorMatrixFilterRowMajor255.cpp @@ -396,7 +396,8 @@ sk_sp ColorMatrixEffect::TestCreate(GrProcessorTestData* d) return ColorMatrixEffect::Make(colorMatrix); } -sk_sp SkColorMatrixFilterRowMajor255::asFragmentProcessor(GrContext*) const { +sk_sp SkColorMatrixFilterRowMajor255::asFragmentProcessor( + GrContext*, SkColorSpace*) const { return ColorMatrixEffect::Make(fMatrix); } diff --git a/src/core/SkColorMatrixFilterRowMajor255.h b/src/core/SkColorMatrixFilterRowMajor255.h index c1158859f8..0372f677a2 100644 --- a/src/core/SkColorMatrixFilterRowMajor255.h +++ b/src/core/SkColorMatrixFilterRowMajor255.h @@ -25,7 +25,7 @@ public: sk_sp makeComposed(sk_sp) const override; #if SK_SUPPORT_GPU - sk_sp asFragmentProcessor(GrContext*) const override; + sk_sp asFragmentProcessor(GrContext*, SkColorSpace*) const override; #endif SK_TO_STRING_OVERRIDE() diff --git a/src/core/SkColorShader.cpp b/src/core/SkColorShader.cpp index cfa071fed8..e66ae206dc 100644 --- a/src/core/SkColorShader.cpp +++ b/src/core/SkColorShader.cpp @@ -89,8 +89,8 @@ SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { #include "SkGr.h" #include "effects/GrConstColorProcessor.h" -sk_sp SkColorShader::asFragmentProcessor(const AsFPArgs&) const { - GrColor color = SkColorToPremulGrColor(fColor); +sk_sp SkColorShader::asFragmentProcessor(const AsFPArgs& args) const { + GrColor4f color = SkColorToPremulGrColor4f(fColor, args.fDstColorSpace); return GrConstColorProcessor::Make(color, GrConstColorProcessor::kModulateA_InputMode); } @@ -208,10 +208,14 @@ SkShader::GradientType SkColor4Shader::asAGradient(GradientInfo* info) const { #include "SkGr.h" #include "effects/GrConstColorProcessor.h" -sk_sp SkColor4Shader::asFragmentProcessor(const AsFPArgs&) const { - // TODO: how to communicate color4f to Gr - GrColor color = SkColorToPremulGrColor(fCachedByteColor); - return GrConstColorProcessor::Make(color, GrConstColorProcessor::kModulateA_InputMode); +sk_sp SkColor4Shader::asFragmentProcessor(const AsFPArgs& args) const { + sk_sp colorSpaceXform = GrColorSpaceXform::Make(fColorSpace.get(), + args.fDstColorSpace); + GrColor4f color = GrColor4f::FromSkColor4f(fColor4); + if (colorSpaceXform) { + color = colorSpaceXform->apply(color); + } + return GrConstColorProcessor::Make(color.premul(), GrConstColorProcessor::kModulateA_InputMode); } #endif diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp index 7696e1632e..51e30ead63 100644 --- a/src/core/SkComposeShader.cpp +++ b/src/core/SkComposeShader.cpp @@ -192,7 +192,7 @@ sk_sp SkComposeShader::asFragmentProcessor(const AsFPArgs& switch (mode) { case SkXfermode::kClear_Mode: - return GrConstColorProcessor::Make(GrColor_TRANSPARENT_BLACK, + return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), GrConstColorProcessor::kIgnore_InputMode); break; case SkXfermode::kSrc_Mode: diff --git a/src/core/SkModeColorFilter.cpp b/src/core/SkModeColorFilter.cpp index 8da7c009ab..977e87f7e5 100644 --- a/src/core/SkModeColorFilter.cpp +++ b/src/core/SkModeColorFilter.cpp @@ -106,13 +106,14 @@ bool SkModeColorFilter::onAppendStages(SkRasterPipeline* p) const { #include "effects/GrConstColorProcessor.h" #include "SkGr.h" -sk_sp SkModeColorFilter::asFragmentProcessor(GrContext*) const { +sk_sp SkModeColorFilter::asFragmentProcessor( + GrContext*, SkColorSpace* dstColorSpace) const { if (SkXfermode::kDst_Mode == fMode) { return nullptr; } sk_sp constFP( - GrConstColorProcessor::Make(SkColorToPremulGrColor(fColor), + GrConstColorProcessor::Make(SkColorToPremulGrColor4f(fColor, dstColorSpace), GrConstColorProcessor::kIgnore_InputMode)); sk_sp fp( GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(constFP), fMode)); diff --git a/src/core/SkModeColorFilter.h b/src/core/SkModeColorFilter.h index c9d75abcea..cd8fe7cb75 100644 --- a/src/core/SkModeColorFilter.h +++ b/src/core/SkModeColorFilter.h @@ -32,7 +32,7 @@ public: #endif #if SK_SUPPORT_GPU - sk_sp asFragmentProcessor(GrContext*) const override; + sk_sp asFragmentProcessor(GrContext*, SkColorSpace*) const override; #endif SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter) diff --git a/src/effects/SkColorCubeFilter.cpp b/src/effects/SkColorCubeFilter.cpp index 3eb70d32d0..2a921d8e50 100644 --- a/src/effects/SkColorCubeFilter.cpp +++ b/src/effects/SkColorCubeFilter.cpp @@ -298,7 +298,8 @@ void GrColorCubeEffect::GLSLProcessor::GenKey(const GrProcessor& proc, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { } -sk_sp SkColorCubeFilter::asFragmentProcessor(GrContext* context) const { +sk_sp SkColorCubeFilter::asFragmentProcessor(GrContext* context, + SkColorSpace*) const { static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); GrUniqueKey key; GrUniqueKey::Builder builder(&key, kDomain, 2); diff --git a/src/effects/SkGammaColorFilter.cpp b/src/effects/SkGammaColorFilter.cpp index eba8e320d8..181ab770f4 100644 --- a/src/effects/SkGammaColorFilter.cpp +++ b/src/effects/SkGammaColorFilter.cpp @@ -50,7 +50,8 @@ void SkGammaColorFilter::toString(SkString* str) const { #endif #if SK_SUPPORT_GPU -sk_sp SkGammaColorFilter::asFragmentProcessor(GrContext*) const { +sk_sp SkGammaColorFilter::asFragmentProcessor(GrContext*, + SkColorSpace*) const { return GrGammaEffect::Make(fGamma); } #endif diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp index ec94eca76d..19b2c72956 100644 --- a/src/effects/SkLumaColorFilter.cpp +++ b/src/effects/SkLumaColorFilter.cpp @@ -111,7 +111,7 @@ private: } }; -sk_sp SkLumaColorFilter::asFragmentProcessor(GrContext*) const { +sk_sp SkLumaColorFilter::asFragmentProcessor(GrContext*, SkColorSpace*) const { return LumaColorFilterEffect::Make(); } #endif diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp index 5dbdab1f32..06bf8135ca 100644 --- a/src/effects/SkPerlinNoiseShader.cpp +++ b/src/effects/SkPerlinNoiseShader.cpp @@ -906,13 +906,17 @@ sk_sp SkPerlinNoiseShader::asFragmentProcessor(const AsFPAr if (0 == fNumOctaves) { if (kFractalNoise_Type == fType) { // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2) + // TODO: Either treat the output of this shader as sRGB or allow client to specify a + // color space of the noise. Either way, this case (and the GLSL) need to convert to + // the destination. sk_sp inner( - GrConstColorProcessor::Make(0x80404040, + GrConstColorProcessor::Make(GrColor4f::FromGrColor(0x80404040), GrConstColorProcessor::kModulateRGBA_InputMode)); return GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)); } // Emit zero. - return GrConstColorProcessor::Make(0x0, GrConstColorProcessor::kIgnore_InputMode); + return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), + GrConstColorProcessor::kIgnore_InputMode); } // Either we don't stitch tiles, either we have a valid tile size diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index ebf646b999..75910882c4 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -49,7 +49,7 @@ public: sk_sp makeComposed(sk_sp inner) const override; #if SK_SUPPORT_GPU - sk_sp asFragmentProcessor(GrContext*) const override; + sk_sp asFragmentProcessor(GrContext*, SkColorSpace*) const override; #endif void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override; @@ -561,13 +561,14 @@ sk_sp ColorTableEffect::TestCreate(GrProcessorTestData* d) (flags & (1 << 2)) ? luts[2] : nullptr, (flags & (1 << 3)) ? luts[3] : nullptr )); - - sk_sp fp = filter->asFragmentProcessor(d->fContext); + sk_sp colorSpace = GrTest::TestColorSpace(d->fRandom); + sk_sp fp = filter->asFragmentProcessor(d->fContext, colorSpace.get()); SkASSERT(fp); return fp; } -sk_sp SkTable_ColorFilter::asFragmentProcessor(GrContext* context) const { +sk_sp SkTable_ColorFilter::asFragmentProcessor(GrContext* context, + SkColorSpace*) const { SkBitmap bitmap; this->asComponentTable(&bitmap); diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp index b0735168b5..2ceba4b385 100644 --- a/src/effects/SkXfermodeImageFilter.cpp +++ b/src/effects/SkXfermodeImageFilter.cpp @@ -268,8 +268,8 @@ sk_sp SkXfermodeImageFilter_Base::filterImageGPU( GrTextureDomain::kDecal_Mode, GrTextureParams::kNone_FilterMode); } else { - bgFP = GrConstColorProcessor::Make(GrColor_TRANSPARENT_BLACK, - GrConstColorProcessor::kIgnore_InputMode); + bgFP = GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), + GrConstColorProcessor::kIgnore_InputMode); } if (foregroundTex) { diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index 123792d251..3f60b4aa0f 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -356,7 +356,11 @@ sk_sp GrFragmentProcessor::RunInSeries(sk_sp> replacementSeries; @@ -364,8 +368,10 @@ sk_sp GrFragmentProcessor::RunInSeries(sk_sp 0 && info.inputColorIsUsed()) { + // See comment above - need to preserve 4f and color spaces during invariant processing. sk_sp colorFP(GrConstColorProcessor::Make( - info.inputColorToFirstEffectiveProccesor(), GrConstColorProcessor::kIgnore_InputMode)); + GrColor4f::FromGrColor(info.inputColorToFirstEffectiveProccesor()), + GrConstColorProcessor::kIgnore_InputMode)); cnt += 1; replacementSeries.reserve(cnt); replacementSeries.emplace_back(std::move(colorFP)); diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp index d33881c09d..c6d7f7d60d 100644 --- a/src/gpu/GrPaint.cpp +++ b/src/gpu/GrPaint.cpp @@ -17,7 +17,7 @@ GrPaint::GrPaint() , fDisableOutputConversionToSRGB(false) , fAllowSRGBInputs(false) , fUsesDistanceVectorField(false) - , fColor(GrColor4f::FromGrColor(GrColor_WHITE)) {} + , fColor(GrColor4f::OpaqueWhite()) {} void GrPaint::setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) { fXPFactory = GrCoverageSetOpXPFactory::Make(regionOp, invertCoverage); diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 150087828e..ed974a7bbe 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -636,8 +636,11 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context, // We can ignore origColor here - alpha is unchanged by gamma GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor()); if (GrColor_WHITE != paintAlpha) { + // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all + // color channels. It's value should be treated as the same in ANY color space. grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make( - paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode)); + GrColor4f::FromGrColor(paintAlpha), + GrConstColorProcessor::kModulateRGBA_InputMode)); } } else { // The shader's FP sees the paint unpremul color @@ -648,10 +651,9 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context, if (primColorMode) { // There is a blend between the primitive color and the paint color. The blend considers // the opaque paint color. The paint's alpha is applied to the post-blended color. - // SRGBTODO: Preserve 4f on this code path sk_sp processor( - GrConstColorProcessor::Make(origColor.opaque().toGrColor(), - GrConstColorProcessor::kIgnore_InputMode)); + GrConstColorProcessor::Make(origColor.opaque(), + GrConstColorProcessor::kIgnore_InputMode)); if (primitiveIsSrc) { processor = GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(processor), *primColorMode); @@ -668,8 +670,11 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context, // We can ignore origColor here - alpha is unchanged by gamma GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor()); if (GrColor_WHITE != paintAlpha) { + // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all + // color channels. It's value should be treated as the same in ANY color space. grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make( - paintAlpha, GrConstColorProcessor::kModulateRGBA_InputMode)); + GrColor4f::FromGrColor(paintAlpha), + GrConstColorProcessor::kModulateRGBA_InputMode)); } } else { // No shader, no primitive color. @@ -691,7 +696,8 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context, colorFilter->filterColor(skPaint.getColor()), false, nullptr)); } } else { - sk_sp cfFP(colorFilter->asFragmentProcessor(context)); + sk_sp cfFP(colorFilter->asFragmentProcessor(context, + dc->getColorSpace())); if (cfFP) { grPaint->addColorFragmentProcessor(std::move(cfFP)); } else { diff --git a/src/gpu/effects/GrConstColorProcessor.cpp b/src/gpu/effects/GrConstColorProcessor.cpp index 0684c9cdb2..019d6991c2 100644 --- a/src/gpu/effects/GrConstColorProcessor.cpp +++ b/src/gpu/effects/GrConstColorProcessor.cpp @@ -14,7 +14,7 @@ class GLConstColorProcessor : public GrGLSLFragmentProcessor { public: - GLConstColorProcessor() : fPrevColor(GrColor_ILLEGAL) {} + GLConstColorProcessor() : fPrevColor(GrColor4f::kIllegalConstructor) {} void emitCode(EmitArgs& args) override { GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; @@ -44,26 +44,18 @@ public: protected: void onSetData(const GrGLSLProgramDataManager& pdm, const GrProcessor& processor) override { - GrColor color = processor.cast().color(); - // We use the "illegal" color value as an uninit sentinel. However, ut isn't inherently - // illegal to use this processor with unpremul colors. So we correctly handle the case - // when the "illegal" color is used but we will always upload it. - if (GrColor_ILLEGAL == color || fPrevColor != color) { - static const float scale = 1.f / 255.f; - float floatColor[4] = { - GrColorUnpackR(color) * scale, - GrColorUnpackG(color) * scale, - GrColorUnpackB(color) * scale, - GrColorUnpackA(color) * scale, - }; - pdm.set4fv(fColorUniform, 1, floatColor); + GrColor4f color = processor.cast().color(); + // We use the "illegal" color value as an uninit sentinel. With GrColor4f, the "illegal" + // color is *really* illegal (not just unpremultiplied), so this check is simple. + if (fPrevColor != color) { + pdm.set4fv(fColorUniform, 1, color.fRGBA); fPrevColor = color; } } private: GrGLSLProgramDataManager::UniformHandle fColorUniform; - GrColor fPrevColor; + GrColor4f fPrevColor; typedef GrGLSLFragmentProcessor INHERITED; }; @@ -72,23 +64,23 @@ private: void GrConstColorProcessor::onComputeInvariantOutput(GrInvariantOutput* inout) const { if (kIgnore_InputMode == fMode) { - inout->setToOther(kRGBA_GrColorComponentFlags, fColor, + inout->setToOther(kRGBA_GrColorComponentFlags, fColor.toGrColor(), GrInvariantOutput::kWillNot_ReadInput); } else { - GrColor r = GrColorUnpackR(fColor); - bool colorIsSingleChannel = r == GrColorUnpackG(fColor) && r == GrColorUnpackB(fColor) && - r == GrColorUnpackA(fColor); + float r = fColor.fRGBA[0]; + bool colorIsSingleChannel = r == fColor.fRGBA[1] && r == fColor.fRGBA[2] && + r == fColor.fRGBA[3]; if (kModulateRGBA_InputMode == fMode) { if (colorIsSingleChannel) { - inout->mulByKnownSingleComponent(r); + inout->mulByKnownSingleComponent(SkToU8(sk_float_round2int(255.0f * r))); } else { - inout->mulByKnownFourComponents(fColor); + inout->mulByKnownFourComponents(fColor.toGrColor()); } } else { if (colorIsSingleChannel) { - inout->mulAlphaByKnownSingleComponent(r); + inout->mulAlphaByKnownSingleComponent(SkToU8(sk_float_round2int(255.0f * r))); } else { - inout->mulAlphaByKnownFourComponents(fColor); + inout->mulAlphaByKnownFourComponents(fColor.toGrColor()); } } } @@ -113,7 +105,7 @@ bool GrConstColorProcessor::onIsEqual(const GrFragmentProcessor& other) const { GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConstColorProcessor); sk_sp GrConstColorProcessor::TestCreate(GrProcessorTestData* d) { - GrColor color SK_INIT_TO_AVOID_WARNING; + GrColor4f color; int colorPicker = d->fRandom->nextULessThan(3); switch (colorPicker) { case 0: { @@ -121,15 +113,15 @@ sk_sp GrConstColorProcessor::TestCreate(GrProcessorTestData uint32_t r = d->fRandom->nextULessThan(a+1); uint32_t g = d->fRandom->nextULessThan(a+1); uint32_t b = d->fRandom->nextULessThan(a+1); - color = GrColorPackRGBA(r, g, b, a); + color = GrColor4f::FromGrColor(GrColorPackRGBA(r, g, b, a)); break; } case 1: - color = 0; + color = GrColor4f::TransparentBlack(); break; case 2: - color = d->fRandom->nextULessThan(0x100); - color = color | (color << 8) | (color << 16) | (color << 24); + uint32_t c = d->fRandom->nextULessThan(0x100); + color = GrColor4f::FromGrColor(c | (c << 8) | (c << 16) | (c << 24)); break; } InputMode mode = static_cast(d->fRandom->nextULessThan(kInputModeCnt)); diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp index 5ce7867997..7ad2c08126 100644 --- a/src/gpu/effects/GrConvexPolyEffect.cpp +++ b/src/gpu/effects/GrConvexPolyEffect.cpp @@ -253,10 +253,11 @@ sk_sp GrConvexPolyEffect::Make(GrPrimitiveEdgeType type, co // skip the draw or omit the clip element. if (!SkPathPriv::CheapComputeFirstDirection(path, &dir)) { if (GrProcessorEdgeTypeIsInverseFill(type)) { - return GrConstColorProcessor::Make(0xFFFFFFFF, + return GrConstColorProcessor::Make(GrColor4f::OpaqueWhite(), GrConstColorProcessor::kModulateRGBA_InputMode); } - return GrConstColorProcessor::Make(0, GrConstColorProcessor::kIgnore_InputMode); + return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), + GrConstColorProcessor::kIgnore_InputMode); } SkVector t; diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp index fba4050f71..935747bccd 100644 --- a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp +++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp @@ -123,7 +123,7 @@ sk_sp GrXfermodeFragmentProcessor::MakeFromTwoProcessors( sk_sp src, sk_sp dst, SkXfermode::Mode mode) { switch (mode) { case SkXfermode::kClear_Mode: - return GrConstColorProcessor::Make(GrColor_TRANSPARENT_BLACK, + return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), GrConstColorProcessor::kIgnore_InputMode); case SkXfermode::kSrc_Mode: return src; @@ -285,7 +285,7 @@ sk_sp GrXfermodeFragmentProcessor::MakeFromDstProcessor( sk_sp dst, SkXfermode::Mode mode) { switch (mode) { case SkXfermode::kClear_Mode: - return GrConstColorProcessor::Make(GrColor_TRANSPARENT_BLACK, + return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), GrConstColorProcessor::kIgnore_InputMode); case SkXfermode::kSrc_Mode: return nullptr; @@ -300,7 +300,7 @@ sk_sp GrXfermodeFragmentProcessor::MakeFromSrcProcessor( sk_sp src, SkXfermode::Mode mode) { switch (mode) { case SkXfermode::kClear_Mode: - return GrConstColorProcessor::Make(GrColor_TRANSPARENT_BLACK, + return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), GrConstColorProcessor::kIgnore_InputMode); case SkXfermode::kDst_Mode: return nullptr; diff --git a/tests/GpuColorFilterTest.cpp b/tests/GpuColorFilterTest.cpp index 0fbce6c562..723e9e9197 100644 --- a/tests/GpuColorFilterTest.cpp +++ b/tests/GpuColorFilterTest.cpp @@ -99,7 +99,8 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(GpuColorFilter, reporter, ctxInfo) { for (size_t i = 0; i < SK_ARRAY_COUNT(filterTests); ++i) { const GetConstantComponentTestCase& test = filterTests[i]; auto cf(SkColorFilter::MakeModeFilter(test.filterColor, test.filterMode)); - sk_sp fp(cf->asFragmentProcessor(ctxInfo.grContext())); + // TODO: Test other color spaces + sk_sp fp(cf->asFragmentProcessor(ctxInfo.grContext(), nullptr)); REPORTER_ASSERT(reporter, fp); GrInvariantOutput inout(test.inputColor, static_cast(test.inputComponents),