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:
Brian Osman 2016-10-25 10:51:28 -04:00 committed by Skia Commit-Bot
parent 18b61f9cb9
commit 618d304eb3
29 changed files with 128 additions and 83 deletions

View File

@ -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(

View File

@ -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));

View File

@ -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 {

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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()

View File

@ -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

View File

@ -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:

View File

@ -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));

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -111,7 +111,7 @@ private:
}
};
sk_sp<GrFragmentProcessor> SkLumaColorFilter::asFragmentProcessor(GrContext*) const {
sk_sp<GrFragmentProcessor> SkLumaColorFilter::asFragmentProcessor(GrContext*, SkColorSpace*) const {
return LumaColorFilterEffect::Make();
}
#endif

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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));

View File

@ -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);

View File

@ -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 {

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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),