Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 8655ec0

Browse files
authored
[Impeller Scene] Add ColorSourceContents for drawing a node (#38485)
1 parent 9b534a5 commit 8655ec0

20 files changed

+258
-27
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,8 @@ ORIGIN: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.cc + ../
12591259
ORIGIN: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.h + ../../../flutter/LICENSE
12601260
ORIGIN: ../../../flutter/impeller/entity/contents/runtime_effect_contents.cc + ../../../flutter/LICENSE
12611261
ORIGIN: ../../../flutter/impeller/entity/contents/runtime_effect_contents.h + ../../../flutter/LICENSE
1262+
ORIGIN: ../../../flutter/impeller/entity/contents/scene_contents.cc + ../../../flutter/LICENSE
1263+
ORIGIN: ../../../flutter/impeller/entity/contents/scene_contents.h + ../../../flutter/LICENSE
12621264
ORIGIN: ../../../flutter/impeller/entity/contents/solid_color_contents.cc + ../../../flutter/LICENSE
12631265
ORIGIN: ../../../flutter/impeller/entity/contents/solid_color_contents.h + ../../../flutter/LICENSE
12641266
ORIGIN: ../../../flutter/impeller/entity/contents/sweep_gradient_contents.cc + ../../../flutter/LICENSE
@@ -3716,6 +3718,8 @@ FILE: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.cc
37163718
FILE: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.h
37173719
FILE: ../../../flutter/impeller/entity/contents/runtime_effect_contents.cc
37183720
FILE: ../../../flutter/impeller/entity/contents/runtime_effect_contents.h
3721+
FILE: ../../../flutter/impeller/entity/contents/scene_contents.cc
3722+
FILE: ../../../flutter/impeller/entity/contents/scene_contents.h
37193723
FILE: ../../../flutter/impeller/entity/contents/solid_color_contents.cc
37203724
FILE: ../../../flutter/impeller/entity/contents/solid_color_contents.h
37213725
FILE: ../../../flutter/impeller/entity/contents/sweep_gradient_contents.cc

impeller/aiks/aiks_unittests.cc

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
#include <array>
66
#include <cmath>
77
#include <iostream>
8+
#include <memory>
89
#include <tuple>
910
#include <utility>
1011

1112
#include "flutter/testing/testing.h"
1213
#include "impeller/aiks/aiks_playground.h"
1314
#include "impeller/aiks/canvas.h"
1415
#include "impeller/aiks/image.h"
16+
#include "impeller/entity/contents/color_source_contents.h"
1517
#include "impeller/entity/contents/filters/inputs/filter_input.h"
18+
#include "impeller/entity/contents/scene_contents.h"
1619
#include "impeller/entity/contents/tiled_texture_contents.h"
1720
#include "impeller/geometry/color.h"
1821
#include "impeller/geometry/geometry_unittests.h"
@@ -21,6 +24,8 @@
2124
#include "impeller/playground/widgets.h"
2225
#include "impeller/renderer/command_buffer.h"
2326
#include "impeller/renderer/snapshot.h"
27+
#include "impeller/scene/material.h"
28+
#include "impeller/scene/node.h"
2429
#include "impeller/typographer/backends/skia/text_frame_skia.h"
2530
#include "impeller/typographer/backends/skia/text_render_context_skia.h"
2631
#include "third_party/skia/include/core/SkData.h"
@@ -1700,5 +1705,53 @@ TEST_P(AiksTest, SaveLayerFiltersScaleWithTransform) {
17001705
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
17011706
}
17021707

1708+
TEST_P(AiksTest, SceneColorSource) {
1709+
// Load up the scene.
1710+
auto mapping =
1711+
flutter::testing::OpenFixtureAsMapping("flutter_logo.glb.ipscene");
1712+
ASSERT_NE(mapping, nullptr);
1713+
1714+
std::shared_ptr<scene::Node> gltf_scene = scene::Node::MakeFromFlatbuffer(
1715+
*mapping, *GetContext()->GetResourceAllocator());
1716+
ASSERT_NE(gltf_scene, nullptr);
1717+
1718+
// Assign a material (temporary stopgap).
1719+
std::shared_ptr<scene::UnlitMaterial> material = scene::Material::MakeUnlit();
1720+
auto color_baked = CreateTextureForFixture("flutter_logo_baked.png");
1721+
ASSERT_NE(color_baked, nullptr);
1722+
material->SetColorTexture(std::move(color_baked));
1723+
material->SetVertexColorWeight(0);
1724+
1725+
ASSERT_EQ(gltf_scene->GetChildren().size(), 1u);
1726+
ASSERT_EQ(gltf_scene->GetChildren()[0]->GetMesh().GetPrimitives().size(), 1u);
1727+
gltf_scene->GetChildren()[0]->GetMesh().GetPrimitives()[0].material =
1728+
std::move(material);
1729+
1730+
auto callback = [&](AiksContext& renderer, RenderTarget& render_target) {
1731+
Paint paint;
1732+
1733+
paint.color_source_type = Paint::ColorSourceType::kScene;
1734+
paint.color_source = [this, gltf_scene]() {
1735+
Scalar angle = GetSecondsElapsed();
1736+
Scalar distance = 2;
1737+
auto camera_position =
1738+
Vector3(distance * std::sin(angle), 2, -distance * std::cos(angle));
1739+
auto contents = std::make_shared<SceneContents>();
1740+
contents->SetNode(gltf_scene);
1741+
contents->SetCameraTransform(
1742+
Matrix::MakePerspective(Degrees(45), GetWindowSize(), 0.1, 1000) *
1743+
Matrix::MakeLookAt(camera_position, {0, 0, 0}, {0, 1, 0}));
1744+
return contents;
1745+
};
1746+
1747+
Canvas canvas;
1748+
canvas.Scale(GetContentScale());
1749+
canvas.DrawPaint(paint);
1750+
return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
1751+
};
1752+
1753+
ASSERT_TRUE(OpenPlaygroundHere(callback));
1754+
}
1755+
17031756
} // namespace testing
17041757
} // namespace impeller

