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

#ifndef skgpu_graphite_geom_CoverageMaskShape_DEFINED
#define skgpu_graphite_geom_CoverageMaskShape_DEFINED

#include "include/core/SkM44.h"
#include "include/core/SkRefCnt.h"
#include "include/private/SkAssert.h"
#include "src/core/SkVx.h"
#include "src/gpu/graphite/TextureProxy.h"
#include "src/gpu/graphite/geom/Rect.h"
#include "src/gpu/graphite/geom/Shape.h"

#include <utility>

namespace skgpu::graphite {

/**
 * CoverageMaskShape represents a shape for which per-pixel coverage data comes from a
 * texture. This excludes font glyphs that are rendered to a persistent atlas, as those are
 * represented by the SubRunData geometry type.
 *
 * Coverage masks are defined relative to an intermediate coordinate space between the final
 * device space and the original geometry and shading's local space. For atlases and simple cases
 * this intermediate space is pixel-aligned with the final device space, meaning only an integer
 * translation is necessary to align the mask with where the original geometry would have been
 * rendered into the device. In complex cases, the remaining transform may include rotation, skew,
 * or even perspective that has to be applied after some filter effect.
 *
 * Regardless, the DrawParams that records the CoverageMaskShape stores this remaining transform as
 * the "local-to-device" tranform, i.e. "local" refers to the mask's coordinate space. The
 * CoverageMaskShape stores the original local-to-device inverse so that it can reconstruct coords
 * for shading. Like other Geometry types, the bounds() returned by CoverageMaskShape are relative
 * to its local space, so they are identical to its mask size.
 */
class CoverageMaskShape {
    using half2 = skvx::half2;
    using int2 = skvx::int2;

public:
    struct MaskInfo {
        // The texture-relative integer UV coordinates of the top-left corner of this shape's
        // coverage mask bounds. This will include the rounded out transformed device space bounds
        // of the shape plus a 1-pixel border.
        half2 fTextureOrigin;

        // The width and height of the bounds of the coverage mask shape in device coordinates. This
        // includes the rounded out transformed device space bounds of the shape + a 1-pixel border
        // added for AA.
        half2 fMaskSize;
    };

    CoverageMaskShape() = default;
    CoverageMaskShape(const Shape& shape,
                      sk_sp<TextureProxy> proxy,
                      const SkM44& maskToDevice,
                      const MaskInfo& maskInfo)
            : fTextureProxy(std::move(proxy))
            , fMaskToDevice(maskToDevice)
            , fInverted(shape.inverted())
            , fMaskInfo(maskInfo) {
        SkASSERT(fTextureProxy);
    }
    CoverageMaskShape(const CoverageMaskShape&) = default;

    ~CoverageMaskShape() = default;

    // NOTE: None of the geometry types benefit from move semantics, so we don't bother
    // defining a move assignment operator for CoverageMaskShape.
    CoverageMaskShape& operator=(CoverageMaskShape&&) = delete;
    CoverageMaskShape& operator=(const CoverageMaskShape&) = default;

    // Returns the mask-space bounds of the clipped coverage mask shape. For inverse fills this
    // is different from the actual draw bounds stored in the Clip.
    Rect bounds() const {
        return Rect(0.f, 0.f, (float) this->maskSize().x(), (float) this->maskSize().y());
    }

    // The transform from the mask's texture coordinate space to device coordinates, which may be
    // different from the local-to-device transform used for shading coordinates.
    const SkM44& maskToDevice() const { return fMaskToDevice; }

    // The texture-relative integer UV coordinates of the top-left corner of this shape's
    // coverage mask bounds.
    const half2& textureOrigin() const { return fMaskInfo.fTextureOrigin; }

    // The width and height of the bounds of the coverage mask shape in the texture.
    const half2& maskSize() const { return fMaskInfo.fMaskSize; }

    // The texture that the shape will be rendered to.
    const TextureProxy* textureProxy() const { return fTextureProxy.get(); }

    // Whether or not the shape will be painted according to an inverse fill rule.
    bool inverted() const { return fInverted; }

private:
    // We store a ref to the texture proxy to keep it alive.
    // TODO: switch to raw pointer once textures/uniforms are extracted in Device::drawGeometry.
    sk_sp<TextureProxy> fTextureProxy;
    SkM44 fMaskToDevice;
    bool fInverted;
    MaskInfo fMaskInfo;
};

}  // namespace skgpu::graphite

#endif  // skgpu_graphite_geom_CoverageMaskShape_DEFINED
