Skip to content

Commit 31abc8f

Browse files
authored
[fuchsia] Set blending mode on flatland images (#30890)
1 parent 5d39fbc commit 31abc8f

File tree

6 files changed

+67
-14
lines changed

6 files changed

+67
-14
lines changed

shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,14 @@ void FlatlandExternalViewEmbedder::SubmitFrame(
258258
{static_cast<uint32_t>(surface_for_layer->GetSize().width()),
259259
static_cast<uint32_t>(surface_for_layer->GetSize().height())});
260260

261+
// Flutter Embedder lacks an API to detect if a layer has alpha or not.
262+
// For now, we assume any layer beyond the first has alpha.
263+
flatland_->flatland()->SetImageBlendingFunction(
264+
{surface_for_layer->GetImageId()},
265+
flatland_layer_index == 0
266+
? fuchsia::ui::composition::BlendMode::SRC
267+
: fuchsia::ui::composition::BlendMode::SRC_OVER);
268+
261269
// Attach the FlatlandLayer to the main scene graph.
262270
flatland_->flatland()->AddChild(
263271
root_transform_id_,
@@ -267,7 +275,6 @@ void FlatlandExternalViewEmbedder::SubmitFrame(
267275
}
268276

269277
// Reset for the next pass:
270-
// +The next layer will not be the first layer.
271278
flatland_layer_index++;
272279
}
273280
}

shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_flatland.cc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,37 @@ void FakeFlatland::SetImageDestinationSize(
621621
image->destination_size = size;
622622
}
623623

624+
void FakeFlatland::SetImageBlendingFunction(
625+
fuchsia::ui::composition::ContentId image_id,
626+
fuchsia::ui::composition::BlendMode blend_mode) {
627+
if (image_id.value == 0) {
628+
// TODO(fxb/85619): Raise a FlatlandError here
629+
FML_CHECK(false)
630+
<< "FakeFlatland::SetImageDestinationSize: ContentId 0 is invalid.";
631+
return;
632+
}
633+
634+
auto found_content = pending_graph_.content_map.find(image_id.value);
635+
if (found_content == pending_graph_.content_map.end()) {
636+
// TODO(fxb/85619): Raise a FlatlandError here
637+
FML_CHECK(false) << "FakeFlatland::SetImageDestinationSize: ContentId "
638+
<< image_id.value << " does not exist.";
639+
return;
640+
}
641+
642+
auto& content = found_content->second;
643+
FML_CHECK(content);
644+
FakeImage* image = std::get_if<FakeImage>(content.get());
645+
if (image == nullptr) {
646+
// TODO(fxb/85619): Raise a FlatlandError here
647+
FML_CHECK(false) << "FakeFlatland::SetImageDestinationSize: ContentId "
648+
<< image_id.value << " is not an Image.";
649+
return;
650+
}
651+
652+
image->blend_mode = blend_mode;
653+
}
654+
624655
void FakeFlatland::SetViewportProperties(
625656
fuchsia::ui::composition::ContentId viewport_id,
626657
fuchsia::ui::composition::ViewportProperties properties) {

shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_flatland.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ class FakeFlatland
276276
void SetImageDestinationSize(fuchsia::ui::composition::ContentId image_id,
277277
fuchsia::math::SizeU size) override;
278278

279+
// |fuchsia::ui::composition::Flatland|
280+
void SetImageBlendingFunction(
281+
fuchsia::ui::composition::ContentId image_id,
282+
fuchsia::ui::composition::BlendMode blend_mode) override;
283+
279284
// |fuchsia::ui::composition::Flatland|
280285
void SetViewportProperties(
281286
fuchsia::ui::composition::ContentId viewport_id,

shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_flatland_types.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ std::shared_ptr<FakeContent> CloneFakeContent(
4040
.sample_region = image->sample_region,
4141
.destination_size = image->destination_size,
4242
.opacity = image->opacity,
43+
.blend_mode = image->blend_mode,
4344
.import_token = image->import_token,
4445
.vmo_index = image->vmo_index,
4546
});
@@ -124,8 +125,8 @@ bool FakeImage::operator==(const FakeImage& other) const {
124125
return id == other.id && image_properties == other.image_properties &&
125126
sample_region == other.sample_region &&
126127
destination_size == other.destination_size &&
127-
opacity == other.opacity && import_token == other.import_token &&
128-
vmo_index == other.vmo_index;
128+
opacity == other.opacity && blend_mode == other.blend_mode &&
129+
import_token == other.import_token && vmo_index == other.vmo_index;
129130
}
130131

131132
bool FakeTransform::operator==(const FakeTransform& other) const {

shell/platform/fuchsia/flutter/tests/fakes/scenic/fake_flatland_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,16 @@ struct FakeImage {
144144
constexpr static fuchsia::math::RectF kDefaultSampleRegion{};
145145
constexpr static fuchsia::math::SizeU kDefaultDestinationSize{};
146146
constexpr static float kDefaultOpacity{1.f};
147+
constexpr static fuchsia::ui::composition::BlendMode kDefaultBlendMode{
148+
fuchsia::ui::composition::BlendMode::SRC_OVER};
147149

148150
fuchsia::ui::composition::ContentId id{kInvalidContentId};
149151

150152
fuchsia::ui::composition::ImageProperties image_properties{};
151153
fuchsia::math::RectF sample_region{kDefaultSampleRegion};
152154
fuchsia::math::SizeU destination_size{kDefaultDestinationSize};
153155
float opacity{kDefaultOpacity};
156+
fuchsia::ui::composition::BlendMode blend_mode{kDefaultBlendMode};
154157

155158
zx_koid_t import_token{};
156159
uint32_t vmo_index{0};

shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ using ::testing::VariantWith;
5151
namespace flutter_runner::testing {
5252
namespace {
5353

54+
constexpr static fuchsia::ui::composition::BlendMode kFirstLayerBlendMode{
55+
fuchsia::ui::composition::BlendMode::SRC};
56+
constexpr static fuchsia::ui::composition::BlendMode kUpperLayerBlendMode{
57+
fuchsia::ui::composition::BlendMode::SRC_OVER};
58+
5459
class FakeSurfaceProducerSurface : public SurfaceProducerSurface {
5560
public:
5661
explicit FakeSurfaceProducerSurface(
@@ -226,7 +231,8 @@ Matcher<FakeGraph> IsFlutterGraph(
226231
}
227232

228233
Matcher<std::shared_ptr<FakeTransform>> IsImageLayer(
229-
const fuchsia::math::SizeU& layer_size) {
234+
const fuchsia::math::SizeU& layer_size,
235+
fuchsia::ui::composition::BlendMode blend_mode) {
230236
return Pointee(FieldsAre(
231237
/*id*/ _, FakeTransform::kDefaultTranslation,
232238
FakeTransform::kDefaultClipBounds, FakeTransform::kDefaultOrientation,
@@ -235,7 +241,7 @@ Matcher<std::shared_ptr<FakeTransform>> IsImageLayer(
235241
Pointee(VariantWith<FakeImage>(FieldsAre(
236242
/*id*/ _, IsImageProperties(layer_size),
237243
FakeImage::kDefaultSampleRegion, layer_size,
238-
FakeImage::kDefaultOpacity,
244+
FakeImage::kDefaultOpacity, blend_mode,
239245
/*buffer_import_token*/ _, /*vmo_index*/ 0)))));
240246
}
241247

@@ -454,13 +460,13 @@ TEST_F(FlatlandExternalViewEmbedderTest, SimpleScene) {
454460
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
455461
view_ref));
456462

457-
// Pump the message loop. The scene updates should propagate to flatland.
463+
// Pump the message loop. The scene updates should propagate to flatland.
458464
loop().RunUntilIdle();
459465
EXPECT_THAT(
460466
fake_flatland().graph(),
461467
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token, view_ref,
462468
/*layers*/
463-
{IsImageLayer(frame_size)}));
469+
{IsImageLayer(frame_size, kFirstLayerBlendMode)}));
464470
}
465471

466472
TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
@@ -549,9 +555,9 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
549555
fake_flatland().graph(),
550556
IsFlutterGraph(
551557
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
552-
{IsImageLayer(frame_size),
558+
{IsImageLayer(frame_size, kFirstLayerBlendMode),
553559
IsViewportLayer(child_view_token, child_view_size, {0, 0}),
554-
IsImageLayer(frame_size)}));
560+
IsImageLayer(frame_size, kUpperLayerBlendMode)}));
555561

