blob: 5de6d5f0c503aae8f8eaf7fbe3d420bb7418e602 [file] [log] [blame]
* 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 {
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; }
* TEMPORARY: SkColorFilters that support asFragmentProcessor(inputFP) should override this
* method to return true. TODO( This will be removed once
* asFragmentProcessor(inputFP, ...) is implemented across all SkColorFilters.
virtual bool colorFilterAcceptsInputFP() const { return false; }
* Deprecated: SkColorFilters should use the newer form of asFragmentProcessor; see below.
virtual std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
GrRecordingContext* context, const GrColorInfo& dstColorInfo) const;
* 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 input FP that generates a premultiplied input color, and
* produces a premultiplied output color.
* A GrFPFailure indicates that the color filter isn't implemented for the GPU backend.
virtual GrFPResult asFragmentProcessor(std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext* context,
const GrColorInfo& dstColorInfo) const;
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*>(
kSkColorFilter_Type, data, size, procs).release()));
SkColorFilterBase() {}
virtual bool onAsAColorMatrix(float[20]) const;
virtual bool onAsAColorMode(SkColor* color, SkBlendMode* bmode) const;
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()));