[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:
parent
6f6e5611c2
commit
7dbe2f50a8
@ -5,6 +5,7 @@
|
|||||||
#include "impeller/typographer/backends/skia/typographer_context_skia.h"
|
#include "impeller/typographer/backends/skia/typographer_context_skia.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -414,14 +415,17 @@ TypographerContextSkia::CollectNewGlyphs(
|
|||||||
std::vector<FontGlyphPair> new_glyphs;
|
std::vector<FontGlyphPair> new_glyphs;
|
||||||
std::vector<Rect> glyph_sizes;
|
std::vector<Rect> glyph_sizes;
|
||||||
size_t generation_id = atlas->GetAtlasGeneration();
|
size_t generation_id = atlas->GetAtlasGeneration();
|
||||||
|
intptr_t atlas_id = reinterpret_cast<intptr_t>(atlas.get());
|
||||||
for (const auto& frame : text_frames) {
|
for (const auto& frame : text_frames) {
|
||||||
|
auto [frame_generation_id, frame_atlas_id] =
|
||||||
|
frame->GetAtlasGenerationAndID();
|
||||||
if (atlas->IsValid() && frame->IsFrameComplete() &&
|
if (atlas->IsValid() && frame->IsFrameComplete() &&
|
||||||
frame->GetAtlasGeneration() == generation_id &&
|
frame_generation_id == generation_id && frame_atlas_id == atlas_id &&
|
||||||
!frame->GetFrameBounds(0).is_placeholder) {
|
!frame->GetFrameBounds(0).is_placeholder) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
frame->ClearFrameBounds();
|
frame->ClearFrameBounds();
|
||||||
frame->SetAtlasGeneration(generation_id);
|
frame->SetAtlasGeneration(generation_id, atlas_id);
|
||||||
|
|
||||||
for (const auto& run : frame->GetRuns()) {
|
for (const auto& run : frame->GetRuns()) {
|
||||||
auto metrics = run.GetFont().GetMetrics();
|
auto metrics = run.GetFont().GetMetrics();
|
||||||
|
@ -144,12 +144,13 @@ const FrameBounds& TextFrame::GetFrameBounds(size_t index) const {
|
|||||||
return bound_values_[index];
|
return bound_values_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t TextFrame::GetAtlasGeneration() const {
|
std::pair<size_t, intptr_t> TextFrame::GetAtlasGenerationAndID() const {
|
||||||
return generation_;
|
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;
|
generation_ = value;
|
||||||
|
atlas_id_ = atlas_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#ifndef FLUTTER_IMPELLER_TYPOGRAPHER_TEXT_FRAME_H_
|
#ifndef FLUTTER_IMPELLER_TYPOGRAPHER_TEXT_FRAME_H_
|
||||||
#define FLUTTER_IMPELLER_TYPOGRAPHER_TEXT_FRAME_H_
|
#define FLUTTER_IMPELLER_TYPOGRAPHER_TEXT_FRAME_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include "impeller/typographer/glyph_atlas.h"
|
#include "impeller/typographer/glyph_atlas.h"
|
||||||
#include "impeller/typographer/text_run.h"
|
#include "impeller/typographer/text_run.h"
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ class TextFrame {
|
|||||||
// with. As long as the frame generation matches the atlas generation,
|
// with. As long as the frame generation matches the atlas generation,
|
||||||
// the contents are guaranteed to be populated and do not need to be
|
// the contents are guaranteed to be populated and do not need to be
|
||||||
// processed.
|
// processed.
|
||||||
size_t GetAtlasGeneration() const;
|
std::pair<size_t, intptr_t> GetAtlasGenerationAndID() const;
|
||||||
|
|
||||||
TextFrame& operator=(TextFrame&& other) = default;
|
TextFrame& operator=(TextFrame&& other) = default;
|
||||||
|
|
||||||
@ -108,7 +109,7 @@ class TextFrame {
|
|||||||
|
|
||||||
void ClearFrameBounds();
|
void ClearFrameBounds();
|
||||||
|
|
||||||
void SetAtlasGeneration(size_t value);
|
void SetAtlasGeneration(size_t value, intptr_t atlas_id);
|
||||||
|
|
||||||
std::vector<TextRun> runs_;
|
std::vector<TextRun> runs_;
|
||||||
Rect bounds_;
|
Rect bounds_;
|
||||||
@ -119,6 +120,7 @@ class TextFrame {
|
|||||||
std::vector<FrameBounds> bound_values_;
|
std::vector<FrameBounds> bound_values_;
|
||||||
Scalar scale_ = 0;
|
Scalar scale_ = 0;
|
||||||
size_t generation_ = 0;
|
size_t generation_ = 0;
|
||||||
|
intptr_t atlas_id_ = 0;
|
||||||
Point offset_;
|
Point offset_;
|
||||||
std::optional<GlyphProperties> properties_;
|
std::optional<GlyphProperties> properties_;
|
||||||
};
|
};
|
||||||
|
@ -585,9 +585,9 @@ TEST_P(TypographerTest, TextFrameAtlasGenerationTracksState) {
|
|||||||
EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
|
EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
|
||||||
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
|
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
|
||||||
// OpenGLES must always increase the atlas backend if the texture grows.
|
// OpenGLES must always increase the atlas backend if the texture grows.
|
||||||
EXPECT_EQ(frame->GetAtlasGeneration(), 1u);
|
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
|
||||||
} else {
|
} else {
|
||||||
EXPECT_EQ(frame->GetAtlasGeneration(), 0u);
|
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
|
atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
|
||||||
@ -598,9 +598,9 @@ TEST_P(TypographerTest, TextFrameAtlasGenerationTracksState) {
|
|||||||
EXPECT_TRUE(frame->IsFrameComplete());
|
EXPECT_TRUE(frame->IsFrameComplete());
|
||||||
EXPECT_FALSE(frame->GetFrameBounds(0).is_placeholder);
|
EXPECT_FALSE(frame->GetFrameBounds(0).is_placeholder);
|
||||||
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
|
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
|
||||||
EXPECT_EQ(frame->GetAtlasGeneration(), 1u);
|
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
|
||||||
} else {
|
} else {
|
||||||
EXPECT_EQ(frame->GetAtlasGeneration(), 0u);
|
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force increase the generation.
|
// Force increase the generation.
|
||||||
@ -609,7 +609,7 @@ TEST_P(TypographerTest, TextFrameAtlasGenerationTracksState) {
|
|||||||
GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
|
GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
|
||||||
atlas_context, frame);
|
atlas_context, frame);
|
||||||
|
|
||||||
EXPECT_EQ(frame->GetAtlasGeneration(), 2u);
|
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 2u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(TypographerTest, InvalidAtlasForcesRepopulation) {
|
TEST_P(TypographerTest, InvalidAtlasForcesRepopulation) {
|
||||||
@ -637,9 +637,9 @@ TEST_P(TypographerTest, InvalidAtlasForcesRepopulation) {
|
|||||||
EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
|
EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
|
||||||
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
|
if (GetBackend() == PlaygroundBackend::kOpenGLES) {
|
||||||
// OpenGLES must always increase the atlas backend if the texture grows.
|
// OpenGLES must always increase the atlas backend if the texture grows.
|
||||||
EXPECT_EQ(frame->GetAtlasGeneration(), 1u);
|
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
|
||||||
} else {
|
} else {
|
||||||
EXPECT_EQ(frame->GetAtlasGeneration(), 0u);
|
EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto second_context = TypographerContextSkia::Make();
|
auto second_context = TypographerContextSkia::Make();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user