Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | List of all members
impeller::EntityPassClipStack Class Reference

A class that tracks all clips that have been recorded in the current entity pass stencil. More...

#include <entity_pass_clip_stack.h>

Classes

struct  ClipStateResult
 
struct  ReplayResult
 

Public Member Functions

 EntityPassClipStack (const Rect &initial_coverage_rect)
 Create a new [EntityPassClipStack] with an initialized coverage rect.
 
 ~EntityPassClipStack ()=default
 
std::optional< RectCurrentClipCoverage () const
 
void PushSubpass (std::optional< Rect > subpass_coverage, size_t clip_height)
 
void PopSubpass ()
 
bool HasCoverage () const
 
ClipStateResult ApplyClipState (Contents::ClipCoverage global_clip_coverage, Entity &entity, size_t clip_height_floor, Point global_pass_position)
 Applies the current clip state to an Entity. If the given Entity is a clip operation, then the clip state is updated accordingly.
 
void RecordEntity (const Entity &entity, Contents::ClipCoverage::Type type, std::optional< Rect > clip_coverage)
 
const std::vector< ReplayResult > & GetReplayEntities () const
 
const std::vector< ClipCoverageLayerGetClipCoverageLayers () const
 

Detailed Description

A class that tracks all clips that have been recorded in the current entity pass stencil.

These clips are replayed when restoring the backdrop so that the stencil buffer is left in an identical state.

Definition at line 24 of file entity_pass_clip_stack.h.

Constructor & Destructor Documentation

◆ EntityPassClipStack()

impeller::EntityPassClipStack::EntityPassClipStack ( const Rect initial_coverage_rect)
explicit

Create a new [EntityPassClipStack] with an initialized coverage rect.

Definition at line 12 of file entity_pass_clip_stack.cc.

12 {
13 subpass_state_.push_back(SubpassState{
14 .clip_coverage =
15 {
16 {ClipCoverageLayer{
17 .coverage = initial_coverage_rect,
18 .clip_height = 0,
19 }},
20 },
21 });
22}

◆ ~EntityPassClipStack()

impeller::EntityPassClipStack::~EntityPassClipStack ( )
default

Member Function Documentation

◆ ApplyClipState()

EntityPassClipStack::ClipStateResult impeller::EntityPassClipStack::ApplyClipState ( Contents::ClipCoverage  global_clip_coverage,
Entity entity,
size_t  clip_height_floor,
Point  global_pass_position 
)

Applies the current clip state to an Entity. If the given Entity is a clip operation, then the clip state is updated accordingly.

Definition at line 52 of file entity_pass_clip_stack.cc.

