Move impl into SkColorFilterBase

No expected changes to results (or public call-sites)

Change-Id: Ia0c5cfe2dc3beda82d91454527eda2e68287afb6
Bug: skia:10426
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/298559
Reviewed-by: John Stiles <johnstiles@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2020-06-24 16:56:33 -04:00 committed by Skia Commit-Bot
parent 0e94f949d1
commit b11e627644
28 changed files with 292 additions and 223 deletions

View File

@ -11,71 +11,44 @@
#include "include/core/SkBlendMode.h"
#include "include/core/SkColor.h"
#include "include/core/SkFlattenable.h"
#include "include/core/SkRefCnt.h"
class GrColorInfo;
class GrFragmentProcessor;
class GrRecordingContext;
class SkArenaAlloc;
class SkBitmap;
class SkColorMatrix;
class SkColorSpace;
struct SkStageRec;
using GrFPResult = std::tuple<bool, std::unique_ptr<GrFragmentProcessor>>;
namespace skvm {
class Builder;
struct F32;
struct Uniforms;
struct Color;
}
/**
* ColorFilters are optional objects in the drawing pipeline. When present in
* a paint, they are called with the "src" colors, and return new colors, which
* are then passed onto the next stage (either ImageFilter or Xfermode).
*
* All subclasses are required to be reentrant-safe : it must be legal to share
* the same instance between several threads.
*/
* ColorFilters are optional objects in the drawing pipeline. When present in
* a paint, they are called with the "src" colors, and return new colors, which
* are then passed onto the next stage (either ImageFilter or Xfermode).
*
* All subclasses are required to be reentrant-safe : it must be legal to share
* the same instance between several threads.
*/
class SK_API SkColorFilter : public SkFlattenable {
public:
// DEPRECATED. skbug.com/8941
bool asColorMode(SkColor* color, SkBlendMode* mode) const {
return this->onAsAColorMode(color, mode);
}
bool asColorMode(SkColor* color, SkBlendMode* mode) const;
/** If the filter can be represented by a source color plus Mode, this
* returns true, and sets (if not NULL) the color and mode appropriately.
* If not, this returns false and ignores the parameters.
*/
bool asAColorMode(SkColor* color, SkBlendMode* mode) const {
return this->onAsAColorMode(color, mode);
}
bool asAColorMode(SkColor* color, SkBlendMode* mode) const;
/** If the filter can be represented by a 5x4 matrix, this
* returns true, and sets the matrix appropriately.
* If not, this returns false and ignores the parameter.
*/
bool asAColorMatrix(float matrix[20]) const {
return this->onAsAColorMatrix(matrix);
}
bool appendStages(const SkStageRec& rec, bool shaderIsOpaque) const;
skvm::Color program(skvm::Builder*, skvm::Color,
SkColorSpace* dstCS, skvm::Uniforms*, SkArenaAlloc*) const;
bool asAColorMatrix(float matrix[20]) const;
// deprecated, use isAlphaUnchanged()
enum Flags {
/** If set the filter methods will not change the alpha channel of the colors.
*/
kAlphaUnchanged_Flag = 1 << 0,
};
uint32_t getFlags() const;
/** Returns the flags for this filter. Override in subclasses to return custom flags.
*/
virtual uint32_t getFlags() const { return 0; }
// Returns true if the filter is guaranteed to never change the alpha of a color it filters.
bool isAlphaUnchanged() const;
SkColor filterColor(SkColor) const;
@ -93,52 +66,13 @@ public:
*/
sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter> inner) const;
#if SK_SUPPORT_GPU
/**
* A subclass may implement this factory function to work with the GPU backend. It returns
* a GrFragmentProcessor that implemets the color filter in GPU shader code.
*
* The fragment processor receives a premultiplied input color and produces a premultiplied
* output color.
*
* A null return indicates that the color filter isn't implemented for the GPU backend.
*/
virtual std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
GrRecordingContext*, const GrColorInfo& dstColorInfo) const;
#endif
bool affectsTransparentBlack() const {
return this->filterColor(SK_ColorTRANSPARENT) != SK_ColorTRANSPARENT;
}
static void RegisterFlattenables();
static SkFlattenable::Type GetFlattenableType() {
return kSkColorFilter_Type;
}
SkFlattenable::Type getFlattenableType() const override {
return kSkColorFilter_Type;
}
static sk_sp<SkColorFilter> Deserialize(const void* data, size_t size,
const SkDeserialProcs* procs = nullptr) {
return sk_sp<SkColorFilter>(static_cast<SkColorFilter*>(
SkFlattenable::Deserialize(
kSkColorFilter_Type, data, size, procs).release()));
}
protected:
SkColorFilter() {}
virtual bool onAsAColorMatrix(float[20]) const;
virtual bool onAsAColorMode(SkColor* color, SkBlendMode* bmode) const;
private:
virtual bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const = 0;
virtual skvm::Color onProgram(skvm::Builder*, skvm::Color,
SkColorSpace* dstCS, skvm::Uniforms*, SkArenaAlloc*) const = 0;
SkColorFilter() = default;
friend class SkColorFilterBase;
typedef SkFlattenable INHERITED;
};

View File

