33// found in the LICENSE file.
44
55#include " flatland_external_view_embedder.h"
6+ #include < algorithm>
67#include < cstdint>
78
89#include " flutter/fml/trace_event.h"
@@ -17,6 +18,24 @@ namespace {
1718// overflows on operations (like FLT_MAX would).
1819constexpr float kMaxHitRegionSize = 1'000'000 .f;
1920
21+ void AttachClipTransformChild (
22+ FlatlandConnection* flatland,
23+ FlatlandExternalViewEmbedder::ClipTransform* parent_clip_transform,
24+ const fuchsia::ui::composition::TransformId& child_transform_id) {
25+ flatland->flatland ()->AddChild (parent_clip_transform->transform_id ,
26+ child_transform_id);
27+ parent_clip_transform->children .push_back (child_transform_id);
28+ }
29+
30+ void DetachClipTransformChildren (
31+ FlatlandConnection* flatland,
32+ FlatlandExternalViewEmbedder::ClipTransform* clip_transform) {
33+ for (auto & child : clip_transform->children ) {
34+ flatland->flatland ()->RemoveChild (clip_transform->transform_id , child);
35+ }
36+ clip_transform->children .clear ();
37+ }
38+
2039} // namespace
2140
2241FlatlandExternalViewEmbedder::FlatlandExternalViewEmbedder (
@@ -263,15 +282,61 @@ void FlatlandExternalViewEmbedder::SubmitFrame(
263282 viewport.transform_id ,
264283 {static_cast <int32_t >(view_mutators.transform .getTranslateX ()),
265284 static_cast <int32_t >(view_mutators.transform .getTranslateY ())});
266-
267285 flatland_->flatland ()->SetScale (
268286 viewport.transform_id , {view_mutators.transform .getScaleX (),
269287 view_mutators.transform .getScaleY ()});
270288 viewport.mutators .transform = view_mutators.transform ;
271289 }
272290
273291 // TODO(fxbug.dev/94000): Set HitTestBehavior.
274- // TODO(fxbug.dev/94000): Set ClipRegions.
292+
293+ // Set clip regions.
294+ if (view_mutators.clips != viewport.mutators .clips ) {
295+ // Expand the clip_transforms array to fit any new transforms.
296+ while (viewport.clip_transforms .size () < view_mutators.clips .size ()) {
297+ ClipTransform clip_transform;
298+ clip_transform.transform_id = flatland_->NextTransformId ();
299+ flatland_->flatland ()->CreateTransform (clip_transform.transform_id );
300+ viewport.clip_transforms .emplace_back (std::move (clip_transform));
301+ }
302+ FML_CHECK (viewport.clip_transforms .size () >=
303+ view_mutators.clips .size ());
304+
305+ // Adjust and re-parent all clip transforms.
306+ for (auto & clip_transform : viewport.clip_transforms ) {
307+ DetachClipTransformChildren (flatland_.get (), &clip_transform);
308+ }
309+
310+ for (size_t c = 0 ; c < view_mutators.clips .size (); c++) {
311+ const SkMatrix& clip_matrix = view_mutators.clips [c].transform ;
312+ const SkRect& clip_rect = view_mutators.clips [c].rect ;
313+
314+ flatland_->flatland ()->SetTranslation (
315+ viewport.clip_transforms [c].transform_id ,
316+ {static_cast <int32_t >(clip_matrix.getTranslateX ()),
317+ static_cast <int32_t >(clip_matrix.getTranslateY ())});
318+ flatland_->flatland ()->SetScale (
319+ viewport.clip_transforms [c].transform_id ,
320+ {clip_matrix.getScaleX (), clip_matrix.getScaleY ()});
321+ fuchsia::math::Rect rect = {
322+ static_cast <int32_t >(clip_rect.x ()),
323+ static_cast <int32_t >(clip_rect.y ()),
324+ static_cast <int32_t >(clip_rect.width ()),
325+ static_cast <int32_t >(clip_rect.height ())};
326+ flatland_->flatland ()->SetClipBoundary (
327+ viewport.clip_transforms [c].transform_id ,
328+ std::make_unique<fuchsia::math::Rect>(std::move (rect)));
329+
330+ const auto child_transform_id =
331+ c != (view_mutators.clips .size () - 1 )
332+ ? viewport.clip_transforms [c + 1 ].transform_id
333+ : viewport.transform_id ;
334+ AttachClipTransformChild (flatland_.get (),
335+ &(viewport.clip_transforms [c]),
336+ child_transform_id);
337+ }
338+ viewport.mutators .clips = view_mutators.clips ;
339+ }
275340
276341 // Set opacity.
277342 if (view_mutators.opacity != viewport.mutators .opacity ) {
@@ -299,9 +364,13 @@ void FlatlandExternalViewEmbedder::SubmitFrame(
299364 }
300365
301366 // Attach the FlatlandView to the main scene graph.
367+ const auto main_child_transform =
368+ viewport.mutators .clips .empty ()
369+ ? viewport.transform_id
370+ : viewport.clip_transforms [0 ].transform_id ;
302371 flatland_->flatland ()->AddChild (root_transform_id_,
303- viewport. transform_id );
304- child_transforms_.emplace_back (viewport. transform_id );
372+ main_child_transform );
373+ child_transforms_.emplace_back (main_child_transform );
305374 }
306375
307376 // Acquire the surface associated with the layer.
@@ -485,19 +554,29 @@ void FlatlandExternalViewEmbedder::DestroyView(
485554
486555 auto viewport_id = flatland_view->second .viewport_id ;
487556 auto transform_id = flatland_view->second .transform_id ;
557+ auto & clip_transforms = flatland_view->second .clip_transforms ;
488558 if (!flatland_view->second .pending_create_viewport_callback ) {
489559 flatland_->flatland ()->ReleaseViewport (viewport_id, [](auto ) {});
490560 }
491- auto itr =
492- std::find_if (child_transforms_.begin (), child_transforms_.end (),
493- [transform_id](fuchsia::ui::composition::TransformId id) {
494- return id.value == transform_id.value ;
495- });
561+ auto itr = std::find_if (
562+ child_transforms_.begin (), child_transforms_.end (),
563+ [transform_id,
564+ &clip_transforms](fuchsia::ui::composition::TransformId id) {
565+ return id.value == transform_id.value ||
566+ (!clip_transforms.empty () &&
567+ (id.value == clip_transforms[0 ].transform_id .value ));
568+ });
496569 if (itr != child_transforms_.end ()) {
497- flatland_->flatland ()->RemoveChild (root_transform_id_, transform_id );
570+ flatland_->flatland ()->RemoveChild (root_transform_id_, *itr );
498571 child_transforms_.erase (itr);
499572 }
573+ for (auto & clip_transform : clip_transforms) {
574+ DetachClipTransformChildren (flatland_.get (), &clip_transform);
575+ }
500576 flatland_->flatland ()->ReleaseTransform (transform_id);
577+ for (auto & clip_transform : clip_transforms) {
578+ flatland_->flatland ()->ReleaseTransform (clip_transform.transform_id );
579+ }
501580
502581 flatland_views_.erase (flatland_view);
503582 on_view_unbound (viewport_id);
0 commit comments