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

Commit 787044d

Browse files
authored
[Impeller Scene] Command encoding (#37977)
1 parent 047b675 commit 787044d

10 files changed

+232
-23
lines changed

impeller/scene/geometry.cc

+19-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
#include <memory>
88

9+
#include "impeller/geometry/point.h"
10+
#include "impeller/geometry/vector.h"
11+
#include "impeller/renderer/formats.h"
12+
#include "impeller/renderer/vertex_buffer_builder.h"
13+
#include "impeller/scene/shaders/geometry.vert.h"
14+
915
namespace impeller {
1016
namespace scene {
1117

@@ -27,9 +33,19 @@ void CuboidGeometry::SetSize(Vector3 size) {
2733
size_ = size;
2834
}
2935

30-
VertexBuffer CuboidGeometry::GetVertexBuffer(
31-
std::shared_ptr<Allocator>& allocator) const {
32-
return {};
36+
VertexBuffer CuboidGeometry::GetVertexBuffer(Allocator& allocator) const {
37+
VertexBufferBuilder<GeometryVertexShader::PerVertexData, uint16_t> builder;
38+
// Layout: position, normal, tangent, uv
39+
builder.AddVertices({
40+
// Front.
41+
{Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 0)},
42+
{Vector3(1, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 0)},
43+
{Vector3(1, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 1)},
44+
{Vector3(1, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 1)},
45+
{Vector3(0, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 1)},
46+
{Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 0)},
47+
});
48+
return builder.CreateVertexBuffer(allocator);
3349
}
3450

3551
} // namespace scene

impeller/scene/geometry.h

+3-6
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,16 @@ class Geometry {
1919
public:
2020
static std::shared_ptr<CuboidGeometry> MakeCuboid(Vector3 size);
2121

22-
private:
23-
virtual VertexBuffer GetVertexBuffer(
24-
std::shared_ptr<Allocator>& allocator) const = 0;
22+
virtual VertexBuffer GetVertexBuffer(Allocator& allocator) const = 0;
2523
};
2624

2725
class CuboidGeometry final : public Geometry {
2826
public:
2927
void SetSize(Vector3 size);
3028

31-
private:
32-
VertexBuffer GetVertexBuffer(
33-
std::shared_ptr<Allocator>& allocator) const override;
29+
VertexBuffer GetVertexBuffer(Allocator& allocator) const override;
3430

31+
private:
3532
Vector3 size_;
3633
};
3734

impeller/scene/material.cc

+56
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
// found in the LICENSE file.
44

55
#include "impeller/scene/material.h"
6+
#include "impeller/renderer/formats.h"
7+
#include "impeller/renderer/sampler_descriptor.h"
8+
#include "impeller/renderer/sampler_library.h"
9+
#include "impeller/scene/scene_context.h"
10+
#include "impeller/scene/shaders/unlit.frag.h"
611

712
#include <memory>
813

@@ -33,6 +38,11 @@ void Material::SetTranslucent(bool is_translucent) {
3338
is_translucent_ = is_translucent;
3439
}
3540

41+
SceneContextOptions Material::GetContextOptions(const RenderPass& pass) const {
42+
// TODO(bdero): Pipeline blend and stencil config.
43+
return {.sample_count = pass.GetRenderTarget().GetSampleCount()};
44+
}
45+
3646
//------------------------------------------------------------------------------
3747
/// UnlitMaterial
3848
///
@@ -41,6 +51,40 @@ void UnlitMaterial::SetColor(Color color) {
4151
color_ = color;
4252
}
4353

54+
void UnlitMaterial::SetColorTexture(std::shared_ptr<Texture> color_texture) {
55+
color_texture_ = std::move(color_texture);
56+
}
57+
58+
// |Material|
59+
std::shared_ptr<Pipeline<PipelineDescriptor>> UnlitMaterial::GetPipeline(
60+
const SceneContext& scene_context,
61+
const RenderPass& pass) const {
62+
return scene_context.GetUnlitPipeline(GetContextOptions(pass));
63+
}
64+
65+
// |Material|
66+
void UnlitMaterial::BindToCommand(const SceneContext& scene_context,
67+
HostBuffer& buffer,
68+
Command& command) const {
69+
// Uniform buffer.
70+
UnlitPipeline::FragmentShader::FragInfo info;
71+
info.color = color_;
72+
UnlitPipeline::FragmentShader::BindFragInfo(command,
73+
buffer.EmplaceUniform(info));
74+
75+
// Textures.
76+
SamplerDescriptor sampler_descriptor;
77+
sampler_descriptor.label = "Trilinear";
78+
sampler_descriptor.min_filter = MinMagFilter::kLinear;
79+
sampler_descriptor.mag_filter = MinMagFilter::kLinear;
80+
sampler_descriptor.mip_filter = MipFilter::kLinear;
81+
UnlitPipeline::FragmentShader::BindBaseColorTexture(
82+
command,
83+
color_texture_ ? color_texture_ : scene_context.GetPlaceholderTexture(),
84+
scene_context.GetContext()->GetSamplerLibrary()->GetSampler(
85+
sampler_descriptor));
86+
}
87+
4488
//------------------------------------------------------------------------------
4589
/// StandardMaterial
4690
///
@@ -78,5 +122,17 @@ void StandardMaterial::SetEnvironmentMap(
78122
environment_map_ = std::move(environment_map);
79123
}
80124

125+
// |Material|
126+
std::shared_ptr<Pipeline<PipelineDescriptor>> StandardMaterial::GetPipeline(
127+
const SceneContext& scene_context,
128+
const RenderPass& pass) const {
129+
return nullptr;
130+
}
131+
132+
// |Material|
133+
void StandardMaterial::BindToCommand(const SceneContext& scene_context,
134+
HostBuffer& buffer,
135+
Command& command) const {}
136+
81137
} // namespace scene
82138
} // namespace impeller