@ -30,30 +30,14 @@ class SkRasterPipeline;
* not luminance, a dot-product of linear color channels. So at least
* SkLumaColorFilter and feColorMatrix+luminanceToAlpha agree there.)
*/
#include "include/core/SkFlattenable.h"
class SK_API SkLumaColorFilter : public SkColorFilter {
class SK_API SkLumaColorFilter {
public:
static sk_sp<SkColorFilter> Make();
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(GrRecordingContext*,
const GrColorInfo&) const override;
#endif
protected:
void flatten(SkWriteBuffer&) const override;
private:
SK_FLATTENABLE_HOOKS(SkLumaColorFilter)
friend class SkFlattenable;
SkLumaColorFilter();
bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override;
skvm::Color onProgram(skvm::Builder*, skvm::Color,
SkColorSpace* dstCS, skvm::Uniforms*, SkArenaAlloc*) const override;
typedef SkColorFilter INHERITED;
static void RegisterFlattenable();
};
#endif

View File

@ -5,13 +5,13 @@
* found in the LICENSE file.
*/
#include "include/core/SkColorFilter.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/core/SkUnPreMultiply.h"
#include "include/private/SkNx.h"
#include "include/private/SkTDArray.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkMatrixProvider.h"
@ -26,28 +26,48 @@
#include "src/gpu/effects/generated/GrMixerEffect.h"
#endif
bool SkColorFilter::onAsAColorMode(SkColor*, SkBlendMode*) const {
bool SkColorFilter::asColorMode(SkColor* color, SkBlendMode* mode) const {
return as_CFB(this)->onAsAColorMode(color, mode);
}
bool SkColorFilter::asAColorMode(SkColor* color, SkBlendMode* mode) const {
return as_CFB(this)->onAsAColorMode(color, mode);
}
bool SkColorFilter::asAColorMatrix(float matrix[20]) const {
return as_CFB(this)->onAsAColorMatrix(matrix);
}
uint32_t SkColorFilter::getFlags() const { return as_CFB(this)->onGetFlags(); }
bool SkColorFilter::isAlphaUnchanged() const {
return SkToBool(this->getFlags() & kAlphaUnchanged_Flag);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
bool SkColorFilterBase::onAsAColorMode(SkColor*, SkBlendMode*) const {
return false;
}
bool SkColorFilter::onAsAColorMatrix(float matrix[20]) const {
bool SkColorFilterBase::onAsAColorMatrix(float matrix[20]) const {
return false;
}
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> SkColorFilter::asFragmentProcessor(GrRecordingContext*,
std::unique_ptr<GrFragmentProcessor> SkColorFilterBase::asFragmentProcessor(GrRecordingContext*,
const GrColorInfo&) const {
return nullptr;
}
#endif
bool SkColorFilter::appendStages(const SkStageRec& rec, bool shaderIsOpaque) const {
bool SkColorFilterBase::appendStages(const SkStageRec& rec, bool shaderIsOpaque) const {
return this->onAppendStages(rec, shaderIsOpaque);
}
skvm::Color SkColorFilter::program(skvm::Builder* p, skvm::Color c,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const {
skvm::Color SkColorFilterBase::program(skvm::Builder* p, skvm::Color c,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const {
skvm::F32 original = c.a;
if ((c = this->onProgram(p,c, dstCS, uniforms,alloc))) {
if (this->getFlags() & kAlphaUnchanged_Flag) {
@ -80,7 +100,7 @@ SkColor4f SkColorFilter::filterColor4f(const SkColor4f& origSrcColor, SkColorSpa
SkStageRec rec = {
&pipeline, &alloc, kRGBA_F32_SkColorType, dstCS, dummyPaint, nullptr, matrixProvider
};
this->onAppendStages(rec, color.fA == 1);
as_CFB(this)->onAppendStages(rec, color.fA == 1);
SkPMColor4f dst;
SkRasterPipeline_MemoryCtx dstPtr = { &dst, 0 };
@ -91,16 +111,16 @@ SkColor4f SkColorFilter::filterColor4f(const SkColor4f& origSrcColor, SkColorSpa
///////////////////////////////////////////////////////////////////////////////////////////////////
class SkComposeColorFilter : public SkColorFilter {
class SkComposeColorFilter : public SkColorFilterBase {
public:
uint32_t getFlags() const override {
uint32_t onGetFlags() const override {
// Can only claim alphaunchanged support if both our proxys do.
return fOuter->getFlags() & fInner->getFlags();
return fOuter->onGetFlags() & fInner->onGetFlags();
}
bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override {
bool innerIsOpaque = shaderIsOpaque;
if (!(fInner->getFlags() & kAlphaUnchanged_Flag)) {
if (!fInner->isAlphaUnchanged()) {
innerIsOpaque = false;
}
return fInner->appendStages(rec, shaderIsOpaque) &&
@ -127,6 +147,8 @@ public:
}
#endif
SK_FLATTENABLE_HOOKS(SkComposeColorFilter)
protected:
void flatten(SkWriteBuffer& buffer) const override {
buffer.writeFlattenable(fOuter.get());
@ -134,14 +156,13 @@ protected:
}
private:
SK_FLATTENABLE_HOOKS(SkComposeColorFilter)
SkComposeColorFilter(sk_sp<SkColorFilter> outer, sk_sp<SkColorFilter> inner)
: fOuter(std::move(outer))
, fInner(std::move(inner)) {}
: fOuter(as_CFB_sp(std::move(outer)))
, fInner(as_CFB_sp(std::move(inner)))
{}
sk_sp<SkColorFilter> fOuter;
sk_sp<SkColorFilter> fInner;
sk_sp<SkColorFilterBase> fOuter;
sk_sp<SkColorFilterBase> fInner;
friend class SkColorFilter;
@ -164,7 +185,7 @@ sk_sp<SkColorFilter> SkColorFilter::makeComposed(sk_sp<SkColorFilter> inner) con
///////////////////////////////////////////////////////////////////////////////////////////////////
class SkSRGBGammaColorFilter : public SkColorFilter {
class SkSRGBGammaColorFilter : public SkColorFilterBase {
public:
enum class Direction {
kLinearToSRGB,
@ -216,19 +237,19 @@ public:
return premul(fSteps.program(p, uniforms, unpremul(c)));
}
SK_FLATTENABLE_HOOKS(SkSRGBGammaColorFilter)
protected:
void flatten(SkWriteBuffer& buffer) const override {
buffer.write32(static_cast<uint32_t>(fDir));
}
private:
SK_FLATTENABLE_HOOKS(SkSRGBGammaColorFilter)
const Direction fDir;
SkColorSpaceXformSteps fSteps;
friend class SkColorFilter;
typedef SkColorFilter INHERITED;
typedef SkColorFilterBase INHERITED;
};
sk_sp<SkFlattenable> SkSRGBGammaColorFilter::CreateProc(SkReadBuffer& buffer) {
@ -255,18 +276,20 @@ sk_sp<SkColorFilter> SkColorFilters::SRGBToLinearGamma() {
///////////////////////////////////////////////////////////////////////////////////////////////////
class SkMixerColorFilter : public SkColorFilter {
class SkMixerColorFilter : public SkColorFilterBase {
public:
SkMixerColorFilter(sk_sp<SkColorFilter> cf0, sk_sp<SkColorFilter> cf1, float weight)
: fCF0(std::move(cf0)), fCF1(std::move(cf1)), fWeight(weight)
: fCF0(as_CFB_sp(std::move(cf0)))
, fCF1(as_CFB_sp(std::move(cf1)))
, fWeight(weight)
{
SkASSERT(fCF0);
SkASSERT(fWeight >= 0 && fWeight <= 1);
}
uint32_t getFlags() const override {
uint32_t f0 = fCF0->getFlags();
uint32_t f1 = fCF1 ? fCF1->getFlags() : ~0U;
uint32_t onGetFlags() const override {
uint32_t f0 = fCF0->onGetFlags();
uint32_t f1 = fCF1 ? fCF1->onGetFlags() : ~0U;
return f0 & f1;
}
@ -319,6 +342,8 @@ public:
}
#endif
SK_FLATTENABLE_HOOKS(SkMixerColorFilter)
protected:
void flatten(SkWriteBuffer& buffer) const override {
buffer.writeFlattenable(fCF0.get());
@ -327,15 +352,13 @@ protected:
}
private:
SK_FLATTENABLE_HOOKS(SkMixerColorFilter)
sk_sp<SkColorFilter> fCF0;
sk_sp<SkColorFilter> fCF1;
const float fWeight;
sk_sp<SkColorFilterBase> fCF0;
sk_sp<SkColorFilterBase> fCF1;
const float fWeight;
friend class SkColorFilter;
typedef SkColorFilter INHERITED;
typedef SkColorFilterBase INHERITED;
};
sk_sp<SkFlattenable> SkMixerColorFilter::CreateProc(SkReadBuffer& buffer) {
@ -374,7 +397,7 @@ sk_sp<SkColorFilter> SkColorFilters::Lerp(float weight, sk_sp<SkColorFilter> cf0
#include "src/core/SkModeColorFilter.h"
void SkColorFilter::RegisterFlattenables() {
void SkColorFilterBase::RegisterFlattenables() {
SK_REGISTER_FLATTENABLE(SkComposeColorFilter);
SK_REGISTER_FLATTENABLE(SkModeColorFilter);
SK_REGISTER_FLATTENABLE(SkSRGBGammaColorFilter);

View File

@ -0,0 +1,108 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkColorFilterBase_DEFINED
#define SkColorFilterBase_DEFINED
#include "include/core/SkColorFilter.h"
class GrColorInfo;
class GrFragmentProcessor;
class GrRecordingContext;
class SkArenaAlloc;
class SkBitmap;
class SkColorSpace;
struct SkStageRec;
using GrFPResult = std::tuple<bool, std::unique_ptr<GrFragmentProcessor>>;
namespace skvm {
class Builder;
struct F32;
struct Uniforms;
struct Color;
}
class SkColorFilterBase : public SkColorFilter {
public:
bool appendStages(const SkStageRec& rec, bool shaderIsOpaque) const;
skvm::Color program(skvm::Builder*, skvm::Color,
SkColorSpace* dstCS, skvm::Uniforms*, SkArenaAlloc*) const;
/** Returns the flags for this filter. Override in subclasses to return custom flags.
*/
virtual uint32_t onGetFlags() const { return 0; }
#if SK_SUPPORT_GPU
/**
* A subclass may implement this factory function to work with the GPU backend. It returns
* a GrFragmentProcessor that implements the color filter in GPU shader code.
*
* The fragment processor receives a premultiplied input color and produces a premultiplied
* output color.
*
* A null return indicates that the color filter isn't implemented for the GPU backend.
*/
virtual std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
GrRecordingContext*, const GrColorInfo& dstColorInfo) const;
#endif
bool affectsTransparentBlack() const {
return this->filterColor(SK_ColorTRANSPARENT) != SK_ColorTRANSPARENT;
}
static void RegisterFlattenables();
static SkFlattenable::Type GetFlattenableType() {
return kSkColorFilter_Type;
}
SkFlattenable::Type getFlattenableType() const override {
return kSkColorFilter_Type;
}
static sk_sp<SkColorFilter> Deserialize(const void* data, size_t size,
const SkDeserialProcs* procs = nullptr) {
return sk_sp<SkColorFilter>(static_cast<SkColorFilter*>(
SkFlattenable::Deserialize(
kSkColorFilter_Type, data, size, procs).release()));
}
protected:
SkColorFilterBase() {}
virtual bool onAsAColorMatrix(float[20]) const;
virtual bool onAsAColorMode(SkColor* color, SkBlendMode* bmode) const;
private:
virtual bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const = 0;
virtual skvm::Color onProgram(skvm::Builder*, skvm::Color,
SkColorSpace* dstCS, skvm::Uniforms*, SkArenaAlloc*) const = 0;
friend class SkColorFilter;
typedef SkFlattenable INHERITED;
};
static inline SkColorFilterBase* as_CFB(SkColorFilter* filter) {
return static_cast<SkColorFilterBase*>(filter);
}
static inline const SkColorFilterBase* as_CFB(const SkColorFilter* filter) {
return static_cast<const SkColorFilterBase*>(filter);
}
static inline const SkColorFilterBase* as_CFB(const sk_sp<SkColorFilter>& filter) {
return static_cast<SkColorFilterBase*>(filter.get());
}
static inline sk_sp<SkColorFilterBase> as_CFB_sp(sk_sp<SkColorFilter> filter) {
return sk_sp<SkColorFilterBase>(static_cast<SkColorFilterBase*>(filter.release()));
}
#endif

View File

@ -26,7 +26,7 @@ static uint16_t ComputeFlags(const float matrix[20]) {
&& SkScalarNearlyZero (srcA[2])
&& SkScalarNearlyEqual(srcA[3], 1)
&& SkScalarNearlyZero (srcA[4])
? SkColorFilter::kAlphaUnchanged_Flag : 0;
? SkColorFilterBase::kAlphaUnchanged_Flag : 0;
}
SkColorFilter_Matrix::SkColorFilter_Matrix(const float array[20], Domain domain)
@ -35,8 +35,8 @@ SkColorFilter_Matrix::SkColorFilter_Matrix(const float array[20], Domain domain)
memcpy(fMatrix, array, 20 * sizeof(float));
}
uint32_t SkColorFilter_Matrix::getFlags() const {
return this->INHERITED::getFlags() | fFlags;
uint32_t SkColorFilter_Matrix::onGetFlags() const {
return this->INHERITED::onGetFlags() | fFlags;
}
void SkColorFilter_Matrix::flatten(SkWriteBuffer& buffer) const {

View File

@ -8,16 +8,15 @@
#ifndef SkColorFilter_Matrix_DEFINED
#define SkColorFilter_Matrix_DEFINED
#include "include/core/SkColorFilter.h"
#include "include/core/SkFlattenable.h"
#include "src/core/SkColorFilterBase.h"
class SkColorFilter_Matrix : public SkColorFilter {
class SkColorFilter_Matrix : public SkColorFilterBase {
public:
enum class Domain : uint8_t { kRGBA, kHSLA };
explicit SkColorFilter_Matrix(const float array[20], Domain);
uint32_t getFlags() const override;
uint32_t onGetFlags() const override;
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(GrRecordingContext*,
@ -41,7 +40,7 @@ private:
uint16_t fFlags;
Domain fDomain;
typedef SkColorFilter INHERITED;
typedef SkColorFilterBase INHERITED;
};
#endif

View File

@ -113,7 +113,7 @@ bool SkImageFilter::asAColorFilter(SkColorFilter** filterPtr) const {
if (!this->isColorFilterNode(filterPtr)) {
return false;
}
if (nullptr != this->getInput(0) || (*filterPtr)->affectsTransparentBlack()) {
if (nullptr != this->getInput(0) || as_CFB(*filterPtr)->affectsTransparentBlack()) {
(*filterPtr)->unref();
return false;
}

View File

@ -38,7 +38,7 @@ bool SkModeColorFilter::onAsAColorMode(SkColor* color, SkBlendMode* mode) const
return true;
}
uint32_t SkModeColorFilter::getFlags() const {
uint32_t SkModeColorFilter::onGetFlags() const {
uint32_t flags = 0;
switch (fMode) {
case SkBlendMode::kDst: //!< [Da, Dc]

View File

@ -8,22 +8,23 @@
#ifndef SkModeColorFilter_DEFINED
#define SkModeColorFilter_DEFINED
#include "include/core/SkColorFilter.h"
#include "include/core/SkFlattenable.h"
#include "src/core/SkColorFilterBase.h"
class SkModeColorFilter : public SkColorFilter {
class SkModeColorFilter : public SkColorFilterBase {
public:
static sk_sp<SkColorFilter> Make(SkColor color, SkBlendMode mode) {
return sk_sp<SkColorFilter>(new SkModeColorFilter(color, mode));
}
uint32_t getFlags() const override;
uint32_t onGetFlags() const override;
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(GrRecordingContext*,
const GrColorInfo&) const override;
#endif
SK_FLATTENABLE_HOOKS(SkModeColorFilter)
protected:
SkModeColorFilter(SkColor color, SkBlendMode mode);
@ -35,14 +36,12 @@ protected:
SkColorSpace*, skvm::Uniforms*, SkArenaAlloc*) const override;
private:
SK_FLATTENABLE_HOOKS(SkModeColorFilter)
SkColor fColor;
SkBlendMode fMode;
friend class SkColorFilter;
typedef SkColorFilter INHERITED;
typedef SkColorFilterBase INHERITED;
};
#endif

View File

@ -7,7 +7,6 @@
#include "include/core/SkPaint.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkData.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkImageFilter.h"
@ -19,6 +18,7 @@
#include "include/core/SkTypeface.h"
#include "include/private/SkMutex.h"
#include "include/private/SkTo.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkDraw.h"
@ -517,7 +517,7 @@ const SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc,
// return true if the filter exists, and may affect alpha
static bool affects_alpha(const SkColorFilter* cf) {
return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
return cf && !as_CFB(cf)->isAlphaUnchanged();
}
// return true if the filter exists, and may affect alpha

View File

@ -5,8 +5,8 @@
* found in the LICENSE file.
*/
#include "include/core/SkColorFilter.h"
#include "include/core/SkPaint.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkPaintPriv.h"
#include "src/core/SkXfermodePriv.h"
@ -15,7 +15,7 @@
static bool changes_alpha(const SkPaint& paint) {
SkColorFilter* cf = paint.getColorFilter();
return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
return cf && !(as_CFB(cf)->getFlags() & SkColorFilterBase::kAlphaUnchanged_Flag);
}
bool SkPaintPriv::Overwrites(const SkPaint* paint, ShaderOverrideOpacity overrideOpacity) {

View File

@ -6,13 +6,13 @@
*/
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkShader.h"
#include "include/private/SkTo.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkBlendModePriv.h"
#include "src/core/SkBlitter.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkMatrixProvider.h"
@ -184,8 +184,9 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
SkStageRec rec = {
colorPipeline, alloc, dst.colorType(), dst.colorSpace(), paint, nullptr, matrixProvider
};
colorFilter->appendStages(rec, is_opaque);
is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
as_CFB(colorFilter)->appendStages(rec, is_opaque);
is_opaque = is_opaque
&& (as_CFB(colorFilter)->getFlags() & SkColorFilterBase::kAlphaUnchanged_Flag);
}
#if defined(SK_LATE_DITHER)

View File

@ -8,7 +8,6 @@
#ifndef SkReadBuffer_DEFINED
#define SkReadBuffer_DEFINED
#include "include/core/SkColorFilter.h"
#include "include/core/SkDrawLooper.h"
#include "include/core/SkFont.h"
#include "include/core/SkImageFilter.h"
@ -18,6 +17,7 @@
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSerialProcs.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkMaskFilterBase.h"
#include "src/core/SkPaintPriv.h"
#include "src/core/SkPicturePriv.h"
@ -108,7 +108,7 @@ public:
template <typename T> sk_sp<T> readFlattenable() {
return sk_sp<T>((T*)this->readFlattenable(T::GetFlattenableType()));
}
sk_sp<SkColorFilter> readColorFilter() { return this->readFlattenable<SkColorFilter>(); }
sk_sp<SkColorFilter> readColorFilter() { return this->readFlattenable<SkColorFilterBase>(); }
sk_sp<SkDrawLooper> readDrawLooper() { return this->readFlattenable<SkDrawLooper>(); }
sk_sp<SkImageFilter> readImageFilter() { return this->readFlattenable<SkImageFilter>(); }
sk_sp<SkMaskFilter> readMaskFilter() { return this->readFlattenable<SkMaskFilterBase>(); }

View File

@ -11,6 +11,7 @@
#include "include/private/SkChecksum.h"
#include "include/private/SkMutex.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkMatrixProvider.h"
@ -770,7 +771,7 @@ static std::vector<skvm::F32> program_fn(skvm::Builder* p,
}
class SkRuntimeColorFilter : public SkColorFilter {
class SkRuntimeColorFilter : public SkColorFilterBase {
public:
SkRuntimeColorFilter(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs)
: fEffect(std::move(effect))

View File

@ -9,6 +9,7 @@
#include "include/private/SkMacros.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkBlendModePriv.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkCoreBlitters.h"
@ -406,7 +407,7 @@ namespace {
}
struct NoopColorFilter : public SkColorFilter {
struct NoopColorFilter : public SkColorFilterBase {
skvm::Color onProgram(skvm::Builder*, skvm::Color c,
SkColorSpace*, skvm::Uniforms*, SkArenaAlloc*) const override {
return c;

View File

@ -9,6 +9,7 @@
#include "include/effects/SkHighContrastFilter.h"
#include "include/private/SkColorData.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkEffectPriv.h"
#include "src/core/SkRasterPipeline.h"
@ -25,7 +26,7 @@
using InvertStyle = SkHighContrastConfig::InvertStyle;
class SkHighContrast_Filter : public SkColorFilter {
class SkHighContrast_Filter : public SkColorFilterBase {
public:
SkHighContrast_Filter(const SkHighContrastConfig& config) {
fConfig = config;

View File

@ -8,6 +8,7 @@
#include "include/core/SkString.h"
#include "include/effects/SkLumaColorFilter.h"
#include "include/private/SkColorData.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkEffectPriv.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkVM.h"
@ -19,39 +20,50 @@
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#endif
bool SkLumaColorFilter::onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const {
rec.fPipeline->append(SkRasterPipeline::bt709_luminance_or_luma_to_alpha);
rec.fPipeline->append(SkRasterPipeline::clamp_0);
rec.fPipeline->append(SkRasterPipeline::clamp_1);
return true;
}
class SkLumaColorFilterImpl : public SkColorFilterBase {
public:
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(GrRecordingContext*,
const GrColorInfo&) const override {
return GrLumaColorFilterEffect::Make(/*inputFP=*/nullptr);
}
#endif
skvm::Color SkLumaColorFilter::onProgram(skvm::Builder* p, skvm::Color c,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const {
return {
p->splat(0.0f),
p->splat(0.0f),
p->splat(0.0f),
clamp01(c.r * 0.2126f + c.g * 0.7152f + c.b * 0.0722f),
};
}
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&) {
return SkLumaColorFilter::Make();
}
protected:
void flatten(SkWriteBuffer&) const override {}
private:
Factory getFactory() const override { return CreateProc; }
const char* getTypeName() const override { return "SkLumaColorFilter"; }
bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override {
rec.fPipeline->append(SkRasterPipeline::bt709_luminance_or_luma_to_alpha);
rec.fPipeline->append(SkRasterPipeline::clamp_0);
rec.fPipeline->append(SkRasterPipeline::clamp_1);
return true;
}
skvm::Color onProgram(skvm::Builder* p, skvm::Color c, SkColorSpace*, skvm::Uniforms*,
SkArenaAlloc*) const override {
return {
p->splat(0.0f),
p->splat(0.0f),
p->splat(0.0f),
clamp01(c.r * 0.2126f + c.g * 0.7152f + c.b * 0.0722f),
};
}
typedef SkColorFilterBase INHERITED;
};
sk_sp<SkColorFilter> SkLumaColorFilter::Make() {
return sk_sp<SkColorFilter>(new SkLumaColorFilter);
return sk_sp<SkColorFilter>(new SkLumaColorFilterImpl);
}
SkLumaColorFilter::SkLumaColorFilter() : INHERITED() {}
sk_sp<SkFlattenable> SkLumaColorFilter::CreateProc(SkReadBuffer&) {
return Make();
void SkLumaColorFilter::RegisterFlattenable() {
SkFlattenable::Register("SkLumaColorFilter", SkLumaColorFilterImpl::CreateProc);
}
void SkLumaColorFilter::flatten(SkWriteBuffer&) const {}
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> SkLumaColorFilter::asFragmentProcessor(
GrRecordingContext*, const GrColorInfo&) const {
return GrLumaColorFilterEffect::Make(/*inputFP=*/nullptr);
}
#endif

View File

@ -13,6 +13,7 @@
#include "include/private/SkColorData.h"
#include "include/private/SkTo.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkEffectPriv.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkReadBuffer.h"
@ -54,7 +55,7 @@ static const uint8_t gIdentityTable[] = {
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
};
class SkTable_ColorFilter : public SkColorFilter {
class SkTable_ColorFilter : public SkColorFilterBase {
public:
SkTable_ColorFilter(const uint8_t tableA[], const uint8_t tableR[],
const uint8_t tableG[], const uint8_t tableB[]) {
@ -377,7 +378,7 @@ std::unique_ptr<GrFragmentProcessor> ColorTableEffect::TestCreate(GrProcessorTes
(flags & (1 << 3)) ? luts[3] : nullptr
));
sk_sp<SkColorSpace> colorSpace = GrTest::TestColorSpace(d->fRandom);
auto fp = filter->asFragmentProcessor(
auto fp = as_CFB(filter)->asFragmentProcessor(
d->context(),
GrColorInfo(GrColorType::kRGBA_8888, kUnknown_SkAlphaType, std::move(colorSpace)));
SkASSERT(fp);

View File

@ -9,6 +9,7 @@
#include "include/core/SkCanvas.h"
#include "include/core/SkColorFilter.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkImageFilter_Base.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkSpecialImage.h"
@ -89,7 +90,7 @@ sk_sp<SkSpecialImage> SkColorFilterImageFilterImpl::onFilterImage(const Context&
sk_sp<SkSpecialImage> input(this->filterInput(0, ctx, &inputOffset));
SkIRect inputBounds;
if (fColorFilter->affectsTransparentBlack()) {
if (as_CFB(fColorFilter)->affectsTransparentBlack()) {
// If the color filter affects transparent black, the bounds are the entire clip.
inputBounds = ctx.clipBounds();
} else if (!input) {
@ -119,7 +120,7 @@ sk_sp<SkSpecialImage> SkColorFilterImageFilterImpl::onFilterImage(const Context&
// TODO: it may not be necessary to clear or drawPaint inside the input bounds
// (see skbug.com/5075)
if (fColorFilter->affectsTransparentBlack()) {
if (as_CFB(fColorFilter)->affectsTransparentBlack()) {
// The subsequent input->draw() call may not fill the entire canvas. For filters which
// affect transparent black, ensure that the filter is applied everywhere.
paint.setColor(SK_ColorTRANSPARENT);
@ -153,5 +154,5 @@ bool SkColorFilterImageFilterImpl::onIsColorFilterNode(SkColorFilter** filter) c
}
bool SkColorFilterImageFilterImpl::affectsTransparentBlack() const {
return fColorFilter->affectsTransparentBlack();
return as_CFB(fColorFilter)->affectsTransparentBlack();
}

View File

@ -20,6 +20,7 @@
#include "include/private/SkTemplates.h"
#include "src/core/SkAutoMalloc.h"
#include "src/core/SkBlendModePriv.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkImagePriv.h"
#include "src/core/SkMaskFilterBase.h"
@ -346,7 +347,7 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
SkColorSpace* dstCS = dstColorInfo.colorSpace();
grPaint->setColor4f(colorFilter->filterColor4f(origColor, dstCS, dstCS).premul());
} else {
auto cfFP = colorFilter->asFragmentProcessor(context, dstColorInfo);
auto cfFP = as_CFB(colorFilter)->asFragmentProcessor(context, dstColorInfo);
if (cfFP) {
grPaint->addColorFragmentProcessor(std::move(cfFP));
} else {

View File

@ -258,6 +258,7 @@ GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSkSLFP);
#include "include/effects/SkArithmeticImageFilter.h"
#include "include/effects/SkOverdrawColorFilter.h"
#include "include/gpu/GrContext.h"
#include "src/core/SkColorFilterBase.h"
#include "src/gpu/effects/generated/GrConstColorProcessor.h"
extern const char* SKSL_ARITHMETIC_SRC;
@ -291,8 +292,8 @@ std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d
for (SkColor& c : colors) {
c = d->fRandom->nextU();
}
return SkOverdrawColorFilter::MakeWithSkColors(colors)
->asFragmentProcessor(d->context(), GrColorInfo{});
auto filter = SkOverdrawColorFilter::MakeWithSkColors(colors);
return as_CFB(filter)->asFragmentProcessor(d->context(), GrColorInfo{});
}
}
SK_ABORT("unreachable");

View File

@ -73,8 +73,8 @@
// Color filters.
SkColorFilter_Matrix::RegisterFlattenables();
SK_REGISTER_FLATTENABLE(SkLumaColorFilter);
SkColorFilter::RegisterFlattenables();
SkLumaColorFilter::RegisterFlattenable();
SkColorFilterBase::RegisterFlattenables();
SkHighContrastFilter::RegisterFlattenables();
SkTableColorFilter::RegisterFlattenables();

View File

@ -8,6 +8,7 @@
#include "include/core/SkShader.h"
#include "include/core/SkString.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkVM.h"
@ -22,7 +23,7 @@ SkColorFilterShader::SkColorFilterShader(sk_sp<SkShader> shader,
float alpha,
sk_sp<SkColorFilter> filter)
: fShader(std::move(shader))
, fFilter(std::move(filter))
, fFilter(as_CFB_sp(std::move(filter)))
, fAlpha (alpha)
{
SkASSERT(fShader);
@ -39,9 +40,7 @@ sk_sp<SkFlattenable> SkColorFilterShader::CreateProc(SkReadBuffer& buffer) {
}
bool SkColorFilterShader::isOpaque() const {
return fShader->isOpaque()
&& fAlpha == 1.0f
&& (fFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag) != 0;
return fShader->isOpaque() && fAlpha == 1.0f && as_CFB(fFilter)->isAlphaUnchanged();
}
void SkColorFilterShader::flatten(SkWriteBuffer& buffer) const {

View File

@ -8,7 +8,7 @@
#ifndef SkColorFilterShader_DEFINED
#define SkColorFilterShader_DEFINED
#include "include/core/SkColorFilter.h"
#include "src/core/SkColorFilterBase.h"
#include "src/shaders/SkShaderBase.h"
class SkArenaAlloc;
@ -33,9 +33,9 @@ private:
SK_FLATTENABLE_HOOKS(SkColorFilterShader)
sk_sp<SkShader> fShader;
sk_sp<SkColorFilter> fFilter;
float fAlpha;
sk_sp<SkShader> fShader;
sk_sp<SkColorFilterBase> fFilter;
float fAlpha;
typedef SkShaderBase INHERITED;
};

View File

@ -17,6 +17,7 @@
#include "include/private/SkIDChangeListener.h"
#include "include/utils/SkRandom.h"
#include "src/core/SkBlurMask.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkColorFilterPriv.h"
#include "src/core/SkDevice.h"
#include "src/core/SkDrawShadowInfo.h"
@ -40,7 +41,7 @@
* Final result is black with alpha of Gaussian(B)*G.
* The assumption is that the original color's alpha is 1.
*/
class SkGaussianColorFilter : public SkColorFilter {
class SkGaussianColorFilter : public SkColorFilterBase {
public:
SkGaussianColorFilter() : INHERITED() {}
@ -73,7 +74,7 @@ protected:
private:
SK_FLATTENABLE_HOOKS(SkGaussianColorFilter)
typedef SkColorFilter INHERITED;
typedef SkColorFilterBase INHERITED;
};
sk_sp<SkFlattenable> SkGaussianColorFilter::CreateProc(SkReadBuffer&) {

View File

@ -294,7 +294,7 @@ DEF_TEST(Flattenable_EmptyDeserialze, reporter) {
test(SkPathEffect);
test(SkMaskFilter);
test(SkShaderBase); // todo: make this just be shader!
test(SkColorFilter);
test(SkColorFilterBase);
test(SkImageFilter);
test(SkDrawLooper);
#undef test

View File

@ -18,6 +18,7 @@
#include "include/effects/SkImageFilters.h"
#include "include/effects/SkPerlinNoiseShader.h"
#include "include/effects/SkTableColorFilter.h"
#include "src/core/SkColorFilterBase.h"
#include "src/core/SkImageFilter_Base.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkSpecialImage.h"
@ -715,7 +716,7 @@ static void test_fail_affects_transparent_black(skiatest::Reporter* reporter, Gr
SkImageFilter_Base::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(0, 0, 1, 1), nullptr,
kN32_SkColorType, nullptr, source.get());
sk_sp<SkColorFilter> green(SkColorFilters::Blend(SK_ColorGREEN, SkBlendMode::kSrc));
SkASSERT(green->affectsTransparentBlack());
SkASSERT(as_CFB(green)->affectsTransparentBlack());
sk_sp<SkImageFilter> greenFilter(SkImageFilters::ColorFilter(std::move(green),
std::move(failFilter)));
SkIPoint offset;
@ -1526,7 +1527,7 @@ DEF_TEST(ImageFilterCanComputeFastBounds, reporter) {
{
SkColorFilter* grayCF;
REPORTER_ASSERT(reporter, gray->asAColorFilter(&grayCF));
REPORTER_ASSERT(reporter, !grayCF->affectsTransparentBlack());
REPORTER_ASSERT(reporter, !as_CFB(grayCF)->affectsTransparentBlack());
grayCF->unref();
}
REPORTER_ASSERT(reporter, gray->canComputeFastBounds());
@ -1545,7 +1546,7 @@ DEF_TEST(ImageFilterCanComputeFastBounds, reporter) {
sk_sp<SkColorFilter> greenCF(SkColorFilters::Matrix(greenMatrix));
sk_sp<SkImageFilter> green(SkImageFilters::ColorFilter(greenCF, nullptr));
REPORTER_ASSERT(reporter, greenCF->affectsTransparentBlack());
REPORTER_ASSERT(reporter,as_CFB( greenCF)->affectsTransparentBlack());
REPORTER_ASSERT(reporter, !green->canComputeFastBounds());
sk_sp<SkImageFilter> greenBlur(SkImageFilters::Blur(SK_Scalar1, SK_Scalar1,
@ -1562,13 +1563,13 @@ DEF_TEST(ImageFilterCanComputeFastBounds, reporter) {
sk_sp<SkColorFilter> identityCF(SkTableColorFilter::MakeARGB(identity, identity,
identity, allOne));
sk_sp<SkImageFilter> identityFilter(SkImageFilters::ColorFilter(identityCF, nullptr));
REPORTER_ASSERT(reporter, !identityCF->affectsTransparentBlack());
REPORTER_ASSERT(reporter, !as_CFB(identityCF)->affectsTransparentBlack());
REPORTER_ASSERT(reporter, identityFilter->canComputeFastBounds());
sk_sp<SkColorFilter> forceOpaqueCF(SkTableColorFilter::MakeARGB(allOne, identity,
identity, identity));
sk_sp<SkImageFilter> forceOpaque(SkImageFilters::ColorFilter(forceOpaqueCF, nullptr));
REPORTER_ASSERT(reporter, forceOpaqueCF->affectsTransparentBlack());
REPORTER_ASSERT(reporter, as_CFB(forceOpaqueCF)->affectsTransparentBlack());
REPORTER_ASSERT(reporter, !forceOpaque->canComputeFastBounds());
}

View File

@ -304,7 +304,8 @@ static void TestColorFilterSerialization(skiatest::Reporter* reporter) {
}
auto colorFilter(SkTableColorFilter::Make(table));
sk_sp<SkColorFilter> copy(
TestFlattenableSerialization<SkColorFilter>(colorFilter.get(), true, reporter));
TestFlattenableSerialization<SkColorFilterBase>((SkColorFilterBase*)colorFilter.get(),
true, reporter));
}
static SkBitmap draw_picture(SkPicture& picture) {