7 #include "flutter/fml/logging.h"
13 subpass_state_.push_back(SubpassState{
25 return subpass_state_.back().clip_coverage.back().coverage;
29 return !subpass_state_.back().clip_coverage.empty();
34 subpass_state_.push_back(SubpassState{
38 .clip_height = clip_height},
41 next_replay_index_ = 0;
45 subpass_state_.pop_back();
46 next_replay_index_ = subpass_state_.back().rendered_clip_entities.size();
49 const std::vector<ClipCoverageLayer>
51 return subpass_state_.back().clip_coverage;
55 Point global_pass_position,
56 size_t restore_height) {
58 auto& subpass_state = GetCurrentSubpassState();
60 if (subpass_state.clip_coverage.back().clip_height <= restore_height) {
65 auto restoration_index =
66 restore_height - subpass_state.clip_coverage.front().clip_height;
67 FML_DCHECK(restoration_index < subpass_state.clip_coverage.size());
71 std::optional<Rect> restore_coverage =
72 (restoration_index + 1 < subpass_state.clip_coverage.size())
73 ? subpass_state.clip_coverage[restoration_index + 1].coverage
75 if (restore_coverage.has_value()) {
77 restore_coverage = restore_coverage->Shift(-global_pass_position);
80 subpass_state.clip_coverage.resize(restoration_index + 1);
83 if (subpass_state.clip_coverage.back().coverage.has_value()) {
84 FML_DCHECK(next_replay_index_ <=
85 subpass_state.rendered_clip_entities.size());
89 if (!subpass_state.rendered_clip_entities.empty()) {
90 subpass_state.rendered_clip_entities.pop_back();
92 if (next_replay_index_ > subpass_state.rendered_clip_entities.size()) {
93 next_replay_index_ = subpass_state.rendered_clip_entities.size();
103 Point global_pass_position,
105 size_t clip_height_floor,
112 if (!maybe_clip_coverage.has_value()) {
115 auto current_clip_coverage = maybe_clip_coverage.value();
118 current_clip_coverage = current_clip_coverage.Shift(-global_pass_position);
122 if (clip_coverage.
coverage.has_value()) {
124 clip_coverage.
coverage->Shift(global_pass_position);
127 SubpassState& subpass_state = GetCurrentSubpassState();
130 size_t previous_clip_height = 0;
131 if (!subpass_state.clip_coverage.empty()) {
132 previous_clip_height = subpass_state.clip_coverage.back().clip_height;
136 previous_clip_height = clip_height_floor;
142 clip_coverage.
coverage.has_value() &&
143 clip_coverage.
coverage.value().Contains(current_clip_coverage)) {
146 .clip_height = previous_clip_height + 1
157 bool should_render =
true;
158 std::optional<Rect> coverage_value = clip_coverage.
coverage;
160 coverage_value.has_value()) {
161 const Rect& coverage = coverage_value.value();
162 constexpr
Scalar threshold = 0.124;
166 std::abs(std::round(coverage.
GetTop()) - coverage.
GetTop()) <=
173 should_render =
false;
179 .clip_height = previous_clip_height + 1
185 FML_DCHECK(subpass_state.clip_coverage.back().clip_height ==
186 subpass_state.clip_coverage.front().clip_height +
187 subpass_state.clip_coverage.size() - 1);
189 FML_DCHECK(next_replay_index_ == subpass_state.rendered_clip_entities.size())
190 <<
"Not all clips have been replayed before appending new clip.";
192 subpass_state.rendered_clip_entities.push_back(
ReplayResult{
195 .clip_coverage = coverage_value,
196 .clip_depth = clip_depth
198 next_replay_index_++;
203 EntityPassClipStack::SubpassState&
204 EntityPassClipStack::GetCurrentSubpassState() {
205 return subpass_state_.back();
208 const std::vector<EntityPassClipStack::ReplayResult>&
210 return subpass_state_.back().rendered_clip_entities;
ClipCoverage GetClipCoverage(const std::optional< Rect > ¤t_clip_coverage) const
Given the current pass space bounding rectangle of the clip buffer, return the expected clip coverage...
std::optional< Rect > CurrentClipCoverage() const
void PushSubpass(std::optional< Rect > subpass_coverage, size_t clip_height)
const std::vector< ReplayResult > & GetReplayEntities() const
ClipStateResult RecordClip(const ClipContents &clip_contents, Matrix transform, Point global_pass_position, uint32_t clip_depth, size_t clip_height_floor, bool is_aa)
ClipStateResult RecordRestore(Point global_pass_position, size_t restore_height)
EntityPassClipStack(const Rect &initial_coverage_rect)
Create a new [EntityPassClipStack] with an initialized coverage rect.
const std::vector< ClipCoverageLayer > GetClipCoverageLayers() const
bool is_difference_or_non_square
std::optional< Rect > coverage
This coverage is the outer coverage of the clip.
std::optional< Rect > coverage
ClipContents clip_contents
A 4x4 matrix using column-major storage.
constexpr auto GetBottom() const
constexpr auto GetTop() const
constexpr auto GetLeft() const
Round(const TRect< U > &r)
constexpr auto GetRight() const