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

#ifndef GrClip_DEFINED
#define GrClip_DEFINED

#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "src/gpu/ganesh/GrAppliedClip.h"

class GrDrawOp;
namespace skgpu { namespace v1 { class SurfaceDrawContext; }}

/**
 * GrClip is an abstract base class for applying a clip. It constructs a clip mask if necessary, and
 * fills out a GrAppliedClip instructing the caller on how to set up the draw state.
 */
class GrClip {
public:
    enum class Effect {
        // The clip conservatively modifies the draw's coverage but doesn't eliminate the draw
        kClipped,
        // The clip definitely does not modify the draw's coverage and the draw can be performed
        // without clipping (beyond the automatic device bounds clip).
        kUnclipped,
        // The clip definitely eliminates all of the draw's coverage and the draw can be skipped
        kClippedOut
    };

    struct PreClipResult {
        Effect  fEffect;
        SkRRect fRRect; // Ignore if 'isRRect' is false
        GrAA    fAA;    // Ignore if 'isRRect' is false
        bool    fIsRRect;

        PreClipResult(Effect effect) : fEffect(effect), fIsRRect(false) {}
        PreClipResult(SkRect rect, GrAA aa) : PreClipResult(SkRRect::MakeRect(rect), aa) {}
        PreClipResult(SkRRect rrect, GrAA aa)
                : fEffect(Effect::kClipped)
                , fRRect(rrect)
                , fAA(aa)
                , fIsRRect(true) {}
    };

    virtual ~GrClip() {}

    /**
     * Compute a conservative pixel bounds restricted to the given render target dimensions.
     * The returned bounds represent the limits of pixels that can be drawn; anything outside of the
     * bounds will be entirely clipped out.
     */
    virtual SkIRect getConservativeBounds() const = 0;

    /**
     * This computes a GrAppliedClip from the clip which in turn can be used to build a GrPipeline.
     * To determine the appropriate clipping implementation the GrClip subclass must know whether
     * the draw will enable HW AA or uses the stencil buffer. On input 'bounds' is a conservative
     * bounds of the draw that is to be clipped. If kClipped or kUnclipped is returned, the 'bounds'
     * will have been updated to be contained within the clip bounds (or the device's, for wide-open
     * clips). If kNoDraw is returned, 'bounds' and the applied clip are in an undetermined state
     * and should be ignored (and the draw should be skipped).
     */
    virtual Effect apply(GrRecordingContext*, skgpu::v1::SurfaceDrawContext*, GrDrawOp*, GrAAType,
                         GrAppliedClip*, SkRect* bounds) const = 0;

    /**
     * Perform preliminary, conservative analysis on the draw bounds as if it were provided to
     * apply(). The results of this are returned the PreClipResults struct, where 'result.fEffect'
     * corresponds to what 'apply' would return. If this value is kUnclipped or kNoDraw, then it
     * can be assumed that apply() would also always result in the same Effect.
     *
     * If kClipped is returned, apply() may further refine the effect to kUnclipped or kNoDraw,
     * with one exception. When 'result.fIsRRect' is true, preApply() reports the single round rect
     * and anti-aliased state that would act as an intersection on the draw geometry. If no further
     * action is taken to modify the draw, apply() will represent this round rect in the applied
     * clip.
     *
     * When set, 'result.fRRect' will intersect with the render target bounds but may extend
     * beyond it. If the render target bounds are the only clip effect on the draw, this is reported
     * as kUnclipped and not as a degenerate rrect that matches the bounds.
     */
    virtual PreClipResult preApply(const SkRect& drawBounds, GrAA aa) const {
        SkIRect pixelBounds = GetPixelIBounds(drawBounds, aa);
        bool outside = !SkIRect::Intersects(pixelBounds, this->getConservativeBounds());
        return outside ? Effect::kClippedOut : Effect::kClipped;
    }

    /**
     * This is the maximum distance that a draw may extend beyond a clip's boundary and still count
     * count as "on the other side". We leave some slack because floating point rounding error is
     * likely to blame. The rationale for 1e-3 is that in the coverage case (and barring unexpected
     * rounding), as long as coverage stays within 0.5 * 1/256 of its intended value it shouldn't
     * have any effect on the final pixel values.
     */
    constexpr static SkScalar kBoundsTolerance = 1e-3f;

    /**
     * This is the slack around a half-pixel vertex coordinate where we don't trust the GPU's
     * rasterizer to round consistently. The rounding method is not defined in GPU specs, and
     * rasterizer precision frequently introduces errors where a fraction < 1/2 still rounds up.
     *
     * For non-AA bounds edges, an edge value between 0.45 and 0.55 will round in or round out
     * depending on what side its on. Outside of this range, the non-AA edge will snap using round()
     */
    constexpr static SkScalar kHalfPixelRoundingTolerance = 5e-2f;

    /**
     * Returns true if the given draw bounds count as entirely inside the clip.

     * @param innerClipBounds   device-space rect fully contained by the clip
     * @param drawBounds        device-space bounds of the query region.
     */
    static bool IsInsideClip(const SkIRect& innerClipBounds, const SkRect& drawBounds, GrAA aa) {
        return innerClipBounds.contains(GetPixelIBounds(drawBounds, aa));
    }

