mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Wire up pipeline library resolution.
This commit is contained in:
parent
5d6dd79bf0
commit
e9938a67af
@ -8,8 +8,8 @@ impeller_component("compositor") {
|
||||
sources = [
|
||||
"context.h",
|
||||
"context.mm",
|
||||
"pipeline_builder.h",
|
||||
"pipeline_builder.mm",
|
||||
"pipeline.h",
|
||||
"pipeline.mm",
|
||||
"pipeline_descriptor.h",
|
||||
"pipeline_descriptor.mm",
|
||||
"pipeline_library.h",
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/compositor/pipeline_library.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
@ -28,11 +29,14 @@ class Context {
|
||||
|
||||
std::shared_ptr<ShaderLibrary> GetShaderLibrary() const;
|
||||
|
||||
std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const;
|
||||
|
||||
private:
|
||||
id<MTLDevice> device_ = nullptr;
|
||||
id<MTLCommandQueue> render_queue_ = nullptr;
|
||||
id<MTLCommandQueue> transfer_queue_ = nullptr;
|
||||
std::shared_ptr<ShaderLibrary> shader_library_;
|
||||
std::shared_ptr<PipelineLibrary> pipeline_library_;
|
||||
bool is_valid_ = false;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(Context);
|
||||
|
||||
35
engine/src/flutter/impeller/impeller/compositor/pipeline.h
Normal file
35
engine/src/flutter/impeller/impeller/compositor/pipeline.h
Normal file
@ -0,0 +1,35 @@
|
||||
// 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 "flutter/fml/macros.h"
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
namespace impeller {
|
||||
|
||||
class PipelineLibrary;
|
||||
|
||||
class Pipeline {
|
||||
public:
|
||||
enum class Type {
|
||||
kUnknown,
|
||||
kRender,
|
||||
};
|
||||
|
||||
~Pipeline();
|
||||
|
||||
private:
|
||||
friend class PipelineLibrary;
|
||||
|
||||
Type type_ = Type::kUnknown;
|
||||
id<MTLRenderPipelineState> state_;
|
||||
|
||||
Pipeline(id<MTLRenderPipelineState> state);
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(Pipeline);
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
17
engine/src/flutter/impeller/impeller/compositor/pipeline.mm
Normal file
17
engine/src/flutter/impeller/impeller/compositor/pipeline.mm
Normal file
@ -0,0 +1,17 @@
|
||||
// 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 "flutter/impeller/impeller/compositor/pipeline.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
Pipeline::Pipeline(id<MTLRenderPipelineState> state) : state_(state) {
|
||||
if (state_ != nil) {
|
||||
type_ = Type::kRender;
|
||||
}
|
||||
}
|
||||
|
||||
Pipeline::~Pipeline() = default;
|
||||
|
||||
} // namespace impeller
|
||||
@ -1,43 +0,0 @@
|
||||
// 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 <functional>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/compositor/pipeline_descriptor.h"
|
||||
#include "impeller/compositor/shader_library.h"
|
||||
#include "impeller/compositor/vertex_descriptor.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
class PipelineBuilder {
|
||||
public:
|
||||
PipelineBuilder();
|
||||
|
||||
~PipelineBuilder();
|
||||
|
||||
PipelineBuilder& SetLabel(const std::string_view& label);
|
||||
|
||||
PipelineBuilder& SetSampleCount(size_t samples);
|
||||
|
||||
PipelineBuilder& AddStageEntrypoint(std::shared_ptr<ShaderFunction> function);
|
||||
|
||||
PipelineBuilder& SetVertexDescriptor(
|
||||
std::shared_ptr<VertexDescriptor> vertex_descriptor);
|
||||
|
||||
private:
|
||||
std::string label_;
|
||||
size_t sample_count_ = 1;
|
||||
std::unordered_map<ShaderStage, std::shared_ptr<ShaderFunction>> entrypoints_;
|
||||
std::shared_ptr<VertexDescriptor> vertex_descriptor_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(PipelineBuilder);
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
@ -1,44 +0,0 @@
|
||||
// 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/compositor/pipeline_builder.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
PipelineBuilder::PipelineBuilder() = default;
|
||||
|
||||
PipelineBuilder::~PipelineBuilder() = default;
|
||||
|
||||
PipelineBuilder& PipelineBuilder::SetLabel(const std::string_view& label) {
|
||||
label_ = {label.data(), label.size()};
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::SetSampleCount(size_t samples) {
|
||||
sample_count_ = samples;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::AddStageEntrypoint(
|
||||
std::shared_ptr<ShaderFunction> function) {
|
||||
if (!function) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (function->GetStage() == ShaderStage::kUnknown) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
entrypoints_[function->GetStage()] = std::move(function);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineBuilder& PipelineBuilder::SetVertexDescriptor(
|
||||
std::shared_ptr<VertexDescriptor> vertex_descriptor) {
|
||||
vertex_descriptor_ = std::move(vertex_descriptor);
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
@ -4,17 +4,53 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/shader_glue/shader_types.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
class ShaderFunction;
|
||||
class VertexDescriptor;
|
||||
|
||||
class PipelineDescriptor {
|
||||
public:
|
||||
struct HashEqual {
|
||||
std::size_t operator()(const PipelineDescriptor& des) const;
|
||||
bool operator()(const PipelineDescriptor& d1,
|
||||
const PipelineDescriptor& d2) const;
|
||||
};
|
||||
|
||||
PipelineDescriptor();
|
||||
|
||||
~PipelineDescriptor();
|
||||
|
||||
PipelineDescriptor& SetLabel(const std::string_view& label);
|
||||
|
||||
PipelineDescriptor& SetSampleCount(size_t samples);
|
||||
|
||||
PipelineDescriptor& AddStageEntrypoint(
|
||||
std::shared_ptr<const ShaderFunction> function);
|
||||
|
||||
PipelineDescriptor& SetVertexDescriptor(
|
||||
std::shared_ptr<VertexDescriptor> vertex_descriptor);
|
||||
|
||||
MTLRenderPipelineDescriptor* GetMTLRenderPipelineDescriptor() const;
|
||||
|
||||
private:
|
||||
std::string label_;
|
||||
size_t sample_count_ = 1;
|
||||
std::map<ShaderStage, std::shared_ptr<const ShaderFunction>> entrypoints_;
|
||||
std::shared_ptr<VertexDescriptor> vertex_descriptor_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(PipelineDescriptor);
|
||||
};
|
||||
|
||||
|
||||
@ -4,10 +4,75 @@
|
||||
|
||||
#include "impeller/compositor/pipeline_descriptor.h"
|
||||
|
||||
#include "flutter/fml/hash_combine.h"
|
||||
#include "impeller/compositor/shader_library.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
PipelineDescriptor::PipelineDescriptor() = default;
|
||||
|
||||
PipelineDescriptor::~PipelineDescriptor() = default;
|
||||
|
||||
std::size_t PipelineDescriptor::HashEqual::operator()(
|
||||
const PipelineDescriptor& des) const {
|
||||
auto seed = fml::HashCombine();
|
||||
fml::HashCombineSeed(seed, des.label_);
|
||||
for (const auto& entry : des.entrypoints_) {
|
||||
fml::HashCombineSeed(seed, entry)
|
||||
}
|
||||
}
|
||||
|
||||
bool PipelineDescriptor::HashEqual::operator()(
|
||||
const PipelineDescriptor& d1,
|
||||
const PipelineDescriptor& d2) const {}
|
||||
|
||||
PipelineDescriptor& PipelineDescriptor::SetLabel(
|
||||
const std::string_view& label) {
|
||||
label_ = {label.data(), label.size()};
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineDescriptor& PipelineDescriptor::SetSampleCount(size_t samples) {
|
||||
sample_count_ = samples;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineDescriptor& PipelineDescriptor::AddStageEntrypoint(
|
||||
std::shared_ptr<const ShaderFunction> function) {
|
||||
if (!function) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (function->GetStage() == ShaderStage::kUnknown) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
entrypoints_[function->GetStage()] = std::move(function);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PipelineDescriptor& PipelineDescriptor::SetVertexDescriptor(
|
||||
std::shared_ptr<VertexDescriptor> vertex_descriptor) {
|
||||
vertex_descriptor_ = std::move(vertex_descriptor);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MTLRenderPipelineDescriptor*
|
||||
PipelineDescriptor::GetMTLRenderPipelineDescriptor() const {
|
||||
auto descriptor = [[MTLRenderPipelineDescriptor alloc] init];
|
||||
descriptor.label = @(label_.c_str());
|
||||
descriptor.sampleCount = sample_count_;
|
||||
|
||||
for (const auto& entry : entrypoints_) {
|
||||
if (entry.first == ShaderStage::kVertex) {
|
||||
descriptor.vertexFunction = entry.second->GetMTLFunction();
|
||||
}
|
||||
if (entry.first == ShaderStage::kFragment) {
|
||||
descriptor.fragmentFunction = entry.second->GetMTLFunction();
|
||||
}
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -4,17 +4,34 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include <future>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/compositor/pipeline.h"
|
||||
#include "impeller/compositor/pipeline_descriptor.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
class PipelineLibrary {
|
||||
public:
|
||||
PipelineLibrary();
|
||||
PipelineLibrary(id<MTLDevice> device);
|
||||
|
||||
~PipelineLibrary();
|
||||
|
||||
std::future<std::shared_ptr<Pipeline>> GetRenderPipeline(
|
||||
PipelineDescriptor descriptor);
|
||||
|
||||
private:
|
||||
using Pipelines = std::unordered_map<PipelineDescriptor,
|
||||
std::shared_ptr<const Pipeline>,
|
||||
PipelineDescriptor::HashEqual,
|
||||
PipelineDescriptor::HashEqual>;
|
||||
id<MTLDevice> device_;
|
||||
Pipelines pipelines_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(PipelineLibrary);
|
||||
};
|
||||
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
// 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/compositor/pipeline_library.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
PipelineLibrary::PipelineLibrary(id<MTLDevice> device) : device_(device) {}
|
||||
|
||||
PipelineLibrary::~PipelineLibrary() = default;
|
||||
|
||||
std::future<std::shared_ptr<Pipeline>> PipelineLibrary::GetRenderPipeline(
|
||||
PipelineDescriptor descriptor) {
|
||||
auto promise = std::make_shared<std::promise<std::shared_ptr<Pipeline>>>();
|
||||
auto future = promise->get_future();
|
||||
if (auto found = pipelines_.find(descriptor); found != pipelines_.end()) {
|
||||
promise->set_value(nullptr);
|
||||
return future;
|
||||
}
|
||||
|
||||
auto completion_handler =
|
||||
^(id<MTLRenderPipelineState> _Nullable render_pipeline_state,
|
||||
NSError* _Nullable error) {
|
||||
if (error != nil) {
|
||||
FML_LOG(ERROR) << "Could not create render pipeline: "
|
||||
<< error.localizedDescription.UTF8String;
|
||||
promise->set_value(nullptr);
|
||||
} else {
|
||||
promise->set_value(
|
||||
std::shared_ptr<Pipeline>(new Pipeline(render_pipeline_state)));
|
||||
}
|
||||
};
|
||||
[device_
|
||||
newRenderPipelineStateWithDescriptor:descriptor
|
||||
.GetMTLRenderPipelineDescriptor()
|
||||
completionHandler:completion_handler];
|
||||
return future;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
@ -9,7 +9,9 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "flutter/fml/hash_combine.h"
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/shader_glue/shader_types.h"
|
||||
|
||||
@ -23,6 +25,8 @@ class ShaderFunction {
|
||||
|
||||
ShaderStage GetStage() const;
|
||||
|
||||
id<MTLFunction> GetMTLFunction() const;
|
||||
|
||||
private:
|
||||
friend class ShaderLibrary;
|
||||
|
||||
@ -38,13 +42,40 @@ class ShaderLibrary {
|
||||
public:
|
||||
~ShaderLibrary();
|
||||
|
||||
std::shared_ptr<ShaderFunction> GetFunction(const std::string_view& name,
|
||||
ShaderStage stage);
|
||||
std::shared_ptr<const ShaderFunction> GetFunction(
|
||||
const std::string_view& name,
|
||||
ShaderStage stage);
|
||||
|
||||
private:
|
||||
friend class Context;
|
||||
|
||||
struct ShaderKey {
|
||||
std::string name;
|
||||
ShaderStage stage = ShaderStage::kUnknown;
|
||||
|
||||
ShaderKey(const std::string_view& p_name, ShaderStage p_stage)
|
||||
: name({p_name.data(), p_name.size()}), stage(p_stage) {}
|
||||
|
||||
struct Hash {
|
||||
size_t operator()(const ShaderKey& key) const {
|
||||
return fml::HashCombine(key.name, key.stage);
|
||||
}
|
||||
};
|
||||
|
||||
struct Equal {
|
||||
constexpr bool operator()(const ShaderKey& k1,
|
||||
const ShaderKey& k2) const {
|
||||
return k1.stage == k2.stage && k1.name == k2.name;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
id<MTLLibrary> library_ = nullptr;
|
||||
using Functions = std::unordered_map<ShaderKey,
|
||||
std::shared_ptr<const ShaderFunction>,
|
||||
ShaderKey::Hash,
|
||||
ShaderKey::Equal>;
|
||||
Functions functions_;
|
||||
|
||||
ShaderLibrary(id<MTLLibrary> library);
|
||||
|
||||
|
||||
@ -11,6 +11,10 @@ ShaderFunction::ShaderFunction(id<MTLFunction> function, ShaderStage stage)
|
||||
|
||||
ShaderFunction::~ShaderFunction() = default;
|
||||
|
||||
id<MTLFunction> ShaderFunction::GetMTLFunction() const {
|
||||
return function_;
|
||||
}
|
||||
|
||||
ShaderStage ShaderFunction::GetStage() const {
|
||||
return stage_;
|
||||
}
|
||||
@ -19,14 +23,24 @@ ShaderLibrary::ShaderLibrary(id<MTLLibrary> library) : library_(library) {}
|
||||
|
||||
ShaderLibrary::~ShaderLibrary() = default;
|
||||
|
||||
std::shared_ptr<ShaderFunction> ShaderLibrary::GetFunction(
|
||||
std::shared_ptr<const ShaderFunction> ShaderLibrary::GetFunction(
|
||||
const std::string_view& name,
|
||||
ShaderStage stage) {
|
||||
ShaderKey key(name, stage);
|
||||
|
||||
if (auto found = functions_.find(key); found != functions_.end()) {
|
||||
return found->second;
|
||||
}
|
||||
|
||||
auto function = [library_ newFunctionWithName:@(name.data())];
|
||||
if (!function) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::shared_ptr<ShaderFunction>(new ShaderFunction(function, stage));
|
||||
|
||||
auto func =
|
||||
std::shared_ptr<ShaderFunction>(new ShaderFunction(function, stage));
|
||||
functions_[key] = func;
|
||||
return func;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -6,21 +6,21 @@
|
||||
|
||||
#include "box.frag.h"
|
||||
#include "box.vert.h"
|
||||
#include "impeller/compositor/pipeline_builder.h"
|
||||
#include "impeller/compositor/pipeline_descriptor.h"
|
||||
#include "impeller/compositor/shader_library.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
void RenderBox(std::shared_ptr<Context> context) {
|
||||
PipelineBuilder builder;
|
||||
|
||||
auto fragment_function = context->GetShaderLibrary()->GetFunction(
|
||||
shader::BoxFragmentInfo::kEntrypointName, ShaderStage::kFragment);
|
||||
auto vertex_function = context->GetShaderLibrary()->GetFunction(
|
||||
shader::BoxVertexInfo::kEntrypointName, ShaderStage::kVertex);
|
||||
|
||||
PipelineDescriptor builder;
|
||||
builder.SetLabel(shader::BoxVertexInfo::kLabel);
|
||||
builder.AddStageEntrypoint(vertex_function);
|
||||
builder.AddStageEntrypoint(fragment_function);
|
||||
builder.SetLabel(shader::BoxVertexInfo::kLabel);
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user