@@ -253,18 +253,15 @@ void EntityPass::AddSubpassInline(std::unique_ptr<EntityPass> pass) {
253253 pass->advanced_blend_reads_from_pass_texture_ ;
254254}
255255
256- static RenderTarget::AttachmentConfig GetDefaultStencilConfig (bool readable) {
257- return RenderTarget::AttachmentConfig{
258- .storage_mode = readable ? StorageMode::kDevicePrivate
259- : StorageMode::kDeviceTransient ,
260- .load_action = LoadAction::kDontCare ,
261- .store_action = StoreAction::kDontCare ,
262- };
263- }
256+ static const constexpr RenderTarget::AttachmentConfig kDefaultStencilConfig =
257+ RenderTarget::AttachmentConfig{
258+ .storage_mode = StorageMode::kDeviceTransient ,
259+ .load_action = LoadAction::kDontCare ,
260+ .store_action = StoreAction::kDontCare ,
261+ };
264262
265263static EntityPassTarget CreateRenderTarget (ContentContext& renderer,
266264 ISize size,
267- bool readable,
268265 const Color& clear_color) {
269266 auto context = renderer.GetContext ();
270267
@@ -285,8 +282,8 @@ static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
285282 .resolve_storage_mode = StorageMode::kDevicePrivate ,
286283 .load_action = LoadAction::kDontCare ,
287284 .store_action = StoreAction::kMultisampleResolve ,
288- .clear_color = clear_color}, // color_attachment_config
289- GetDefaultStencilConfig (readable) // stencil_attachment_config
285+ .clear_color = clear_color}, // color_attachment_config
286+ kDefaultStencilConfig // stencil_attachment_config
290287 );
291288 } else {
292289 target = RenderTarget::CreateOffscreen (
@@ -299,8 +296,8 @@ static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
299296 .load_action = LoadAction::kDontCare ,
300297 .store_action = StoreAction::kDontCare ,
301298 .clear_color = clear_color,
302- }, // color_attachment_config
303- GetDefaultStencilConfig (readable) // stencil_attachment_config
299+ }, // color_attachment_config
300+ kDefaultStencilConfig // stencil_attachment_config
304301 );
305302 }
306303
@@ -361,9 +358,9 @@ bool EntityPass::Render(ContentContext& renderer,
361358 // and then blit the results onto the onscreen texture. If using this branch,
362359 // there's no need to set up a stencil attachment on the root render target.
363360 if (!supports_onscreen_backdrop_reads && reads_from_onscreen_backdrop) {
364- auto offscreen_target = CreateRenderTarget (
365- renderer, root_render_target.GetRenderTargetSize (), true ,
366- GetClearColor (render_target.GetRenderTargetSize ()));
361+ auto offscreen_target =
362+ CreateRenderTarget ( renderer, root_render_target.GetRenderTargetSize (),
363+ GetClearColor (render_target.GetRenderTargetSize ()));
367364
368365 if (!OnRender (renderer, // renderer
369366 capture, // capture
@@ -465,8 +462,7 @@ bool EntityPass::Render(ContentContext& renderer,
465462 *renderer.GetContext (), *renderer.GetRenderTargetCache (),
466463 color0.texture ->GetSize (),
467464 renderer.GetContext ()->GetCapabilities ()->SupportsOffscreenMSAA (),
468- " ImpellerOnscreen" ,
469- GetDefaultStencilConfig (reads_from_onscreen_backdrop));
465+ " ImpellerOnscreen" , kDefaultStencilConfig );
470466 }
471467
472468 // Set up the clear color of the root pass.
@@ -503,10 +499,10 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
503499 // --------------------------------------------------------------------------
504500 // / Setup entity element.
505501 // /
506-
507502 if (const auto & entity = std::get_if<Entity>(&element)) {
508503 element_entity = *entity;
509504 element_entity.SetCapture (capture.CreateChild (" Entity" ));
505+
510506 if (!global_pass_position.IsZero ()) {
511507 // If the pass image is going to be rendered with a non-zero position,
512508 // apply the negative translation to entity copies before rendering them
@@ -515,16 +511,15 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
515511 Matrix::MakeTranslation (Vector3 (-global_pass_position)) *
516512 element_entity.GetTransformation ());
517513 }
514+ return EntityPass::EntityResult::Success (element_entity);
518515 }
519516
520517 // --------------------------------------------------------------------------
521518 // / Setup subpass element.
522519 // /
523-
524- else if (const auto & subpass_ptr =
525- std::get_if<std::unique_ptr<EntityPass>>(&element)) {
520+ if (const auto & subpass_ptr =
521+ std::get_if<std::unique_ptr<EntityPass>>(&element)) {
526522 auto subpass = subpass_ptr->get ();
527-
528523 if (subpass->delegate_ ->CanElide ()) {
529524 return EntityPass::EntityResult::Skip ();
530525 }
@@ -625,10 +620,9 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
625620 }
626621
627622 auto subpass_target = CreateRenderTarget (
628- renderer, // renderer
629- subpass_size, // size
630- subpass->GetTotalPassReads (renderer) > 0 , // readable
631- subpass->GetClearColor (subpass_size)); // clear_color
623+ renderer, // renderer
624+ subpass_size, // size
625+ subpass->GetClearColor (subpass_size)); // clear_color
632626
633627 if (!subpass_target.IsValid ()) {
634628 VALIDATION_LOG << " Subpass render target is invalid." ;
@@ -696,11 +690,10 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
696690 element_entity.SetTransformation (subpass_texture_capture.AddMatrix (
697691 " Transform" , Matrix::MakeTranslation (Vector3 (subpass_coverage->origin -
698692 global_pass_position))));
699- } else {
700- FML_UNREACHABLE ();
701- }
702693
703- return EntityPass::EntityResult::Success (element_entity);
694+ return EntityPass::EntityResult::Success (element_entity);
695+ }
696+ FML_UNREACHABLE ();
704697}
705698
706699bool EntityPass::RenderElement (Entity& element_entity,
@@ -724,6 +717,15 @@ bool EntityPass::RenderElement(Entity& element_entity,
724717 // blit the non-MSAA resolve texture of the previous pass to MSAA textures
725718 // (let alone a transient one).
726719 if (result.backdrop_texture ) {
720+ // Restore any clips that were recorded before the backdrop filter was
721+ // applied.
722+ auto & replay_entities = clip_replay_->GetReplayEntities ();
723+ for (const auto & entity : replay_entities) {
724+ if (!entity.Render (renderer, *result.pass )) {
725+ VALIDATION_LOG << " Failed to render entity for clip restore." ;
726+ }
727+ }
728+
727729 auto size_rect = Rect::MakeSize (result.pass ->GetRenderTargetSize ());
728730 auto msaa_backdrop_contents = TextureContents::MakeRect (size_rect);
729731 msaa_backdrop_contents->SetStencilEnabled (false );
@@ -836,6 +838,7 @@ bool EntityPass::RenderElement(Entity& element_entity,
836838#endif
837839
838840 element_entity.SetClipDepth (element_entity.GetClipDepth () - clip_depth_floor);
841+ clip_replay_->RecordEntity (element_entity, clip_coverage.type );
839842 if (!element_entity.Render (renderer, *result.pass )) {
840843 VALIDATION_LOG << " Failed to render entity." ;
841844 return false ;
@@ -1180,4 +1183,24 @@ void EntityPass::SetEnableOffscreenCheckerboard(bool enabled) {
11801183 enable_offscreen_debug_checkerboard_ = enabled;
11811184}
11821185
1186+ EntityPassClipRecorder::EntityPassClipRecorder () {}
1187+
1188+ void EntityPassClipRecorder::RecordEntity (const Entity& entity,
1189+ Contents::ClipCoverage::Type type) {
1190+ switch (type) {
1191+ case Contents::ClipCoverage::Type::kNoChange :
1192+ return ;
1193+ case Contents::ClipCoverage::Type::kAppend :
1194+ rendered_clip_entities_.push_back (entity);
1195+ break ;
1196+ case Contents::ClipCoverage::Type::kRestore :
1197+ rendered_clip_entities_.pop_back ();
1198+ break ;
1199+ }
1200+ }
1201+
1202+ const std::vector<Entity>& EntityPassClipRecorder::GetReplayEntities () const {
1203+ return rendered_clip_entities_;
1204+ }
1205+
11831206} // namespace impeller
0 commit comments