/*
 * Copyright 2021 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/geom/Shape.h"

#include "include/private/base/SkAlign.h"
#include "src/core/SkPathPriv.h"
#include "src/core/SkRRectPriv.h"
#include "src/utils/SkPolyUtils.h"

namespace {
// Keys for paths may be extracted from the path data for small paths, to maximize matches
// even when the genIDs may differ. The value is based on emperical experience, to trade off
// matches vs. key size.
constexpr int kMaxKeyFromDataVerbCnt = 10;
}

namespace skgpu::graphite {

Shape& Shape::operator=(const Shape& shape) {
    switch (shape.type()) {
        case Type::kEmpty: this->reset();                         break;
        case Type::kLine:  this->setLine(shape.p0(), shape.p1()); break;
        case Type::kRect:  this->setRect(shape.rect());           break;
        case Type::kRRect: this->setRRect(shape.rrect());         break;
        case Type::kPath:  this->setPath(shape.path());           break;
    }

    fInverted = shape.fInverted;
    return *this;
}

bool Shape::conservativeContains(const Rect& rect) const {
    switch (fType) {
        case Type::kEmpty: return false;
        case Type::kLine:  return false;
        case Type::kRect:  return fRect.contains(rect);
        case Type::kRRect: return fRRect.contains(rect.asSkRect());
        case Type::kPath:  return fPath.conservativelyContainsRect(rect.asSkRect());
    }
    SkUNREACHABLE;
}

bool Shape::conservativeContains(skvx::float2 point) const {
    switch (fType) {
        case Type::kEmpty: return false;
        case Type::kLine:  return false;
        case Type::kRect:  return fRect.contains(Rect::Point(point));
        case Type::kRRect: return SkRRectPriv::ContainsPoint(fRRect, {point.x(), point.y()});
        case Type::kPath:  return fPath.contains(point.x(), point.y());
    }
    SkUNREACHABLE;
}

bool Shape::convex(bool simpleFill) const {
    if (this->isPath()) {
        // SkPath.isConvex() really means "is this path convex were it to be closed".
        return (simpleFill || fPath.isLastContourClosed()) && fPath.isConvex();
    } else {
        // Every other shape type is convex by construction.
        return true;
    }
}

Rect Shape::bounds() const {
    switch (fType) {
        case Type::kEmpty: return Rect(0, 0, 0, 0);
        case Type::kLine:  return fRect.makeSorted(); // sorting corners computes bbox of segment
        case Type::kRect:  return fRect; // assuming it's sorted
        case Type::kRRect: return fRRect.getBounds();
        case Type::kPath:  return fPath.getBounds();
    }
    SkUNREACHABLE;
}

SkPath Shape::asPath() const {
    if (fType == Type::kPath) {
        return fPath;
    }

    SkPathBuilder builder(this->fillType());
    switch (fType) {
        case Type::kEmpty: /* do nothing */                            break;
        case Type::kLine:  builder.moveTo(fRect.left(), fRect.top())
                                  .lineTo(fRect.right(), fRect.bot()); break;
        case Type::kRect:  builder.addRect(fRect.asSkRect());          break;
        case Type::kRRect: builder.addRRect(fRRect);                   break;
        case Type::kPath:  SkUNREACHABLE;
    }
    return builder.detach();
}

namespace {
int path_key_from_data_size(const SkPath& path) {
    const int verbCnt = path.countVerbs();
    if (verbCnt > kMaxKeyFromDataVerbCnt) {
        return -1;
    }
    const int pointCnt = path.countPoints();
    const int conicWeightCnt = SkPathPriv::ConicWeightCnt(path);

    static_assert(sizeof(SkPoint) == 2 * sizeof(uint32_t));
    static_assert(sizeof(SkScalar) == sizeof(uint32_t));
    // 1 is for the verb count. Each verb is a byte but we'll pad the verb data out to
    // a uint32_t length.
    return 1 + (SkAlign4(verbCnt) >> 2) + 2 * pointCnt + conicWeightCnt;
}

// Writes the path data key into the passed pointer.
void write_path_key_from_data(const SkPath& path, uint32_t* origKey) {
    uint32_t* key = origKey;
    // The check below should take care of negative values casted positive.
    const int verbCnt = path.countVerbs();
    const int pointCnt = path.countPoints();
    const int conicWeightCnt = SkPathPriv::ConicWeightCnt(path);
    SkASSERT(verbCnt <= kMaxKeyFromDataVerbCnt);
    SkASSERT(pointCnt && verbCnt);
    *key++ = verbCnt;
    memcpy(key, SkPathPriv::VerbData(path), verbCnt * sizeof(uint8_t));
    int verbKeySize = SkAlign4(verbCnt);
    // pad out to uint32_t alignment using value that will stand out when debugging.
    uint8_t* pad = reinterpret_cast<uint8_t*>(key)+ verbCnt;
    memset(pad, 0xDE, verbKeySize - verbCnt);
    key += verbKeySize >> 2;

    memcpy(key, SkPathPriv::PointData(path), sizeof(SkPoint) * pointCnt);
    static_assert(sizeof(SkPoint) == 2 * sizeof(uint32_t));
    key += 2 * pointCnt;
    sk_careful_memcpy(key, SkPathPriv::ConicWeightData(path), sizeof(SkScalar) * conicWeightCnt);
    static_assert(sizeof(SkScalar) == sizeof(uint32_t));
    SkDEBUGCODE(key += conicWeightCnt);
    SkASSERT(key - origKey == path_key_from_data_size(path));
}
} // anonymous namespace

