/*
 * Copyright 2017 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h"

#include "include/private/base/SkTo.h"
#include "src/base/SkArenaAlloc.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrDstProxyView.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrProcessorAnalysis.h"
#include "src/gpu/ganesh/GrProcessorSet.h"
#include "src/gpu/ganesh/GrProgramInfo.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"

enum class GrXferBarrierFlags;
struct SkRect;

GrSimpleMeshDrawOpHelper::GrSimpleMeshDrawOpHelper(GrProcessorSet* processorSet,
                                                   GrAAType aaType,
                                                   InputFlags inputFlags)
        : fProcessors(processorSet)
        , fPipelineFlags((GrPipeline::InputFlags)inputFlags)
        , fAAType((int)aaType)
        , fUsesLocalCoords(false)
        , fCompatibleWithCoverageAsAlpha(false) {
    SkDEBUGCODE(fDidAnalysis = false);
    SkDEBUGCODE(fMadePipeline = false);
}

GrSimpleMeshDrawOpHelper::~GrSimpleMeshDrawOpHelper() {
    if (fProcessors) {
        fProcessors->~GrProcessorSet();
    }
}

GrDrawOp::FixedFunctionFlags GrSimpleMeshDrawOpHelper::fixedFunctionFlags() const {
    return GrAATypeIsHW(this->aaType()) ? GrDrawOp::FixedFunctionFlags::kUsesHWAA
                                        : GrDrawOp::FixedFunctionFlags::kNone;
}

bool GrSimpleMeshDrawOpHelper::isCompatible(const GrSimpleMeshDrawOpHelper& that,
                                            const GrCaps& caps, const SkRect& thisBounds,
                                            const SkRect& thatBounds, bool ignoreAAType) const {
    if (SkToBool(fProcessors) != SkToBool(that.fProcessors)) {
        return false;
    }
    if (fProcessors) {
        if (*fProcessors != *that.fProcessors) {
            return false;
        }
    }

#ifdef SK_DEBUG
    if (ignoreAAType) {
        // If we're ignoring AA it should be bc we already know they are the same or that
        // the are different but are compatible (i.e., one is AA and the other is None)
        SkASSERT(fAAType == that.fAAType ||
                 GrMeshDrawOp::CanUpgradeAAOnMerge(this->aaType(), that.aaType()));
    }
#endif

    bool result = fPipelineFlags == that.fPipelineFlags &&
                  (ignoreAAType || fAAType == that.fAAType);
    SkASSERT(!result || fCompatibleWithCoverageAsAlpha == that.fCompatibleWithCoverageAsAlpha);
    SkASSERT(!result || fUsesLocalCoords == that.fUsesLocalCoords);
    return result;
}

GrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
        const GrCaps& caps, const GrAppliedClip* clip, GrClampType clampType,
        GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor, bool* wideColor) {
    GrProcessorAnalysisColor color = *geometryColor;
    auto result = this->finalizeProcessors(caps, clip, clampType, geometryCoverage, &color);
    color.isConstant(geometryColor);
    if (wideColor) {
        *wideColor = !geometryColor->fitsInBytes();
    }
    return result;
}

GrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
        const GrCaps& caps, const GrAppliedClip* clip, const GrUserStencilSettings* userStencil,
        GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
        GrProcessorAnalysisColor* geometryColor) {
    SkDEBUGCODE(fDidAnalysis = true);
    GrProcessorSet::Analysis analysis;
    if (fProcessors) {
        GrProcessorAnalysisCoverage coverage = geometryCoverage;
        if (GrProcessorAnalysisCoverage::kNone == coverage) {
            coverage = (clip && clip->hasCoverageFragmentProcessor())
                               ? GrProcessorAnalysisCoverage::kSingleChannel
                               : GrProcessorAnalysisCoverage::kNone;
        }
        SkPMColor4f overrideColor;
        analysis = fProcessors->finalize(*geometryColor, coverage, clip, userStencil, caps,
                                         clampType, &overrideColor);
        if (analysis.inputColorIsOverridden()) {
            *geometryColor = overrideColor;
        }
    } else {
        analysis = GrProcessorSet::EmptySetAnalysis();
    }
    fUsesLocalCoords = analysis.usesLocalCoords();
    fCompatibleWithCoverageAsAlpha = analysis.isCompatibleWithCoverageAsAlpha();
    return analysis;
}

const GrPipeline* GrSimpleMeshDrawOpHelper::CreatePipeline(const GrCaps* caps,
                                                           SkArenaAlloc* arena,
                                                           skgpu::Swizzle writeViewSwizzle,
                                                           GrAppliedClip&& appliedClip,
                                                           const GrDstProxyView& dstProxyView,
                                                           GrProcessorSet&& processorSet,
                                                           GrPipeline::InputFlags pipelineFlags) {
    GrPipeline::InitArgs pipelineArgs;

    pipelineArgs.fInputFlags = pipelineFlags;
    pipelineArgs.fCaps = caps;
    pipelineArgs.fDstProxyView = dstProxyView;
    pipelineArgs.fWriteSwizzle = writeViewSwizzle;

    return arena->make<GrPipeline>(pipelineArgs,
                                   std::move(processorSet),
                                   std::move(appliedClip));
}

const GrPipeline* GrSimpleMeshDrawOpHelper::CreatePipeline(GrOpFlushState* flushState,
                                                           GrProcessorSet&& processorSet,
                                                           GrPipeline::InputFlags pipelineFlags) {
    return CreatePipeline(&flushState->caps(),
                          flushState->allocator(),
                          flushState->writeView().swizzle(),
                          flushState->detachAppliedClip(),
                          flushState->dstProxyView(),
                          std::move(processorSet),
                          pipelineFlags);
}

const GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(GrOpFlushState* flushState) {
    return CreatePipeline(&flushState->caps(),
                          flushState->allocator(),
                          flushState->writeView().swizzle(),
                          flushState->detachAppliedClip(),
                          flushState->dstProxyView(),
                          this->detachProcessorSet(),
                          this->pipelineFlags());
}

const GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(const GrCaps* caps,
                                                           SkArenaAlloc* arena,
                                                           skgpu::Swizzle writeViewSwizzle,
                                                           GrAppliedClip&& appliedClip,
                                                           const GrDstProxyView& dstProxyView) {
    return GrSimpleMeshDrawOpHelper::CreatePipeline(caps,
                                                    arena,
                                                    writeViewSwizzle,
                                                    std::move(appliedClip),
                                                    dstProxyView,
                                                    this->detachProcessorSet(),
                                                    this->pipelineFlags());
}

GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(
            const GrCaps* caps,
            SkArenaAlloc* arena,
            const GrSurfaceProxyView& writeView,
            bool usesMSAASurface,
            GrAppliedClip&& appliedClip,
            const GrDstProxyView& dstProxyView,
            GrGeometryProcessor* geometryProcessor,
            GrProcessorSet&& processorSet,
            GrPrimitiveType primitiveType,
            GrXferBarrierFlags renderPassXferBarriers,
            GrLoadOp colorLoadOp,
            GrPipeline::InputFlags pipelineFlags,
            const GrUserStencilSettings* stencilSettings) {
    auto pipeline = CreatePipeline(caps,
                                   arena,
                                   writeView.swizzle(),
                                   std::move(appliedClip),
                                   dstProxyView,
                                   std::move(processorSet),
                                   pipelineFlags);

    return CreateProgramInfo(caps, arena, pipeline, writeView, usesMSAASurface, geometryProcessor,
                             primitiveType, renderPassXferBarriers, colorLoadOp, stencilSettings);
}

GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(const GrCaps* caps,
                                                           SkArenaAlloc* arena,
                                                           const GrPipeline* pipeline,
                                                           const GrSurfaceProxyView& writeView,
                                                           bool usesMSAASurface,
                                                           GrGeometryProcessor* geometryProcessor,
                                                           GrPrimitiveType primitiveType,
                                                           GrXferBarrierFlags xferBarrierFlags,
                                                           GrLoadOp colorLoadOp,
                                                           const GrUserStencilSettings* stencilSettings) {
    auto tmp = arena->make<GrProgramInfo>(*caps,
                                          writeView,
                                          usesMSAASurface,
                                          pipeline,
                                          stencilSettings,
                                          geometryProcessor,
                                          primitiveType,
                                          xferBarrierFlags,
                                          colorLoadOp);
    return tmp;
}

GrProgramInfo* GrSimpleMeshDrawOpHelper::createProgramInfo(
                                            const GrCaps* caps,
                                            SkArenaAlloc* arena,
                                            const GrSurfaceProxyView& writeView,
                                            bool usesMSAASurface,
                                            GrAppliedClip&& appliedClip,
                                            const GrDstProxyView& dstProxyView,
                                            GrGeometryProcessor* gp,
                                            GrPrimitiveType primType,
                                            GrXferBarrierFlags renderPassXferBarriers,
                                            GrLoadOp colorLoadOp) {
    return CreateProgramInfo(caps,
                             arena,
                             writeView,
                             usesMSAASurface,
                             std::move(appliedClip),
                             dstProxyView,
                             gp,
                             this->detachProcessorSet(),
                             primType,
                             renderPassXferBarriers,
                             colorLoadOp,
                             this->pipelineFlags());
}

#if defined(GPU_TEST_UTILS)
static void dump_pipeline_flags(GrPipeline::InputFlags flags, SkString* result) {
    if (GrPipeline::InputFlags::kNone != flags) {
        if (flags & GrPipeline::InputFlags::kSnapVerticesToPixelCenters) {
            result->append("Snap vertices to pixel center.\n");
        }
        if (flags & GrPipeline::InputFlags::kWireframe) {
            result->append("Wireframe enabled.\n");
        }
        if (flags & GrPipeline::InputFlags::kConservativeRaster) {
            result->append("Conservative raster enabled.\n");
        }
        return;
    }
    result->append("No pipeline flags\n");
}

SkString GrSimpleMeshDrawOpHelper::dumpInfo() const {
    const GrProcessorSet& processors = fProcessors ? *fProcessors : GrProcessorSet::EmptySet();
    SkString result = processors.dumpProcessors();
    result.append("AA Type: ");
    switch (this->aaType()) {
        case GrAAType::kNone:
            result.append(" none\n");
            break;
        case GrAAType::kCoverage:
            result.append(" coverage\n");
            break;
        case GrAAType::kMSAA:
            result.append(" msaa\n");
            break;
    }
    dump_pipeline_flags(fPipelineFlags, &result);
    return result;
}
#endif
