Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b290657

Browse files
committed
[Impeller] Fix nullopt access in GetSubpassCoverage.
1 parent d88d2d1 commit b290657

File tree

1 file changed

+31
-25
lines changed

1 file changed

+31
-25
lines changed

impeller/entity/entity_pass.cc

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// FLUTTER_NOLINT: https://github.com/flutter/flutter/issues/132129
6-
75
#include "impeller/entity/entity_pass.h"
86

97
#include <memory>
@@ -97,19 +95,20 @@ size_t EntityPass::GetSubpassesDepth() const {
9795

9896
std::optional<Rect> EntityPass::GetElementsCoverage(
9997
std::optional<Rect> coverage_limit) const {
100-
std::optional<Rect> result;
98+
std::optional<Rect> accumulated_coverage;
10199
for (const auto& element : elements_) {
102-
std::optional<Rect> coverage;
100+
std::optional<Rect> element_coverage;
103101

104102
if (auto entity = std::get_if<Entity>(&element)) {
105-
coverage = entity->GetCoverage();
103+
element_coverage = entity->GetCoverage();
106104

107105
// When the coverage limit is std::nullopt, that means there is no limit,
108106
// as opposed to empty coverage.
109-
if (coverage.has_value() && coverage_limit.has_value()) {
107+
if (element_coverage.has_value() && coverage_limit.has_value()) {
110108
const auto* filter = entity->GetContents()->AsFilter();
111109
if (!filter || filter->IsTranslationOnly()) {
112-
coverage = coverage->Intersection(coverage_limit.value());
110+
element_coverage =
111+
element_coverage->Intersection(coverage_limit.value());
113112
}
114113
}
115114
} else if (auto subpass_ptr =
@@ -122,17 +121,18 @@ std::optional<Rect> EntityPass::GetElementsCoverage(
122121
// If the current pass elements have any coverage so far and there's a
123122
// backdrop filter, then incorporate the backdrop filter in the
124123
// pre-filtered coverage of the subpass.
125-
if (result.has_value() && subpass.backdrop_filter_proc_) {
124+
if (accumulated_coverage.has_value() && subpass.backdrop_filter_proc_) {
126125
std::shared_ptr<FilterContents> backdrop_filter =
127-
subpass.backdrop_filter_proc_(FilterInput::Make(result.value()),
128-
subpass.xformation_,
129-
Entity::RenderingMode::kSubpass);
126+
subpass.backdrop_filter_proc_(
127+
FilterInput::Make(accumulated_coverage.value()),
128+
subpass.xformation_, Entity::RenderingMode::kSubpass);
130129
if (backdrop_filter) {
131130
auto backdrop_coverage = backdrop_filter->GetCoverage({});
132-
backdrop_coverage->origin += result->origin;
133131
if (backdrop_coverage.has_value()) {
132+
backdrop_coverage->origin += accumulated_coverage->origin;
134133
if (unfiltered_coverage.has_value()) {
135-
unfiltered_coverage = coverage->Union(*backdrop_coverage);
134+
unfiltered_coverage =
135+
unfiltered_coverage->Union(*backdrop_coverage);
136136
} else {
137137
unfiltered_coverage = backdrop_coverage;
138138
}
@@ -161,29 +161,31 @@ std::optional<Rect> EntityPass::GetElementsCoverage(
161161
if (image_filter) {
162162
Entity subpass_entity;
163163
subpass_entity.SetTransformation(subpass.xformation_);
164-
coverage = image_filter->GetCoverage(subpass_entity);
164+
element_coverage = image_filter->GetCoverage(subpass_entity);
165165
} else {
166-
coverage = unfiltered_coverage;
166+
element_coverage = unfiltered_coverage;
167167
}
168168

169-
if (coverage.has_value() && coverage_limit.has_value() &&
169+
if (element_coverage.has_value() && coverage_limit.has_value() &&
170170
(!image_filter || image_filter->IsTranslationOnly())) {
171-
coverage = coverage->Intersection(coverage_limit.value());
171+
element_coverage =
172+
element_coverage->Intersection(coverage_limit.value());
172173
}
173174
} else {
174175
FML_UNREACHABLE();
175176
}
176177

177-
if (!result.has_value() && coverage.has_value()) {
178-
result = coverage;
178+
if (!accumulated_coverage.has_value() && element_coverage.has_value()) {
179+
accumulated_coverage = element_coverage;
179180
continue;
180181
}
181-
if (!coverage.has_value()) {
182+
if (!element_coverage.has_value()) {
182183
continue;
183184
}
184-
result = result->Union(coverage.value());
185+
accumulated_coverage =
186+
accumulated_coverage->Union(element_coverage.value());
185187
}
186-
return result;
188+
return accumulated_coverage;
187189
}
188190

189191
std::optional<Rect> EntityPass::GetSubpassCoverage(
@@ -760,13 +762,17 @@ bool EntityPass::RenderElement(Entity& element_entity,
760762
// rendered output will actually be used, and so we set this to the current
761763
// clip coverage (which is the max clip bounds). The contents may
762764
// optionally use this hint to avoid unnecessary rendering work.
763-
if (element_entity.GetContents()->GetCoverageHint().has_value()) {
765+
auto element_coverage_hint = element_entity.GetContents()->GetCoverageHint();
766+
if (element_coverage_hint.has_value() &&
767+
// If the `current_clip_coverage` is `std::nullopt`, just fall into the
768+
// else case and let std::nullopt get assigned as the coverage hint.
769+
current_clip_coverage.has_value()) {
764770
// If the element already has a coverage hint (because its an advanced
765771
// blend), then we need to intersect the clip coverage hint with the
766772
// existing coverage hint.
767773
element_entity.GetContents()->SetCoverageHint(
768-
current_clip_coverage->Intersection(
769-
element_entity.GetContents()->GetCoverageHint().value()));
774+
element_coverage_hint.value().Intersection(
775+
current_clip_coverage.value()));
770776
} else {
771777
element_entity.GetContents()->SetCoverageHint(current_clip_coverage);
772778
}

0 commit comments

Comments
 (0)