/*
 * Copyright 2022 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/AtlasTypes.h"

#include "include/core/SkAlphaType.h"
#include "include/core/SkImageInfo.h"
#include "include/private/base/SkMalloc.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkSwizzlePriv.h"

namespace skgpu {

Plot::Plot(int pageIndex, int plotIndex, AtlasGenerationCounter* generationCounter,
           int offX, int offY, int width, int height, SkColorType colorType, size_t bpp)
        : fLastUpload(AtlasToken::InvalidToken())
        , fLastUse(AtlasToken::InvalidToken())
        , fFlushesSinceLastUse(0)
        , fPageIndex(pageIndex)
        , fPlotIndex(plotIndex)
        , fGenerationCounter(generationCounter)
        , fGenID(fGenerationCounter->next())
        , fPlotLocator(fPageIndex, fPlotIndex, fGenID)
        , fData(nullptr)
        , fWidth(width)
        , fHeight(height)
        , fX(offX)
        , fY(offY)
        , fRectanizer(width, height)
        , fOffset(SkIPoint16::Make(fX * fWidth, fY * fHeight))
        , fColorType(colorType)
        , fBytesPerPixel(bpp)
#ifdef SK_DEBUG
        , fDirty(false)
#endif
{
    // We expect the allocated dimensions to be a multiple of 4 bytes
    SkASSERT(((width*fBytesPerPixel) & 0x3) == 0);
    // The padding for faster uploads only works for 1, 2 and 4 byte texels
    SkASSERT(fBytesPerPixel != 3 && fBytesPerPixel <= 4);
    fDirtyRect.setEmpty();
}

Plot::~Plot() {
    sk_free(fData);
}

bool Plot::addRect(int width, int height, AtlasLocator* atlasLocator) {
    SkASSERT(width <= fWidth && height <= fHeight);

    SkIPoint16 loc;
    if (!fRectanizer.addRect(width, height, &loc)) {
        return false;
    }

    auto rect = skgpu::IRect16::MakeXYWH(loc.fX, loc.fY, width, height);
    fDirtyRect.join({rect.fLeft, rect.fTop, rect.fRight, rect.fBottom});

    rect.offset(fOffset.fX, fOffset.fY);
    atlasLocator->updateRect(rect);
    SkDEBUGCODE(fDirty = true;)

    return true;
}

void* Plot::dataAt(const AtlasLocator& atlasLocator) {
    if (!fData) {
        fData = reinterpret_cast<unsigned char*>(
                        sk_calloc_throw(fBytesPerPixel * fWidth * fHeight));
    }
    // point ourselves at the right starting spot
    unsigned char* dataPtr = fData;
    SkIPoint topLeft = atlasLocator.topLeft();
    // Assert if we're not accessing the correct Plot
    SkASSERT(topLeft.fX >= fOffset.fX && topLeft.fX < fOffset.fX + fWidth &&
             topLeft.fY >= fOffset.fY && topLeft.fY < fOffset.fY + fHeight);
    topLeft -= SkIPoint::Make(fOffset.fX, fOffset.fY);
    dataPtr += fBytesPerPixel * fWidth * topLeft.fY;
    dataPtr += fBytesPerPixel * topLeft.fX;

    return dataPtr;
}

SkIPoint Plot::prepForRender(const AtlasLocator& al, SkAutoPixmapStorage* pixmap) {
    if (!fData) {
        fData = reinterpret_cast<unsigned char*>(
                        sk_calloc_throw(fBytesPerPixel * fWidth * fHeight));
    }
    pixmap->reset(SkImageInfo::Make(fWidth, fHeight, fColorType, kOpaque_SkAlphaType),
                  fData, fBytesPerPixel * fWidth);
    return al.topLeft() - SkIPoint::Make(fOffset.fX, fOffset.fY);
}

void Plot::copySubImage(const AtlasLocator& al, const void* image) {
    const unsigned char* imagePtr = (const unsigned char*)image;
    unsigned char* dataPtr = (unsigned char*)this->dataAt(al);
    int width = al.width();
    int height = al.height();
    size_t rowBytes = width * fBytesPerPixel;

    // copy into the data buffer, swizzling as we go if this is ARGB data
    constexpr bool kBGRAIsNative = kN32_SkColorType == kBGRA_8888_SkColorType;
    if (4 == fBytesPerPixel && kBGRAIsNative) {
        for (int i = 0; i < height; ++i) {
            SkOpts::RGBA_to_BGRA((uint32_t*)dataPtr, (const uint32_t*)imagePtr, width);
            dataPtr += fBytesPerPixel * fWidth;
            imagePtr += rowBytes;
        }
    } else {
        for (int i = 0; i < height; ++i) {
            memcpy(dataPtr, imagePtr, rowBytes);
            dataPtr += fBytesPerPixel * fWidth;
            imagePtr += rowBytes;
        }
    }
}

bool Plot::addSubImage(int width, int height, const void* image, AtlasLocator* atlasLocator) {
    if (!this->addRect(width, height, atlasLocator)) {
        return false;
    }
    this->copySubImage(*atlasLocator, image);

    return true;
}

std::pair<const void*, SkIRect> Plot::prepareForUpload() {
    // We should only be issuing uploads if we are dirty
    SkASSERT(fDirty);
    if (!fData) {
        return {nullptr, {}};
    }
    size_t rowBytes = fBytesPerPixel * fWidth;
    const unsigned char* dataPtr;
    SkIRect offsetRect;
    // Clamp to 4-byte aligned boundaries
    unsigned int clearBits = 0x3 / fBytesPerPixel;
    fDirtyRect.fLeft &= ~clearBits;
    fDirtyRect.fRight += clearBits;
    fDirtyRect.fRight &= ~clearBits;
    SkASSERT(fDirtyRect.fRight <= fWidth);
    // Set up dataPtr
    dataPtr = fData;
    dataPtr += rowBytes * fDirtyRect.fTop;
    dataPtr += fBytesPerPixel * fDirtyRect.fLeft;
    offsetRect = fDirtyRect.makeOffset(fOffset.fX, fOffset.fY);

    fDirtyRect.setEmpty();
    SkDEBUGCODE(fDirty = false);

    return { dataPtr, offsetRect };
}

void Plot::resetRects() {
    fRectanizer.reset();
    fGenID = fGenerationCounter->next();
    fPlotLocator = PlotLocator(fPageIndex, fPlotIndex, fGenID);
    fLastUpload = AtlasToken::InvalidToken();
    fLastUse = AtlasToken::InvalidToken();

    // zero out the plot
    if (fData) {
        sk_bzero(fData, fBytesPerPixel * fWidth * fHeight);
    }

    fDirtyRect.setEmpty();
    SkDEBUGCODE(fDirty = false;)
}

} // namespace skgpu