impeller/scene/material.h

+39-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@
88

99
#include "impeller/geometry/scalar.h"
1010
#include "impeller/renderer/formats.h"
11+
#include "impeller/renderer/render_pass.h"
1112
#include "impeller/renderer/texture.h"
1213

1314
namespace impeller {
1415
namespace scene {
1516

17+
class SceneContext;
18+
struct SceneContextOptions;
19+
class Geometry;
20+
1621
class UnlitMaterial;
1722
class StandardMaterial;
1823

@@ -40,7 +45,16 @@ class Material {
4045

4146
void SetTranslucent(bool is_translucent);
4247

48+
virtual std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
49+
const SceneContext& scene_context,
50+
const RenderPass& pass) const = 0;
51+
virtual void BindToCommand(const SceneContext& scene_context,
52+
HostBuffer& buffer,
53+
Command& command) const = 0;
54+
4355
protected:
56+
SceneContextOptions GetContextOptions(const RenderPass& pass) const;
57+
4458
BlendConfig blend_config_;
4559
StencilConfig stencil_config_;
4660
bool is_translucent_ = false;
@@ -50,8 +64,21 @@ class UnlitMaterial final : public Material {
5064
public:
5165
void SetColor(Color color);
5266

67+
void SetColorTexture(std::shared_ptr<Texture> color_texture);
68+
69+
// |Material|
70+
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
71+
const SceneContext& scene_context,
72+
const RenderPass& pass) const override;
73+
74+
// |Material|
75+
void BindToCommand(const SceneContext& scene_context,
76+
HostBuffer& buffer,
77+
Command& command) const override;
78+
5379
private:
54-
Color color_;
80+
Color color_ = Color::White();
81+
std::shared_ptr<Texture> color_texture_;
5582
};
5683

5784
class StandardMaterial final : public Material {
@@ -67,8 +94,18 @@ class StandardMaterial final : public Material {
6794

6895
void SetEnvironmentMap(std::shared_ptr<Texture> environment_map);
6996

97+
// |Material|
98+
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
99+
const SceneContext& scene_context,
100+
const RenderPass& pass) const override;
101+
102+
// |Material|
103+
void BindToCommand(const SceneContext& scene_context,
104+
HostBuffer& buffer,
105+
Command& command) const override;
106+
70107
private:
71-
Color albedo_ = Color::CornflowerBlue();
108+
Color albedo_ = Color::White();
72109
Scalar roughness_ = 0.5;
73110
Scalar metallic_ = 0.5;
74111

impeller/scene/scene.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ bool Scene::Render(const RenderTarget& render_target,
3232
}
3333

3434
// Encode the commands.
35+
3536
std::shared_ptr<CommandBuffer> command_buffer =
36-
encoder.BuildSceneCommandBuffer(*scene_context_->GetContext(),
37-
render_target);
37+
encoder.BuildSceneCommandBuffer(*scene_context_, render_target);
3838

3939
// TODO(bdero): Do post processing.
4040

impeller/scene/scene_context.cc

+26
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44

55
#include "impeller/scene/scene_context.h"
6+
#include "impeller/renderer/formats.h"
67

78
namespace impeller {
89
namespace scene {
@@ -33,6 +34,27 @@ SceneContext::SceneContext(std::shared_ptr<Context> context)
3334

3435
unlit_pipeline_[{}] = CreateDefaultPipeline<UnlitPipeline>(*context_);
3536

37+
{
38+
impeller::TextureDescriptor texture_descriptor;
39+
texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
40+
texture_descriptor.format = PixelFormat::kDefaultColor;
41+
texture_descriptor.size = {1, 1};
42+
texture_descriptor.mip_count = 1u;
43+
44+
placeholder_texture_ =
45+
context_->GetResourceAllocator()->CreateTexture(texture_descriptor);
46+
if (!placeholder_texture_) {
47+
FML_DLOG(ERROR) << "Could not create placeholder texture.";
48+
return;
49+
}
50+
51+
uint8_t pixel[] = {0xFF, 0xFF, 0xFF, 0xFF};
52+
if (!placeholder_texture_->SetContents(pixel, 4, 0)) {
53+
FML_DLOG(ERROR) << "Could not set contents of placeholder texture.";
54+
return;
55+
}
56+
}
57+
3658
is_valid_ = true;
3759
}
3860

@@ -46,5 +68,9 @@ std::shared_ptr<Context> SceneContext::GetContext() const {
4668
return context_;
4769
}
4870

71+
std::shared_ptr<Texture> SceneContext::GetPlaceholderTexture() const {
72+
return placeholder_texture_;
73+
}
74+
4975
} // namespace scene
5076
} // namespace impeller

impeller/scene/scene_context.h

+10-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#pragma once
66

7+
#include <memory>
8+
79
#include "impeller/renderer/context.h"
810
#include "impeller/renderer/pipeline_descriptor.h"
911
#include "impeller/scene/shaders/geometry.vert.h"
@@ -46,22 +48,19 @@ class SceneContext {
4648

4749
std::shared_ptr<Context> GetContext() const;
4850

51+
std::shared_ptr<Texture> GetPlaceholderTexture() const;
52+
4953
std::shared_ptr<Pipeline<PipelineDescriptor>> GetUnlitPipeline(
5054
SceneContextOptions opts) const {
5155
return GetPipeline(unlit_pipeline_, opts);
5256
}
5357

5458
private:
55-
std::shared_ptr<Context> context_;
56-
5759
template <class T>
5860
using Variants = std::unordered_map<SceneContextOptions,
5961
std::unique_ptr<T>,
6062
SceneContextOptions::Hash,
6163
SceneContextOptions::Equal>;
62-
63-
mutable Variants<UnlitPipeline> unlit_pipeline_;
64-
6564
template <class TypedPipeline>
6665
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
6766
Variants<TypedPipeline>& container,
@@ -91,7 +90,13 @@ class SceneContext {
9190
return variant_pipeline;
9291
}
9392

93+
std::shared_ptr<Context> context_;
94+
mutable Variants<UnlitPipeline> unlit_pipeline_;
95+
9496
bool is_valid_ = false;
97+
// A 1x1 opaque white texture that can be used as a placeholder binding.
98+
// Available for the lifetime of the scene context
99+
std::shared_ptr<Texture> placeholder_texture_;
95100

96101
FML_DISALLOW_COPY_AND_ASSIGN(SceneContext);
97102
};

impeller/scene/scene_encoder.cc

+50-3
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,71 @@
44

55
#include "flutter/fml/macros.h"
66

7-
#include "fml/logging.h"
7+
#include "flutter/fml/logging.h"
8+
#include "impeller/renderer/command.h"
89
#include "impeller/renderer/render_target.h"
10+
#include "impeller/scene/scene_context.h"
911
#include "impeller/scene/scene_encoder.h"
12+
#include "impeller/scene/shaders/geometry.vert.h"
1013

1114
namespace impeller {
1215
namespace scene {
1316

1417
SceneEncoder::SceneEncoder() = default;
1518

19+
void SceneEncoder::Add(const SceneCommand& command) {
20+
// TODO(bdero): Manage multi-pass translucency ordering.
21+
commands_.push_back(command);
22+
}
23+
24+
static void EncodeCommand(const SceneContext& scene_context,
25+
RenderPass& render_pass,
26+
const SceneCommand& scene_command) {
27+
auto& host_buffer = render_pass.GetTransientsBuffer();
28+
29+
Command cmd;
30+
cmd.label = scene_command.label;
31+
cmd.stencil_reference =
32+
0; // TODO(bdero): Configurable stencil ref per-command.
33+
34+
cmd.BindVertices(scene_command.geometry->GetVertexBuffer(
35+
*scene_context.GetContext()->GetResourceAllocator()));
36+
37+
cmd.pipeline =
38+
scene_command.material->GetPipeline(scene_context, render_pass);
39+
scene_command.material->BindToCommand(scene_context, host_buffer, cmd);
40+
41+
GeometryVertexShader::VertInfo info;
42+
info.mvp = scene_command.transform;
43+
GeometryVertexShader::BindVertInfo(cmd, host_buffer.EmplaceUniform(info));
44+
45+
render_pass.AddCommand(std::move(cmd));
46+
}
47+
1648
std::shared_ptr<CommandBuffer> SceneEncoder::BuildSceneCommandBuffer(
17-
Context& context,
49+
const SceneContext& scene_context,
1850
const RenderTarget& render_target) const {
19-
auto command_buffer = context.CreateCommandBuffer();
51+
auto command_buffer = scene_context.GetContext()->CreateCommandBuffer();
2052
if (!command_buffer) {
2153
FML_LOG(ERROR) << "Failed to create command buffer.";
2254
return nullptr;
2355
}
2456

57+
auto render_pass = command_buffer->CreateRenderPass(render_target);
58+
if (!render_pass) {
59+
FML_LOG(ERROR) << "Failed to create render pass.";
60+
return nullptr;
61+
}
62+
63+
for (auto& command : commands_) {
64+
EncodeCommand(scene_context, *render_pass, command);
65+
}
66+
67+
if (!render_pass->EncodeCommands()) {
68+
FML_LOG(ERROR) << "Failed to encode render pass commands.";
69+
return nullptr;
70+
}
71+
2572
return command_buffer;
2673
}
2774

0 commit comments

Comments
 (0)