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

#ifndef GrGrAtlasInstancedHelper_DEFINED
#define GrGrAtlasInstancedHelper_DEFINED

#include "src/core/SkIPoint16.h"
#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrSurfaceProxyView.h"
#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"

struct GrVertexWriter;

// This class encapsulates all the necessary steps for an instanced GrGeometryProcessor to clip
// against a path mask from an atlas.
class GrAtlasInstancedHelper {
public:
    enum class ShaderFlags {
        kNone = 0,
        kInvertCoverage = 1 << 0,
        kCheckBounds = 1 << 1
    };

    GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(ShaderFlags);

    constexpr static int kNumShaderFlags = 2;

    GrAtlasInstancedHelper(GrSurfaceProxyView atlasView, ShaderFlags shaderFlags)
            : fAtlasProxy(atlasView.detachProxy())
            , fAtlasSwizzle(atlasView.swizzle())
            , fShaderFlags(shaderFlags) {
        // Bottom left origin is not supported.
        SkASSERT(atlasView.origin() == kTopLeft_GrSurfaceOrigin);
    }

    GrSurfaceProxy* proxy() const { return fAtlasProxy.get(); }
    const GrSwizzle& atlasSwizzle() const { return fAtlasSwizzle; }

    // Returns whether the two helpers can be batched together in a single draw.
    bool isCompatible(const GrAtlasInstancedHelper& helper) {
        // TODO: We may want to consider two helpers compatible if they only differ in the
        // kCheckBounds flag -- we can always promote one to checking its bounds.
        SkASSERT(fAtlasProxy != helper.fAtlasProxy || fAtlasSwizzle == helper.fAtlasSwizzle);
        return fAtlasProxy == helper.fAtlasProxy && fShaderFlags == helper.fShaderFlags;
    }

    // Adds bits to the shader key that uniquely identify this specific helper's shader code.
    void getKeyBits(GrProcessorKeyBuilder* b) const {
        b->addBits(kNumShaderFlags, (int)fShaderFlags, "atlasFlags");
    }

    // Appends the instanced input attribs to the back of the array that we will need in order to
    // locate our path in the atlas.
    void appendInstanceAttribs(SkTArray<GrGeometryProcessor::Attribute>* instanceAttribs) const;

    struct Instance {
        Instance(SkIPoint16 locationInAtlas, const SkIRect& pathDevIBounds, bool transposedInAtlas)
                : fLocationInAtlas(locationInAtlas)
                , fPathDevIBounds(pathDevIBounds)
                , fTransposedInAtlas(transposedInAtlas) {
            SkASSERT(fLocationInAtlas.x() >= 0);
            SkASSERT(fLocationInAtlas.y() >= 0);
        }
        SkIPoint16 fLocationInAtlas;
        SkIRect fPathDevIBounds;
        bool fTransposedInAtlas;
    };

    // Writes out the given instance data, formatted for the specific attribs that we added during
    // appendInstanceAttribs().
    void writeInstanceData(GrVertexWriter* instanceWriter, const Instance*) const;

    // Injects vertex code, fragment code, varyings, and uniforms to ultimately multiply
    // "args.fOutputCoverage" in the fragment shader by the atlas coverage.
    //
    // The caller is responsible to store "atlasAdjustUniformHandle" and pass it to
    // setUniformData().
    void injectShaderCode(const GrGLSLGeometryProcessor::EmitArgs&, const GrShaderVar& devCoord,
                          GrGLSLUniformHandler::UniformHandle* atlasAdjustUniformHandle) const;

    // The atlas clip requires one uniform value -- "atlasAdjustUniform". The caller should have
    // stored this handle after its call to injectShaderCode(). This method sets its value prior to
    // drawing.
    void setUniformData(const GrGLSLProgramDataManager&,
                        const GrGLSLUniformHandler::UniformHandle& atlasAdjustUniformHandle) const;

private:
    const sk_sp<GrSurfaceProxy> fAtlasProxy;
    const GrSwizzle fAtlasSwizzle;
    const ShaderFlags fShaderFlags;
};

GR_MAKE_BITFIELD_CLASS_OPS(GrAtlasInstancedHelper::ShaderFlags);

#endif
