[Impeller] invalidate cached atlas data, take 2. (flutter/engine#56925)

Fixes https://github.com/flutter/flutter/issues/159704, but for real this time.
This commit is contained in:
Jonah Williams 2024-12-03 11:09:53 -08:00 committed by GitHub
parent 6f6e5611c2
commit 7dbe2f50a8
4 changed files with 21 additions and 14 deletions

View File

@ -5,6 +5,7 @@
#include "impeller/typographer/backends/skia/typographer_context_skia.h"
#include <cstddef>
#include <cstdint>
#include <memory>
#include <numeric>
#include <utility>
@ -414,14 +415,17 @@ TypographerContextSkia::CollectNewGlyphs(
std::vector<FontGlyphPair> new_glyphs;
std::vector<Rect> glyph_sizes;
size_t generation_id = atlas->GetAtlasGeneration();
intptr_t atlas_id = reinterpret_cast<intptr_t>(atlas.get());
for (const auto& frame : text_frames) {
auto [frame_generation_id, frame_atlas_id] =
frame->GetAtlasGenerationAndID();
if (atlas->IsValid() && frame->IsFrameComplete() &&
frame->GetAtlasGeneration() == generation_id &&
frame_generation_id == generation_id && frame_atlas_id == atlas_id &&
!frame->GetFrameBounds(0).is_placeholder) {
continue;
}
frame->ClearFrameBounds();
frame->SetAtlasGeneration(generation_id);
frame->SetAtlasGeneration(generation_id, atlas_id);
for (const auto& run : frame->GetRuns()) {
auto metrics = run.GetFont().GetMetrics();

View File

@ -144,12 +144,13 @@ const FrameBounds& TextFrame::GetFrameBounds(size_t index) const {
return bound_values_[index];
}
size_t TextFrame::GetAtlasGeneration() const {
return generation_;
std::pair<size_t, intptr_t> TextFrame::GetAtlasGenerationAndID() const {
return std::make_pair(generation_, atlas_id_);
}
void TextFrame::SetAtlasGeneration(size_t value) {
void TextFrame::SetAtlasGeneration(size_t value, intptr_t atlas_id) {
generation_ = value;
atlas_id_ = atlas_id;
}
} // namespace impeller

View File

@ -5,6 +5,7 @@
#ifndef FLUTTER_IMPELLER_TYPOGRAPHER_TEXT_FRAME_H_
#define FLUTTER_IMPELLER_TYPOGRAPHER_TEXT_FRAME_H_
#include <cstdint>
#include "impeller/typographer/glyph_atlas.h"
#include "impeller/typographer/text_run.h"
@ -88,7 +89,7 @@ class TextFrame {
// with. As long as the frame generation matches the atlas generation,
// the contents are guaranteed to be populated and do not need to be
// processed.
size_t GetAtlasGeneration() const;
std::pair<size_t, intptr_t> GetAtlasGenerationAndID() const;
TextFrame& operator=(TextFrame&& other) = default;
@ -108,7 +109,7 @@ class TextFrame {
void ClearFrameBounds();
void SetAtlasGeneration(size_t value);
void SetAtlasGeneration(size_t value, intptr_t atlas_id);
std::vector<TextRun> runs_;
Rect bounds_;
@ -119,6 +120,7 @@ class TextFrame {
std::vector<FrameBounds> bound_values_;
Scalar scale_ = 0;
size_t generation_ = 0;
intptr_t atlas_id_ = 0;
Point offset_;
std::optional<GlyphProperties> properties_;
};

View File

@ -585,9 +585,9 @@ TEST_P(TypographerTest, TextFrameAtlasGenerationTracksState) {
EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
// OpenGLES must always increase the atlas backend if the texture grows.
EXPECT_EQ(frame->GetAtlasGeneration(), 1u);
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
} else {
EXPECT_EQ(frame->GetAtlasGeneration(), 0u);
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
}
atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
@ -598,9 +598,9 @@ TEST_P(TypographerTest, TextFrameAtlasGenerationTracksState) {
EXPECT_TRUE(frame->IsFrameComplete());
EXPECT_FALSE(frame->GetFrameBounds(0).is_placeholder);
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
EXPECT_EQ(frame->GetAtlasGeneration(), 1u);
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
} else {
EXPECT_EQ(frame->GetAtlasGeneration(), 0u);
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
}
// Force increase the generation.
@ -609,7 +609,7 @@ TEST_P(TypographerTest, TextFrameAtlasGenerationTracksState) {
GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
atlas_context, frame);
EXPECT_EQ(frame->GetAtlasGeneration(), 2u);
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 2u);
}
TEST_P(TypographerTest, InvalidAtlasForcesRepopulation) {
@ -637,9 +637,9 @@ TEST_P(TypographerTest, InvalidAtlasForcesRepopulation) {
EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
// OpenGLES must always increase the atlas backend if the texture grows.
EXPECT_EQ(frame->GetAtlasGeneration(), 1u);
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
} else {
EXPECT_EQ(frame->GetAtlasGeneration(), 0u);
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
}
auto second_context = TypographerContextSkia::Make();