int Shape::keySize() const {
    int count = 1; // Every key has the state flags from the Shape
    switch(this->type()) {
        case Type::kLine:
            static_assert(0 == sizeof(skvx::float4) % sizeof(uint32_t));
            count += sizeof(skvx::float4) / sizeof(uint32_t);
            break;
        case Type::kRect:
            static_assert(0 == sizeof(Rect) % sizeof(uint32_t));
            count += sizeof(Rect) / sizeof(uint32_t);
            break;
        case Type::kRRect:
            static_assert(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
            count += SkRRect::kSizeInMemory / sizeof(uint32_t);
            break;
        case Type::kPath: {
            if (this->path().isVolatile()) {
                return -1; // volatile, so won't be keyed
            }
            if (this->path().isEmpty()) {
                return -1; // empty, so won't be keyed
            }
            int dataKeySize = path_key_from_data_size(this->path());
            if (dataKeySize >= 0) {
                count += dataKeySize;
            } else {
                count++; // Just adds the gen ID.
            }
            break;
        }
        default:
            // else it's empty, which just needs the state flags for its key
            SkASSERT(this->isEmpty());
    }
    return count;
}

void Shape::writeKey(uint32_t* key, bool includeInverted) const {
    SkASSERT(this->keySize());
    SkDEBUGCODE(uint32_t* origKey = key;)

    // Every key starts with the state from the Shape (this includes path fill type,
    // and any tracked inversion, as well as the class of geometry).
    *key++ = this->stateKey(includeInverted);

    switch(this->type()) {
        case Type::kPath: {
            SkASSERT(!this->path().isVolatile());
            SkASSERT(!this->path().isEmpty());
            // Ensure that the path's inversion matches our state so that the path's key suffices.
            SkASSERT(this->inverted() == this->path().isInverseFillType());

            int dataKeySize = path_key_from_data_size(this->path());
            if (dataKeySize >= 0) {
                write_path_key_from_data(this->path(), key);
                return;
            } else {
                *key++ = this->path().getGenerationID();
            }
            break;
        }
        case Type::kRect:
            memcpy(key, &this->rect(), sizeof(Rect));
            key += sizeof(Rect) / sizeof(uint32_t);
            break;
        case Type::kRRect:
            this->rrect().writeToMemory(key);
            key += SkRRect::kSizeInMemory / sizeof(uint32_t);
            break;
        case Type::kLine: {
            skvx::float4 line = this->line();
            memcpy(key, &line, sizeof(skvx::float4));
            key += sizeof(skvx::float4) / sizeof(uint32_t);
            break;
        }
        default:
            // Nothing other than the flag state is needed in the key for an empty shape
            SkASSERT(this->isEmpty());
    }
    SkASSERT(key - origKey == this->keySize());
}

namespace {
SkPathFillType noninverted_fill_type(SkPathFillType fillType) {
    switch (fillType) {
        case SkPathFillType::kWinding:
        case SkPathFillType::kInverseWinding:
            return SkPathFillType::kWinding;
        case SkPathFillType::kEvenOdd:
        case SkPathFillType::kInverseEvenOdd:
            return SkPathFillType::kEvenOdd;
    }
    SkUNREACHABLE;
}
} // anonymous namespace

uint32_t Shape::stateKey(bool includeInverted) const {
    uint32_t key;
    if (includeInverted) {
        // Use the path's full fill type instead of just whether or not it's inverted.
        key = this->isPath() ? static_cast<uint32_t>(fPath.getFillType())
                             : (fInverted ? 1 : 0);
    } else {
        // Use the path's noninverted fill type.
        key = this->isPath() ? static_cast<uint32_t>(noninverted_fill_type(fPath.getFillType()))
                             : 0;
    }
    key |= ((uint32_t) fType) << 2; // fill type was 2 bits
    return key;
}

} // namespace skgpu::graphite
