
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef GrPaint_DEFINED
#define GrPaint_DEFINED

#include "include/core/SkBlendMode.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkRegion.h"
#include "src/core/SkTLazy.h"
#include "src/gpu/GrColor.h"
#include "src/gpu/GrFragmentProcessor.h"

class GrTextureProxy;
class GrXPFactory;

/**
 * The paint describes how color and coverage are computed at each pixel by GrContext draw
 * functions and the how color is blended with the destination pixel.
 *
 * The paint allows installation of custom color and coverage stages. New types of stages are
 * created by subclassing GrProcessor.
 *
 * The primitive color computation starts with the color specified by setColor(). This color is the
 * input to the first color stage. Each color stage feeds its output to the next color stage.
 *
 * Fractional pixel coverage follows a similar flow. The GrGeometryProcessor (specified elsewhere)
 * provides the initial coverage which is passed to the first coverage fragment processor, which
 * feeds its output to next coverage fragment processor.
 *
 * setXPFactory is used to control blending between the output color and dest. It also implements
 * the application of fractional coverage from the coverage pipeline.
 */
class GrPaint {
public:
    GrPaint() = default;
    ~GrPaint() = default;

    static GrPaint Clone(const GrPaint& src) { return GrPaint(src); }

    /**
     * The initial color of the drawn primitive. Defaults to solid white.
     */
    void setColor4f(const SkPMColor4f& color) { fColor = color; }
    const SkPMColor4f& getColor4f() const { return fColor; }

    void setXPFactory(const GrXPFactory* xpFactory) {
        fXPFactory = xpFactory;
        fTrivial &= !SkToBool(xpFactory);
    }

    void setPorterDuffXPFactory(SkBlendMode mode);

    void setCoverageSetOpXPFactory(SkRegion::Op, bool invertCoverage = false);

    /**
     * Sets a processor for color computation.
     */
    void setColorFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp) {
        SkASSERT(fp);
        SkASSERT(fColorFragmentProcessor == nullptr);
        fColorFragmentProcessor = std::move(fp);
        fTrivial = false;
    }

    /**
     * Appends an additional coverage processor to the coverage computation.
     */
    void setCoverageFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp) {
        SkASSERT(fp);
        SkASSERT(fCoverageFragmentProcessor == nullptr);
        fCoverageFragmentProcessor = std::move(fp);
        fTrivial = false;
    }

    bool hasColorFragmentProcessor() const { return fColorFragmentProcessor ? true : false; }
    int hasCoverageFragmentProcessor() const { return fCoverageFragmentProcessor ? true : false; }
    int numTotalFragmentProcessors() const {
        return (this->hasColorFragmentProcessor() ? 1 : 0) +
               (this->hasCoverageFragmentProcessor() ? 1 : 0);
    }

    const GrXPFactory* getXPFactory() const { return fXPFactory; }

    GrFragmentProcessor* getColorFragmentProcessor() const {
        return fColorFragmentProcessor.get();
    }
    GrFragmentProcessor* getCoverageFragmentProcessor() const {
        return fCoverageFragmentProcessor.get();
    }
    bool usesLocalCoords() const {
        // The sample coords for the top level FPs are implicitly the GP's local coords.
        return (fColorFragmentProcessor && fColorFragmentProcessor->usesSampleCoords()) ||
               (fCoverageFragmentProcessor && fCoverageFragmentProcessor->usesSampleCoords());
    }

    /**
     * Returns true if the paint's output color will be constant after blending. If the result is
     * true, constantColor will be updated to contain the constant color. Note that we can conflate
     * coverage and color, so the actual values written to pixels with partial coverage may still
     * not seem constant, even if this function returns true.
     */
    bool isConstantBlendedColor(SkPMColor4f* constantColor) const;

    /**
     * A trivial paint is one that uses src-over and has no fragment processors.
     * It may have variable sRGB settings.
     **/
    bool isTrivial() const { return fTrivial; }

    friend void assert_alive(GrPaint& p) {
        SkASSERT(p.fAlive);
    }

private:
    // Since paint copying is expensive if there are fragment processors, we require going through
    // the Clone() method.
    GrPaint(const GrPaint&);
    GrPaint& operator=(const GrPaint&) = delete;

    friend class GrProcessorSet;

    const GrXPFactory* fXPFactory = nullptr;
    std::unique_ptr<GrFragmentProcessor> fColorFragmentProcessor;
    std::unique_ptr<GrFragmentProcessor> fCoverageFragmentProcessor;
    bool fTrivial = true;
    SkPMColor4f fColor = SK_PMColor4fWHITE;
    SkDEBUGCODE(bool fAlive = true;)  // Set false after moved from.
};

#endif