impeller/aiks/paint.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct Paint {
4444
kConicalGradient,
4545
kSweepGradient,
4646
kRuntimeEffect,
47+
kScene,
4748
};
4849

4950
struct MaskBlurDescriptor {

impeller/display_list/display_list_dispatcher.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "impeller/entity/contents/linear_gradient_contents.h"
2828
#include "impeller/entity/contents/radial_gradient_contents.h"
2929
#include "impeller/entity/contents/runtime_effect_contents.h"
30+
#include "impeller/entity/contents/scene_contents.h"
3031
#include "impeller/entity/contents/sweep_gradient_contents.h"
3132
#include "impeller/entity/contents/tiled_texture_contents.h"
3233
#include "impeller/entity/entity.h"
@@ -500,6 +501,20 @@ void DisplayListDispatcher::setColorSource(
500501
};
501502
return;
502503
}
504+
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+
510+
paint_.color_source = [/*scene_node, camera_transform*/]() {
511+
auto contents = std::make_shared<SceneContents>();
512+
// contents->SetNode(scene_node);
513+
// contents->SetCameraTransform(camera_transform);
514+
return contents;
515+
};
516+
}
517+
return;
503518
case Paint::ColorSourceType::kConicalGradient:
504519
UNIMPLEMENTED;
505520
break;

