7#include <fuchsia/math/cpp/fidl.h>
8#include <fuchsia/sysmem/cpp/fidl.h>
9#include <fuchsia/ui/composition/cpp/fidl.h>
10#include <fuchsia/ui/views/cpp/fidl.h>
11#include <lib/async-testing/test_loop.h>
12#include <lib/zx/event.h>
13#include <lib/zx/eventpair.h>
26#include "third_party/skia/include/core/SkColor.h"
27#include "third_party/skia/include/core/SkSize.h"
28#include "third_party/skia/include/core/SkSurface.h"
34#include "gmock/gmock.h"
35#include "gtest/gtest.h"
42using fuchsia::scenic::scheduling::FramePresentedInfo;
43using fuchsia::scenic::scheduling::FuturePresentationTimes;
44using fuchsia::scenic::scheduling::PresentReceivedInfo;
46using ::testing::AllOf;
47using ::testing::Contains;
48using ::testing::ElementsAre;
50using ::testing::Field;
51using ::testing::FieldsAre;
52using ::testing::IsEmpty;
53using ::testing::Matcher;
54using ::testing::Pointee;
55using ::testing::Property;
56using ::testing::SizeIs;
57using ::testing::VariantWith;
62constexpr static fuchsia::ui::composition::BlendMode kFirstLayerBlendMode{
63 fuchsia::ui::composition::BlendMode::SRC};
64constexpr static fuchsia::ui::composition::BlendMode kUpperLayerBlendMode{
65 fuchsia::ui::composition::BlendMode::SRC_OVER};
68class FakeSurfaceProducerSurface :
public SurfaceProducerSurface {
70 explicit FakeSurfaceProducerSurface(
71 fidl::InterfaceRequest<fuchsia::sysmem2::BufferCollectionToken>
73 fuchsia::ui::composition::BufferCollectionImportToken buffer_import_token,
75 : sysmem_token_request_(
std::move(sysmem_token_request)),
76 buffer_import_token_(
std::move(buffer_import_token)),
78 zx_status_t acquire_status = zx::event::create(0, &acquire_fence_);
79 if (acquire_status != ZX_OK) {
81 <<
"FakeSurfaceProducerSurface: Failed to create acquire event";
83 zx_status_t release_status = zx::event::create(0, &release_fence_);
84 if (release_status != ZX_OK) {
86 <<
"FakeSurfaceProducerSurface: Failed to create release event";
89 ~FakeSurfaceProducerSurface()
override {}
91 bool IsValid()
const override {
return true; }
93 SkISize GetSize()
const override {
97 void SetImageId(uint32_t image_id)
override { image_id_ = image_id; }
98 uint32_t GetImageId()
override {
return image_id_; }
100 sk_sp<SkSurface> GetSkiaSurface()
const override {
return surface_; }
102 fuchsia::ui::composition::BufferCollectionImportToken
103 GetBufferCollectionImportToken()
override {
104 return std::move(buffer_import_token_);
107 zx::event GetAcquireFence()
override {
109 acquire_fence_.duplicate(ZX_RIGHT_SAME_RIGHTS, &fence);
113 zx::event GetReleaseFence()
override {
115 release_fence_.duplicate(ZX_RIGHT_SAME_RIGHTS, &fence);
119 void SetReleaseImageCallback(
122 size_t AdvanceAndGetAge()
override {
return 0; }
123 bool FlushSessionAcquireAndReleaseEvents()
override {
return true; }
124 void SignalWritesFinished(
125 const std::function<
void(
void)>& on_writes_committed)
override {}
128 fidl::InterfaceRequest<fuchsia::sysmem2::BufferCollectionToken>
129 sysmem_token_request_;
130 fuchsia::ui::composition::BufferCollectionImportToken buffer_import_token_;
131 zx::event acquire_fence_;
132 zx::event release_fence_;
135 uint32_t image_id_{0};
138class FakeSurfaceProducer :
public SurfaceProducer {
140 explicit FakeSurfaceProducer(
141 fuchsia::ui::composition::AllocatorHandle flatland_allocator)
143 ~FakeSurfaceProducer()
override =
default;
146 GrDirectContext* gr_context()
const override {
return nullptr; }
149 std::unique_ptr<SurfaceProducerSurface> ProduceOffscreenSurface(
150 const SkISize& size)
override {
155 std::unique_ptr<SurfaceProducerSurface> ProduceSurface(
156 const SkISize& size)
override {
157 auto [buffer_export_token, buffer_import_token] =
159 fuchsia::sysmem2::BufferCollectionTokenHandle sysmem_token;
160 auto sysmem_token_request = sysmem_token.NewRequest();
162 fuchsia::ui::composition::RegisterBufferCollectionArgs
163 buffer_collection_args;
164 buffer_collection_args.set_export_token(std::move(buffer_export_token));
165 buffer_collection_args.set_buffer_collection_token2(
166 std::move(sysmem_token));
167 buffer_collection_args.set_usage(
168 fuchsia::ui::composition::RegisterBufferCollectionUsage::DEFAULT);
170 std::move(buffer_collection_args),
171 [](fuchsia::ui::composition::Allocator_RegisterBufferCollection_Result
173 if (result.is_err()) {
175 <<
"fuhsia::ui::composition::RegisterBufferCollection error: "
176 << static_cast<uint32_t>(result.err());
180 return std::make_unique<FakeSurfaceProducerSurface>(
181 std::move(sysmem_token_request), std::move(buffer_import_token), size);
186 std::vector<std::unique_ptr<SurfaceProducerSurface>> surfaces)
override {}
191Matcher<fuchsia::ui::composition::ImageProperties> IsImageProperties(
192 const fuchsia::math::SizeU& size) {
194 Property(
"has_size", &fuchsia::ui::composition::ImageProperties::has_size,
196 Property(
"size", &fuchsia::ui::composition::ImageProperties::size,
size));
199Matcher<fuchsia::ui::composition::ViewportProperties> IsViewportProperties(
200 const fuchsia::math::SizeU& logical_size,
201 const fuchsia::math::Inset& inset) {
203 Property(
"has_logical_size",
204 &fuchsia::ui::composition::ViewportProperties::has_logical_size,
206 Property(
"logical_size",
207 &fuchsia::ui::composition::ViewportProperties::logical_size,
209 Property(
"has_inset",
210 &fuchsia::ui::composition::ViewportProperties::has_inset,
true),
211 Property(
"inset", &fuchsia::ui::composition::ViewportProperties::inset,
215Matcher<fuchsia::ui::composition::HitRegion> IsHitRegion(
220 const fuchsia::ui::composition::HitTestInteraction hit_test) {
224Matcher<FakeGraph> IsEmptyGraph() {
225 return FieldsAre(IsEmpty(), IsEmpty(), Eq(
nullptr), Eq(std::nullopt));
228Matcher<FakeGraph> IsFlutterGraph(
229 const fuchsia::ui::composition::ParentViewportWatcherPtr&
230 parent_viewport_watcher,
231 const fuchsia::ui::views::ViewportCreationToken& viewport_creation_token,
232 const fuchsia::ui::views::ViewRef& view_ref,
233 std::vector<Matcher<std::shared_ptr<FakeTransform>>> layer_matchers = {},
235 auto viewport_token_koids =
GetKoids(viewport_creation_token);
236 auto view_ref_koids =
GetKoids(view_ref);
237 auto watcher_koids =
GetKoids(parent_viewport_watcher);
245 ElementsAreArray(layer_matchers),
248 .view_token = viewport_token_koids.second,
249 .view_ref = view_ref_koids.first,
250 .view_ref_control = view_ref_koids.second,
251 .view_ref_focused = ZX_KOID_INVALID,
252 .focuser = ZX_KOID_INVALID,
253 .touch_source = ZX_KOID_INVALID,
254 .mouse_source = ZX_KOID_INVALID,
255 .parent_viewport_watcher = watcher_koids.second,
259Matcher<std::shared_ptr<FakeTransform>> IsImageLayer(
260 const fuchsia::math::SizeU& layer_size,
261 fuchsia::ui::composition::BlendMode blend_mode,
262 std::vector<Matcher<fuchsia::ui::composition::HitRegion>>
263 hit_region_matchers) {
264 return Pointee(FieldsAre(
270 Pointee(VariantWith<FakeImage>(FieldsAre(
271 _, IsImageProperties(layer_size),
275 ElementsAreArray(hit_region_matchers)));
278Matcher<std::shared_ptr<FakeTransform>> IsViewportLayer(
279 const fuchsia::ui::views::ViewCreationToken& view_token,
280 const fuchsia::math::SizeU& view_logical_size,
281 const fuchsia::math::Inset& view_inset,
282 const fuchsia::math::Vec& view_translation,
283 const fuchsia::math::VecF& view_scale,
284 const float view_opacity) {
285 return Pointee(FieldsAre(
286 _, view_translation, view_scale,
290 Pointee(VariantWith<FakeViewport>(FieldsAre(
291 _, IsViewportProperties(view_logical_size, view_inset),
297Matcher<std::shared_ptr<FakeTransform>> IsClipTransformLayer(
298 const fuchsia::math::Vec& transform_translation,
299 const fuchsia::math::VecF& transform_scale,
300 std::optional<fuchsia::math::Rect> clip_bounds,
301 Matcher<std::shared_ptr<FakeTransform>> viewport_matcher) {
302 return Pointee(FieldsAre(
303 _, transform_translation, transform_scale,
306 ElementsAre(viewport_matcher),
311Matcher<std::shared_ptr<FakeTransform>> IsInputShield() {
312 return Pointee(AllOf(
320fuchsia::ui::composition::OnNextFrameBeginValues WithPresentCredits(
321 uint32_t additional_present_credits) {
322 fuchsia::ui::composition::OnNextFrameBeginValues values;
323 values.set_additional_present_credits(additional_present_credits);
324 fuchsia::scenic::scheduling::PresentationInfo info_1;
325 info_1.set_presentation_time(123);
326 std::vector<fuchsia::scenic::scheduling::PresentationInfo> infos;
327 infos.push_back(std::move(info_1));
328 values.set_future_presentation_infos(std::move(infos));
332void DrawSimpleFrame(ExternalViewEmbedder& external_view_embedder,
336 external_view_embedder.BeginFrame(
nullptr,
nullptr);
337 external_view_embedder.PrepareFlutterView(frame_size, frame_dpr);
340 external_view_embedder.PostPrerollAction(
nullptr);
341 draw_callback(root_canvas);
343 external_view_embedder.EndFrame(
false,
nullptr);
346 external_view_embedder.SubmitFlutterView(
348 std::make_unique<flutter::SurfaceFrame>(
349 nullptr, std::move(framebuffer_info),
356void DrawFrameWithView(
357 ExternalViewEmbedder& external_view_embedder,
364 external_view_embedder.BeginFrame(
nullptr,
nullptr);
365 external_view_embedder.PrepareFlutterView(frame_size, frame_dpr);
368 external_view_embedder.PrerollCompositeEmbeddedView(
369 view_id, std::make_unique<flutter::EmbeddedViewParams>(view_params));
370 external_view_embedder.PostPrerollAction(
nullptr);
371 background_draw_callback(root_canvas);
373 external_view_embedder.CompositeEmbeddedView(
view_id);
374 overlay_draw_callback(overlay_canvas);
376 external_view_embedder.EndFrame(
false,
nullptr);
379 external_view_embedder.SubmitFlutterView(
381 std::make_unique<flutter::SurfaceFrame>(
382 nullptr, std::move(framebuffer_info),
394 : session_subloop_(loop_.StartNewLoop()),
395 flatland_connection_(CreateFlatlandConnection()),
396 fake_surface_producer_(
397 std::make_shared<FakeSurfaceProducer>(CreateFlatlandAllocator())) {}
400 async::TestLoop&
loop() {
return loop_; }
403 return fake_surface_producer_;
409 return flatland_connection_;
413 fuchsia::ui::composition::AllocatorHandle CreateFlatlandAllocator() {
415 fuchsia::ui::composition::AllocatorHandle flatland_allocator =
418 return flatland_allocator;
421 std::shared_ptr<FlatlandConnection> CreateFlatlandConnection() {
423 fuchsia::ui::composition::FlatlandHandle flatland =
426 const auto test_name =
427 ::testing::UnitTest::GetInstance()->current_test_info()->name();
428 return std::make_shared<FlatlandConnection>(
429 std::move(test_name), std::move(flatland),
430 [] { FAIL(); }, [](
auto...) {});
438 async::TestLoop loop_;
439 std::unique_ptr<async::LoopInterface> session_subloop_;
441 FakeFlatland fake_flatland_;
443 std::shared_ptr<FlatlandConnection> flatland_connection_;
444 std::shared_ptr<FakeSurfaceProducer> fake_surface_producer_;
448 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
449 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
450 fuchsia::ui::views::ViewCreationToken view_creation_token;
451 fuchsia::ui::views::ViewRef view_ref_clone;
452 auto view_creation_token_status = zx::channel::create(
453 0u, &viewport_creation_token.value, &view_creation_token.value);
454 ASSERT_EQ(view_creation_token_status, ZX_OK);
456 fuchsia::ui::views::ViewRefControl view_ref_control;
457 fuchsia::ui::views::ViewRef view_ref;
458 auto status = zx::eventpair::create(
459 0u, &view_ref_control.reference, &view_ref.reference);
460 ASSERT_EQ(status, ZX_OK);
461 view_ref_control.reference.replace(
462 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
463 &view_ref_control.reference);
464 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
465 view_ref.Clone(&view_ref_clone);
468 std::move(view_creation_token),
469 fuchsia::ui::views::ViewIdentityOnCreation{
470 .view_ref = std::move(view_ref),
471 .view_ref_control = std::move(view_ref_control),
473 fuchsia::ui::composition::ViewBoundProtocols{},
474 parent_viewport_watcher.NewRequest(), flatland_connection(),
475 fake_surface_producer());
476 EXPECT_THAT(fake_flatland().graph(), IsEmptyGraph());
480 loop().RunUntilIdle();
481 EXPECT_THAT(fake_flatland().graph(), IsEmptyGraph());
484 flatland_connection()->Present();
485 loop().RunUntilIdle();
486 EXPECT_THAT(fake_flatland().graph(),
487 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
492 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
493 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
494 fuchsia::ui::views::ViewCreationToken view_creation_token;
495 fuchsia::ui::views::ViewRef view_ref_clone;
496 auto view_creation_token_status = zx::channel::create(
497 0u, &viewport_creation_token.value, &view_creation_token.value);
498 ASSERT_EQ(view_creation_token_status, ZX_OK);
500 fuchsia::ui::views::ViewRefControl view_ref_control;
501 fuchsia::ui::views::ViewRef view_ref;
502 auto status = zx::eventpair::create(
503 0u, &view_ref_control.reference, &view_ref.reference);
504 ASSERT_EQ(status, ZX_OK);
505 view_ref_control.reference.replace(
506 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
507 &view_ref_control.reference);
508 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
509 view_ref.Clone(&view_ref_clone);
514 std::move(view_creation_token),
515 fuchsia::ui::views::ViewIdentityOnCreation{
516 .view_ref = std::move(view_ref),
517 .view_ref_control = std::move(view_ref_control),
519 fuchsia::ui::composition::ViewBoundProtocols{},
520 parent_viewport_watcher.NewRequest(), flatland_connection(),
521 fake_surface_producer());
522 flatland_connection()->Present();
523 loop().RunUntilIdle();
524 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
525 loop().RunUntilIdle();
526 EXPECT_THAT(fake_flatland().graph(),
527 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
531 const DlISize frame_size_signed = DlISize(512, 512);
532 const fuchsia::math::SizeU frame_size{
533 static_cast<uint32_t
>(frame_size_signed.width),
534 static_cast<uint32_t
>(frame_size_signed.height)};
536 external_view_embedder, frame_size_signed, 1.f,
541 canvas->
Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
542 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
544 EXPECT_THAT(fake_flatland().graph(),
545 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
549 loop().RunUntilIdle();
552 fake_flatland().graph(),
554 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
557 frame_size, kFirstLayerBlendMode,
564 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
568 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
569 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
570 fuchsia::ui::views::ViewCreationToken view_creation_token;
571 fuchsia::ui::views::ViewRef view_ref_clone;
572 auto view_creation_token_status = zx::channel::create(
573 0u, &viewport_creation_token.value, &view_creation_token.value);
574 ASSERT_EQ(view_creation_token_status, ZX_OK);
576 fuchsia::ui::views::ViewRefControl view_ref_control;
577 fuchsia::ui::views::ViewRef view_ref;
578 auto status = zx::eventpair::create(
579 0u, &view_ref_control.reference, &view_ref.reference);
580 ASSERT_EQ(status, ZX_OK);
581 view_ref_control.reference.replace(
582 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
583 &view_ref_control.reference);
584 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
585 view_ref.Clone(&view_ref_clone);
590 std::move(view_creation_token),
591 fuchsia::ui::views::ViewIdentityOnCreation{
592 .view_ref = std::move(view_ref),
593 .view_ref_control = std::move(view_ref_control),
595 fuchsia::ui::composition::ViewBoundProtocols{},
596 parent_viewport_watcher.NewRequest(), flatland_connection(),
597 fake_surface_producer());
598 flatland_connection()->Present();
599 loop().RunUntilIdle();
600 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
601 loop().RunUntilIdle();
602 EXPECT_THAT(fake_flatland().graph(),
603 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
607 const DlSize child_view_size_signed = DlSize(256.f, 512.f);
608 const fuchsia::math::SizeU child_view_size{
609 static_cast<uint32_t
>(child_view_size_signed.width),
610 static_cast<uint32_t
>(child_view_size_signed.height)};
612 const uint32_t child_view_id = child_viewport_token.value.get();
614 const uint8_t kOpacity = 200u;
615 const float kOpacityFloat = DlColor::toOpacity(kOpacity);
616 const fuchsia::math::VecF kScale{3.0f, 4.0f};
618 DlMatrix matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
621 mutators_stack.PushOpacity(kOpacity);
622 mutators_stack.PushTransform(matrix);
626 external_view_embedder.CreateView(
627 child_view_id, []() {},
628 [](fuchsia::ui::composition::ContentId,
629 fuchsia::ui::composition::ChildViewWatcherHandle) {});
630 const SkRect child_view_occlusion_hint = SkRect::MakeLTRB(1, 2, 3, 4);
631 const fuchsia::math::Inset child_view_inset{
632 static_cast<int32_t
>(child_view_occlusion_hint.top()),
633 static_cast<int32_t
>(child_view_occlusion_hint.right()),
634 static_cast<int32_t
>(child_view_occlusion_hint.bottom()),
635 static_cast<int32_t
>(child_view_occlusion_hint.left())};
636 external_view_embedder.SetViewProperties(
637 child_view_id, child_view_occlusion_hint,
false,
641 const float kDPR = 2.0f;
642 const float kInvDPR = 1.f / kDPR;
645 const DlISize frame_size_signed = DlISize(512, 512);
646 const fuchsia::math::SizeU frame_size{
647 static_cast<uint32_t
>(frame_size_signed.width),
648 static_cast<uint32_t
>(frame_size_signed.height)};
650 external_view_embedder, frame_size_signed, kDPR, child_view_id,
656 canvas->
Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
657 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
663 canvas->
Translate(canvas_size.width * 3.f / 4.f,
664 canvas_size.height / 2.f);
665 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
667 EXPECT_THAT(fake_flatland().graph(),
668 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
672 loop().RunUntilIdle();
673 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
674 loop().RunUntilIdle();
677 fake_flatland().graph(),
679 parent_viewport_watcher, viewport_creation_token,
682 frame_size, kFirstLayerBlendMode,
689 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
690 IsViewportLayer(child_view_token, child_view_size, child_view_inset,
691 {0, 0}, kScale, kOpacityFloat),
693 frame_size, kUpperLayerBlendMode,
700 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})},
701 {kInvDPR, kInvDPR}));
704 external_view_embedder.DestroyView(
705 child_view_id, [](fuchsia::ui::composition::ContentId) {});
707 fake_flatland().graph(),
709 parent_viewport_watcher, viewport_creation_token,
712 frame_size, kFirstLayerBlendMode,
719 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
720 IsViewportLayer(child_view_token, child_view_size, child_view_inset,
721 {0, 0}, kScale, kOpacityFloat),
723 frame_size, kUpperLayerBlendMode,
730 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})},
731 {kInvDPR, kInvDPR}));
735 external_view_embedder, frame_size_signed, 1.f,
740 canvas->
Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
741 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
744 fake_flatland().graph(),
746 parent_viewport_watcher, viewport_creation_token,
749 frame_size, kFirstLayerBlendMode,
756 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
757 IsViewportLayer(child_view_token, child_view_size, child_view_inset,
758 {0, 0}, kScale, kOpacityFloat),
760 frame_size, kUpperLayerBlendMode,
767 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})},
768 {kInvDPR, kInvDPR}));
771 loop().RunUntilIdle();
773 fake_flatland().graph(),
775 parent_viewport_watcher, viewport_creation_token,
778 frame_size, kFirstLayerBlendMode,
785 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
789 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
790 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
791 fuchsia::ui::views::ViewCreationToken view_creation_token;
792 fuchsia::ui::views::ViewRef view_ref_clone;
793 auto view_creation_token_status = zx::channel::create(
794 0u, &viewport_creation_token.value, &view_creation_token.value);
795 ASSERT_EQ(view_creation_token_status, ZX_OK);
797 fuchsia::ui::views::ViewRefControl view_ref_control;
798 fuchsia::ui::views::ViewRef view_ref;
799 auto status = zx::eventpair::create(
800 0u, &view_ref_control.reference, &view_ref.reference);
801 ASSERT_EQ(status, ZX_OK);
802 view_ref_control.reference.replace(
803 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
804 &view_ref_control.reference);
805 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
806 view_ref.Clone(&view_ref_clone);
811 std::move(view_creation_token),
812 fuchsia::ui::views::ViewIdentityOnCreation{
813 .view_ref = std::move(view_ref),
814 .view_ref_control = std::move(view_ref_control),
816 fuchsia::ui::composition::ViewBoundProtocols{},
817 parent_viewport_watcher.NewRequest(), flatland_connection(),
818 fake_surface_producer());
819 flatland_connection()->Present();
820 loop().RunUntilIdle();
821 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
822 loop().RunUntilIdle();
823 EXPECT_THAT(fake_flatland().graph(),
824 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
828 const DlSize child_view_size_signed = DlSize(256.f, 512.f);
829 const fuchsia::math::SizeU child_view_size{
830 static_cast<uint32_t
>(child_view_size_signed.width),
831 static_cast<uint32_t
>(child_view_size_signed.height)};
833 const uint32_t child_view_id = child_viewport_token.value.get();
835 const uint8_t kOpacity = 200u;
836 const float kOpacityFloat = DlColor::toOpacity(kOpacity);
837 const fuchsia::math::VecF kScale{3.0f, 4.0f};
838 const int kTranslateX = 10;
839 const int kTranslateY = 20;
841 DlMatrix matrix = DlMatrix::MakeTranslation({kTranslateX, kTranslateY}) *
842 DlMatrix::MakeScale({kScale.x, kScale.y, 1});
844 DlRect kClipRect = DlRect::MakeXYWH(30, 40, child_view_size_signed.width - 50,
845 child_view_size_signed.height - 60);
846 fuchsia::math::Rect kClipInMathRect = {
847 static_cast<int32_t
>(kClipRect.GetX()),
848 static_cast<int32_t
>(kClipRect.GetY()),
849 static_cast<int32_t
>(kClipRect.GetWidth()),
850 static_cast<int32_t
>(kClipRect.GetHeight())};
853 mutators_stack.PushOpacity(kOpacity);
854 mutators_stack.PushTransform(matrix);
855 mutators_stack.PushClipRect(kClipRect);
859 external_view_embedder.CreateView(
860 child_view_id, []() {},
861 [](fuchsia::ui::composition::ContentId,
862 fuchsia::ui::composition::ChildViewWatcherHandle) {});
863 const SkRect child_view_occlusion_hint = SkRect::MakeLTRB(1, 2, 3, 4);
864 const fuchsia::math::Inset child_view_inset{
865 static_cast<int32_t
>(child_view_occlusion_hint.top()),
866 static_cast<int32_t
>(child_view_occlusion_hint.right()),
867 static_cast<int32_t
>(child_view_occlusion_hint.bottom()),
868 static_cast<int32_t
>(child_view_occlusion_hint.left())};
869 external_view_embedder.SetViewProperties(
870 child_view_id, child_view_occlusion_hint,
false,
874 const float kDPR = 2.0f;
875 const float kInvDPR = 1.f / kDPR;
878 const DlISize frame_size_signed = DlISize(512, 512);
879 const fuchsia::math::SizeU frame_size{
880 static_cast<uint32_t
>(frame_size_signed.width),
881 static_cast<uint32_t
>(frame_size_signed.height)};
883 external_view_embedder, frame_size_signed, kDPR, child_view_id,
889 canvas->
Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
890 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
896 canvas->
Translate(canvas_size.width * 3.f / 4.f,
897 canvas_size.height / 2.f);
898 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
900 EXPECT_THAT(fake_flatland().graph(),
901 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
905 loop().RunUntilIdle();
906 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
907 loop().RunUntilIdle();
910 fake_flatland().graph(),
912 parent_viewport_watcher, viewport_creation_token,
915 frame_size, kFirstLayerBlendMode,
922 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
923 IsClipTransformLayer(
924 {kTranslateX, kTranslateY}, kScale, kClipInMathRect,
925 IsViewportLayer(child_view_token, child_view_size,
926 child_view_inset, {0, 0},
929 frame_size, kUpperLayerBlendMode,
936 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})},
937 {kInvDPR, kInvDPR}));
941 DlMatrix new_matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
943 new_mutators_stack.PushOpacity(kOpacity);
944 new_mutators_stack.PushTransform(new_matrix);
946 new_matrix, child_view_size_signed, new_mutators_stack);
948 external_view_embedder, frame_size_signed, kDPR, child_view_id,
949 new_child_view_params,
954 canvas->
Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
955 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
961 canvas->
Translate(canvas_size.width * 3.f / 4.f,
962 canvas_size.height / 2.f);
963 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
965 loop().RunUntilIdle();
966 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
967 loop().RunUntilIdle();
969 fake_flatland().graph(),
971 parent_viewport_watcher, viewport_creation_token,
974 frame_size, kFirstLayerBlendMode,
981 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
982 IsViewportLayer(child_view_token, child_view_size, child_view_inset,
983 {0, 0}, kScale, kOpacityFloat),
985 frame_size, kUpperLayerBlendMode,
992 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})},
993 {kInvDPR, kInvDPR}));
996 external_view_embedder.DestroyView(
997 child_view_id, [](fuchsia::ui::composition::ContentId) {});
999 external_view_embedder, frame_size_signed, 1.f,
1004 canvas->
Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1005 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1007 loop().RunUntilIdle();
1009 fake_flatland().graph(),
1011 parent_viewport_watcher, viewport_creation_token,
1014 frame_size, kFirstLayerBlendMode,
1021 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1025 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
1026 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
1027 fuchsia::ui::views::ViewCreationToken view_creation_token;
1028 fuchsia::ui::views::ViewRef view_ref_clone;
1029 auto view_creation_token_status = zx::channel::create(
1030 0u, &viewport_creation_token.value, &view_creation_token.value);
1031 ASSERT_EQ(view_creation_token_status, ZX_OK);
1033 fuchsia::ui::views::ViewRefControl view_ref_control;
1034 fuchsia::ui::views::ViewRef view_ref;
1035 auto status = zx::eventpair::create(
1036 0u, &view_ref_control.reference, &view_ref.reference);
1037 ASSERT_EQ(status, ZX_OK);
1038 view_ref_control.reference.replace(
1039 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
1040 &view_ref_control.reference);
1041 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
1042 view_ref.Clone(&view_ref_clone);
1047 std::move(view_creation_token),
1048 fuchsia::ui::views::ViewIdentityOnCreation{
1049 .view_ref = std::move(view_ref),
1050 .view_ref_control = std::move(view_ref_control),
1052 fuchsia::ui::composition::ViewBoundProtocols{},
1053 parent_viewport_watcher.NewRequest(), flatland_connection(),
1054 fake_surface_producer());
1055 flatland_connection()->Present();
1056 loop().RunUntilIdle();
1057 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1058 loop().RunUntilIdle();
1059 EXPECT_THAT(fake_flatland().graph(),
1060 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1064 const DlSize child_view_size_signed = DlSize(256.f, 512.f);
1065 const fuchsia::math::SizeU child_view_size{
1066 static_cast<uint32_t
>(child_view_size_signed.width),
1067 static_cast<uint32_t
>(child_view_size_signed.height)};
1069 const uint32_t child_view_id = child_viewport_token.value.get();
1071 const uint8_t kOpacity = 125u;
1072 const float kOpacityFloat = DlColor::toOpacity(kOpacity);
1073 const fuchsia::math::VecF kScale{2.f, 3.0f};
1075 DlMatrix matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
1078 mutators_stack.PushOpacity(kOpacity);
1079 mutators_stack.PushTransform(matrix);
1083 external_view_embedder.CreateView(
1084 child_view_id, []() {},
1085 [](fuchsia::ui::composition::ContentId,
1086 fuchsia::ui::composition::ChildViewWatcherHandle) {});
1089 const DlISize frame_size_signed = DlISize(512, 512);
1090 const fuchsia::math::SizeU frame_size{
1091 static_cast<uint32_t
>(frame_size_signed.width),
1092 static_cast<uint32_t
>(frame_size_signed.height)};
1094 external_view_embedder, frame_size_signed, 1.f, child_view_id,
1100 canvas->
Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1101 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1104 EXPECT_THAT(fake_flatland().graph(),
1105 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1109 loop().RunUntilIdle();
1110 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1111 loop().RunUntilIdle();
1113 fake_flatland().graph(),
1115 parent_viewport_watcher, viewport_creation_token,
1118 frame_size, kFirstLayerBlendMode,
1125 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
1126 IsViewportLayer(child_view_token, child_view_size,
1131 external_view_embedder.DestroyView(
1132 child_view_id, [](fuchsia::ui::composition::ContentId) {});
1134 fake_flatland().graph(),
1136 parent_viewport_watcher, viewport_creation_token,
1139 frame_size, kFirstLayerBlendMode,
1146 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
1147 IsViewportLayer(child_view_token, child_view_size,
1153 external_view_embedder, frame_size_signed, 1.f,
1158 canvas->
Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1159 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1163 fake_flatland().graph(),
1165 parent_viewport_watcher, viewport_creation_token,
1168 frame_size, kFirstLayerBlendMode,
1175 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
1176 IsViewportLayer(child_view_token, child_view_size,
1181 loop().RunUntilIdle();
1183 fake_flatland().graph(),
1185 parent_viewport_watcher, viewport_creation_token,
1188 frame_size, kFirstLayerBlendMode,
1195 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1199 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
1200 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
1201 fuchsia::ui::views::ViewCreationToken view_creation_token;
1202 fuchsia::ui::views::ViewRef view_ref_clone;
1203 auto view_creation_token_status = zx::channel::create(
1204 0u, &viewport_creation_token.value, &view_creation_token.value);
1205 ASSERT_EQ(view_creation_token_status, ZX_OK);
1207 fuchsia::ui::views::ViewRefControl view_ref_control;
1208 fuchsia::ui::views::ViewRef view_ref;
1209 auto status = zx::eventpair::create(
1210 0u, &view_ref_control.reference, &view_ref.reference);
1211 ASSERT_EQ(status, ZX_OK);
1212 view_ref_control.reference.replace(
1213 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
1214 &view_ref_control.reference);
1215 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
1216 view_ref.Clone(&view_ref_clone);
1221 std::move(view_creation_token),
1222 fuchsia::ui::views::ViewIdentityOnCreation{
1223 .view_ref = std::move(view_ref),
1224 .view_ref_control = std::move(view_ref_control),
1226 fuchsia::ui::composition::ViewBoundProtocols{},
1227 parent_viewport_watcher.NewRequest(), flatland_connection(),
1228 fake_surface_producer());
1229 flatland_connection()->Present();
1230 loop().RunUntilIdle();
1231 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1232 loop().RunUntilIdle();
1233 EXPECT_THAT(fake_flatland().graph(),
1234 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1239 const uint32_t child_view_id = child_viewport_token.value.get();
1240 external_view_embedder.CreateView(
1241 child_view_id, []() {},
1242 [](fuchsia::ui::composition::ContentId,
1243 fuchsia::ui::composition::ChildViewWatcherHandle) {});
1246 const DlISize frame_size_signed = DlISize(512, 512);
1247 const fuchsia::math::SizeU frame_size{
1248 static_cast<uint32_t
>(frame_size_signed.width),
1249 static_cast<uint32_t
>(frame_size_signed.height)};
1251 external_view_embedder, frame_size_signed, 1.f,
1256 canvas->
Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1257 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1261 loop().RunUntilIdle();
1262 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1263 loop().RunUntilIdle();
1265 fake_flatland().graph(),
1267 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
1270 frame_size, kFirstLayerBlendMode,
1277 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1280 external_view_embedder.DestroyView(
1281 child_view_id, [](fuchsia::ui::composition::ContentId) {});
1283 fake_flatland().graph(),
1285 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
1288 frame_size, kFirstLayerBlendMode,
1295 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1299 const DlISize new_frame_size_signed = DlISize(256, 256);
1300 const fuchsia::math::SizeU new_frame_size{
1301 static_cast<uint32_t
>(new_frame_size_signed.width),
1302 static_cast<uint32_t
>(new_frame_size_signed.height)};
1304 external_view_embedder, new_frame_size_signed, 1.f,
1309 canvas->
Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1310 canvas->
DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1313 fake_flatland().graph(),
1315 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
1318 frame_size, kFirstLayerBlendMode,
1325 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1328 loop().RunUntilIdle();
1330 fake_flatland().graph(),
1332 parent_viewport_watcher, viewport_creation_token,
1335 new_frame_size, kFirstLayerBlendMode,
1342 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1349 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
1350 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
1351 fuchsia::ui::views::ViewCreationToken view_creation_token;
1352 fuchsia::ui::views::ViewRef view_ref_clone;
1353 auto view_creation_token_status = zx::channel::create(
1354 0u, &viewport_creation_token.value, &view_creation_token.value);
1355 ASSERT_EQ(view_creation_token_status, ZX_OK);
1357 fuchsia::ui::views::ViewRefControl view_ref_control;
1358 fuchsia::ui::views::ViewRef view_ref;
1359 auto status = zx::eventpair::create(
1360 0u, &view_ref_control.reference, &view_ref.reference);
1361 ASSERT_EQ(status, ZX_OK);
1362 view_ref_control.reference.replace(
1363 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
1364 &view_ref_control.reference);
1365 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
1366 view_ref.Clone(&view_ref_clone);
1371 std::move(view_creation_token),
1372 fuchsia::ui::views::ViewIdentityOnCreation{
1373 .view_ref = std::move(view_ref),
1374 .view_ref_control = std::move(view_ref_control),
1376 fuchsia::ui::composition::ViewBoundProtocols{},
1377 parent_viewport_watcher.NewRequest(), flatland_connection(),
1378 fake_surface_producer());
1379 flatland_connection()->Present();
1380 loop().RunUntilIdle();
1381 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1382 loop().RunUntilIdle();
1383 EXPECT_THAT(fake_flatland().graph(),
1384 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1388 const DlISize frame_size_signed = DlISize(512, 512);
1389 const fuchsia::math::SizeU frame_size{
1390 static_cast<uint32_t
>(frame_size_signed.width),
1391 static_cast<uint32_t
>(frame_size_signed.height)};
1392 DrawSimpleFrame(external_view_embedder, frame_size_signed, 1.f,
1396 DlRect paint_region_1, paint_region_2;
1398 paint_region_1 = DlRect::MakeXYWH(
1399 canvas_size.width / 4.f, canvas_size.height / 2.f,
1400 canvas_size.width / 32.f, canvas_size.height / 32.f);
1404 canvas->
DrawRect(paint_region_1, rect_paint);
1406 paint_region_2 = DlRect::MakeXYWH(
1407 canvas_size.width * 3.f / 4.f, canvas_size.height / 2.f,
1408 canvas_size.width / 32.f, canvas_size.height / 32.f);
1411 canvas->
DrawRect(paint_region_2, rect_paint);
1413 EXPECT_THAT(fake_flatland().graph(),
1414 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1418 loop().RunUntilIdle();
1421 fake_flatland().graph(),
1423 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
1426 frame_size, kFirstLayerBlendMode,
1433 fuchsia::ui::composition::HitTestInteraction::DEFAULT),
1440 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1448 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
1449 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
1450 fuchsia::ui::views::ViewCreationToken view_creation_token;
1451 fuchsia::ui::views::ViewRef view_ref_clone;
1452 auto view_creation_token_status = zx::channel::create(
1453 0u, &viewport_creation_token.value, &view_creation_token.value);
1454 ASSERT_EQ(view_creation_token_status, ZX_OK);
1456 fuchsia::ui::views::ViewRefControl view_ref_control;
1457 fuchsia::ui::views::ViewRef view_ref;
1458 auto status = zx::eventpair::create(
1459 0u, &view_ref_control.reference, &view_ref.reference);
1460 ASSERT_EQ(status, ZX_OK);
1461 view_ref_control.reference.replace(
1462 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
1463 &view_ref_control.reference);
1464 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
1465 view_ref.Clone(&view_ref_clone);
1470 std::move(view_creation_token),
1471 fuchsia::ui::views::ViewIdentityOnCreation{
1472 .view_ref = std::move(view_ref),
1473 .view_ref_control = std::move(view_ref_control),
1475 fuchsia::ui::composition::ViewBoundProtocols{},
1476 parent_viewport_watcher.NewRequest(), flatland_connection(),
1477 fake_surface_producer());
1478 flatland_connection()->Present();
1479 loop().RunUntilIdle();
1480 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1481 loop().RunUntilIdle();
1482 EXPECT_THAT(fake_flatland().graph(),
1483 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1487 const DlISize frame_size_signed = DlISize(512, 512);
1488 const fuchsia::math::SizeU frame_size{
1489 static_cast<uint32_t
>(frame_size_signed.width),
1490 static_cast<uint32_t
>(frame_size_signed.height)};
1492 external_view_embedder, frame_size_signed, 1.f,
1496 DlRect paint_region_1, paint_region_2;
1498 paint_region_1 = DlRect::MakeXYWH(
1499 canvas_size.width / 4.f, canvas_size.height / 2.f,
1500 3.f * canvas_size.width / 8.f, canvas_size.height / 4.f);
1504 canvas->
DrawRect(paint_region_1, rect_paint);
1506 paint_region_2 = DlRect::MakeXYWH(
1507 canvas_size.width * 3.f / 8.f, canvas_size.height / 2.f,
1508 3.f * canvas_size.width / 8.f, canvas_size.height / 4.f);
1511 canvas->
DrawRect(paint_region_2, rect_paint);
1513 EXPECT_THAT(fake_flatland().graph(),
1514 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1518 loop().RunUntilIdle();
1521 fake_flatland().graph(),
1523 parent_viewport_watcher, viewport_creation_token, view_ref_clone,
1526 frame_size, kFirstLayerBlendMode,
1533 fuchsia::ui::composition::HitTestInteraction::DEFAULT)})}));
1537 fuchsia::ui::composition::ParentViewportWatcherPtr parent_viewport_watcher;
1538 fuchsia::ui::views::ViewportCreationToken viewport_creation_token;
1539 fuchsia::ui::views::ViewCreationToken view_creation_token;
1540 fuchsia::ui::views::ViewRef view_ref_clone;
1541 auto view_creation_token_status = zx::channel::create(
1542 0u, &viewport_creation_token.value, &view_creation_token.value);
1543 ASSERT_EQ(view_creation_token_status, ZX_OK);
1545 fuchsia::ui::views::ViewRefControl view_ref_control;
1546 fuchsia::ui::views::ViewRef view_ref;
1547 auto status = zx::eventpair::create(
1548 0u, &view_ref_control.reference, &view_ref.reference);
1549 ASSERT_EQ(status, ZX_OK);
1550 view_ref_control.reference.replace(
1551 ZX_DEFAULT_EVENTPAIR_RIGHTS & (~ZX_RIGHT_DUPLICATE),
1552 &view_ref_control.reference);
1553 view_ref.reference.replace(ZX_RIGHTS_BASIC, &view_ref.reference);
1554 view_ref.Clone(&view_ref_clone);
1559 std::move(view_creation_token),
1560 fuchsia::ui::views::ViewIdentityOnCreation{
1561 .view_ref = std::move(view_ref),
1562 .view_ref_control = std::move(view_ref_control),
1564 fuchsia::ui::composition::ViewBoundProtocols{},
1565 parent_viewport_watcher.NewRequest(), flatland_connection(),
1566 fake_surface_producer(),
1569 flatland_connection()->Present();
1570 loop().RunUntilIdle();
1571 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1572 loop().RunUntilIdle();
1573 EXPECT_THAT(fake_flatland().graph(),
1574 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1575 view_ref_clone, {IsInputShield()}));
1578 const DlSize child_view_size_signed = DlSize(256.f, 512.f);
1579 const fuchsia::math::SizeU child_view_size{
1580 static_cast<uint32_t
>(child_view_size_signed.width),
1581 static_cast<uint32_t
>(child_view_size_signed.height)};
1583 const uint32_t child_view_id = child_viewport_token.value.get();
1585 const uint8_t kOpacity = 200u;
1586 const float kOpacityFloat = DlColor::toOpacity(kOpacity);
1587 const fuchsia::math::VecF kScale{3.0f, 4.0f};
1589 DlMatrix matrix = DlMatrix::MakeScale({kScale.x, kScale.y, 1});
1592 mutators_stack.PushOpacity(kOpacity);
1593 mutators_stack.PushTransform(matrix);
1597 external_view_embedder.CreateView(
1598 child_view_id, []() {},
1599 [](fuchsia::ui::composition::ContentId,
1600 fuchsia::ui::composition::ChildViewWatcherHandle) {});
1601 const SkRect child_view_occlusion_hint = SkRect::MakeLTRB(1, 2, 3, 4);
1602 const fuchsia::math::Inset child_view_inset{
1603 static_cast<int32_t
>(child_view_occlusion_hint.top()),
1604 static_cast<int32_t
>(child_view_occlusion_hint.right()),
1605 static_cast<int32_t
>(child_view_occlusion_hint.bottom()),
1606 static_cast<int32_t
>(child_view_occlusion_hint.left())};
1607 external_view_embedder.SetViewProperties(
1608 child_view_id, child_view_occlusion_hint,
false,
1612 const float kDPR = 2.0f;
1613 const float kInvDPR = 1.f / kDPR;
1616 const DlISize frame_size_signed = DlISize(512, 512);
1617 const fuchsia::math::SizeU frame_size{
1618 static_cast<uint32_t
>(frame_size_signed.width),
1619 static_cast<uint32_t
>(frame_size_signed.height)};
1621 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1624 canvas->Translate(canvas_size.width / 4.f, canvas_size.height / 2.f);
1625 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1628 const DlSize canvas_size(canvas->GetBaseLayerDimensions());
1631 canvas->Translate(canvas_size.width * 3.f / 4.f, canvas_size.height / 2.f);
1632 canvas->DrawRect(DlRect::MakeSize(canvas_size / 32.f), rect_paint);
1634 DrawFrameWithView(external_view_embedder, frame_size_signed, kDPR,
1635 child_view_id, child_view_params, background_draw_callback,
1636 overlay_draw_callback);
1637 EXPECT_THAT(fake_flatland().graph(),
1638 IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
1639 view_ref_clone, {IsInputShield()}));
1642 loop().RunUntilIdle();
1643 fake_flatland().FireOnNextFrameBeginEvent(WithPresentCredits(1u));
1644 loop().RunUntilIdle();
1647 fake_flatland().graph(),
1649 parent_viewport_watcher, viewport_creation_token,
1652 frame_size, kFirstLayerBlendMode,
1659 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
1660 IsViewportLayer(child_view_token, child_view_size, child_view_inset,
1661 {0, 0}, kScale, kOpacityFloat),
1663 frame_size, kUpperLayerBlendMode,
1670 fuchsia::ui::composition::HitTestInteraction::DEFAULT)}),
1672 {kInvDPR, kInvDPR}));
Developer-facing API for rendering anything within the engine.
virtual DlISize GetBaseLayerDimensions() const =0
virtual void DrawRect(const DlRect &rect, const DlPaint &paint)=0
virtual void Translate(DlScalar tx, DlScalar ty)=0
DlPaint & setColor(DlColor color)
~ExternalViewEmbedderTest() override=default
std::shared_ptr< FlatlandConnection > flatland_connection()
FakeFlatland & fake_flatland()
std::shared_ptr< FakeSurfaceProducer > fake_surface_producer()
ExternalViewEmbedderTest()
fuchsia::ui::composition::FlatlandHandle ConnectFlatland(async_dispatcher_t *dispatcher=nullptr)
fuchsia::ui::composition::AllocatorHandle ConnectAllocator(async_dispatcher_t *dispatcher=nullptr)
bool is_allocator_connected() const
bool is_flatland_connected() const
G_BEGIN_DECLS FlutterViewId view_id
#define FML_LOG(severity)
#define FML_CHECK(condition)
fuchsia::ui::composition::AllocatorPtr flatland_allocator_
static constexpr FlutterViewId kImplicitViewId
bool Contains(const Container &container, const Value &value)
std::pair< zx_koid_t, zx_koid_t > GetKoids(const ZX &kobj)
TEST_F(FocusDelegateTest, WatchCallbackSeries)
static constexpr fuchsia::ui::composition::HitRegion kInfiniteHitRegion
std::function< void()> ReleaseImageCallback
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
static constexpr DlColor kRed()
static constexpr DlColor kGreen()
static BufferCollectionTokenPair New()
static constexpr fuchsia::math::RectF kDefaultSampleRegion
static constexpr float kDefaultOpacity
static constexpr fuchsia::math::Inset kDefaultViewportInset
static ViewTokenPair New()
A 4x4 matrix using column-major storage.