/*
 * 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/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
