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

#ifndef GrQuadUtils_DEFINED
#define GrQuadUtils_DEFINED

#include "src/base/SkVx.h"
#include "src/gpu/ganesh/geometry/GrQuad.h"

enum class GrQuadAAFlags;
enum class GrAA : bool;
enum class GrAAType : unsigned;
struct SkRect;

namespace GrQuadUtils {

    // Resolve disagreements between the overall requested AA type and the per-edge quad AA flags.
    // Both outAAType and outEdgeFlags will be updated.
    void ResolveAAType(GrAAType requestedAAType, GrQuadAAFlags requestedEdgeFlags,
                       const GrQuad& quad, GrAAType* outAAtype, GrQuadAAFlags* outEdgeFlags);

    /**
     * Clip the device vertices of 'quad' to be in front of the W = 0 plane (w/in epsilon). The
     * local coordinates will be updated to match the new clipped vertices. This returns the number
     * of clipped quads that need to be drawn: 0 if 'quad' was entirely behind the plane, 1 if
     * 'quad' did not need to be clipped or if 2 or 3 vertices were clipped, or 2 if 'quad' had one
     * vertex clipped (producing a pentagonal shape spanned by 'quad' and 'extraVertices').
     */
    int ClipToW0(DrawQuad* quad, DrawQuad* extraVertices);

    /**
     * Crops quad to the provided device-space axis-aligned rectangle. If the intersection of this
     * quad (projected) and cropRect results in a quadrilateral, this returns true. If not, this
     * quad may be updated to be a smaller quad of the same type such that its intersection with
     * cropRect is visually the same. This function assumes that the 'quad' coordinates are finite.
     *
     * The provided edge flags are updated to reflect edges clipped by cropRect (toggling on or off
     * based on cropAA policy). If provided, the local coordinates will be updated to reflect the
     * updated device coordinates of this quad.
     *
     * If 'computeLocal' is false, the local coordinates in 'quad' will not be modified.
     */
    bool CropToRect(const SkRect& cropRect, GrAA cropAA, DrawQuad* quad, bool computeLocal=true);

    inline void Outset(const skvx::float4& edgeDistances, GrQuad* quad);

    bool WillUseHairline(const GrQuad& quad, GrAAType aaType, GrQuadAAFlags edgeFlags);

    class TessellationHelper {
    public:
        // Set the original device and (optional) local coordinates that are inset or outset
        // by the requested edge distances. Use nullptr if there are no local coordinates to update.
        // This assumes all device coordinates have been clipped to W > 0.
        void reset(const GrQuad& deviceQuad, const GrQuad* localQuad);

        // Calculates a new quadrilateral with edges parallel to the original except that they
        // have been moved inwards by edgeDistances (which should be positive). Distances are
        // ordered L, B, T, R to match CCW tristrip ordering of GrQuad vertices. Edges that are
        // not moved (i.e. distance == 0) will not be used in calculations and the corners will
        // remain on that edge.
        //
        // The per-vertex coverage will be returned. When the inset geometry does not collapse to
        // a point or line, this will be 1.0 for every vertex. When it does collapse, the per-vertex
        // coverages represent estimated pixel coverage to simulate drawing the subpixel-sized
        // original quad.
        //
        // Note: the edge distances are in device pixel units, so after rendering the new quad
        // edge's shortest distance to the original quad's edge would be equal to provided edge dist
        skvx::float4 inset(const skvx::float4& edgeDistances,
                           GrQuad* deviceInset, GrQuad* localInset);

        // Calculates a new quadrilateral that outsets the original edges by the given distances.
        // Other than moving edges outwards, this function is equivalent to inset(). If the exact
        // same edge distances are provided, certain internal computations can be reused across
        // consecutive calls to inset() and outset() (in any order).
        void outset(const skvx::float4& edgeDistances,
                    GrQuad* deviceOutset, GrQuad* localOutset);

        // Compute the edge equations of the original device space quad passed to 'reset()'. The
        // coefficients are stored per-edge in 'a', 'b', and 'c', such that ax + by + c = 0, and
        // a positive distance indicates the interior of the quad. Edges are ordered L, B, T, R,
        // matching edge distances passed to inset() and outset().
        void getEdgeEquations(skvx::float4* a,
                              skvx::float4* b,
                              skvx::float4* c);

        // Compute the edge lengths of the original device space quad passed to 'reset()'. The
        // edge lengths are ordered LBTR to match distances passed to inset() and outset().
        skvx::float4 getEdgeLengths();

        // Determine if the original device space quad has vertices closer than 1px to its opposing
        // edges, without going through the full work of computing the insets (assuming that the
        // inset distances would be 0.5px).
        bool isSubpixel();

    private:
        // NOTE: This struct is named 'EdgeVectors' because it holds a lot of cached calculations
        // pertaining to the edge vectors of the input quad, projected into 2D device coordinates.
        // While they are not direction vectors, this struct represents a convenient storage space
        // for the projected corners of the quad.
        struct EdgeVectors {
            // Projected corners (x/w and y/w); these are the 2D coordinates that determine the
            // actual edge direction vectors, dx, dy, and invLengths
            skvx::float4 fX2D, fY2D;
            // Normalized edge vectors of the device space quad, ordered L, B, T, R
            // (i.e. next_ccw(x) - x).
            skvx::float4 fDX, fDY;
            // Reciprocal of edge length of the device space quad, i.e. 1 / sqrt(dx*dx + dy*dy)
            skvx::float4 fInvLengths;
            // Theta represents the angle formed by the two edges connected at each corner.
            skvx::float4 fCosTheta;
            skvx::float4 fInvSinTheta; // 1 / sin(theta)

