/*
 * 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/core/SkOpts.h"
#include "src/core/SkPipelineData.h"
#include "src/core/SkShaderCodeDictionary.h"

#ifdef SK_GRAPHITE_ENABLED
SkPipelineDataGatherer::SkPipelineDataGatherer(skgpu::graphite::Layout layout)
        : fUniformManager(layout)
        , fSnippetRequirementFlags(SnippetRequirementFlags::kNone) {
}
#endif

void SkPipelineDataGatherer::reset() {
#ifdef SK_GRAPHITE_ENABLED
    fTextureDataBlock.reset();
    fUniformManager.reset();
#endif
    fSnippetRequirementFlags = SnippetRequirementFlags::kNone;
}

#ifdef SK_DEBUG
void SkPipelineDataGatherer::checkReset() {
#ifdef SK_GRAPHITE_ENABLED
    SkASSERT(fTextureDataBlock.empty());
    SkDEBUGCODE(fUniformManager.checkReset());
#endif
    SkASSERT(fSnippetRequirementFlags == SnippetRequirementFlags::kNone);
}
#endif // SK_DEBUG

void SkPipelineDataGatherer::addFlags(SnippetRequirementFlags flags) {
    fSnippetRequirementFlags |= flags;
}

bool SkPipelineDataGatherer::needsLocalCoords() const {
    return fSnippetRequirementFlags & SnippetRequirementFlags::kLocalCoords;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
SkUniformDataBlock* SkUniformDataBlock::Make(const SkUniformDataBlock& other,
                                             SkArenaAlloc* arena) {
    static constexpr size_t kUniformAlignment = alignof(void*);
    char* mem = static_cast<char*>(arena->makeBytesAlignedTo(other.size(), kUniformAlignment));
    memcpy(mem, other.data(), other.size());

    return arena->make([&](void* ptr) {
        return new (ptr) SkUniformDataBlock(SkSpan<const char>(mem, other.size()));
    });
}

uint32_t SkUniformDataBlock::hash() const {
    return SkOpts::hash_fn(fData.data(), fData.size(), 0);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef SK_GRAPHITE_ENABLED
static constexpr int kSkFilterModeCount = static_cast<int>(SkFilterMode::kLast) + 1;

std::unique_ptr<SkTextureDataBlock> SkTextureDataBlock::Make(const SkTextureDataBlock& other,
                                                             SkArenaAlloc* /* arena */) {
    return std::make_unique<SkTextureDataBlock>(other);
}

bool SkTextureDataBlock::TextureInfo::operator==(const TextureInfo& other) const {
    return fProxy == other.fProxy &&
           fSamplingOptions == other.fSamplingOptions &&
           fTileModes[0] == other.fTileModes[0] &&
           fTileModes[1] == other.fTileModes[1];
}

uint32_t SkTextureDataBlock::TextureInfo::samplerKey() const {
    static_assert(kSkTileModeCount <= 4 && kSkFilterModeCount <= 2);
    return (static_cast<int>(fTileModes[0])           << 0) |
           (static_cast<int>(fTileModes[1])           << 2) |
           (static_cast<int>(fSamplingOptions.filter) << 4) |
           (static_cast<int>(fSamplingOptions.mipmap) << 5);
}

bool SkTextureDataBlock::operator==(const SkTextureDataBlock& other) const {
    if (fTextureData.size() != other.fTextureData.size()) {
        return false;
    }

    for (size_t i = 0; i < fTextureData.size(); ++i) {
        if (fTextureData[i] != other.fTextureData[i]) {
            return false;
        }
    }

    return true;
}

uint32_t SkTextureDataBlock::hash() const {
    uint32_t hash = 0;

    for (auto& d : fTextureData) {
        uint32_t samplerKey = d.samplerKey();
        hash = SkOpts::hash_fn(&samplerKey, sizeof(samplerKey), hash);

        // Because the lifetime of the TextureDataCache is for just one Recording and the
        // TextureDataBlocks hold refs on their proxies, we can just use the proxy's pointer
        // for the hash here. This is a bit sloppy though in that it would be nice if proxies backed
        // by the same scratch texture hashed the same (it is tough to see how we could do that
        // at DrawPass creation time though).
        hash = SkOpts::hash_fn(d.fProxy.get(), sizeof(skgpu::graphite::TextureProxy*), hash);
    }

    return hash;
}

#endif
