/*
 * 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 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;
#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
