[fuchsia] Use the newly added viewinset field (flutter/engine#35974)

This commit is contained in:
Emircan Uysaler 2022-09-14 16:45:59 -04:00 committed by GitHub
parent 94f887388f
commit b0c1e2aca2
4 changed files with 85 additions and 40 deletions

View File

@ -203,8 +203,10 @@ void FlatlandExternalViewEmbedder::SubmitFrame(
if (viewport.pending_create_viewport_callback) {
if (view_size.fWidth && view_size.fHeight) {
viewport.pending_create_viewport_callback(view_size);
viewport.pending_create_viewport_callback(
view_size, viewport.pending_occlusion_hint);
viewport.size = view_size;
viewport.occlusion_hint = viewport.pending_occlusion_hint;
} else {
FML_DLOG(WARNING)
<< "Failed to create viewport because width or height is zero.";
@ -226,16 +228,22 @@ void FlatlandExternalViewEmbedder::SubmitFrame(
// TODO(fxbug.dev/94000): Set HitTestBehavior.
// TODO(fxbug.dev/94000): Set opacity.
// Set size
// TODO(): Set occlusion hint, and focusable.
if (view_size != viewport.size) {
// Set size and occlusion hint.
if (view_size != viewport.size ||
viewport.pending_occlusion_hint != viewport.occlusion_hint) {
fuchsia::ui::composition::ViewportProperties properties;
properties.set_logical_size(
{static_cast<uint32_t>(view_size.fWidth),
static_cast<uint32_t>(view_size.fHeight)});
properties.set_inset(
{static_cast<int32_t>(viewport.pending_occlusion_hint.fTop),
static_cast<int32_t>(viewport.pending_occlusion_hint.fRight),
static_cast<int32_t>(viewport.pending_occlusion_hint.fBottom),
static_cast<int32_t>(viewport.pending_occlusion_hint.fLeft)});
flatland_->flatland()->SetViewportProperties(viewport.viewport_id,
std::move(properties));
viewport.size = view_size;
viewport.occlusion_hint = viewport.pending_occlusion_hint;
}
// Attach the FlatlandView to the main scene graph.
@ -374,11 +382,15 @@ void FlatlandExternalViewEmbedder::CreateView(
fuchsia::ui::composition::ChildViewWatcherHandle child_view_watcher;
new_view.pending_create_viewport_callback =
[this, transform_id, viewport_id, view_id,
child_view_watcher_request =
child_view_watcher.NewRequest()](const SkSize& size) mutable {
child_view_watcher_request = child_view_watcher.NewRequest()](
const SkSize& size, const SkRect& inset) mutable {
fuchsia::ui::composition::ViewportProperties properties;
properties.set_logical_size({static_cast<uint32_t>(size.fWidth),
static_cast<uint32_t>(size.fHeight)});
properties.set_inset({static_cast<int32_t>(inset.fTop),
static_cast<int32_t>(inset.fRight),
static_cast<int32_t>(inset.fBottom),
static_cast<int32_t>(inset.fLeft)});
flatland_->flatland()->CreateViewport(
viewport_id, {zx::channel((zx_handle_t)view_id)},
std::move(properties), std::move(child_view_watcher_request));
@ -424,8 +436,10 @@ void FlatlandExternalViewEmbedder::SetViewProperties(
auto found = flatland_views_.find(view_id);
FML_CHECK(found != flatland_views_.end());
// TODO(fxbug.dev/94000): Set occlusion_hint, hit_testable and focusable. Note
// that pending_create_viewport_callback might not have run at this point.
// Note that pending_create_viewport_callback might not have run at this
// point.
auto& viewport = found->second;
viewport.pending_occlusion_hint = occlusion_hint;
}
void FlatlandExternalViewEmbedder::Reset() {

View File

@ -165,7 +165,10 @@ class FlatlandExternalViewEmbedder final
fuchsia::ui::composition::ContentId viewport_id;
ViewMutators mutators;
SkSize size = SkSize::MakeEmpty();
fit::callback<void(const SkSize&)> pending_create_viewport_callback;
SkRect pending_occlusion_hint = SkRect::MakeEmpty();
SkRect occlusion_hint = SkRect::MakeEmpty();
fit::callback<void(const SkSize&, const SkRect&)>
pending_create_viewport_callback;
};
struct FlatlandLayer {

View File

@ -28,6 +28,12 @@ inline bool operator==(const fuchsia::math::SizeU& a,
return a.width == b.width && a.height == b.height;
}
inline bool operator==(const fuchsia::math::Inset& a,
const fuchsia::math::Inset& b) {
return a.top == b.top && a.left == b.left && a.right == b.right &&
a.bottom == b.bottom;
}
inline bool operator==(const fuchsia::math::Vec& a,
const fuchsia::math::Vec& b) {
return a.x == b.x && a.y == b.y;
@ -129,6 +135,7 @@ struct FakeViewport {
bool operator==(const FakeViewport& other) const;
constexpr static fuchsia::math::SizeU kDefaultViewportLogicalSize{};
constexpr static fuchsia::math::Inset kDefaultViewportInset{};
fuchsia::ui::composition::ContentId id{kInvalidContentId};

View File

@ -187,14 +187,19 @@ Matcher<fuchsia::ui::composition::ImageProperties> IsImageProperties(
}
Matcher<fuchsia::ui::composition::ViewportProperties> IsViewportProperties(
const fuchsia::math::SizeU& logical_size) {
const fuchsia::math::SizeU& logical_size,
const fuchsia::math::Inset& inset) {
return AllOf(
Property("has_logical_size",
&fuchsia::ui::composition::ViewportProperties::has_logical_size,
true),
Property("logical_size",
&fuchsia::ui::composition::ViewportProperties::logical_size,
logical_size));
logical_size),
Property("has_inset",
&fuchsia::ui::composition::ViewportProperties::has_inset, true),
Property("inset", &fuchsia::ui::composition::ViewportProperties::inset,
inset));
}
Matcher<FakeGraph> IsEmptyGraph() {
@ -250,17 +255,18 @@ Matcher<std::shared_ptr<FakeTransform>> IsImageLayer(
Matcher<std::shared_ptr<FakeTransform>> IsViewportLayer(
const fuchsia::ui::views::ViewCreationToken& view_token,
const fuchsia::math::SizeU& view_logical_size,
const fuchsia::math::Inset& view_inset,
const fuchsia::math::Vec& view_transform) {
return Pointee(
FieldsAre(/* id */ _, view_transform,
/*clip_bounds*/ _, FakeTransform::kDefaultOrientation,
/*children*/ IsEmpty(),
/*content*/
Pointee(VariantWith<FakeViewport>(FieldsAre(
/* id */ _, IsViewportProperties(view_logical_size),
/* viewport_token */ GetKoids(view_token).second,
/* child_view_watcher */ _))),
/*num_hit_regions*/ 0));
return Pointee(FieldsAre(
/* id */ _, view_transform,
/*clip_bounds*/ _, FakeTransform::kDefaultOrientation,
/*children*/ IsEmpty(),
/*content*/
Pointee(VariantWith<FakeViewport>(FieldsAre(
/* id */ _, IsViewportProperties(view_logical_size, view_inset),
/* viewport_token */ GetKoids(view_token).second,
/* child_view_watcher */ _))),
/*num_hit_regions*/ 0));
}
fuchsia::ui::composition::OnNextFrameBeginValues WithPresentCredits(
@ -517,8 +523,17 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
child_view_id, []() {},
[](fuchsia::ui::composition::ContentId,
fuchsia::ui::composition::ChildViewWatcherHandle) {});
const SkRect child_view_occlusion_hint = SkRect::MakeLTRB(1, 2, 3, 4);
const fuchsia::math::Inset child_view_inset{
static_cast<int32_t>(child_view_occlusion_hint.top()),
static_cast<int32_t>(child_view_occlusion_hint.right()),
static_cast<int32_t>(child_view_occlusion_hint.bottom()),
static_cast<int32_t>(child_view_occlusion_hint.left())};
external_view_embedder.SetViewProperties(
child_view_id, child_view_occlusion_hint, /*hit_testable=*/false,
/*focusable=*/false);
// Draw the scene. The scene graph shouldn't change yet.
// Draw the scene. The scene graph shouldn't change yet.
const SkISize frame_size_signed = SkISize::Make(512, 512);
const fuchsia::math::SizeU frame_size{
static_cast<uint32_t>(frame_size_signed.width()),
@ -558,22 +573,24 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
loop().RunUntilIdle();
EXPECT_THAT(
fake_flatland().graph(),
IsFlutterGraph(
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
IsViewportLayer(child_view_token, child_view_size, {0, 0}),
IsImageLayer(frame_size, kUpperLayerBlendMode, 1)}));
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
view_ref, /*layers*/
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
IsViewportLayer(child_view_token, child_view_size,
child_view_inset, {0, 0}),
IsImageLayer(frame_size, kUpperLayerBlendMode, 1)}));
// Destroy the view. The scene graph shouldn't change yet.
external_view_embedder.DestroyView(
child_view_id, [](fuchsia::ui::composition::ContentId) {});
EXPECT_THAT(
fake_flatland().graph(),
IsFlutterGraph(
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
IsViewportLayer(child_view_token, child_view_size, {0, 0}),
IsImageLayer(frame_size, kUpperLayerBlendMode, 1)}));
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
view_ref, /*layers*/
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
IsViewportLayer(child_view_token, child_view_size,
child_view_inset, {0, 0}),
IsImageLayer(frame_size, kUpperLayerBlendMode, 1)}));
// Draw another frame without the view. The scene graph shouldn't change yet.
DrawSimpleFrame(
@ -590,11 +607,12 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
});
EXPECT_THAT(
fake_flatland().graph(),
IsFlutterGraph(
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
IsViewportLayer(child_view_token, child_view_size, {0, 0}),
IsImageLayer(frame_size, kUpperLayerBlendMode, 1)}));
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
view_ref, /*layers*/
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
IsViewportLayer(child_view_token, child_view_size,
child_view_inset, {0, 0}),
IsImageLayer(frame_size, kUpperLayerBlendMode, 1)}));
// Pump the message loop. The scene updates should propagate to flatland.
loop().RunUntilIdle();
@ -682,7 +700,8 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView_NoOverlay) {
IsFlutterGraph(
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
IsViewportLayer(child_view_token, child_view_size, {0, 0})}));
IsViewportLayer(child_view_token, child_view_size,
FakeViewport::kDefaultViewportInset, {0, 0})}));
// Destroy the view. The scene graph shouldn't change yet.
external_view_embedder.DestroyView(
@ -692,7 +711,8 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView_NoOverlay) {
IsFlutterGraph(
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
IsViewportLayer(child_view_token, child_view_size, {0, 0})}));
IsViewportLayer(child_view_token, child_view_size,
FakeViewport::kDefaultViewportInset, {0, 0})}));
// Draw another frame without the view. The scene graph shouldn't change yet.
DrawSimpleFrame(
@ -712,7 +732,8 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView_NoOverlay) {
IsFlutterGraph(
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
{IsImageLayer(frame_size, kFirstLayerBlendMode, 1),
IsViewportLayer(child_view_token, child_view_size, {0, 0})}));
IsViewportLayer(child_view_token, child_view_size,
FakeViewport::kDefaultViewportInset, {0, 0})}));
// Pump the message loop. The scene updates should propagate to flatland.
loop().RunUntilIdle();