    /**
     * Returns true if the given draw bounds count as entirely outside the clip.

     * @param outerClipBounds   device-space rect that contains the clip
     * @param drawBounds        device-space bounds of the query region.
     * @param aa                whether or not the draw will use anti-aliasing
     */
    static bool IsOutsideClip(const SkIRect& outerClipBounds, const SkRect& drawBounds, GrAA aa) {
        return !SkIRect::Intersects(outerClipBounds, GetPixelIBounds(drawBounds, aa));
    }

    // Modifies the behavior of GetPixelIBounds
    enum class BoundsType {
        /**
         * Returns the tightest integer pixel bounding box such that the rasterization of a shape
         * contained in the analytic 'bounds', using the 'aa' method, will only have non-zero
         * coverage for pixels inside the returned bounds. Pixels outside the bounds will either
         * not be touched, or will have 0 coverage that creates no visual change.
         */
        kExterior,
        /**
         * Returns the largest integer pixel bounding box such that were 'bounds' to be rendered as
         * a solid fill using 'aa', every pixel in the returned bounds will have full coverage.
         *
         * This effectively determines the pixels that are definitely covered by a draw or clip. It
         * effectively performs the opposite operations as GetOuterPixelBounds. It rounds in instead
         * of out for coverage AA and non-AA near pixel centers.
         */
        kInterior
    };

    /**
     * Convert the analytic bounds of a shape into an integer pixel bounds, where the given aa type
     * is used when the shape is rendered. The bounds mode can be used to query exterior or interior
     * pixel boundaries. Interior bounds only make sense when its know that the analytic bounds
     * are filled completely.
     *
     * NOTE: When using kExterior_Bounds, some coverage-AA rendering methods may still touch a pixel
     * center outside of these bounds but will evaluate to 0 coverage. This is visually acceptable,
     * but an additional outset of 1px should be used for dst proxy access.
     */
    static SkIRect GetPixelIBounds(const SkRect& bounds, GrAA aa,
                                   BoundsType mode = BoundsType::kExterior) {
        auto roundLow = [aa](float v) {
            v += kBoundsTolerance;
            return aa == GrAA::kNo ? SkScalarRoundToInt(v - kHalfPixelRoundingTolerance)
                                   : SkScalarFloorToInt(v);
        };
        auto roundHigh = [aa](float v) {
            v -= kBoundsTolerance;
            return aa == GrAA::kNo ? SkScalarRoundToInt(v + kHalfPixelRoundingTolerance)
                                   : SkScalarCeilToInt(v);
        };

        if (bounds.isEmpty()) {
            return SkIRect::MakeEmpty();
        }

        if (mode == BoundsType::kExterior) {
            return SkIRect::MakeLTRB(roundLow(bounds.fLeft),   roundLow(bounds.fTop),
                                     roundHigh(bounds.fRight), roundHigh(bounds.fBottom));
        } else {
            return SkIRect::MakeLTRB(roundHigh(bounds.fLeft), roundHigh(bounds.fTop),
                                     roundLow(bounds.fRight), roundLow(bounds.fBottom));
        }
    }

    /**
     * Returns true if the given rect counts as aligned with pixel boundaries.
     */
    static bool IsPixelAligned(const SkRect& rect) {
        return SkScalarAbs(SkScalarRoundToScalar(rect.fLeft) - rect.fLeft) <= kBoundsTolerance &&
               SkScalarAbs(SkScalarRoundToScalar(rect.fTop) - rect.fTop) <= kBoundsTolerance &&
               SkScalarAbs(SkScalarRoundToScalar(rect.fRight) - rect.fRight) <= kBoundsTolerance &&
               SkScalarAbs(SkScalarRoundToScalar(rect.fBottom) - rect.fBottom) <= kBoundsTolerance;
    }
};


/**
 * GrHardClip never uses coverage FPs. It can only enforce the clip using the already-existing
 * stencil buffer contents and/or fixed-function state like scissor. Always aliased if MSAA is off.
 */
class GrHardClip : public GrClip {
public:
    /**
     * Sets the appropriate hardware state modifications on GrAppliedHardClip that will implement
     * the clip. On input 'bounds' is a conservative bounds of the draw that is to be clipped. After
     * return 'bounds' has been intersected with a conservative bounds of the clip.
     */
    virtual Effect apply(GrAppliedHardClip* out, SkIRect* bounds) const = 0;

private:
    Effect apply(GrRecordingContext*,
                 skgpu::v1::SurfaceDrawContext*,
                 GrDrawOp*,
                 GrAAType aa,
                 GrAppliedClip* out,
                 SkRect* bounds) const final {
        SkIRect pixelBounds = GetPixelIBounds(*bounds, GrAA(aa != GrAAType::kNone));
        Effect effect = this->apply(&out->hardClip(), &pixelBounds);
        bounds->intersect(SkRect::Make(pixelBounds));
        return effect;
    }
};

#endif
