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

#ifndef sktext_gpu_GlyphVector_DEFINED
#define sktext_gpu_GlyphVector_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/core/SkSpan.h"
#include "src/core/SkGlyph.h"
#include "src/gpu/AtlasTypes.h"
#include "src/text/StrikeForGPU.h"
#include "src/text/gpu/StrikeCache.h"

#include <cstddef>
#include <cstdint>
#include <optional>
#include <tuple>

class SkReadBuffer;
class SkStrikeClient;
class SkWriteBuffer;

class GrMeshDrawTarget;
namespace skgpu::ganesh { class AtlasTextOp; }
namespace skgpu::graphite {
class Device;
class Recorder;
}

namespace sktext::gpu {
class Glyph;
class SubRunAllocator;

// -- GlyphVector ----------------------------------------------------------------------------------
// GlyphVector provides a way to delay the lookup of Glyphs until the code is running on the GPU
// in single threaded mode. The GlyphVector is created in a multi-threaded environment, but the
// StrikeCache is only single threaded (and must be single threaded because of the atlas).
class GlyphVector {
public:
    union Variant {
        // Initially, filled with packed id, but changed to Glyph* in the onPrepare stage.
        SkPackedGlyphID packedGlyphID;
        Glyph* glyph;
        // Add ctors to help SkArenaAlloc create arrays.
        Variant() : glyph{nullptr} {}
        Variant(SkPackedGlyphID id) : packedGlyphID{id} {}
    };

    GlyphVector(SkStrikePromise&& strikePromise, SkSpan<Variant> glyphs);

    static GlyphVector Make(SkStrikePromise&& promise,
                            SkSpan<const SkPackedGlyphID> glyphs,
                            SubRunAllocator* alloc);

    SkSpan<const Glyph*> glyphs() const;

    static std::optional<GlyphVector> MakeFromBuffer(SkReadBuffer& buffer,
                                                     const SkStrikeClient* strikeClient,
                                                     SubRunAllocator* alloc);
    void flatten(SkWriteBuffer& buffer) const;

    // This doesn't need to include sizeof(GlyphVector) because this is embedded in each of
    // the sub runs.
    int unflattenSize() const { return GlyphVectorSize(fGlyphs.size()); }

    void packedGlyphIDToGlyph(StrikeCache* cache);

    static size_t GlyphVectorSize(size_t count) {
        return sizeof(Variant) * count;
    }

private:
    friend class GlyphVectorTestingPeer;
    friend class ::skgpu::graphite::Device;
    friend class ::skgpu::ganesh::AtlasTextOp;

    // This function is implemented in ganesh/text/GrAtlasManager.cpp, and should only be called
    // from AtlasTextOp or linking issues may occur.
    std::tuple<bool, int> regenerateAtlasForGanesh(
            int begin, int end,
            skgpu::MaskFormat maskFormat,
            int srcPadding,
            GrMeshDrawTarget*);

    // This function is implemented in graphite/text/AtlasManager.cpp, and should only be called
    // from graphite::Device or linking issues may occur.
    std::tuple<bool, int> regenerateAtlasForGraphite(
            int begin, int end,
            skgpu::MaskFormat maskFormat,
            int srcPadding,
            skgpu::graphite::Recorder*);

    SkStrikePromise fStrikePromise;
    SkSpan<Variant> fGlyphs;
    sk_sp<TextStrike> fTextStrike{nullptr};
    uint64_t fAtlasGeneration{skgpu::AtlasGenerationCounter::kInvalidGeneration};
    skgpu::BulkUsePlotUpdater fBulkUseUpdater;
};
}  // namespace sktext::gpu
#endif  // sktext_gpu_GlyphVector_DEFINED
