diff options
author | 2017-10-19 15:42:01 -0400 | |
---|---|---|
committer | 2017-10-19 20:09:44 +0000 | |
commit | d43f7b68186096430b9de9af0de8ba66013aa448 (patch) | |
tree | 8989981d59df4f3bcd140da23a1707bcae16454d /src | |
parent | a4aa1332a4c6a70d6c54a3bbc6172d26fc2dce15 (diff) |
Simplify GrGradientEffect color handling
For analytic gradients, hoist the byte -> float, premultiplication,
and color space transformation to creation time. Eliminates second
array (only one was ever used), and four different onSetData helpers.
Bug: skia:
Change-Id: Ib5740b37ef2a5dcf2551e85b1e72f64d8cbcc5fa
Reviewed-on: https://skia-review.googlesource.com/62120
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/shaders/gradients/SkGradientShader.cpp | 162 | ||||
-rw-r--r-- | src/shaders/gradients/SkGradientShaderPriv.h | 14 |
2 files changed, 33 insertions, 143 deletions
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp index 2925ce14c2..53f25643c6 100644 --- a/src/shaders/gradients/SkGradientShader.cpp +++ b/src/shaders/gradients/SkGradientShader.cpp @@ -1308,93 +1308,6 @@ void GrGradientEffect::GLSLProcessor::emitUniforms(GrGLSLUniformHandler* uniform } } -static inline void set_after_interp_color_uni_array( - const GrGLSLProgramDataManager& pdman, - const GrGLSLProgramDataManager::UniformHandle uni, - const SkTDArray<SkColor4f>& colors, - const GrColorSpaceXform* colorSpaceXform) { - int count = colors.count(); - if (colorSpaceXform) { - constexpr int kSmallCount = 10; - SkAutoSTArray<4 * kSmallCount, float> vals(4 * count); - - for (int i = 0; i < count; i++) { - colorSpaceXform->srcToDst().mapScalars(colors[i].vec(), &vals[4 * i]); - } - - pdman.set4fv(uni, count, vals.get()); - } else { - pdman.set4fv(uni, count, (float*)&colors[0]); - } -} - -static inline void set_before_interp_color_uni_array( - const GrGLSLProgramDataManager& pdman, - const GrGLSLProgramDataManager::UniformHandle uni, - const SkTDArray<SkColor4f>& colors, - const GrColorSpaceXform* colorSpaceXform) { - int count = colors.count(); - constexpr int kSmallCount = 10; - SkAutoSTArray<4 * kSmallCount, float> vals(4 * count); - - for (int i = 0; i < count; i++) { - float a = colors[i].fA; - vals[4 * i + 0] = colors[i].fR * a; - vals[4 * i + 1] = colors[i].fG * a; - vals[4 * i + 2] = colors[i].fB * a; - vals[4 * i + 3] = a; - } - - if (colorSpaceXform) { - for (int i = 0; i < count; i++) { - colorSpaceXform->srcToDst().mapScalars(&vals[4 * i]); - } - } - - pdman.set4fv(uni, count, vals.get()); -} - -static inline void set_after_interp_color_uni_array(const GrGLSLProgramDataManager& pdman, - const GrGLSLProgramDataManager::UniformHandle uni, - const SkTDArray<SkColor>& colors) { - int count = colors.count(); - constexpr int kSmallCount = 10; - - SkAutoSTArray<4*kSmallCount, float> vals(4*count); - - for (int i = 0; i < colors.count(); i++) { - // RGBA - vals[4*i + 0] = SkColorGetR(colors[i]) / 255.f; - vals[4*i + 1] = SkColorGetG(colors[i]) / 255.f; - vals[4*i + 2] = SkColorGetB(colors[i]) / 255.f; - vals[4*i + 3] = SkColorGetA(colors[i]) / 255.f; - } - - pdman.set4fv(uni, colors.count(), vals.get()); -} - -static inline void set_before_interp_color_uni_array(const GrGLSLProgramDataManager& pdman, - const GrGLSLProgramDataManager::UniformHandle uni, - const SkTDArray<SkColor>& colors) { - int count = colors.count(); - constexpr int kSmallCount = 10; - - SkAutoSTArray<4*kSmallCount, float> vals(4*count); - - for (int i = 0; i < count; i++) { - float a = SkColorGetA(colors[i]) / 255.f; - float aDiv255 = a / 255.f; - - // RGBA - vals[4*i + 0] = SkColorGetR(colors[i]) * aDiv255; - vals[4*i + 1] = SkColorGetG(colors[i]) * aDiv255; - vals[4*i + 2] = SkColorGetB(colors[i]) * aDiv255; - vals[4*i + 3] = a; - } - - pdman.set4fv(uni, count, vals.get()); -} - void GrGradientEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor) { const GrGradientEffect& e = processor.cast<GrGradientEffect>(); @@ -1412,24 +1325,7 @@ void GrGradientEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager& case GrGradientEffect::kHardStopLeftEdged_ColorType: case GrGradientEffect::kHardStopRightEdged_ColorType: case GrGradientEffect::kTwo_ColorType: { - if (e.fColors4f.count() > 0) { - // Gamma-correct / color-space aware - if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { - set_before_interp_color_uni_array(pdman, fColorsUni, e.fColors4f, - e.fColorSpaceXform.get()); - } else { - set_after_interp_color_uni_array(pdman, fColorsUni, e.fColors4f, - e.fColorSpaceXform.get()); - } - } else { - // Legacy mode. Would be nice if we had converted the 8-bit colors to float earlier - if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) { - set_before_interp_color_uni_array(pdman, fColorsUni, e.fColors); - } else { - set_after_interp_color_uni_array(pdman, fColorsUni, e.fColors); - } - } - + pdman.set4fv(fColorsUni, e.fColors4f.count(), (float*)&e.fColors4f[0]); break; } @@ -1645,13 +1541,36 @@ GrGradientEffect::GrGradientEffect(ClassID classID, const CreateArgs& args, bool fColorType = this->determineColorType(shader); fColorSpaceXform = std::move(args.fColorSpaceXform); + fWrapMode = args.fWrapMode; - if (kTexture_ColorType != fColorType) { - SkASSERT(shader.fOrigColors && shader.fOrigColors4f); - if (args.fGammaCorrect) { - fColors4f = SkTDArray<SkColor4f>(shader.fOrigColors4f, shader.fColorCount); + if (kTexture_ColorType == fColorType) { + // Doesn't matter how this is set, just be consistent because it is part of the effect key. + fPremulType = kBeforeInterp_PremulType; + } else { + if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getGradFlags()) { + fPremulType = kBeforeInterp_PremulType; } else { - fColors = SkTDArray<SkColor>(shader.fOrigColors, shader.fColorCount); + fPremulType = kAfterInterp_PremulType; + } + + // Convert input colors to GrColor4f, possibly premul, and apply color space xform + SkASSERT(shader.fOrigColors && shader.fOrigColors4f); + fColors4f.setCount(shader.fColorCount); + for (int i = 0; i < shader.fColorCount; ++i) { + if (args.fGammaCorrect) { + fColors4f[i] = GrColor4f::FromSkColor4f(shader.fOrigColors4f[i]); + } else { + GrColor grColor = SkColorToUnpremulGrColor(shader.fOrigColors[i]); + fColors4f[i] = GrColor4f::FromGrColor(grColor); + } + + if (kBeforeInterp_PremulType == fPremulType) { + fColors4f[i] = fColors4f[i].premul(); + } + + if (fColorSpaceXform) { + fColorSpaceXform->srcToDst().mapScalars(fColors4f[i].fRGBA, fColors4f[i].fRGBA); + } } if (shader.fOrigPos) { @@ -1662,31 +1581,17 @@ GrGradientEffect::GrGradientEffect(ClassID classID, const CreateArgs& args, bool } } - fWrapMode = args.fWrapMode; - switch (fColorType) { - // The two and three color specializations do not currently support tiling. case kTwo_ColorType: case kThree_ColorType: case kHardStopLeftEdged_ColorType: case kHardStopRightEdged_ColorType: case kSingleHardStop_ColorType: fRow = -1; - - if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getGradFlags()) { - fPremulType = kBeforeInterp_PremulType; - } else { - fPremulType = kAfterInterp_PremulType; - } - fCoordTransform.reset(*args.fMatrix); - break; - case kTexture_ColorType: - // doesn't matter how this is set, just be consistent because it is part of the - // effect key. - fPremulType = kBeforeInterp_PremulType; + case kTexture_ColorType: SkGradientShaderBase::GradientBitmapType bitmapType = SkGradientShaderBase::GradientBitmapType::kLegacy; if (args.fGammaCorrect) { @@ -1756,7 +1661,6 @@ GrGradientEffect::GrGradientEffect(ClassID classID, const CreateArgs& args, bool GrGradientEffect::GrGradientEffect(const GrGradientEffect& that) : INHERITED(that.classID(), OptFlags(that.fIsOpaque)) - , fColors(that.fColors) , fColors4f(that.fColors4f) , fColorSpaceXform(that.fColorSpaceXform) , fPositions(that.fPositions) @@ -1802,16 +1706,10 @@ bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const { } } if (this->getPremulType() != ge.getPremulType() || - this->fColors.count() != ge.fColors.count() || this->fColors4f.count() != ge.fColors4f.count()) { return false; } - for (int i = 0; i < this->fColors.count(); i++) { - if (*this->getColors(i) != *ge.getColors(i)) { - return false; - } - } for (int i = 0; i < this->fColors4f.count(); i++) { if (*this->getColors4f(i) != *ge.getColors4f(i)) { return false; diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h index 0abfd35e99..da9098cb5d 100644 --- a/src/shaders/gradients/SkGradientShaderPriv.h +++ b/src/shaders/gradients/SkGradientShaderPriv.h @@ -402,13 +402,7 @@ public: PremulType getPremulType() const { return fPremulType; } - const SkColor* getColors(int pos) const { - SkASSERT(fColorType != kTexture_ColorType); - SkASSERT(pos < fColors.count()); - return &fColors[pos]; - } - - const SkColor4f* getColors4f(int pos) const { + const GrColor4f* getColors4f(int pos) const { SkASSERT(fColorType != kTexture_ColorType); SkASSERT(pos < fColors4f.count()); return &fColors4f[pos]; @@ -453,11 +447,9 @@ protected: private: static OptimizationFlags OptFlags(bool isOpaque); - // If we're in legacy mode, then fColors will be populated. If we're gamma-correct, then - // fColors4f and fColorSpaceXform will be populated. - SkTDArray<SkColor> fColors; + SkTDArray<GrColor4f> fColors4f; - SkTDArray<SkColor4f> fColors4f; + // Only present if a color space transformation is needed sk_sp<GrColorSpaceXform> fColorSpaceXform; SkTDArray<SkScalar> fPositions; |