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

#ifndef GrDefaultGeoProcFactory_DEFINED
#define GrDefaultGeoProcFactory_DEFINED

#include "GrColorSpaceXform.h"
#include "GrGeometryProcessor.h"
#include "GrShaderCaps.h"

constexpr int kMaxBones = 80; // Supports up to 80 bones per mesh.

/*
 * A factory for creating default Geometry Processors which simply multiply position by the uniform
 * view matrix and wire through color, coverage, UV coords if requested.
 */
namespace GrDefaultGeoProcFactory {
    struct Color {
        enum Type {
            kPremulGrColorUniform_Type,
            kPremulGrColorAttribute_Type,
            kPremulWideColorAttribute_Type,
            kUnpremulSkColorAttribute_Type,
        };
        explicit Color(const SkPMColor4f& color)
                : fType(kPremulGrColorUniform_Type)
                , fColor(color)
                , fColorSpaceXform(nullptr) {}
        Color(Type type)
                : fType(type)
                , fColor(SK_PMColor4fILLEGAL)
                , fColorSpaceXform(nullptr) {
            SkASSERT(type != kPremulGrColorUniform_Type);
        }

        Type fType;
        SkPMColor4f fColor;

        // This only applies to SkColor. Any GrColors are assumed to have been color converted
        // during paint conversion.
        sk_sp<GrColorSpaceXform> fColorSpaceXform;
    };

    struct Coverage {
        enum Type {
            kSolid_Type,
            kUniform_Type,
            kAttribute_Type,
            kAttributeTweakAlpha_Type,
        };
        explicit Coverage(uint8_t coverage) : fType(kUniform_Type), fCoverage(coverage) {}
        Coverage(Type type) : fType(type), fCoverage(0xff) {
            SkASSERT(type != kUniform_Type);
        }

        Type fType;
        uint8_t fCoverage;
    };

    struct LocalCoords {
        enum Type {
            kUnused_Type,
            kUsePosition_Type,
            kHasExplicit_Type,
            kHasTransformed_Type,
        };
        LocalCoords(Type type) : fType(type), fMatrix(nullptr) {}
        LocalCoords(Type type, const SkMatrix* matrix) : fType(type), fMatrix(matrix) {
            SkASSERT(kUnused_Type != type);
        }
        bool hasLocalMatrix() const { return nullptr != fMatrix; }

        Type fType;
        const SkMatrix* fMatrix;
    };

    struct Bones {
        Bones(const float bones[], int boneCount)
            : fBones(bones)
            , fBoneCount(boneCount) {}

        const float* fBones;
        int fBoneCount;
    };

    sk_sp<GrGeometryProcessor> Make(const GrShaderCaps*,
                                    const Color&,
                                    const Coverage&,
                                    const LocalCoords&,
                                    const SkMatrix& viewMatrix);

    /*
     * Use this factory to create a GrGeometryProcessor that expects a device space vertex position
     * attribute. The view matrix must still be provided to compute correctly transformed
     * coordinates for GrFragmentProcessors. It may fail if the view matrix is not invertible.
     */
    sk_sp<GrGeometryProcessor> MakeForDeviceSpace(const GrShaderCaps*,
                                                  const Color&,
                                                  const Coverage&,
                                                  const LocalCoords&,
                                                  const SkMatrix& viewMatrix);

    /*
     * Use this factory to create a GrGeometryProcessor that supports skeletal animation through
     * deformation of vertices using matrices that are passed in. This should only be called from
     * GrDrawVerticesOp.
     */
    sk_sp<GrGeometryProcessor> MakeWithBones(const GrShaderCaps*,
                                             const Color&,
                                             const Coverage&,
                                             const LocalCoords&,
                                             const Bones&,
                                             const SkMatrix& viewMatrix);
};

#endif
