Skip to content

Commit 716bb91

Browse files
authored
[Impeller Scene] Add DisplayList OP and Dart bindings (flutter#38676)
1 parent 4f0cdcd commit 716bb91

29 files changed

+810
-88
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,7 +1703,8 @@ ORIGIN: ../../../flutter/lib/ui/dart_runtime_hooks.h + ../../../flutter/LICENSE
17031703
ORIGIN: ../../../flutter/lib/ui/dart_ui.cc + ../../../flutter/LICENSE
17041704
ORIGIN: ../../../flutter/lib/ui/dart_ui.h + ../../../flutter/LICENSE
17051705
ORIGIN: ../../../flutter/lib/ui/dart_wrapper.h + ../../../flutter/LICENSE
1706-
ORIGIN: ../../../flutter/lib/ui/experiments/compositing_3d.dart + ../../../flutter/LICENSE
1706+
ORIGIN: ../../../flutter/lib/ui/experiments/scene.dart + ../../../flutter/LICENSE
1707+
ORIGIN: ../../../flutter/lib/ui/experiments/setup_hooks.dart + ../../../flutter/LICENSE
17071708
ORIGIN: ../../../flutter/lib/ui/experiments/ui.dart + ../../../flutter/LICENSE
17081709
ORIGIN: ../../../flutter/lib/ui/geometry.dart + ../../../flutter/LICENSE
17091710
ORIGIN: ../../../flutter/lib/ui/hash_codes.dart + ../../../flutter/LICENSE
@@ -1783,6 +1784,10 @@ ORIGIN: ../../../flutter/lib/ui/painting/picture_recorder.cc + ../../../flutter/
17831784
ORIGIN: ../../../flutter/lib/ui/painting/picture_recorder.h + ../../../flutter/LICENSE
17841785
ORIGIN: ../../../flutter/lib/ui/painting/rrect.cc + ../../../flutter/LICENSE
17851786
ORIGIN: ../../../flutter/lib/ui/painting/rrect.h + ../../../flutter/LICENSE
1787+
ORIGIN: ../../../flutter/lib/ui/painting/scene/scene_node.cc + ../../../flutter/LICENSE
1788+
ORIGIN: ../../../flutter/lib/ui/painting/scene/scene_node.h + ../../../flutter/LICENSE
1789+
ORIGIN: ../../../flutter/lib/ui/painting/scene/scene_shader.cc + ../../../flutter/LICENSE
1790+
ORIGIN: ../../../flutter/lib/ui/painting/scene/scene_shader.h + ../../../flutter/LICENSE
17861791
ORIGIN: ../../../flutter/lib/ui/painting/shader.cc + ../../../flutter/LICENSE
17871792
ORIGIN: ../../../flutter/lib/ui/painting/shader.h + ../../../flutter/LICENSE
17881793
ORIGIN: ../../../flutter/lib/ui/painting/single_frame_codec.cc + ../../../flutter/LICENSE
@@ -1805,6 +1810,7 @@ ORIGIN: ../../../flutter/lib/ui/semantics/semantics_update_builder.cc + ../../..
18051810
ORIGIN: ../../../flutter/lib/ui/semantics/semantics_update_builder.h + ../../../flutter/LICENSE
18061811
ORIGIN: ../../../flutter/lib/ui/semantics/string_attribute.cc + ../../../flutter/LICENSE
18071812
ORIGIN: ../../../flutter/lib/ui/semantics/string_attribute.h + ../../../flutter/LICENSE
1813+
ORIGIN: ../../../flutter/lib/ui/setup_hooks.dart + ../../../flutter/LICENSE
18081814
ORIGIN: ../../../flutter/lib/ui/snapshot_delegate.h + ../../../flutter/LICENSE
18091815
ORIGIN: ../../../flutter/lib/ui/text.dart + ../../../flutter/LICENSE
18101816
ORIGIN: ../../../flutter/lib/ui/text/asset_manager_font_provider.cc + ../../../flutter/LICENSE
@@ -4178,7 +4184,8 @@ FILE: ../../../flutter/lib/ui/dart_runtime_hooks.h
41784184
FILE: ../../../flutter/lib/ui/dart_ui.cc
41794185
FILE: ../../../flutter/lib/ui/dart_ui.h
41804186
FILE: ../../../flutter/lib/ui/dart_wrapper.h
4181-
FILE: ../../../flutter/lib/ui/experiments/compositing_3d.dart
4187+
FILE: ../../../flutter/lib/ui/experiments/scene.dart
4188+
FILE: ../../../flutter/lib/ui/experiments/setup_hooks.dart
41824189
FILE: ../../../flutter/lib/ui/experiments/ui.dart
41834190
FILE: ../../../flutter/lib/ui/geometry.dart
41844191
FILE: ../../../flutter/lib/ui/hash_codes.dart
@@ -4258,6 +4265,10 @@ FILE: ../../../flutter/lib/ui/painting/picture_recorder.cc
42584265
FILE: ../../../flutter/lib/ui/painting/picture_recorder.h
42594266
FILE: ../../../flutter/lib/ui/painting/rrect.cc
42604267
FILE: ../../../flutter/lib/ui/painting/rrect.h
4268+
FILE: ../../../flutter/lib/ui/painting/scene/scene_node.cc
4269+
FILE: ../../../flutter/lib/ui/painting/scene/scene_node.h
4270+
FILE: ../../../flutter/lib/ui/painting/scene/scene_shader.cc
4271+
FILE: ../../../flutter/lib/ui/painting/scene/scene_shader.h
42614272
FILE: ../../../flutter/lib/ui/painting/shader.cc
42624273
FILE: ../../../flutter/lib/ui/painting/shader.h
42634274
FILE: ../../../flutter/lib/ui/painting/single_frame_codec.cc
@@ -4280,6 +4291,7 @@ FILE: ../../../flutter/lib/ui/semantics/semantics_update_builder.cc
42804291
FILE: ../../../flutter/lib/ui/semantics/semantics_update_builder.h
42814292
FILE: ../../../flutter/lib/ui/semantics/string_attribute.cc
42824293
FILE: ../../../flutter/lib/ui/semantics/string_attribute.h
4294+
FILE: ../../../flutter/lib/ui/setup_hooks.dart
42834295
FILE: ../../../flutter/lib/ui/snapshot_delegate.h
42844296
FILE: ../../../flutter/lib/ui/text.dart
42854297
FILE: ../../../flutter/lib/ui/text/asset_manager_font_provider.cc

display_list/BUILD.gn

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ source_set("display_list") {
7171
"//flutter/impeller/runtime_stage",
7272
"//third_party/skia",
7373
]
74+
75+
if (!defined(defines)) {
76+
defines = []
77+
}
78+
if (impeller_enable_3d) {
79+
defines += [ "IMPELLER_ENABLE_3D" ]
80+
public_deps += [ "//flutter/impeller/scene" ]
81+
}
7482
}
7583