impeller/entity/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ impeller_component("entity") {
134134
"contents/rrect_shadow_contents.h",
135135
"contents/runtime_effect_contents.cc",
136136
"contents/runtime_effect_contents.h",
137+
"contents/scene_contents.cc",
138+
"contents/scene_contents.h",
137139
"contents/solid_color_contents.cc",
138140
"contents/solid_color_contents.h",
139141
"contents/sweep_gradient_contents.cc",
@@ -164,6 +166,7 @@ impeller_component("entity") {
164166
"../archivist",
165167
"../image",
166168
"../renderer",
169+
"../scene",
167170
"../typographer",
168171
]
169172

impeller/entity/contents/color_source_contents.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ ColorSourceContents::ColorSourceContents() = default;
1313

1414
ColorSourceContents::~ColorSourceContents() = default;
1515

16-
void ColorSourceContents::SetGeometry(std::unique_ptr<Geometry> geometry) {
16+
void ColorSourceContents::SetGeometry(std::shared_ptr<Geometry> geometry) {
1717
geometry_ = std::move(geometry);
1818
}
1919

20-
const std::unique_ptr<Geometry>& ColorSourceContents::GetGeometry() const {
20+
const std::shared_ptr<Geometry>& ColorSourceContents::GetGeometry() const {
2121
return geometry_;
2222
}
2323

impeller/entity/contents/color_source_contents.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ColorSourceContents : public Contents {
1818

1919
~ColorSourceContents() override;
2020

21-
void SetGeometry(std::unique_ptr<Geometry> geometry);
21+
void SetGeometry(std::shared_ptr<Geometry> geometry);
2222

2323
void SetMatrix(Matrix matrix);
2424

@@ -32,14 +32,14 @@ class ColorSourceContents : public Contents {
3232
const std::optional<Rect>& stencil_coverage) const override;
3333

3434
protected:
35-
const std::unique_ptr<Geometry>& GetGeometry() const;
35+
const std::shared_ptr<Geometry>& GetGeometry() const;
3636

3737
const Matrix& GetInverseMatrix() const;
3838

3939
Scalar GetAlpha() const;
4040

4141
private:
42-
std::unique_ptr<Geometry> geometry_;
42+
std::shared_ptr<Geometry> geometry_;
4343
Matrix inverse_matrix_;
4444
Scalar alpha_ = 1.0;
4545

impeller/entity/contents/content_context.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "impeller/entity/contents/content_context.h"
66

7+
#include <memory>
78
#include <sstream>
89

910
#include "impeller/entity/entity.h"
@@ -146,7 +147,8 @@ static std::unique_ptr<PipelineT> CreateDefaultPipeline(
146147
ContentContext::ContentContext(std::shared_ptr<Context> context)
147148
: context_(std::move(context)),
148149
tessellator_(std::make_shared<Tessellator>()),
149-
glyph_atlas_context_(std::make_shared<GlyphAtlasContext>()) {
150+
glyph_atlas_context_(std::make_shared<GlyphAtlasContext>()),
151+
scene_context_(std::make_shared<scene::SceneContext>(context_)) {
150152
if (!context_ || !context_->IsValid()) {
151153
return;
152154
}
@@ -298,6 +300,10 @@ std::shared_ptr<Texture> ContentContext::MakeSubpass(
298300
return subpass_texture;
299301
}
300302

303+
std::shared_ptr<scene::SceneContext> ContentContext::GetSceneContext() const {
304+
return scene_context_;
305+
}
306+
301307
std::shared_ptr<Tessellator> ContentContext::GetTessellator() const {
302308
return tessellator_;
303309
}

impeller/entity/contents/content_context.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#include <unordered_map>
99

1010
#include "flutter/fml/hash_combine.h"
11+
#include "flutter/fml/logging.h"
1112
#include "flutter/fml/macros.h"
12-
#include "fml/logging.h"
1313
#include "impeller/base/validation.h"
1414
#include "impeller/entity/advanced_blend.vert.h"
1515
#include "impeller/entity/advanced_blend_color.frag.h"
@@ -65,11 +65,13 @@
6565
#include "impeller/entity/yuv_to_rgb_filter.vert.h"
6666
#include "impeller/renderer/formats.h"
6767
#include "impeller/renderer/pipeline.h"
68+
#include "impeller/scene/scene_context.h"
6869

6970
#include "impeller/entity/position.vert.h"
7071
#include "impeller/entity/position_color.vert.h"
7172
#include "impeller/entity/position_uv.vert.h"
7273

74+
#include "impeller/scene/scene_context.h"
7375
#include "impeller/typographer/glyph_atlas.h"
7476

7577
#include "impeller/entity/linear_gradient_ssbo_fill.frag.h"
@@ -216,6 +218,8 @@ class ContentContext {
216218

217219
bool IsValid() const;
218220

221+
std::shared_ptr<scene::SceneContext> GetSceneContext() const;
222+
219223
std::shared_ptr<Tessellator> GetTessellator() const;
220224

221225
std::shared_ptr<Pipeline<PipelineDescriptor>> GetLinearGradientFillPipeline(
@@ -522,6 +526,7 @@ class ContentContext {
522526
bool is_valid_ = false;
523527
std::shared_ptr<Tessellator> tessellator_;
524528
std::shared_ptr<GlyphAtlasContext> glyph_atlas_context_;
529+
std::shared_ptr<scene::SceneContext> scene_context_;
525530

526531
FML_DISALLOW_COPY_AND_ASSIGN(ContentContext);
527532
};
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "impeller/entity/contents/scene_contents.h"
6+
7+
#include "impeller/entity/contents/content_context.h"
8+
#include "impeller/entity/contents/tiled_texture_contents.h"
9+
#include "impeller/entity/entity.h"
10+
#include "impeller/geometry/path_builder.h"
11+
#include "impeller/renderer/formats.h"
12+
#include "impeller/scene/camera.h"
13+
#include "impeller/scene/scene.h"
14+
15+
namespace impeller {
16+
17+
SceneContents::SceneContents() = default;
18+
19+
SceneContents::~SceneContents() = default;
20+
21+
void SceneContents::SetCameraTransform(Matrix matrix) {
22+
camera_transform_ = matrix;
23+
}
24+
25+
void SceneContents::SetNode(std::shared_ptr<scene::Node> node) {
26+
node_ = std::move(node);
27+
}
28+
29+
bool SceneContents::Render(const ContentContext& renderer,
30+
const Entity& entity,
31+
RenderPass& pass) const {
32+
if (!node_) {
33+
return true;
34+
}
35+
36+
auto coverage = GetCoverage(entity);
37+
if (!coverage.has_value()) {
38+
return true;
39+
}
40+
41+
// This happens for CoverGeometry (DrawPaint). In this situation,
42+
// Draw the scene to the full layer.
43+
if (coverage.value().IsMaximum()) {
44+
coverage = Rect::MakeSize(pass.GetRenderTargetSize());
45+
}
46+
47+
RenderTarget subpass_target = RenderTarget::CreateOffscreenMSAA(
48+
*renderer.GetContext(), // context
49+
ISize(coverage.value().size), // size
50+
"SceneContents", // label
51+
StorageMode::kDeviceTransient, // color_storage_mode
52+
StorageMode::kDevicePrivate, // color_resolve_storage_mode
53+
LoadAction::kClear, // color_load_action
54+
StoreAction::kMultisampleResolve, // color_store_action
55+
StorageMode::kDeviceTransient, // stencil_storage_mode
56+
LoadAction::kDontCare, // stencil_load_action
57+
StoreAction::kDontCare // stencil_store_action
58+
);
59+
if (!subpass_target.IsValid()) {
60+
return false;
61+
}
62+
63+
scene::Scene scene(renderer.GetSceneContext());
64+
scene.GetRoot().AddChild(node_);
65+
66+
if (!scene.Render(subpass_target, camera_transform_)) {
67+
return false;
68+
}
69+
70+
// Render the texture to the pass.
71+
TiledTextureContents contents;
72+
contents.SetGeometry(GetGeometry());
73+
contents.SetTexture(subpass_target.GetRenderTargetTexture());
74+
return contents.Render(renderer, entity, pass);
75+
}
76+
77+
} // namespace impeller
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include <memory>
6+
7+
#include "impeller/entity/contents/color_source_contents.h"
8+
9+
#include "impeller/geometry/matrix.h"
10+
#include "impeller/geometry/rect.h"
11+
#include "impeller/scene/node.h"
12+
13+
namespace impeller {
14+
15+
class SceneContents final : public ColorSourceContents {
16+
public:
17+
SceneContents();
18+
19+
~SceneContents() override;
20+
21+
void SetCameraTransform(Matrix matrix);
22+
23+
void SetNode(std::shared_ptr<scene::Node> node);
24+
25+
// |Contents|
26+
bool Render(const ContentContext& renderer,
27+
const Entity& entity,
28+
RenderPass& pass) const override;
29+
30+
private:
31+
Matrix camera_transform_;
32+
std::shared_ptr<scene::Node> node_;
33+
};
34+
35+
} // namespace impeller

0 commit comments

Comments
 (0)