@@ -43,27 +43,41 @@ size_t EntityPass::GetSubpassesDepth() const {
43
43
return max_subpass_depth + 1u ;
44
44
}
45
45
46
- Rect EntityPass::GetCoverageRect () const {
47
- std::optional<Point > min, max ;
46
+ std::optional< Rect > EntityPass::GetEntitiesCoverage () const {
47
+ std::optional<Rect > result ;
48
48
for (const auto & entity : entities_) {
49
- auto coverage = entity.GetPath ().GetMinMaxCoveragePoints ();
50
- if (!coverage.has_value ()) {
49
+ auto coverage = entity.GetCoverage ();
50
+ if (!result.has_value () && coverage.has_value ()) {
51
+ result = coverage;
51
52
continue ;
52
53
}
53
- if (!min.has_value ()) {
54
- min = coverage->first ;
55
- }
56
- if (!max.has_value ()) {
57
- max = coverage->second ;
54
+ if (!coverage.has_value ()) {
55
+ continue ;
58
56
}
59
- min = min->Min (coverage->first );
60
- max = max->Max (coverage->second );
57
+ result = result->Union (coverage.value ());
58
+ }
59
+ return result;
60
+ }
61
+
62
+ std::optional<Rect > EntityPass::GetSubpassCoverage (
63
+ const EntityPass& subpass) const {
64
+ auto entities_coverage = subpass.GetEntitiesCoverage ();
65
+ // The entities don't cover anything. There is nothing to do.
66
+ if (!entities_coverage.has_value ()) {
67
+ return std::nullopt;
61
68
}
62
- if (!min.has_value () || !max.has_value ()) {
63
- return {};
69
+
70
+ // The delegates don't have an opinion on what the entity coverage has to be.
71
+ // Just use that as-is.
72
+ auto delegate_coverage = delegate_->GetCoverageRect ();
73
+ if (!delegate_coverage.has_value ()) {
74
+ return entities_coverage;
64
75
}
65
- const auto diff = *max - *min;
66
- return {min->x , min->y , diff.x , diff.y };
76
+
77
+ // If the delete tells us the coverage is smaller than it needs to be, then
78
+ // great. OTOH, if the delegate is being wasteful, limit coverage to what is
79
+ // actually needed.
80
+ return entities_coverage->Intersection (delegate_coverage.value ());
67
81
}
68
82
69
83
EntityPass* EntityPass::GetSuperpass () const {
@@ -74,18 +88,6 @@ const EntityPass::Subpasses& EntityPass::GetSubpasses() const {
74
88
return subpasses_;
75
89
}
76
90
77
- Rect EntityPass::GetSubpassCoverage (const EntityPass& subpass) const {
78
- auto subpass_coverage = subpass.GetCoverageRect ();
79
- auto delegate_coverage =
80
- delegate_->GetCoverageRect ().value_or (subpass_coverage);
81
- Rect coverage;
82
- coverage.origin = subpass_coverage.origin ;
83
- // TODO(csg): This must still be restricted to the max texture size. Or,
84
- // decide if this must be done by the allocator.
85
- coverage.size = subpass_coverage.size .Min (delegate_coverage.size );
86
- return coverage;
87
- }
88
-
89
91
EntityPass* EntityPass::AddSubpass (std::unique_ptr<EntityPass> pass) {
90
92
if (!pass) {
91
93
return nullptr ;
@@ -117,7 +119,11 @@ bool EntityPass::Render(ContentRenderer& renderer,
117
119
118
120
const auto subpass_coverage = GetSubpassCoverage (*subpass);
119
121
120
- if (subpass_coverage.IsEmpty ()) {
122
+ if (!subpass_coverage.has_value ()) {
123
+ continue ;
124
+ }
125
+
126
+ if (subpass_coverage->size .IsEmpty ()) {
121
127
// It is not an error to have an empty subpass. But subpasses that can't
122
128
// create their intermediates must trip errors.
123
129
continue ;
@@ -126,7 +132,7 @@ bool EntityPass::Render(ContentRenderer& renderer,
126
132
auto context = renderer.GetContext ();
127
133
128
134
auto subpass_target = RenderTarget::CreateOffscreen (
129
- *context, ISize::Ceil (subpass_coverage. size ));
135
+ *context, ISize::Ceil (subpass_coverage-> size ));
130
136
131
137
auto subpass_texture = subpass_target.GetRenderTargetTexture ();
132
138
@@ -178,7 +184,8 @@ bool EntityPass::Render(ContentRenderer& renderer,
178
184
}
179
185
180
186
Entity entity;
181
- entity.SetPath (PathBuilder{}.AddRect (subpass_coverage).CreatePath ());
187
+ entity.SetPath (
188
+ PathBuilder{}.AddRect (subpass_coverage.value ()).CreatePath ());
182
189
entity.SetContents (std::move (offscreen_texture_contents));
183
190
entity.SetStencilDepth (stencil_depth_);
184
191
entity.SetTransformation (xformation_);
0 commit comments