56 {
57 ClipStateResult result = {.should_render = false, .clip_did_change = false};
58
59 auto& subpass_state = GetCurrentSubpassState();
60 switch (global_clip_coverage.type) {
62 break;
64 auto op = CurrentClipCoverage();
65
66 // Compute the previous clip height.
67 size_t previous_clip_height = 0;
68 if (!subpass_state.clip_coverage.empty()) {
69 previous_clip_height = subpass_state.clip_coverage.back().clip_height;
70 } else {
71 // If there is no clip coverage, then the previous clip height is the
72 // clip height floor.
73 previous_clip_height = clip_height_floor;
74 }
75
76 subpass_state.clip_coverage.push_back(
77 ClipCoverageLayer{.coverage = global_clip_coverage.coverage,
78 .clip_height = previous_clip_height + 1});
79 result.clip_did_change = true;
80
81 FML_DCHECK(subpass_state.clip_coverage.back().clip_height ==
82 subpass_state.clip_coverage.front().clip_height +
83 subpass_state.clip_coverage.size() - 1);
84
85 if (!op.has_value()) {
86 // Running this append op won't impact the clip buffer because the
87 // whole screen is already being clipped, so skip it.
88 return result;
89 }
90 } break;
92 ClipRestoreContents* restore_contents =
93 reinterpret_cast<ClipRestoreContents*>(entity.GetContents().get());
94 size_t restore_height = restore_contents->GetRestoreHeight();
95
96 if (subpass_state.clip_coverage.back().clip_height <= restore_height) {
97 // Drop clip restores that will do nothing.
98 return result;
99 }
100
101 auto restoration_index =
102 restore_height - subpass_state.clip_coverage.front().clip_height;
103 FML_DCHECK(restoration_index < subpass_state.clip_coverage.size());
104
105 // We only need to restore the area that covers the coverage of the
106 // clip rect at target height + 1.
107 std::optional<Rect> restore_coverage =
108 (restoration_index + 1 < subpass_state.clip_coverage.size())
109 ? subpass_state.clip_coverage[restoration_index + 1].coverage
110 : std::nullopt;
111 if (restore_coverage.has_value()) {
112 // Make the coverage rectangle relative to the current pass.
113 restore_coverage = restore_coverage->Shift(-global_pass_position);
114 }
115 subpass_state.clip_coverage.resize(restoration_index + 1);
116 result.clip_did_change = true;
117
118 // Skip all clip restores when stencil-then-cover is enabled.
119 if (subpass_state.clip_coverage.back().coverage.has_value()) {
120 RecordEntity(entity, global_clip_coverage.type, Rect());
121 }
122 return result;
123
124 } break;
125 }
126
127#ifdef IMPELLER_ENABLE_CAPTURE
128 {
129 auto element_entity_coverage = entity.GetCoverage();
130 if (element_entity_coverage.has_value()) {
131 element_entity_coverage =
132 element_entity_coverage->Shift(global_pass_position);
133 entity.GetCapture().AddRect("Coverage", *element_entity_coverage,
134 {.readonly = true});
135 }
136 }
137#endif
138
139 RecordEntity(entity, global_clip_coverage.type,
140 subpass_state.clip_coverage.back().coverage);
141
142 result.should_render = true;
143 return result;
144}
std::optional< Rect > CurrentClipCoverage() const
void RecordEntity(const Entity &entity, Contents::ClipCoverage::Type type, std::optional< Rect > clip_coverage)
GAsyncResult * result
#define FML_DCHECK(condition)
Definition logging.h:103
TRect< Scalar > Rect
Definition rect.h:746
Definition ref_ptr.h:256

◆ CurrentClipCoverage()

std::optional< Rect > impeller::EntityPassClipStack::CurrentClipCoverage ( ) const

Definition at line 24 of file entity_pass_clip_stack.cc.

24 {
25 return subpass_state_.back().clip_coverage.back().coverage;
26}

◆ GetClipCoverageLayers()

const std::vector< ClipCoverageLayer > impeller::EntityPassClipStack::GetClipCoverageLayers ( ) const

Definition at line 48 of file entity_pass_clip_stack.cc.

48 {
49 return subpass_state_.back().clip_coverage;
50}

◆ GetReplayEntities()

const std::vector< EntityPassClipStack::ReplayResult > & impeller::EntityPassClipStack::GetReplayEntities ( ) const

Definition at line 171 of file entity_pass_clip_stack.cc.

171 {
172 return subpass_state_.back().rendered_clip_entities;
173}

◆ HasCoverage()

bool impeller::EntityPassClipStack::HasCoverage ( ) const

Definition at line 28 of file entity_pass_clip_stack.cc.

28 {
29 return !subpass_state_.back().clip_coverage.empty();
30}

◆ PopSubpass()

void impeller::EntityPassClipStack::PopSubpass ( )

Definition at line 43 of file entity_pass_clip_stack.cc.

43 {
44 subpass_state_.pop_back();
45}

◆ PushSubpass()

void impeller::EntityPassClipStack::PushSubpass ( std::optional< Rect subpass_coverage,
size_t  clip_height 
)

Definition at line 32 of file entity_pass_clip_stack.cc.

33 {
34 subpass_state_.push_back(SubpassState{
35 .clip_coverage =
36 {
37 ClipCoverageLayer{.coverage = subpass_coverage,
38 .clip_height = clip_height},
39 },
40 });
41}

◆ RecordEntity()

void impeller::EntityPassClipStack::RecordEntity ( const Entity entity,
Contents::ClipCoverage::Type  type,
std::optional< Rect clip_coverage 
)

Definition at line 146 of file entity_pass_clip_stack.cc.

148 {
149 auto& subpass_state = GetCurrentSubpassState();
150 switch (type) {
152 return;
154 subpass_state.rendered_clip_entities.push_back(
155 {.entity = entity.Clone(), .clip_coverage = clip_coverage});
156 break;
158 if (!subpass_state.rendered_clip_entities.empty()) {
159 subpass_state.rendered_clip_entities.pop_back();
160 }
161 break;
162 }
163}

The documentation for this class was generated from the following files: