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

[Impeller Scene] Wire up pipelines #37961

Merged
merged 3 commits into from
Nov 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1598,11 +1598,15 @@ FILE: ../../../flutter/impeller/scene/material.cc
FILE: ../../../flutter/impeller/scene/material.h
FILE: ../../../flutter/impeller/scene/scene.cc
FILE: ../../../flutter/impeller/scene/scene.h
FILE: ../../../flutter/impeller/scene/scene_context.cc
FILE: ../../../flutter/impeller/scene/scene_context.h
FILE: ../../../flutter/impeller/scene/scene_encoder.cc
FILE: ../../../flutter/impeller/scene/scene_encoder.h
FILE: ../../../flutter/impeller/scene/scene_entity.cc
FILE: ../../../flutter/impeller/scene/scene_entity.h
FILE: ../../../flutter/impeller/scene/scene_unittests.cc
FILE: ../../../flutter/impeller/scene/shaders/geometry.vert
FILE: ../../../flutter/impeller/scene/shaders/unlit.frag
FILE: ../../../flutter/impeller/scene/static_mesh_entity.cc
FILE: ../../../flutter/impeller/scene/static_mesh_entity.h
FILE: ../../../flutter/impeller/tessellator/c/tessellator.cc
Expand Down
1 change: 1 addition & 0 deletions impeller/playground/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impeller_component("playground") {
"../entity:modern_entity_shaders",
"../fixtures:shader_fixtures",
"../renderer",
"../scene/shaders",
"imgui:imgui_impeller_backend",
"//flutter/fml",
"//third_party/glfw",
Expand Down
3 changes: 3 additions & 0 deletions impeller/playground/backend/gles/playground_impl_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "impeller/playground/imgui/gles/imgui_shaders_gles.h"
#include "impeller/renderer/backend/gles/context_gles.h"
#include "impeller/renderer/backend/gles/surface_gles.h"
#include "impeller/scene/shaders/gles/scene_shaders_gles.h"

namespace impeller {

Expand Down Expand Up @@ -94,6 +95,8 @@ ShaderLibraryMappingsForPlayground() {
impeller_fixtures_shaders_gles_length),
std::make_shared<fml::NonOwnedMapping>(
impeller_imgui_shaders_gles_data, impeller_imgui_shaders_gles_length),
std::make_shared<fml::NonOwnedMapping>(
impeller_scene_shaders_gles_data, impeller_scene_shaders_gles_length),
};
}

Expand Down
3 changes: 3 additions & 0 deletions impeller/playground/backend/metal/playground_impl_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "impeller/renderer/backend/metal/formats_mtl.h"
#include "impeller/renderer/backend/metal/surface_mtl.h"
#include "impeller/renderer/backend/metal/texture_mtl.h"
#include "impeller/scene/shaders/mtl/scene_shaders.h"

namespace impeller {

Expand All @@ -40,6 +41,8 @@
impeller_fixtures_shaders_length),
std::make_shared<fml::NonOwnedMapping>(impeller_imgui_shaders_data,
impeller_imgui_shaders_length),
std::make_shared<fml::NonOwnedMapping>(impeller_scene_shaders_data,
impeller_scene_shaders_length),

};
}
Expand Down
3 changes: 3 additions & 0 deletions impeller/playground/backend/vulkan/playground_impl_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "impeller/renderer/backend/vulkan/formats_vk.h"
#include "impeller/renderer/backend/vulkan/surface_vk.h"
#include "impeller/renderer/backend/vulkan/texture_vk.h"
#include "impeller/scene/shaders/vk/scene_shaders_vk.h"

namespace impeller {

Expand All @@ -34,6 +35,8 @@ ShaderLibraryMappingsForPlayground() {
impeller_fixtures_shaders_vk_length),
std::make_shared<fml::NonOwnedMapping>(impeller_imgui_shaders_vk_data,
impeller_imgui_shaders_vk_length),
std::make_shared<fml::NonOwnedMapping>(impeller_scene_shaders_vk_data,
impeller_scene_shaders_vk_length),

};
}
Expand Down
7 changes: 6 additions & 1 deletion impeller/scene/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ impeller_component("scene") {
"material.h",
"scene.cc",
"scene.h",
"scene_context.cc",
"scene_context.h",
"scene_encoder.cc",
"scene_encoder.h",
"scene_entity.cc",
Expand All @@ -22,7 +24,10 @@ impeller_component("scene") {
"static_mesh_entity.h",
]

public_deps = [ "../renderer" ]
public_deps = [
"../renderer",
"shaders",
]

deps = [ "//flutter/fml" ]
}
Expand Down
7 changes: 5 additions & 2 deletions impeller/scene/scene.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@

#include "flutter/fml/logging.h"
#include "impeller/renderer/render_target.h"
#include "impeller/scene/scene_context.h"
#include "impeller/scene/scene_encoder.h"

namespace impeller {
namespace scene {

Scene::Scene(const std::shared_ptr<Context>& context) : context_(context){};
Scene::Scene(std::shared_ptr<Context> context)
: scene_context_(std::make_unique<SceneContext>(std::move(context))){};

void Scene::Add(const std::shared_ptr<SceneEntity>& child) {
root_.Add(child);
Expand All @@ -31,7 +33,8 @@ bool Scene::Render(const RenderTarget& render_target,

// Encode the commands.
std::shared_ptr<CommandBuffer> command_buffer =
encoder.BuildSceneCommandBuffer(*context_, render_target);
encoder.BuildSceneCommandBuffer(*scene_context_->GetContext(),
render_target);

// TODO(bdero): Do post processing.

Expand Down
5 changes: 3 additions & 2 deletions impeller/scene/scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "impeller/renderer/render_target.h"
#include "impeller/scene/camera.h"
#include "impeller/scene/scene_context.h"
#include "impeller/scene/scene_entity.h"

namespace impeller {
Expand All @@ -19,13 +20,13 @@ namespace scene {
class Scene {
public:
Scene() = delete;
explicit Scene(const std::shared_ptr<Context>& context);
explicit Scene(std::shared_ptr<Context> context);

void Add(const std::shared_ptr<SceneEntity>& child);
bool Render(const RenderTarget& render_target, const Camera& camera) const;

private:
std::shared_ptr<Context> context_;
std::unique_ptr<SceneContext> scene_context_;
SceneEntity root_;

FML_DISALLOW_COPY_AND_ASSIGN(Scene);
Expand Down
50 changes: 50 additions & 0 deletions impeller/scene/scene_context.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/scene/scene_context.h"

namespace impeller {
namespace scene {

void SceneContextOptions::ApplyToPipelineDescriptor(
PipelineDescriptor& desc) const {
desc.SetSampleCount(sample_count);
desc.SetPrimitiveType(primitive_type);
}

template <typename PipelineT>
static std::unique_ptr<PipelineT> CreateDefaultPipeline(
const Context& context) {
auto desc = PipelineT::Builder::MakeDefaultPipelineDescriptor(context);
if (!desc.has_value()) {
return nullptr;
}
// Apply default ContentContextOptions to the descriptor.
SceneContextOptions{}.ApplyToPipelineDescriptor(*desc);
return std::make_unique<PipelineT>(context, desc);
}

SceneContext::SceneContext(std::shared_ptr<Context> context)
: context_(std::move(context)) {
if (!context_ || !context_->IsValid()) {
return;
}

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

is_valid_ = true;
}

SceneContext::~SceneContext() = default;

bool SceneContext::IsValid() const {
return is_valid_;
}

std::shared_ptr<Context> SceneContext::GetContext() const {
return context_;
}

} // namespace scene
} // namespace impeller
100 changes: 100 additions & 0 deletions impeller/scene/scene_context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include "impeller/renderer/context.h"
#include "impeller/renderer/pipeline_descriptor.h"
#include "impeller/scene/shaders/geometry.vert.h"
#include "impeller/scene/shaders/unlit.frag.h"

namespace impeller {
namespace scene {

using UnlitPipeline =
RenderPipelineT<GeometryVertexShader, UnlitFragmentShader>;

struct SceneContextOptions {
SampleCount sample_count = SampleCount::kCount1;
PrimitiveType primitive_type = PrimitiveType::kTriangle;

struct Hash {
constexpr std::size_t operator()(const SceneContextOptions& o) const {
return fml::HashCombine(o.sample_count, o.primitive_type);
}
};

struct Equal {
constexpr bool operator()(const SceneContextOptions& lhs,
const SceneContextOptions& rhs) const {
return lhs.sample_count == rhs.sample_count &&
lhs.primitive_type == rhs.primitive_type;
}
};

void ApplyToPipelineDescriptor(PipelineDescriptor& desc) const;
};

class SceneContext {
public:
explicit SceneContext(std::shared_ptr<Context> context);

~SceneContext();

bool IsValid() const;

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

std::shared_ptr<Pipeline<PipelineDescriptor>> GetUnlitPipeline(
SceneContextOptions opts) const {
return GetPipeline(unlit_pipeline_, opts);
}

private:
std::shared_ptr<Context> context_;

template <class T>
using Variants = std::unordered_map<SceneContextOptions,
std::unique_ptr<T>,
SceneContextOptions::Hash,
SceneContextOptions::Equal>;

mutable Variants<UnlitPipeline> unlit_pipeline_;

template <class TypedPipeline>
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
Variants<TypedPipeline>& container,
SceneContextOptions opts) const {
if (!IsValid()) {
return nullptr;
}

if (auto found = container.find(opts); found != container.end()) {
return found->second->WaitAndGet();
}

auto prototype = container.find({});

// The prototype must always be initialized in the constructor.
FML_CHECK(prototype != container.end());

auto variant_future = prototype->second->WaitAndGet()->CreateVariant(
[&opts, variants_count = container.size()](PipelineDescriptor& desc) {
opts.ApplyToPipelineDescriptor(desc);
desc.SetLabel(
SPrintF("%s V#%zu", desc.GetLabel().c_str(), variants_count));
});
auto variant = std::make_unique<TypedPipeline>(std::move(variant_future));
auto variant_pipeline = variant->WaitAndGet();
container[opts] = std::move(variant);
return variant_pipeline;
}

bool is_valid_ = false;

FML_DISALLOW_COPY_AND_ASSIGN(SceneContext);
};

} // namespace scene
} // namespace impeller
28 changes: 14 additions & 14 deletions impeller/scene/scene_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,26 @@ namespace testing {
using SceneTest = PlaygroundTest;
INSTANTIATE_PLAYGROUND_SUITE(SceneTest);

TEST_P(SceneTest, UnlitScene) {
auto allocator = GetContext()->GetResourceAllocator();
auto scene = Scene(GetContext());
TEST_P(SceneTest, CuboidUnlit) {
Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
auto allocator = GetContext()->GetResourceAllocator();
auto scene = Scene(GetContext());

{
auto mesh = SceneEntity::MakeStaticMesh();
{
auto mesh = SceneEntity::MakeStaticMesh();

auto material = Material::MakeUnlit();
material->SetColor(Color::Red());
mesh->SetMaterial(std::move(material));
auto material = Material::MakeUnlit();
material->SetColor(Color::Red());
mesh->SetMaterial(std::move(material));

Vector3 size(1, 2, 3);
mesh->SetGeometry(Geometry::MakeCuboid(size));
Vector3 size(1, 2, 3);
mesh->SetGeometry(Geometry::MakeCuboid(size));

mesh->SetLocalTransform(Matrix::MakeTranslation(size / 2));
mesh->SetLocalTransform(Matrix::MakeTranslation(size / 2));

scene.Add(mesh);
}
scene.Add(mesh);
}

Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
auto camera = Camera::MakePerspective(
/* fov */ kPiOver4,
/* position */ {50, -30, 50})
Expand Down
14 changes: 14 additions & 0 deletions impeller/scene/shaders/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//flutter/impeller/tools/impeller.gni")

impeller_shaders("shaders") {
name = "scene"

shaders = [
"geometry.vert",
"unlit.frag",
]
}
26 changes: 26 additions & 0 deletions impeller/scene/shaders/geometry.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

uniform VertInfo {
mat4 mvp;
}
vert_info;

in vec3 position;
in vec3 normal;
in vec3 tangent;
in vec2 texture_coords;

out vec3 v_position;
out mat3 v_tangent_space;
out vec2 v_texture_coords;

void main() {
gl_Position = vert_info.mvp * vec4(position, 1.0);
v_position = gl_Position.xyz;

v_tangent_space =
mat3(vert_info.mvp) * mat3(tangent, cross(normal, tangent), normal);
v_texture_coords = texture_coords;
}
Loading