blob: 7c57d42a0eb46e7c9dd3a7cd8ba8ed8f75ea15df [file]
/*
* Copyright 2025 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef skgpu_ganesh_GlyphData_DEFINED
#define skgpu_ganesh_GlyphData_DEFINED
#include "include/core/SkRefCnt.h"
#include "include/core/SkSpan.h"
#include "src/core/SkColorData.h"
#include "src/core/SkGlyph.h"
#include "src/gpu/ganesh/GrAtlasTypes.h"
#include "src/gpu/ganesh/text/TextStrike.h"
#include <cstdint>
#include <tuple>
class GrMeshDrawTarget;
class SkMatrix;
namespace sktext::gpu {
class GlyphVector;
class StrikeCache;
class VertexFiller;
}
namespace skgpu {
enum class MaskFormat : int;
}
namespace skgpu::ganesh {
class TextStrike;
struct GlyphEntryKey {
explicit GlyphEntryKey(SkPackedGlyphID id, MaskFormat format) : fPackedID(id), fFormat(format) {}
const SkPackedGlyphID fPackedID;
MaskFormat fFormat;
bool operator==(const GlyphEntryKey& that) const {
return fPackedID == that.fPackedID && fFormat == that.fFormat;
}
bool operator!=(const GlyphEntryKey& that) const {
return !(*this == that);
}
uint32_t hash() const {
return fPackedID.hash();
}
};
/**
* Ganesh-specific glyph type with atlas location information.
*/
struct GlyphEntry {
explicit GlyphEntry(SkPackedGlyphID id, MaskFormat format) : fGlyphEntryKey(id, format) {}
const GlyphEntryKey fGlyphEntryKey;
GrAtlasLocator fAtlasLocator;
};
/** Adapts GlyphEntry* to conform to GlyphVectors GlyphType requirements. */
class Glyph {
GlyphEntry* fEntry;
Glyph() = delete;
Glyph(const Glyph&) = delete;
Glyph(Glyph&&) = delete;
Glyph& operator=(const Glyph&) = delete;
Glyph& operator=(Glyph&&) = delete;
public:
explicit Glyph(GlyphEntry* entry) : fEntry{entry} { SkASSERT(entry); }
SkPackedGlyphID packedID() const { return fEntry->fGlyphEntryKey.fPackedID; }
GlyphEntry& entry() const { return *fEntry; }
};
/**
* Stored on SubRun. It maintains mapping from SubRun's packed glyph IDs to atlas locations,
* coordinating updates to this data as the data in the atlas evolves.
*/
class GlyphData final {
public:
static sk_sp<TextStrike> FindStrike(sktext::gpu::StrikeCache* cache, const SkStrikeSpec& spec) {
return TextStrike::GetOrCreate(cache, spec);
}
GlyphData(sk_sp<TextStrike>);
~GlyphData();
Glyph makeGlyphFromID(SkPackedGlyphID, MaskFormat);
// Regenerate atlas entries for glyphs in range [begin, end).
// Returns {success, glyphs_placed_in_atlas}.
std::tuple<bool, int> regenerateAtlas(int begin,
int end,
sktext::gpu::GlyphVector& glyphVector,
MaskFormat maskFormat,
int srcPadding,
GrMeshDrawTarget* target);
size_t vertexStride(MaskFormat, const SkMatrix& positionMatrix) const;
void fillVertexData(const sktext::gpu::VertexFiller& vf,
SkSpan<const Glyph> glyphs,
int offset,
int count,
const SkPMColor4f& pmColor,
const SkMatrix& positionMatrix,
SkIRect clip,
void* vertexBuffer);
private:
GlyphData(const GlyphData&) = delete;
GlyphData(GlyphData&&) = delete;
GlyphData& operator=(const GlyphData&) = delete;
GlyphData& operator=(GlyphData&&) = delete;
GlyphData(int glyphCount);
sk_sp<TextStrike> fTextStrike{nullptr};
uint64_t fAtlasGeneration{GrAtlasGenerationCounter::kInvalidGeneration};
GrBulkUsePlotUpdater fBulkUseUpdater;
};
} // namespace skgpu::ganesh
#endif // skgpu_ganesh_GlyphData_DEFINED