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

#ifndef GrSimpleMeshDrawOpHelper_DEFINED
#define GrSimpleMeshDrawOpHelper_DEFINED

#include "include/gpu/GrRecordingContext.h"
#include "src/gpu/GrMemoryPool.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/ops/GrMeshDrawOp.h"
#include "src/gpu/ops/GrOp.h"
#include <new>

struct SkRect;

/**
 * This class can be used to help implement simple mesh draw ops. It reduces the amount of
 * boilerplate code to type and also provides a mechanism for optionally allocating space for a
 * GrProcessorSet based on a GrPaint. It is intended to be used by ops that construct a single
 * GrPipeline for a uniform primitive color and a GrPaint.
 */
class GrSimpleMeshDrawOpHelper {
public:
    /**
     * This can be used by a Op class to perform allocation and initialization such that a
     * GrProcessorSet (if required) is allocated as part of the the same allocation that as
     * the Op instance. It requires that Op implements a constructor of the form:
     *      Op(ProcessorSet*, GrColor, OpArgs...).
     */
    template <typename Op, typename... OpArgs>
    static GrOp::Owner FactoryHelper(GrRecordingContext*, GrPaint&&, OpArgs&&...);

    // Here we allow callers to specify a subset of the GrPipeline::InputFlags upon creation.
    enum class InputFlags : uint8_t {
        kNone = 0,
        kSnapVerticesToPixelCenters = (uint8_t)GrPipeline::InputFlags::kSnapVerticesToPixelCenters,
        kConservativeRaster = (uint8_t)GrPipeline::InputFlags::kConservativeRaster,
    };
    GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(InputFlags);

    GrSimpleMeshDrawOpHelper(GrProcessorSet*, GrAAType, InputFlags = InputFlags::kNone);
    ~GrSimpleMeshDrawOpHelper();

    GrSimpleMeshDrawOpHelper() = delete;
    GrSimpleMeshDrawOpHelper(const GrSimpleMeshDrawOpHelper&) = delete;
    GrSimpleMeshDrawOpHelper& operator=(const GrSimpleMeshDrawOpHelper&) = delete;

    GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;

    // ignoreAAType should be set to true if the op already knows the AA settings are acceptible
    bool isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps&, const SkRect& thisBounds,
                      const SkRect& thatBounds, bool ignoreAAType = false) const;

    /**
     * Finalizes the processor set and determines whether the destination must be provided
     * to the fragment shader as a texture for blending.
     *
     * @param geometryCoverage Describes the coverage output of the op's geometry processor
     * @param geometryColor An in/out param. As input this informs processor analysis about the
     *                      color the op expects to output from its geometry processor. As output
     *                      this may be set to a known color in which case the op must output this
     *                      color from its geometry processor instead.
     */
    GrProcessorSet::Analysis finalizeProcessors(
            const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
            GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
            GrProcessorAnalysisColor* geometryColor) {
        return this->finalizeProcessors(
                caps, clip, &GrUserStencilSettings::kUnused, hasMixedSampledCoverage, clampType,
                geometryCoverage, geometryColor);
    }

    /**
     * Version of above that can be used by ops that have a constant color geometry processor
     * output. The op passes this color as 'geometryColor' and after return if 'geometryColor' has
     * changed the op must override its geometry processor color output with the new color.
     */
    GrProcessorSet::Analysis finalizeProcessors(
            const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType,
            GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor,
            bool* wideColor);

    bool isTrivial() const {
      return fProcessors == nullptr;
    }

    bool usesLocalCoords() const {
        SkASSERT(fDidAnalysis);
        return fUsesLocalCoords;
    }

    bool compatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }

    void visitProxies(const GrOp::VisitProxyFunc& func) const {
        if (fProcessors) {
            fProcessors->visitProxies(func);
        }
    }

#if GR_TEST_UTILS
    SkString dumpInfo() const;
#endif
    GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }

    void setAAType(GrAAType aaType) {
        fAAType = static_cast<unsigned>(aaType);
    }

    static const GrPipeline* CreatePipeline(
                                const GrCaps*,
                                SkArenaAlloc*,
                                GrSwizzle writeViewSwizzle,
                                GrAppliedClip&&,
                                const GrXferProcessor::DstProxyView&,
                                GrProcessorSet&&,
                                GrPipeline::InputFlags pipelineFlags);
    static const GrPipeline* CreatePipeline(
                                GrOpFlushState*,
                                GrProcessorSet&&,
                                GrPipeline::InputFlags pipelineFlags);

    const GrPipeline* createPipeline(GrOpFlushState* flushState);

    const GrPipeline* createPipeline(const GrCaps*,
                                     SkArenaAlloc*,
                                     GrSwizzle writeViewSwizzle,
                                     GrAppliedClip&&,
                                     const GrXferProcessor::DstProxyView&);

    static GrProgramInfo* CreateProgramInfo(SkArenaAlloc*,
                                            const GrPipeline*,
                                            const GrSurfaceProxyView& writeView,
                                            GrGeometryProcessor*,
                                            GrPrimitiveType,
                                            GrXferBarrierFlags renderPassXferBarriers,
                                            GrLoadOp colorLoadOp,
                                            const GrUserStencilSettings*
                                                                = &GrUserStencilSettings::kUnused);

    // Create a programInfo with the following properties:
    //     its primitive processor uses no textures
    //     it has no dynamic state besides the scissor clip
    static GrProgramInfo* CreateProgramInfo(const GrCaps*,
                                            SkArenaAlloc*,
                                            const GrSurfaceProxyView& writeView,
                                            GrAppliedClip&&,
                                            const GrXferProcessor::DstProxyView&,
                                            GrGeometryProcessor*,
                                            GrProcessorSet&&,
                                            GrPrimitiveType,
                                            GrXferBarrierFlags renderPassXferBarriers,
                                            GrLoadOp colorLoadOp,
                                            GrPipeline::InputFlags pipelineFlags
                                                                = GrPipeline::InputFlags::kNone,
                                            const GrUserStencilSettings*
                                                                = &GrUserStencilSettings::kUnused);

    GrProgramInfo* createProgramInfo(const GrCaps*,
                                     SkArenaAlloc*,
                                     const GrSurfaceProxyView& writeView,
                                     GrAppliedClip&&,
                                     const GrXferProcessor::DstProxyView&,
                                     GrGeometryProcessor*,
                                     GrPrimitiveType,
                                     GrXferBarrierFlags renderPassXferBarriers,
                                     GrLoadOp colorLoadOp);

    GrProcessorSet detachProcessorSet() {
        return fProcessors ? std::move(*fProcessors) : GrProcessorSet::MakeEmptySet();
    }

    GrPipeline::InputFlags pipelineFlags() const { return fPipelineFlags; }

protected:
    GrProcessorSet::Analysis finalizeProcessors(
            const GrCaps& caps, const GrAppliedClip*, const GrUserStencilSettings*,
            bool hasMixedSampledCoverage, GrClampType, GrProcessorAnalysisCoverage geometryCoverage,
            GrProcessorAnalysisColor* geometryColor);

    GrProcessorSet* fProcessors;
    GrPipeline::InputFlags fPipelineFlags;
    unsigned fAAType : 2;
    unsigned fUsesLocalCoords : 1;
    unsigned fCompatibleWithCoverageAsAlpha : 1;
    SkDEBUGCODE(unsigned fMadePipeline : 1;)
    SkDEBUGCODE(unsigned fDidAnalysis : 1;)
};

template<typename Op, typename... Args>
GrOp::Owner GrOp::MakeWithProcessorSet(
        GrRecordingContext* context, const SkPMColor4f& color,
        GrPaint&& paint, Args&&... args) {
#if defined(GR_OP_ALLOCATE_USE_POOL)
    GrMemoryPool* pool = context->priv().opMemoryPool();
    char* bytes = (char*)pool->allocate(sizeof(Op) + sizeof(GrProcessorSet));
    char* setMem = bytes + sizeof(Op);
    GrProcessorSet* processorSet = new (setMem)  GrProcessorSet{std::move(paint)};
    return Owner{new (bytes) Op(processorSet, color, std::forward<Args>(args)...), pool};
#else
    char* bytes = (char*)::operator new(sizeof(Op) + sizeof(GrProcessorSet));
    char* setMem = bytes + sizeof(Op);
    GrProcessorSet* processorSet = new (setMem)  GrProcessorSet{std::move(paint)};
    return Owner{new (bytes) Op(processorSet, color, std::forward<Args>(args)...)};
#endif
}

template <typename Op, typename... OpArgs>
GrOp::Owner GrSimpleMeshDrawOpHelper::FactoryHelper(GrRecordingContext* context,
                                                    GrPaint&& paint,
                                                    OpArgs&& ... opArgs) {
    auto color = paint.getColor4f();
    if (paint.isTrivial()) {
        return GrOp::Make<Op>(context, nullptr, color, std::forward<OpArgs>(opArgs)...);
    } else {
        return GrOp::MakeWithProcessorSet<Op>(
                context, color, std::move(paint), std::forward<OpArgs>(opArgs)...);
    }
}

GR_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::InputFlags)

#endif
