/*
 * Copyright 2026 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/GlobalResourceStats.h"

#include "include/gpu/GpuTypes.h"
#include "src/core/SkTraceEvent.h"

#if !defined(SK_DISABLE_TRACING)

namespace skgpu {

GlobalResourceStats& GlobalResourceStats::Singleton(Protected isProtected) {
    static GlobalResourceStats kUnprotected{Protected::kNo};
    static GlobalResourceStats kProtected{Protected::kYes};
    return isProtected == Protected::kYes ? kProtected : kUnprotected;
}

void GlobalResourceStats::recordNewResource(size_t size, Budgeted budgeted) {
    fHasBeenUsed = true;
    if (budgeted == Budgeted::kYes) {
        fBudgetedBytes += size;
    } else {
        fUnbudgetedBytes += size;
    }
}

void GlobalResourceStats::recordPurgeResource(size_t size) {
    fHasBeenUsed = true;
    // This assumes all unbudgeted resources transition to budgeted resources before they are purged
    fBudgetedBytes -= size;
}

void GlobalResourceStats::recordResourceBudgetChange(size_t size, Budgeted newBudget) {
    fHasBeenUsed = true;
    // We're not worrying about synchronizing the update between unbudgeted and budgeted, tracing
    // will eventually show the right state.
    if (newBudget == Budgeted::kYes) {
        // We're assuming that this budget change will not happen on a wrapped resource, so no need
        // to adjust fWrappedBytes.
        fUnbudgetedBytes -= size;
        fBudgetedBytes += size;
    } else {
        fBudgetedBytes -= size;
        fUnbudgetedBytes += size;
    }
}

void GlobalResourceStats::recordResourceUpdatedSize(size_t newSize,
                                                    size_t oldSize,
                                                    Budgeted budgeted) {
    fHasBeenUsed = true;
    // We could structure this as subtracting oldSize and then adding newSize, but we can keep it
    // atomic by choosing += or -=.
    if (budgeted == Budgeted::kYes) {
        if (oldSize > newSize) {
            fBudgetedBytes -= (oldSize - newSize);
        } else {
            fBudgetedBytes += (newSize - oldSize);
        }
    } else {
        // We're assuming that this size change does not happen on a wrapped resource, so no need
        // to adjust fWrappedBytes (this is possible because Ganesh does not query for changed
        // resource sizes and Graphite does not cache wrapped resources so fWrappedBytes is 0).
        if (oldSize > newSize) {
            fUnbudgetedBytes -= (oldSize - newSize);
        } else {
            fUnbudgetedBytes += (newSize - oldSize);
        }
    }
}

void GlobalResourceStats::recordResourcePurgeable(size_t size) {
    fHasBeenUsed = true;
    fPurgeableBytes += size;
}

void GlobalResourceStats::recordResourceNonpurgeable(size_t size) {
    fHasBeenUsed = true;
    fPurgeableBytes -= size;
}

void GlobalResourceStats::recordCreateBackendTexture(size_t size) {
    fHasBeenUsed = true;
    fBackendTexBytes += size;
    // Trigger a trace for backend texture records since they happen outside the regular
    // flush/submit flow.
    this->traceStatsSummary();
}

void GlobalResourceStats::recordDeleteBackendTexture(size_t size) {
    fHasBeenUsed = true;
    fBackendTexBytes -= size;
    this->traceStatsSummary();
}

void GlobalResourceStats::traceStatsSummary() const {
    if (!fHasBeenUsed) {
        return;
    }

    // Grab a snapshot (these won't change, but they aren't loaded atomically)
          size_t budgeted   = fBudgetedBytes;
    const size_t unbudgeted = fUnbudgetedBytes;
    const size_t purgeable  = fPurgeableBytes;
    const size_t backendTex = fBackendTexBytes;

    // Separate budgeted and purgeable into a non-overlapping categories
    if (budgeted > purgeable) {
        budgeted -= purgeable;
    } else {
        budgeted = 0;
    }

    // While the total could be derived within the trace data, it is helpful to trace the total
    // as a visual anchor.
    const size_t total = backendTex + unbudgeted + budgeted + purgeable;

    // This pushes the protected label to the front since Perfetto sorts tracks alphabetically.
    #define TRACE_STATS(label) \
        TRACE_COUNTER1_ALWAYS("skia.gpu.cache", label " Total GPU Bytes",           total);      \
        TRACE_COUNTER1_ALWAYS("skia.gpu.cache", label " Purgeable GPU Bytes",       purgeable);  \
        TRACE_COUNTER1_ALWAYS("skia.gpu.cache", label " Budgeted GPU Bytes",        budgeted);   \
        TRACE_COUNTER1_ALWAYS("skia.gpu.cache", label " Unbudgeted GPU Bytes",      unbudgeted); \
        TRACE_COUNTER1_ALWAYS("skia.gpu.cache", label " Backend Texture GPU Bytes", backendTex);

    // Issue traces with different counter names depending on protected or unprotected so they
    // appear in separate tracks.
    if (fProtected == Protected::kYes) {
        TRACE_STATS("Skia Protected")
    } else {
        TRACE_STATS("Skia Unprotected")
    }

    #undef TRACE_STATS
}

} // namespace skgpu

#endif // !defined(SK_DISABLE_TRACING)
