Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions impeller/typographer/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ impeller_component("typographer") {
"../renderer",
]

if (!is_fuchsia) {
public_deps +=
[ "//flutter/third_party/abseil-cpp/absl/container:flat_hash_map" ]
}

deps = [ "//flutter/fml" ]
}

Expand Down
32 changes: 15 additions & 17 deletions impeller/typographer/font_glyph_pair.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@ struct ScaledFont {
Font font;
Scalar scale;

struct Hash {
constexpr std::size_t operator()(const impeller::ScaledFont& sf) const {
return fml::HashCombine(sf.font.GetHash(), sf.scale);
}
};
template <typename H>
friend H AbslHashValue(H h, const ScaledFont& sf) {
return H::combine(std::move(h), sf.font.GetHash(), sf.scale);
}

struct Equal {
constexpr bool operator()(const impeller::ScaledFont& lhs,
Expand All @@ -70,19 +69,18 @@ struct SubpixelGlyph {
subpixel_offset(p_subpixel_offset),
properties(p_properties) {}

struct Hash {
constexpr std::size_t operator()(const impeller::SubpixelGlyph& sg) const {
if (!sg.properties.has_value()) {
return fml::HashCombine(sg.glyph.index, sg.subpixel_offset.x,
sg.subpixel_offset.y);
}
return fml::HashCombine(
sg.glyph.index, sg.subpixel_offset.x, sg.subpixel_offset.y,
sg.properties->color.ToARGB(), sg.properties->stroke,
sg.properties->stroke_cap, sg.properties->stroke_join,
sg.properties->stroke_miter, sg.properties->stroke_width);
template <typename H>
friend H AbslHashValue(H h, const SubpixelGlyph& sg) {
if (!sg.properties.has_value()) {
return H::combine(std::move(h), sg.glyph.index, sg.subpixel_offset.x,
sg.subpixel_offset.y);
}
};
return H::combine(std::move(h), sg.glyph.index, sg.subpixel_offset.x,
sg.subpixel_offset.y, sg.properties->color.ToARGB(),
sg.properties->stroke, sg.properties->stroke_cap,
sg.properties->stroke_join, sg.properties->stroke_miter,
sg.properties->stroke_width);
}

struct Equal {
constexpr bool operator()(const impeller::SubpixelGlyph& lhs,
Expand Down
13 changes: 6 additions & 7 deletions impeller/typographer/glyph_atlas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ void GlyphAtlas::SetAtlasGeneration(size_t generation) {
void GlyphAtlas::AddTypefaceGlyphPositionAndBounds(const FontGlyphPair& pair,
Rect position,
Rect bounds) {
font_atlas_map_[pair.scaled_font].positions_[pair.glyph] =
FontAtlasMap::iterator it = font_atlas_map_.find(pair.scaled_font);
FML_DCHECK(it != font_atlas_map_.end());
it->second.positions_[pair.glyph] =
FrameBounds{position, bounds, /*is_placeholder=*/false};
}

Expand All @@ -93,12 +95,9 @@ std::optional<FrameBounds> GlyphAtlas::FindFontGlyphBounds(

FontGlyphAtlas* GlyphAtlas::GetOrCreateFontGlyphAtlas(
const ScaledFont& scaled_font) {
const auto& found = font_atlas_map_.find(scaled_font);
if (found != font_atlas_map_.end()) {
return &found->second;
}
font_atlas_map_[scaled_font] = FontGlyphAtlas();
return &font_atlas_map_[scaled_font];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this flow had 3 lookups, the new one has 1

auto [iter, inserted] =
font_atlas_map_.try_emplace(scaled_font, FontGlyphAtlas());
return &iter->second;
}

size_t GlyphAtlas::GetGlyphCount() const {
Expand Down
73 changes: 61 additions & 12 deletions impeller/typographer/glyph_atlas.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@
#include <functional>
#include <memory>
#include <optional>
#include <unordered_map>

#include "flutter/fml/build_config.h"

#if defined(OS_FUCHSIA)
// TODO(gaaclarke): Migrate to use absl. I couldn't get it working since absl
// has special logic in its GN files for Fuchsia that I couldn't sort out.
#define IMPELLER_TYPOGRAPHER_USE_STD_HASH
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🫡

#else
#include "flutter/third_party/abseil-cpp/absl/container/flat_hash_map.h"
#endif

#include "impeller/core/texture.h"
#include "impeller/geometry/rect.h"
Expand All @@ -19,6 +28,30 @@ namespace impeller {

class FontGlyphAtlas;

/// Helper for AbslHashAdapter. Tallies a hash value with fml::HashCombine.
template <typename T>
struct AbslHashAdapterCombiner {
std::size_t value = 0;

template <typename... Args>
static AbslHashAdapterCombiner combine(AbslHashAdapterCombiner combiner,
const Args&... args) {
combiner.value = fml::HashCombine(combiner.value, args...);
return combiner;
}
};

/// Adapts AbslHashValue functions to be used with std::unordered_map and the
/// fml hash functions.
template <typename T>
struct AbslHashAdapter {
constexpr std::size_t operator()(const T& element) const {
AbslHashAdapterCombiner<T> combiner;
combiner = AbslHashValue(std::move(combiner), element);
return combiner.value;
}
};

struct FrameBounds {
/// The bounds of the glyph within the glyph atlas.
Rect atlas_bounds;
Expand Down Expand Up @@ -160,11 +193,19 @@ class GlyphAtlas {
std::shared_ptr<Texture> texture_;
size_t generation_ = 0;

std::unordered_map<ScaledFont,
FontGlyphAtlas,
ScaledFont::Hash,
ScaledFont::Equal>
font_atlas_map_;
#if defined(IMPELLER_TYPOGRAPHER_USE_STD_HASH)
using FontAtlasMap = std::unordered_map<ScaledFont,
FontGlyphAtlas,
AbslHashAdapter<ScaledFont>,
ScaledFont::Equal>;
#else
using FontAtlasMap = absl::flat_hash_map<ScaledFont,
FontGlyphAtlas,
absl::Hash<ScaledFont>,
ScaledFont::Equal>;
#endif

FontAtlasMap font_atlas_map_;

GlyphAtlas(const GlyphAtlas&) = delete;

Expand Down Expand Up @@ -228,6 +269,7 @@ class GlyphAtlasContext {
class FontGlyphAtlas {
public:
FontGlyphAtlas() = default;
FontGlyphAtlas(FontGlyphAtlas&&) = default;

//----------------------------------------------------------------------------
/// @brief Find the location of a glyph in the atlas.
Expand All @@ -249,12 +291,19 @@ class FontGlyphAtlas {
private:
friend class GlyphAtlas;

std::unordered_map<SubpixelGlyph,
FrameBounds,
SubpixelGlyph::Hash,
SubpixelGlyph::Equal>
positions_;

#if defined(IMPELLER_TYPOGRAPHER_USE_STD_HASH)
using PositionsMap = std::unordered_map<SubpixelGlyph,
FrameBounds,
AbslHashAdapter<SubpixelGlyph>,
SubpixelGlyph::Equal>;
#else
using PositionsMap = absl::flat_hash_map<SubpixelGlyph,
FrameBounds,
absl::Hash<SubpixelGlyph>,
SubpixelGlyph::Equal>;
#endif

PositionsMap positions_;
FontGlyphAtlas(const FontGlyphAtlas&) = delete;
};

Expand Down
Loading