7684
if (enable_unittests) {

display_list/display_list.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ void DisplayList::Dispatch(Dispatcher& dispatcher,
184184
break;
185185

186186
FOR_EACH_DISPLAY_LIST_OP(DL_OP_DISPATCH)
187+
#ifdef IMPELLER_ENABLE_3D
188+
DL_OP_DISPATCH(SetSceneColorSource)
189+
#endif // IMPELLER_ENABLE_3D
187190

188191
#undef DL_OP_DISPATCH
189192

@@ -209,6 +212,9 @@ void DisplayList::DisposeOps(uint8_t* ptr, uint8_t* end) {
209212
break;
210213

211214
FOR_EACH_DISPLAY_LIST_OP(DL_OP_DISPOSE)
215+
#ifdef IMPELLER_ENABLE_3D
216+
DL_OP_DISPOSE(SetSceneColorSource)
217+
#endif // IMPELLER_ENABLE_3D
212218

213219
#undef DL_OP_DISPOSE
214220

@@ -247,6 +253,9 @@ static bool CompareOps(uint8_t* ptrA,
247253
break;
248254

249255
FOR_EACH_DISPLAY_LIST_OP(DL_OP_EQUALS)
256+
#ifdef IMPELLER_ENABLE_3D
257+
DL_OP_EQUALS(SetSceneColorSource)
258+
#endif // IMPELLER_ENABLE_3D
250259

251260
#undef DL_OP_EQUALS
252261

display_list/display_list.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,12 @@ namespace flutter {
159159
V(DrawShadowTransparentOccluder)
160160

161161
#define DL_OP_TO_ENUM_VALUE(name) k##name,
162-
enum class DisplayListOpType { FOR_EACH_DISPLAY_LIST_OP(DL_OP_TO_ENUM_VALUE) };
162+
enum class DisplayListOpType {
163+
FOR_EACH_DISPLAY_LIST_OP(DL_OP_TO_ENUM_VALUE)
164+
#ifdef IMPELLER_ENABLE_3D
165+
DL_OP_TO_ENUM_VALUE(SetSceneColorSource)
166+
#endif // IMPELLER_ENABLE_3D
167+
};
163168
#undef DL_OP_TO_ENUM_VALUE
164169

165170
class Dispatcher;

display_list/display_list_builder.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "flutter/display_list/display_list_canvas_dispatcher.h"
1010
#include "flutter/display_list/display_list_color_source.h"
1111
#include "flutter/display_list/display_list_ops.h"
12+
#include "fml/logging.h"
1213

1314
namespace flutter {
1415

@@ -206,6 +207,14 @@ void DisplayListBuilder::onSetColorSource(const DlColorSource* source) {
206207
Push<SetRuntimeEffectColorSourceOp>(0, 0, effect);
207208
break;
208209
}
210+
#ifdef IMPELLER_ENABLE_3D
211+
case DlColorSourceType::kScene: {
212+
const DlSceneColorSource* scene = source->asScene();
213+
FML_DCHECK(scene);
214+
Push<SetSceneColorSourceOp>(0, 0, scene);
215+
break;
216+
}
217+
#endif // IMPELLER_ENABLE_3D
209218
case DlColorSourceType::kUnknown:
210219
Push<SetSkColorSourceOp>(0, 0, source->skia_object());
211220
break;

display_list/display_list_color_source.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222
#include "third_party/skia/include/effects/SkGradientShader.h"
2323
#include "third_party/skia/include/effects/SkRuntimeEffect.h"
2424

25+
#ifdef IMPELLER_ENABLE_3D
26+
#include "impeller/geometry/matrix.h" // nogncheck
27+
#include "impeller/scene/node.h" // nogncheck
28+
namespace flutter {
29+
class DlSceneColorSource;
30+
}
31+
#endif // IMPELLER_ENABLE_3D
32+
2533
namespace flutter {
2634

2735
class DlColorColorSource;
@@ -51,6 +59,9 @@ enum class DlColorSourceType {
5159
kConicalGradient,
5260
kSweepGradient,
5361
kRuntimeEffect,
62+
#ifdef IMPELLER_ENABLE_3D
63+
kScene,
64+
#endif // IMPELLER_ENABLE_3D
5465
kUnknown
5566
};
5667

@@ -160,6 +171,10 @@ class DlColorSource
160171
return nullptr;
161172
}
162173

174+
#ifdef IMPELLER_ENABLE_3D
175+
virtual const DlSceneColorSource* asScene() const { return nullptr; }
176+
#endif // IMPELLER_ENABLE_3D
177+
163178
// If this filter contains images, specifies the owning context for those
164179
// images.
165180
// Images with a DlImage::OwningContext::kRaster must only call skia_object
@@ -754,6 +769,48 @@ class DlRuntimeEffectColorSource final : public DlColorSource {
754769
FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlRuntimeEffectColorSource);
755770
};
756771

772+
#ifdef IMPELLER_ENABLE_3D
773+
class DlSceneColorSource final : public DlColorSource {
774+
public:
775+
DlSceneColorSource(std::shared_ptr<impeller::scene::Node> node,
776+
impeller::Matrix camera_matrix)
777+
: node_(std::move(node)), camera_matrix_(camera_matrix) {}
778+
779+
const DlSceneColorSource* asScene() const override { return this; }
780+
781+
std::shared_ptr<DlColorSource> shared() const override {
782+
return std::make_shared<DlSceneColorSource>(node_, camera_matrix_);
783+
}
784+
785+
DlColorSourceType type() const override { return DlColorSourceType::kScene; }
786+
size_t size() const override { return sizeof(*this); }
787+
788+
bool is_opaque() const override { return false; }
789+
790+
std::shared_ptr<impeller::scene::Node> scene_node() const { return node_; }
791+
792+
impeller::Matrix camera_matrix() const { return camera_matrix_; }
793+
794+
sk_sp<SkShader> skia_object() const override { return nullptr; }
795+
796+
protected:
797+
bool equals_(DlColorSource const& other) const override {
798+
FML_DCHECK(other.type() == DlColorSourceType::kScene);
799+
auto that = static_cast<DlSceneColorSource const*>(&other);
800+
if (node_ != that->node_) {
801+
return false;
802+
}
803+
return true;
804+
}
805+
806+
private:
807+
std::shared_ptr<impeller::scene::Node> node_;
808+
impeller::Matrix camera_matrix_; // the view-projection matrix of the scene.
809+
810+
FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlSceneColorSource);
811+
};
812+
#endif // IMPELLER_ENABLE_3D
813+
757814
class DlUnknownColorSource final : public DlColorSource {
758815
public:
759816
DlUnknownColorSource(sk_sp<SkShader> shader)

display_list/display_list_ops.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,26 @@ struct SetRuntimeEffectColorSourceOp : DLOp {
312312
}
313313
};
314314

315+
#ifdef IMPELLER_ENABLE_3D
316+
struct SetSceneColorSourceOp : DLOp {
317+
static const auto kType = DisplayListOpType::kSetSceneColorSource;
318+
319+
SetSceneColorSourceOp(const DlSceneColorSource* source)
320+
: source(source->scene_node(), source->camera_matrix()) {}
321+
322+
const DlSceneColorSource source;
323+
324+
void dispatch(DispatchContext& ctx) const {
325+
ctx.dispatcher.setColorSource(&source);
326+
}
327+
328+
DisplayListCompare equals(const SetSceneColorSourceOp* other) const {
329+
return (source == other->source) ? DisplayListCompare::kEqual
330+
: DisplayListCompare::kNotEqual;
331+
}
332+
};
333+
#endif // IMPELLER_ENABLE_3D
334+
315335
// 4 byte header + 16 byte payload uses 24 total bytes (4 bytes unused)
316336
struct SetSharedImageFilterOp : DLOp {
317337
static const auto kType = DisplayListOpType::kSetSharedImageFilter;

impeller/display_list/BUILD.gn

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ impeller_component("display_list") {
2222
"//flutter/fml",
2323
"//third_party/skia",
2424
]
25+
26+
if (!defined(defines)) {
27+
defines = []
28+
}
29+
if (impeller_enable_3d) {
30+
defines += [ "IMPELLER_ENABLE_3D" ]
31+
}
2532
}
2633

2734
impeller_component("display_list_unittests") {
@@ -37,4 +44,11 @@ impeller_component("display_list_unittests") {
3744
":display_list",
3845
"../playground:playground_test",
3946
]
47+
48+
if (!defined(defines)) {
49+
defines = []
50+
}
51+
if (impeller_enable_3d) {
52+
defines += [ "IMPELLER_ENABLE_3D" ]
53+
}
4054
}

impeller/display_list/display_list_dispatcher.cc

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@ static std::optional<Paint::ColorSourceType> ToColorSourceType(
337337
return Paint::ColorSourceType::kSweepGradient;
338338
case flutter::DlColorSourceType::kRuntimeEffect:
339339
return Paint::ColorSourceType::kRuntimeEffect;
340+
#ifdef IMPELLER_ENABLE_3D
341+
case flutter::DlColorSourceType::kScene:
342+
return Paint::ColorSourceType::kScene;
343+
#endif // IMPELLER_ENABLE_3D
340344
case flutter::DlColorSourceType::kUnknown:
341345
return std::nullopt;
342346
}
@@ -502,19 +506,24 @@ void DisplayListDispatcher::setColorSource(
502506
return;
503507
}
504508
case Paint::ColorSourceType::kScene: {
505-
// const flutter::DlSceneColorSource* scene_color_source =
506-
// source->asScene(); std::shared_ptr<scene::Node> scene_node =
507-
// scene_color_source->node(); Matrix camera_transform =
508-
// scene_color_node->camera_transform();
509+
#ifdef IMPELLER_ENABLE_3D
510+
const flutter::DlSceneColorSource* scene_color_source = source->asScene();
511+
std::shared_ptr<scene::Node> scene_node =
512+
scene_color_source->scene_node();
513+
Matrix camera_transform = scene_color_source->camera_matrix();
509514

510-
paint_.color_source = [/*scene_node, camera_transform*/]() {
515+
paint_.color_source = [scene_node, camera_transform]() {
511516
auto contents = std::make_shared<SceneContents>();
512-
// contents->SetNode(scene_node);
513-
// contents->SetCameraTransform(camera_transform);
517+
contents->SetNode(scene_node);
518+
contents->SetCameraTransform(camera_transform);
514519
return contents;
515520
};
516-
}
521+
#else // IMPELLER_ENABLE_3D
522+
FML_LOG(ERROR) << "ColorSourceType::kScene can only be used if Impeller "
523+
"Scene is enabled.";
524+
#endif // IMPELLER_ENABLE_3D
517525
return;
526+
}
518527
case Paint::ColorSourceType::kConicalGradient:
519528
UNIMPLEMENTED;
520529
break;

impeller/display_list/display_list_unittests.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "impeller/geometry/constants.h"
2424
#include "impeller/geometry/point.h"
2525
#include "impeller/playground/widgets.h"
26+
#include "impeller/scene/node.h"
2627
#include "third_party/imgui/imgui.h"
2728
#include "third_party/skia/include/core/SkBlurTypes.h"
2829
#include "third_party/skia/include/core/SkClipOp.h"
@@ -1158,5 +1159,32 @@ TEST_P(DisplayListTest, DrawShapes) {
11581159
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
11591160
}
11601161

1162+
#ifdef IMPELLER_ENABLE_3D
1163+
TEST_P(DisplayListTest, SceneColorSource) {
1164+
// Load up the scene.
1165+
auto mapping =
1166+
flutter::testing::OpenFixtureAsMapping("flutter_logo_baked.glb.ipscene");
1167+
ASSERT_NE(mapping, nullptr);
1168+
1169+
std::shared_ptr<scene::Node> gltf_scene =
1170+
impeller::scene::Node::MakeFromFlatbuffer(
1171+
*mapping, *GetContext()->GetResourceAllocator());
1172+
ASSERT_NE(gltf_scene, nullptr);
1173+
1174+
flutter::DisplayListBuilder builder;
1175+
1176+
auto color_source = std::make_shared<flutter::DlSceneColorSource>(
1177+
gltf_scene,
1178+
Matrix::MakePerspective(Degrees(45), GetWindowSize(), 0.1, 1000) *
1179+
Matrix::MakeLookAt({3, 2, -5}, {0, 0, 0}, {0, 1, 0}));
1180+
1181+
flutter::DlPaint paint = flutter::DlPaint().setColorSource(color_source);
1182+
1183+
builder.drawPaint(paint);
1184+
1185+
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1186+
}
1187+
#endif
1188+
11611189
} // namespace testing
11621190
} // namespace impeller

impeller/entity/contents/scene_contents.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ bool SceneContents::Render(const ContentContext& renderer,
7171
TiledTextureContents contents;
7272
contents.SetGeometry(GetGeometry());
7373
contents.SetTexture(subpass_target.GetRenderTargetTexture());
74+
contents.SetMatrix(
75+
Matrix::MakeScale(1 / entity.GetTransformation().GetScale()));
7476
return contents.Render(renderer, entity, pass);
7577
}
7678

impeller/scene/node.cc

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,19 @@ Matrix Node::GetGlobalTransform() const {
287287
}
288288

289289
bool Node::AddChild(std::shared_ptr<Node> node) {
290-
// This ensures that cycles are impossible.
291-
if (node->parent_ != nullptr) {
292-
VALIDATION_LOG
293-
<< "Cannot add a node as a child which already has a parent.";
294-
return false;
295-
}
290+
// TODO(bdero): Figure out a better paradigm/rules for nodes with multiple
291+
// parents. We should probably disallow this, make deep
292+
// copying of nodes cheap and easy, add mesh instancing, etc.
293+
// Today, the parent link is only used for skin posing, and so
294+
// it's reasonable to not have a check and allow multi-parenting.
295+
// Even still, there should still be some kind of cycle
296+
// prevention/detection, ideally at the protocol level.
297+
//
298+
// if (node->parent_ != nullptr) {
299+
// VALIDATION_LOG
300+
// << "Cannot add a node as a child which already has a parent.";
301+
// return false;
302+
// }
296303
node->parent_ = this;
297304
children_.push_back(std::move(node));
298305

0 commit comments

Comments
 (0)