GrConstColorProcessor uses 4f colors in the destination space
Many places that construct one are explicitly specifying opaque white or transparent black, which we can assume (based on the semantics of the operation) should remain (0,0,0,0) or (1,1,1,1), so that's simple. In other cases, we convert our source color to destination space. One wrinkle is tht SkColorFilter now needs to know the destination color space, due to SkModeColorFilter. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3903 Change-Id: I4969c0260588f4021300733f601b47dc606adf79 Reviewed-on: https://skia-review.googlesource.com/3903 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
18b61f9cb9
commit
618d304eb3
@ -1334,13 +1334,17 @@ sk_sp<GrFragmentProcessor> 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<GrFragmentProcessor> 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<GrTexture> permutationsTexture(
|
||||
|
@ -103,7 +103,7 @@ protected:
|
||||
&grPaint));
|
||||
|
||||
GrConstColorProcessor::InputMode mode = (GrConstColorProcessor::InputMode) m;
|
||||
GrColor color = kColors[procColor];
|
||||
GrColor4f color = GrColor4f::FromGrColor(kColors[procColor]);
|
||||
sk_sp<GrFragmentProcessor> fp(GrConstColorProcessor::Make(color, mode));
|
||||
|
||||
grPaint.addColorFragmentProcessor(std::move(fp));
|
||||
|
@ -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<GrFragmentProcessor> asFragmentProcessor(GrContext*) const;
|
||||
virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*,
|
||||
SkColorSpace* dstColorSpace) const;
|
||||
#endif
|
||||
|
||||
bool affectsTransparentBlack() const {
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
uint32_t getFlags() const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const override;
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const override;
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const override;
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
@ -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);
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
};
|
||||
static const int kInputModeCnt = kLastInputMode + 1;
|
||||
|
||||
static sk_sp<GrFragmentProcessor> Make(GrColor color, InputMode mode) {
|
||||
static sk_sp<GrFragmentProcessor> Make(GrColor4f color, InputMode mode) {
|
||||
return sk_sp<GrFragmentProcessor>(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<GrConstColorProcessor>();
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ private:
|
||||
|
||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
|
||||
|
||||
GrColor fColor;
|
||||
GrColor4f fColor;
|
||||
InputMode fMode;
|
||||
|
||||
typedef GrFragmentProcessor INHERITED;
|
||||
|
@ -32,7 +32,7 @@ bool SkColorFilter::asComponentTable(SkBitmap*) const {
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> SkColorFilter::asFragmentProcessor(GrContext*) const {
|
||||
sk_sp<GrFragmentProcessor> SkColorFilter::asFragmentProcessor(GrContext*, SkColorSpace*) const {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
@ -114,9 +114,10 @@ public:
|
||||
#endif
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext* context) const override {
|
||||
sk_sp<GrFragmentProcessor> innerFP(fInner->asFragmentProcessor(context));
|
||||
sk_sp<GrFragmentProcessor> outerFP(fOuter->asFragmentProcessor(context));
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext* context,
|
||||
SkColorSpace* dstColorSpace) const override {
|
||||
sk_sp<GrFragmentProcessor> innerFP(fInner->asFragmentProcessor(context, dstColorSpace));
|
||||
sk_sp<GrFragmentProcessor> outerFP(fOuter->asFragmentProcessor(context, dstColorSpace));
|
||||
if (!innerFP || !outerFP) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -104,7 +104,8 @@ sk_sp<GrFragmentProcessor> SkColorFilterShader::asFragmentProcessor(const AsFPAr
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrFragmentProcessor> fp2(fFilter->asFragmentProcessor(args.fContext));
|
||||
sk_sp<GrFragmentProcessor> fp2(fFilter->asFragmentProcessor(args.fContext,
|
||||
args.fDstColorSpace));
|
||||
if (!fp2) {
|
||||
return fp1;
|
||||
}
|
||||
|
@ -396,7 +396,8 @@ sk_sp<GrFragmentProcessor> ColorMatrixEffect::TestCreate(GrProcessorTestData* d)
|
||||
return ColorMatrixEffect::Make(colorMatrix);
|
||||
}
|
||||
|
||||
sk_sp<GrFragmentProcessor> SkColorMatrixFilterRowMajor255::asFragmentProcessor(GrContext*) const {
|
||||
sk_sp<GrFragmentProcessor> SkColorMatrixFilterRowMajor255::asFragmentProcessor(
|
||||
GrContext*, SkColorSpace*) const {
|
||||
return ColorMatrixEffect::Make(fMatrix);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter>) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const override;
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
@ -89,8 +89,8 @@ SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
|
||||
|
||||
#include "SkGr.h"
|
||||
#include "effects/GrConstColorProcessor.h"
|
||||
sk_sp<GrFragmentProcessor> SkColorShader::asFragmentProcessor(const AsFPArgs&) const {
|
||||
GrColor color = SkColorToPremulGrColor(fColor);
|
||||
sk_sp<GrFragmentProcessor> 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<GrFragmentProcessor> 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<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(const AsFPArgs& args) const {
|
||||
sk_sp<GrColorSpaceXform> 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
|
||||
|
@ -192,7 +192,7 @@ sk_sp<GrFragmentProcessor> 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:
|
||||
|
@ -106,13 +106,14 @@ bool SkModeColorFilter::onAppendStages(SkRasterPipeline* p) const {
|
||||
#include "effects/GrConstColorProcessor.h"
|
||||
#include "SkGr.h"
|
||||
|
||||
sk_sp<GrFragmentProcessor> SkModeColorFilter::asFragmentProcessor(GrContext*) const {
|
||||
sk_sp<GrFragmentProcessor> SkModeColorFilter::asFragmentProcessor(
|
||||
GrContext*, SkColorSpace* dstColorSpace) const {
|
||||
if (SkXfermode::kDst_Mode == fMode) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrFragmentProcessor> constFP(
|
||||
GrConstColorProcessor::Make(SkColorToPremulGrColor(fColor),
|
||||
GrConstColorProcessor::Make(SkColorToPremulGrColor4f(fColor, dstColorSpace),
|
||||
GrConstColorProcessor::kIgnore_InputMode));
|
||||
sk_sp<GrFragmentProcessor> fp(
|
||||
GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(constFP), fMode));
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
#endif
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const override;
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
|
||||
#endif
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter)
|
||||
|
||||
|
@ -298,7 +298,8 @@ void GrColorCubeEffect::GLSLProcessor::GenKey(const GrProcessor& proc,
|
||||
const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
|
||||
}
|
||||
|
||||
sk_sp<GrFragmentProcessor> SkColorCubeFilter::asFragmentProcessor(GrContext* context) const {
|
||||
sk_sp<GrFragmentProcessor> SkColorCubeFilter::asFragmentProcessor(GrContext* context,
|
||||
SkColorSpace*) const {
|
||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||
GrUniqueKey key;
|
||||
GrUniqueKey::Builder builder(&key, kDomain, 2);
|
||||
|
@ -50,7 +50,8 @@ void SkGammaColorFilter::toString(SkString* str) const {
|
||||
#endif
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> SkGammaColorFilter::asFragmentProcessor(GrContext*) const {
|
||||
sk_sp<GrFragmentProcessor> SkGammaColorFilter::asFragmentProcessor(GrContext*,
|
||||
SkColorSpace*) const {
|
||||
return GrGammaEffect::Make(fGamma);
|
||||
}
|
||||
#endif
|
||||
|
@ -111,7 +111,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
sk_sp<GrFragmentProcessor> SkLumaColorFilter::asFragmentProcessor(GrContext*) const {
|
||||
sk_sp<GrFragmentProcessor> SkLumaColorFilter::asFragmentProcessor(GrContext*, SkColorSpace*) const {
|
||||
return LumaColorFilterEffect::Make();
|
||||
}
|
||||
#endif
|
||||
|
@ -906,13 +906,17 @@ sk_sp<GrFragmentProcessor> 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<GrFragmentProcessor> 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
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter> inner) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const override;
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
|
||||
#endif
|
||||
|
||||
void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override;
|
||||
@ -561,13 +561,14 @@ sk_sp<GrFragmentProcessor> ColorTableEffect::TestCreate(GrProcessorTestData* d)
|
||||
(flags & (1 << 2)) ? luts[2] : nullptr,
|
||||
(flags & (1 << 3)) ? luts[3] : nullptr
|
||||
));
|
||||
|
||||
sk_sp<GrFragmentProcessor> fp = filter->asFragmentProcessor(d->fContext);
|
||||
sk_sp<SkColorSpace> colorSpace = GrTest::TestColorSpace(d->fRandom);
|
||||
sk_sp<GrFragmentProcessor> fp = filter->asFragmentProcessor(d->fContext, colorSpace.get());
|
||||
SkASSERT(fp);
|
||||
return fp;
|
||||
}
|
||||
|
||||
sk_sp<GrFragmentProcessor> SkTable_ColorFilter::asFragmentProcessor(GrContext* context) const {
|
||||
sk_sp<GrFragmentProcessor> SkTable_ColorFilter::asFragmentProcessor(GrContext* context,
|
||||
SkColorSpace*) const {
|
||||
SkBitmap bitmap;
|
||||
this->asComponentTable(&bitmap);
|
||||
|
||||
|
@ -268,7 +268,7 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::filterImageGPU(
|
||||
GrTextureDomain::kDecal_Mode,
|
||||
GrTextureParams::kNone_FilterMode);
|
||||
} else {
|
||||
bgFP = GrConstColorProcessor::Make(GrColor_TRANSPARENT_BLACK,
|
||||
bgFP = GrConstColorProcessor::Make(GrColor4f::TransparentBlack(),
|
||||
GrConstColorProcessor::kIgnore_InputMode);
|
||||
}
|
||||
|
||||
|
@ -356,7 +356,11 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProc
|
||||
info.calcWithInitialValues(sk_sp_address_as_pointer_address(series), cnt,
|
||||
0x0, kNone_GrColorComponentFlags, false, false);
|
||||
if (kRGBA_GrColorComponentFlags == info.validFlags()) {
|
||||
return GrConstColorProcessor::Make(info.color(), GrConstColorProcessor::kIgnore_InputMode);
|
||||
// TODO: We need to preserve 4f and color spaces during invariant processing. This color
|
||||
// has definitely lost precision, and could easily be in the wrong gamut (or have been
|
||||
// built from colors in multiple spaces).
|
||||
return GrConstColorProcessor::Make(GrColor4f::FromGrColor(info.color()),
|
||||
GrConstColorProcessor::kIgnore_InputMode);
|
||||
}
|
||||
|
||||
SkTArray<sk_sp<GrFragmentProcessor>> replacementSeries;
|
||||
@ -364,8 +368,10 @@ sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProc
|
||||
int firstIdx = info.firstEffectiveProcessorIndex();
|
||||
cnt -= firstIdx;
|
||||
if (firstIdx > 0 && info.inputColorIsUsed()) {
|
||||
// See comment above - need to preserve 4f and color spaces during invariant processing.
|
||||
sk_sp<GrFragmentProcessor> 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));
|
||||
|
@ -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);
|
||||
|
@ -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,9 +651,8 @@ 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<GrFragmentProcessor> processor(
|
||||
GrConstColorProcessor::Make(origColor.opaque().toGrColor(),
|
||||
GrConstColorProcessor::Make(origColor.opaque(),
|
||||
GrConstColorProcessor::kIgnore_InputMode));
|
||||
if (primitiveIsSrc) {
|
||||
processor = GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(processor),
|
||||
@ -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<GrFragmentProcessor> cfFP(colorFilter->asFragmentProcessor(context));
|
||||
sk_sp<GrFragmentProcessor> cfFP(colorFilter->asFragmentProcessor(context,
|
||||
dc->getColorSpace()));
|
||||
if (cfFP) {
|
||||
grPaint->addColorFragmentProcessor(std::move(cfFP));
|
||||
} else {
|
||||
|
@ -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<GrConstColorProcessor>().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<GrConstColorProcessor>().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<GrFragmentProcessor> 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<GrFragmentProcessor> 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<InputMode>(d->fRandom->nextULessThan(kInputModeCnt));
|
||||
|
@ -253,10 +253,11 @@ sk_sp<GrFragmentProcessor> 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;
|
||||
|
@ -123,7 +123,7 @@ sk_sp<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromTwoProcessors(
|
||||
sk_sp<GrFragmentProcessor> src, sk_sp<GrFragmentProcessor> 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<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromDstProcessor(
|
||||
sk_sp<GrFragmentProcessor> 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<GrFragmentProcessor> GrXfermodeFragmentProcessor::MakeFromSrcProcessor(
|
||||
sk_sp<GrFragmentProcessor> 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;
|
||||
|
@ -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<GrFragmentProcessor> fp(cf->asFragmentProcessor(ctxInfo.grContext()));
|
||||
// TODO: Test other color spaces
|
||||
sk_sp<GrFragmentProcessor> fp(cf->asFragmentProcessor(ctxInfo.grContext(), nullptr));
|
||||
REPORTER_ASSERT(reporter, fp);
|
||||
GrInvariantOutput inout(test.inputColor,
|
||||
static_cast<GrColorComponentFlags>(test.inputComponents),
|
||||
|
Loading…
Reference in New Issue
Block a user