556562
// Destroy the view. The scene graph shouldn't change yet.
557563
external_view_embedder.DestroyView(
@@ -560,9 +566,9 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
560566
fake_flatland().graph(),
561567
IsFlutterGraph(
562568
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
563-
{IsImageLayer(frame_size),
569+
{IsImageLayer(frame_size, kFirstLayerBlendMode),
564570
IsViewportLayer(child_view_token, child_view_size, {0, 0}),
565-
IsImageLayer(frame_size)}));
571+
IsImageLayer(frame_size, kUpperLayerBlendMode)}));
566572

567573
// Draw another frame without the view. The scene graph shouldn't change yet.
568574
DrawSimpleFrame(
@@ -581,16 +587,16 @@ TEST_F(FlatlandExternalViewEmbedderTest, SceneWithOneView) {
581587
fake_flatland().graph(),
582588
IsFlutterGraph(
583589
parent_viewport_watcher, viewport_creation_token, view_ref, /*layers*/
584-
{IsImageLayer(frame_size),
590+
{IsImageLayer(frame_size, kFirstLayerBlendMode),
585591
IsViewportLayer(child_view_token, child_view_size, {0, 0}),
586-
IsImageLayer(frame_size)}));
592+
IsImageLayer(frame_size, kUpperLayerBlendMode)}));
587593

588594
// Pump the message loop. The scene updates should propagate to flatland.
589595
loop().RunUntilIdle();
590596
EXPECT_THAT(fake_flatland().graph(),
591597
IsFlutterGraph(parent_viewport_watcher, viewport_creation_token,
592598
view_ref, /*layers*/
593-
{IsImageLayer(frame_size)}));
599+
{IsImageLayer(frame_size, kFirstLayerBlendMode)}));
594600
}
595601

596602
} // namespace flutter_runner::testing

0 commit comments

Comments
 (0)