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

#include "src/gpu/graphite/RasterPathUtils.h"

#include "include/core/SkStrokeRec.h"
#include "include/private/base/SkFixed.h"
#include "src/base/SkFloatBits.h"
#include "src/core/SkBlitter_A8.h"
#include "src/gpu/graphite/geom/Shape.h"
#include "src/gpu/graphite/geom/Transform.h"

namespace skgpu::graphite {

bool RasterMaskHelper::init(SkISize pixmapSize, SkIVector transformedMaskOffset) {
    if (!fPixels) {
        return false;
    }

    // Allocate pixmap if needed
    if (!fPixels->addr()) {
        const SkImageInfo bmImageInfo = SkImageInfo::MakeA8(pixmapSize);
        if (!fPixels->tryAlloc(bmImageInfo)) {
            return false;
        }
        fPixels->erase(0);
    } else if (fPixels->dimensions() != pixmapSize) {
        return false;
    }

    fDraw.fBlitterChooser = SkA8Blitter_Choose;
    fDraw.fDst = *fPixels;
    fDraw.fRC = &fRasterClip;
    fTransformedMaskOffset = transformedMaskOffset;
    return true;
}

void RasterMaskHelper::clear(uint8_t alpha, const SkIRect& shapeBounds) {
    fPixels->erase(SkColorSetARGB(alpha, 0xFF, 0xFF, 0xFF), shapeBounds);
}

void RasterMaskHelper::drawShape(const Shape& shape,
                                 const Transform& localToDevice,
                                 const SkStrokeRec& strokeRec,
                                 const SkIRect& shapeBounds) {
    fRasterClip.setRect(shapeBounds);

    SkPaint paint;
    paint.setBlendMode(SkBlendMode::kSrc);  // "Replace" mode
    paint.setAntiAlias(true);
    // SkPaint's color is unpremul so this will produce alpha in every channel.
    paint.setColor(SK_ColorWHITE);
    strokeRec.applyToPaint(&paint);

    SkMatrix translatedMatrix = SkMatrix(localToDevice);
    // The atlas transform of the shape is `localToDevice` translated by the top-left offset of the
    // resultBounds and the inverse of the base mask transform offset for the current set of shapes.
    // We will need to translate draws so the bound's UL corner is at the origin
    translatedMatrix.postTranslate(shapeBounds.x() - fTransformedMaskOffset.x(),
                                   shapeBounds.y() - fTransformedMaskOffset.y());

    fDraw.fCTM = &translatedMatrix;
    // TODO: use drawRect, drawRRect, drawArc
    SkPath path = shape.asPath();
    if (path.isInverseFillType()) {
        // The shader will handle the inverse fill in this case
        path.toggleInverseFillType();
    }
    fDraw.drawPathCoverage(path, paint);
}

void RasterMaskHelper::drawClip(const Shape& shape,
                                const Transform& localToDevice,
                                uint8_t alpha,
                                const SkIRect& resultBounds) {
    fRasterClip.setRect(resultBounds);

    SkPaint paint;
    paint.setBlendMode(SkBlendMode::kSrc);  // "Replace" mode
    paint.setAntiAlias(true);
    // SkPaint's color is unpremul so this will produce alpha in every channel.
    paint.setColor(SkColorSetARGB(alpha, 0xFF, 0xFF, 0xFF));

    SkMatrix translatedMatrix = SkMatrix(localToDevice);
    // The atlas transform of the shape is `localToDevice` translated by the top-left offset of the
    // resultBounds and the inverse of the base mask transform offset for the current set of shapes.
    // We will need to translate draws so the bound's UL corner is at the origin
    translatedMatrix.postTranslate(resultBounds.x() - fTransformedMaskOffset.x(),
                                   resultBounds.y() - fTransformedMaskOffset.y());

    fDraw.fCTM = &translatedMatrix;
    // TODO: use drawRect, drawRRect, drawArc
    SkPath path = shape.asPath();
    // Because we could be combining multiple paths into one entry we don't touch
    // the inverse fill in this case.
    if (0xFF == alpha) {
        SkASSERT(0xFF == paint.getAlpha());
        fDraw.drawPathCoverage(path, paint);
    } else {
        fDraw.drawPath(path, paint, nullptr, true);
    }
}

uint32_t add_transform_key(skgpu::UniqueKey::Builder* builder,
                           int startIndex,
                           const Transform& transform) {
    // We require the upper left 2x2 of the matrix to match exactly for a cache hit.
    SkMatrix mat = transform.matrix().asM33();
    SkScalar sx = mat.get(SkMatrix::kMScaleX);
    SkScalar sy = mat.get(SkMatrix::kMScaleY);
    SkScalar kx = mat.get(SkMatrix::kMSkewX);
    SkScalar ky = mat.get(SkMatrix::kMSkewY);
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
    // Fractional translate does not affect caching on Android. This is done for better cache
    // hit ratio and speed and is matching HWUI behavior, which didn't consider the matrix
    // at all when caching paths.
    SkFixed fracX = 0;
    SkFixed fracY = 0;
#else
    SkScalar tx = mat.get(SkMatrix::kMTransX);
    SkScalar ty = mat.get(SkMatrix::kMTransY);
    // Allow 8 bits each in x and y of subpixel positioning.
    SkFixed fracX = SkScalarToFixed(SkScalarFraction(tx)) & 0x0000FF00;
    SkFixed fracY = SkScalarToFixed(SkScalarFraction(ty)) & 0x0000FF00;
#endif
    (*builder)[startIndex + 0] = SkFloat2Bits(sx);
    (*builder)[startIndex + 1] = SkFloat2Bits(sy);
    (*builder)[startIndex + 2] = SkFloat2Bits(kx);
    (*builder)[startIndex + 3] = SkFloat2Bits(ky);
    // FracX and fracY are &ed with 0x0000ff00, so need to shift one down to fill 16 bits.
    uint32_t fracBits = fracX | (fracY >> 8);

    return fracBits;
}

skgpu::UniqueKey GeneratePathMaskKey(const Shape& shape,
                                     const Transform& transform,
                                     const SkStrokeRec& strokeRec,
                                     skvx::half2 maskOrigin,
                                     skvx::half2 maskSize) {
    skgpu::UniqueKey maskKey;
    {
        static const skgpu::UniqueKey::Domain kDomain = skgpu::UniqueKey::GenerateDomain();
        int styleKeySize = 7;
        if (!strokeRec.isHairlineStyle() && !strokeRec.isFillStyle()) {
            // Add space for width and miter if needed
            styleKeySize += 2;
        }
        skgpu::UniqueKey::Builder builder(&maskKey, kDomain, styleKeySize + shape.keySize(),
                                          "Raster Path Mask");
        builder[0] = maskOrigin.x() | (maskOrigin.y() << 16);
        builder[1] = maskSize.x() | (maskSize.y() << 16);

        // Add transform key and get packed fractional translation bits
        uint32_t fracBits = add_transform_key(&builder, 2, transform);
        // Distinguish between path styles. For anything but fill, we also need to include
        // the cap. (SW grows hairlines by 0.5 pixel with round and square caps). For stroke
        // or fill-and-stroke we need to include the join, width, and miter.
        static_assert(SkStrokeRec::kStyleCount <= (1 << 2));
        static_assert(SkPaint::kCapCount <= (1 << 2));
        static_assert(SkPaint::kJoinCount <= (1 << 2));
        uint32_t styleBits = strokeRec.getStyle();
        if (!strokeRec.isFillStyle()) {
            styleBits |= (strokeRec.getCap() << 2);
        }
        if (!strokeRec.isHairlineStyle() && !strokeRec.isFillStyle()) {
            styleBits |= (strokeRec.getJoin() << 4);
            builder[6] = SkFloat2Bits(strokeRec.getWidth());
            builder[7] = SkFloat2Bits(strokeRec.getMiter());
        }
        builder[styleKeySize-1] = fracBits | (styleBits << 16);
        shape.writeKey(&builder[styleKeySize], /*includeInverted=*/false);
    }
    return maskKey;
}

skgpu::UniqueKey GenerateClipMaskKey(uint32_t stackRecordID,
                                     const ClipStack::ElementList* elementsForMask) {
    skgpu::UniqueKey maskKey;
    {
        static constexpr int kMaxShapeCountForKey = 2;

        static const skgpu::UniqueKey::Domain kDomain = skgpu::UniqueKey::GenerateDomain();
        // if the element list is too large we just use the stackRecordID
        if (elementsForMask->size() <= kMaxShapeCountForKey) {
            constexpr int kXformKeySize = 5;
            int keySize = 0;
            bool canCreateKey = true;
            // Iterate through to get key size and see if we can create a key at all
            for (int i = 0; i < elementsForMask->size(); ++i) {
                int shapeKeySize = (*elementsForMask)[i]->fShape.keySize();
                if (shapeKeySize < 0) {
                    canCreateKey = false;
                    break;
                }
                keySize += kXformKeySize + shapeKeySize;
            }
            if (canCreateKey) {
                skgpu::UniqueKey::Builder builder(&maskKey, kDomain, keySize,
                                                  "Clip Path Mask");
                int elementKeyIndex = 0;
                for (int i = 0; i < elementsForMask->size(); ++i) {
                    const ClipStack::Element* element = (*elementsForMask)[i];

                    // Add transform key and get packed fractional translation bits
                    uint32_t fracBits = add_transform_key(&builder,
                                                          elementKeyIndex,
                                                          element->fLocalToDevice);
                    uint32_t opBits = static_cast<uint32_t>(element->fOp);
                    builder[elementKeyIndex + 4] = fracBits | (opBits << 16);

                    const Shape& shape = element->fShape;
                    shape.writeKey(&builder[elementKeyIndex + kXformKeySize],
                                   /*includeInverted=*/true);

                    elementKeyIndex += kXformKeySize + shape.keySize();
                }

                return maskKey;
            }
        }

        // Either we have too many elements or at least one shape can't create a key
        skgpu::UniqueKey::Builder builder(&maskKey, kDomain, 1, "Clip Path Mask");
        builder[0] = stackRecordID;
    }

    return maskKey;
}

}  // namespace skgpu::graphite