            void reset(const skvx::float4& xs, const skvx::float4& ys,
                       const skvx::float4& ws, GrQuad::Type quadType);
        };

        struct EdgeEquations {
            // a * x + b * y + c = 0; positive distance is inside the quad; ordered LBTR.
            skvx::float4 fA, fB, fC;

            void reset(const EdgeVectors& edgeVectors);

            skvx::float4 estimateCoverage(const skvx::float4& x2d,
                                          const skvx::float4& y2d) const;

            bool isSubpixel(const skvx::float4& x2d, const skvx::float4& y2d) const;

            // Outsets or insets 'x2d' and 'y2d' in place. To be used when the interior is very
            // small, edges are near parallel, or edges are very short/zero-length. Returns number
            // of effective vertices in the degenerate quad.
            int computeDegenerateQuad(const skvx::float4& signedEdgeDistances,
                                      skvx::float4* x2d, skvx::float4* y2d,
                                      skvx::Vec<4, int32_t>* aaMask) const;
        };

        struct OutsetRequest {
            // Positive edge distances to move each edge of the quad. These distances represent the
            // shortest (perpendicular) distance between the original edge and the inset or outset
            // edge. If the distance is 0, then the edge will not move.
            skvx::float4 fEdgeDistances;
            // True if the new corners cannot be calculated by simply adding scaled edge vectors.
            // The quad may be degenerate because of the original geometry (near colinear edges), or
            // be because of the requested edge distances (collapse of inset, etc.)
            bool fInsetDegenerate;
            bool fOutsetDegenerate;

            void reset(const EdgeVectors& edgeVectors, GrQuad::Type quadType,
                       const skvx::float4& edgeDistances);
        };

        struct Vertices {
            // X, Y, and W coordinates in device space. If not perspective, w should be set to 1.f
            skvx::float4 fX, fY, fW;
            // U, V, and R coordinates representing local quad.
            // Ignored depending on uvrCount (0, 1, 2).
            skvx::float4 fU, fV, fR;
            int fUVRCount;

            void reset(const GrQuad& deviceQuad, const GrQuad* localQuad);

            void asGrQuads(GrQuad* deviceOut, GrQuad::Type deviceType,
                           GrQuad* localOut, GrQuad::Type localType) const;

            // Update the device and optional local coordinates by moving the corners along their
            // edge vectors such that the new edges have moved 'signedEdgeDistances' from their
            // original lines. This should only be called if the 'edgeVectors' fInvSinTheta data is
            // numerically sound.
            void moveAlong(const EdgeVectors& edgeVectors,
                           const skvx::float4& signedEdgeDistances);

            // Update the device coordinates by deriving (x,y,w) that project to (x2d, y2d), with
            // optional local coordinates updated to match the new vertices. It is assumed that
            // 'mask' was respected when determining (x2d, y2d), but it is used to ensure that only
            // unmasked unprojected edge vectors are used when computing device and local coords.
            void moveTo(const skvx::float4& x2d,
                        const skvx::float4& y2d,
                        const skvx::Vec<4, int32_t>& mask);
        };

        Vertices            fOriginal;
        EdgeVectors         fEdgeVectors;
        GrQuad::Type        fDeviceType;
        GrQuad::Type        fLocalType;

        // Lazily computed as needed; use accessor functions instead of direct access.
        OutsetRequest       fOutsetRequest;
        EdgeEquations       fEdgeEquations;

        // Validity of Vertices/EdgeVectors (always true after first call to set()).
        bool fVerticesValid      = false;
        // Validity of outset request (true after calling getOutsetRequest() until next set() call
        // or next inset/outset() with different edge distances).
        bool fOutsetRequestValid = false;
        // Validity of edge equations (true after calling getEdgeEquations() until next set() call).
        bool fEdgeEquationsValid = false;

        // The requested edge distances must be positive so that they can be reused between inset
        // and outset calls.
        const OutsetRequest& getOutsetRequest(const skvx::float4& edgeDistances);
        const EdgeEquations& getEdgeEquations();

        // Outsets or insets 'vertices' by the given perpendicular 'signedEdgeDistances' (inset or
        // outset is determined implicitly by the sign of the distances).
        void adjustVertices(const skvx::float4& signedEdgeDistances, Vertices* vertices);
        // Like adjustVertices() but handles empty edges, collapsed quads, numerical issues, and
        // returns the number of effective vertices in the adjusted shape.
        int adjustDegenerateVertices(const skvx::float4& signedEdgeDistances,
                                     Vertices* vertices);

        friend int ClipToW0(DrawQuad*, DrawQuad*); // To reuse Vertices struct
    };

} // namespace GrQuadUtils

void GrQuadUtils::Outset(const skvx::float4& edgeDistances, GrQuad* quad) {
    TessellationHelper outsetter;
    outsetter.reset(*quad, nullptr);
    outsetter.outset(edgeDistances, quad, nullptr);
}

#endif
