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

#ifndef GrDrawOp_DEFINED
#define GrDrawOp_DEFINED

#include <functional>
#include "src/core/SkIPoint16.h"
#include "src/gpu/GrDeferredUpload.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/ops/GrOp.h"

class GrAppliedClip;
class GrSurfaceDrawContext;
class GrShape;

/**
 * Base class for GrOps that draw. These ops can draw into an op list's GrRenderTarget.
 */
class GrDrawOp : public GrOp {
public:
    GrDrawOp(uint32_t classID) : INHERITED(classID) {}

    /**
     * Called before setting up the GrAppliedClip and before finalize. This information is required
     * to determine how to compute a GrAppliedClip from a GrClip for this op.
     */
    virtual bool usesMSAA() const {
        return this->fixedFunctionFlags() & FixedFunctionFlags::kUsesHWAA;
    }

    /**
     * Specifies the effect of clipToShape().
     */
    enum class ClipResult {
        // No clip was applied.
        kFail,
        // The clip was applied to the op's actual geometry. The clip stack is free to disable the
        // scissor test.
        kClippedGeometrically,
        // The clip was applied via shader coverage. The clip stack will still use a scissor test
        // in order to reduce overdraw of transparent pixels.
        kClippedInShader,
        // The op can be thrown out entirely.
        kClippedOut
    };

    /**
     * This is called while the clip is being computed, before finalize(), and before any attempts
     * to combine with other ops. If the op knows how to clip its own geometry then it will
     * generally be much faster than a generalized clip method.
     */
    virtual ClipResult clipToShape(GrSurfaceDrawContext*, SkClipOp, const SkMatrix& clipMatrix,
                                   const GrShape&, GrAA) {
        return ClipResult::kFail;
    }

    /**
     * This is called after the GrAppliedClip has been computed and just prior to recording the op
     * or combining it with a previously recorded op. The op should convert any proxies or resources
     * it owns to "pending io" status so that resource allocation can be more optimal. Additionally,
     * at this time the op must report whether a copy of the destination (or destination texture
     * itself) needs to be provided to the GrXferProcessor when this op executes.
     */
    virtual GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) = 0;

    /**
     * Called after finalize, at which point every op should know whether it will need stencil.
     */
    virtual bool usesStencil() const {
        return this->fixedFunctionFlags() & FixedFunctionFlags::kUsesStencil;
    }

#ifdef SK_DEBUG
    bool fAddDrawOpCalled = false;

    void validate() const override {
        SkASSERT(fAddDrawOpCalled);
    }
#endif

#if GR_TEST_UTILS
    // This is really only intended for GrTextureOp and GrFillRectOp to override
    virtual int numQuads() const { return -1; }
#endif

protected:
    /**
     * DEPRECATED: This is a legacy implementation for usesMSAA() and usesStencil(). Newer ops
     * should override those methods directly.
     */
    enum class FixedFunctionFlags : uint32_t {
        kNone = 0x0,
        /** Indices that the op will enable MSAA. */
        kUsesHWAA = 0x1,
        /** Indices that the op reads and/or writes the stencil buffer */
        kUsesStencil = 0x2,
    };
    GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(FixedFunctionFlags);
    virtual FixedFunctionFlags fixedFunctionFlags() const {
        // Override usesMSAA() and usesStencil() instead.
        SK_ABORT("fixedFunctionFlags() not implemented.");
    }

private:
    friend class GrSimpleMeshDrawOpHelper;  // For FixedFunctionFlags.
    friend class GrSimpleMeshDrawOpHelperWithStencil;  // For FixedFunctionFlags.

    using INHERITED = GrOp;
};

GR_MAKE_BITFIELD_CLASS_OPS(GrDrawOp::FixedFunctionFlags)

#endif
