| Flutter Impeller |

text_shadow_cache.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "impeller/entity/contents/text_shadow_cache.h"
6
7 #include "fml/closure.h"
8 #include "impeller/entity/contents/content_context.h"
9 #include "impeller/entity/contents/contents.h"
10 #include "impeller/entity/contents/filters/filter_contents.h"
11 #include "impeller/geometry/sigma.h"
12
13 namespace impeller {
14
15 // Rounds sigma values for gaussian blur to nearest decimal.
16 static constexpr int32_t kMaxSigmaDenominator = 10;
17
18 TextShadowCache::TextShadowCacheKey::TextShadowCacheKey(Scalar p_max_basis,
19 int64_t p_identifier,
20 bool p_is_single_glyph,
21 const Font& p_font,
22 Sigma p_sigma)
23 : max_basis(p_max_basis),
24 identifier(p_identifier),
25 is_single_glyph(p_is_single_glyph),
26 font(p_font),
27 rounded_sigma(Rational(std::round(p_sigma.sigma * kMaxSigmaDenominator),
28 kMaxSigmaDenominator)) {}
29
30 void TextShadowCache::MarkFrameStart() {
31 for (auto& entry : entries_) {
32 entry.second.used_this_frame = false;
33 }
34 }
35
36 void TextShadowCache::MarkFrameEnd() {
37 absl::erase_if(entries_,
38 [](const auto& pair) { return !pair.second.used_this_frame; });
39 }
40
41 std::optional<Entity> TextShadowCache::Lookup(
42 const ContentContext& renderer,
43 const Entity& entity,
44 const std::shared_ptr<FilterContents>& contents,
45 const TextShadowCacheKey& text_key) {
46 auto it = entries_.find(text_key);
47
48 if (it != entries_.end()) {
49 it->second.used_this_frame = true;
50 Entity cache_entity = it->second.entity.Clone();
51 cache_entity.SetClipDepth(entity.GetClipDepth());
52 cache_entity.SetTransform(entity.GetTransform() * it->second.key_matrix);
53 return cache_entity;
54 }
55
56 std::optional<Rect> filter_coverage = contents->GetCoverage(entity);
57 if (!filter_coverage.has_value()) {
58 return std::nullopt;
59 }
60
61 // Execute the filter to produce a snapshot that can be resued on subsequent
62 // frames. To prevent this texture from being re-used by the render target
63 // cache, we temporarily disable any RT caching.
64 renderer.GetRenderTargetCache()->DisableCache();
65 fml::ScopedCleanupClosure closure(
66 [&] { renderer.GetRenderTargetCache()->EnableCache(); });
67 std::optional<Entity> maybe_entity =
68 contents->GetEntity(renderer, entity, contents->GetCoverageHint());
69 if (!maybe_entity.has_value()) {
70 return std::nullopt;
71 }
72
73 // The original entity has a transform matrix A. The snapshot entity has a
74 // transform matrix B. We need a function that converts A to B, so that if we
75 // render an entity with a slightly different transform matrix A', it appears
76 // in the correct position.
77 // A * K = B
78 // A-1 * A * K = A-1 * B
79 // K = A-1 * B
80 //
81 // The transform matrix K can be computed by inverse A times B. Multiplying
82 // any subsequent entity transforms by this matrix will correctly position
83 // them.
84 Matrix key_matrix =
85 entity.GetTransform().Invert() * maybe_entity->GetTransform();
86 entries_[text_key] =
87 TextShadowCacheData{.entity = maybe_entity.value().Clone(),
88 .used_this_frame = true,
89 .key_matrix = key_matrix};
90
91 maybe_entity->SetClipDepth(entity.GetClipDepth());
92 return maybe_entity;
93 }
94
95 } // namespace impeller
impeller::ContentContext
Definition: content_context.h:138
impeller::ContentContext::GetRenderTargetCache
const std::shared_ptr< RenderTargetAllocator > & GetRenderTargetCache() const
Definition: content_context.h:269
impeller::Entity
Definition: entity.h:26
impeller::Entity::SetTransform
void SetTransform(const Matrix &transform)
Set the global transform matrix for this Entity.
Definition: entity.cc:60
impeller::Entity::GetCoverage
std::optional< Rect > GetCoverage() const
Definition: entity.cc:64
impeller::Entity::SetClipDepth
void SetClipDepth(uint32_t clip_depth)
Definition: entity.cc:80
impeller::Entity::Clone
Entity Clone() const
Definition: entity.cc:158
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:44
impeller::Entity::GetClipDepth
uint32_t GetClipDepth() const
Definition: entity.cc:84
impeller::Font
Describes a typeface along with any modifications to its intrinsic properties.
Definition: font.h:35
impeller::Rational
Definition: rational.h:13
impeller::TextShadowCache::MarkFrameStart
void MarkFrameStart()
Mark all glyph textures as unused this frame.
Definition: text_shadow_cache.cc:30
impeller::TextShadowCache::Lookup
std::optional< Entity > Lookup(const ContentContext &renderer, const Entity &entity, const std::shared_ptr< FilterContents > &contents, const TextShadowCacheKey &)
Lookup the entity in the cache with the given filter/text contents, returning the new entity to rende...
Definition: text_shadow_cache.cc:41
impeller::TextShadowCache::MarkFrameEnd
void MarkFrameEnd()
Remove all glyph textures that were not referenced at least once.
Definition: text_shadow_cache.cc:36
content_context.h
contents.h
filter_contents.h
impeller
Definition: allocation.cc:12
impeller::Scalar
float Scalar
Definition: scalar.h:19
impeller::kMaxSigmaDenominator
static constexpr int32_t kMaxSigmaDenominator
Definition: text_shadow_cache.cc:16
std
Definition: comparable.h:95
sigma.h
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Matrix::Invert
Matrix Invert() const
Definition: matrix.cc:99
impeller::Sigma
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32
impeller::TextShadowCache::TextShadowCacheKey
A key to look up cached glyph textures.
Definition: text_shadow_cache.h:38
impeller::TextShadowCache::TextShadowCacheKey::TextShadowCacheKey
TextShadowCacheKey(Scalar p_max_basis, int64_t p_identifier, bool p_is_single_glyph, const Font &p_font, Sigma p_sigma)
Definition: text_shadow_cache.cc:18
text_shadow_cache.h