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

#include "tools/gpu/ganesh/GrAtlasTools.h"

#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkDataTable.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/encode/SkPngEncoder.h"
#include "include/gpu/GrDirectContext.h"
#include "include/private/base/SkDebug.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/SurfaceContext.h"

#include <cstdio>
#include <utility>

/**
 * Write the contents of the surface proxy to a PNG. Returns true if successful.
 * @param filename      Full path to desired file
 */
static bool save_pixels(GrDirectContext* dContext,
                        GrSurfaceProxyView view,
                        GrColorType colorType,
                        const char* filename) {
    if (!view.proxy()) {
        return false;
    }

    auto ii = SkImageInfo::Make(
            view.proxy()->dimensions(), kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    SkBitmap bm;
    if (!bm.tryAllocPixels(ii)) {
        return false;
    }

    auto sContext =
            dContext->priv().makeSC(std::move(view), {colorType, kUnknown_SkAlphaType, nullptr});
    if (!sContext || !sContext->asTextureProxy()) {
        return false;
    }

    bool result = sContext->readPixels(dContext, bm.pixmap(), {0, 0});
    if (!result) {
        SkDebugf("------ failed to read pixels for %s\n", filename);
        return false;
    }

    // remove any previous version of this file
    remove(filename);

    SkFILEWStream file(filename);
    if (!file.isValid()) {
        SkDebugf("------ failed to create file: %s\n", filename);
        remove(filename);  // remove any partial file
        return false;
    }

    if (!SkPngEncoder::Encode(&file, bm.pixmap(), {})) {
        SkDebugf("------ failed to encode %s\n", filename);
        remove(filename);  // remove any partial file
        return false;
    }

    return true;
}

void GrAtlasManagerTools::Dump(const GrAtlasManager* am, GrDirectContext* context) {
    SkASSERT(am);
    static int gDumpCount = 0;
    for (int i = 0; i < skgpu::kMaskFormatCount; ++i) {
        if (am->fAtlases[i]) {
            const GrSurfaceProxyView* views = am->fAtlases[i]->getViews();
            for (uint32_t pageIdx = 0; pageIdx < am->fAtlases[i]->numActivePages(); ++pageIdx) {
                SkASSERT(views[pageIdx].proxy());
                SkString filename;
#ifdef SK_BUILD_FOR_ANDROID
                filename.printf("/sdcard/fontcache_%d%d%d.png", gDumpCount, i, pageIdx);
#else
                filename.printf("fontcache_%d%d%u.png", gDumpCount, i, pageIdx);
#endif
                SkColorType ct = MaskFormatToColorType(GrAtlasManager::AtlasIndexToMaskFormat(i));
                save_pixels(
                        context, views[pageIdx], SkColorTypeToGrColorType(ct), filename.c_str());
            }
        }
    }
    ++gDumpCount;
}

void GrAtlasManagerTools::SetAtlasDimensionsToMinimum(GrAtlasManager* am) {
    SkASSERT(am);
    // Delete any old atlases.
    // This should be safe to do as long as we are not in the middle of a flush.
    for (int i = 0; i < skgpu::kMaskFormatCount; i++) {
        am->fAtlases[i] = nullptr;
    }

    // Set all the atlas sizes to 1x1 plot each.
    new (&am->fAtlasConfig) GrDrawOpAtlasConfig{};
}

void GrAtlasManagerTools::SetMaxPages(GrAtlasManager* am, uint32_t maxPages) {
    SkASSERT(am);
    for (int i = 0; i < skgpu::kMaskFormatCount; i++) {
        if (am->fAtlases[i]) {
            GrDrawOpAtlasTools::SetMaxPages(am->fAtlases[i].get(), maxPages);
        }
    }
}

int GrDrawOpAtlasTools::NumAllocated(const GrDrawOpAtlas* doa) {
    SkASSERT(doa);
    int count = 0;
    for (uint32_t i = 0; i < doa->maxPages(); ++i) {
        if (doa->fViews[i].proxy()->isInstantiated()) {
            ++count;
        }
    }

    return count;
}

void GrDrawOpAtlasTools::SetMaxPages(GrDrawOpAtlas* doa, uint32_t maxPages) {
    SkASSERT(!doa->fNumActivePages);

    doa->fMaxPages = maxPages;
}
