diff --git a/engine/src/flutter/impeller/host/impeller_renderer.mm b/engine/src/flutter/impeller/host/impeller_renderer.mm index 87a3906b0ae..51ea49a43c1 100644 --- a/engine/src/flutter/impeller/host/impeller_renderer.mm +++ b/engine/src/flutter/impeller/host/impeller_renderer.mm @@ -41,7 +41,7 @@ static const size_t kAlignedUniformsSize = (sizeof(Uniforms) & ~0xFF) + 0x100; float _rotation; MTKMesh* _mesh; - impeller::Renderer renderer_; + std::unique_ptr renderer_; } - (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)view { @@ -53,7 +53,9 @@ static const size_t kAlignedUniformsSize = (sizeof(Uniforms) & ~0xFF) + 0x100; [self _loadAssets]; } - if (!renderer_.IsValid()) { + renderer_ = std::make_unique( + impeller::ImpellerShadersDirectory()); + if (!renderer_->IsValid()) { FML_LOG(ERROR) << "Impeller Renderer is not valid."; } @@ -226,7 +228,7 @@ static const size_t kAlignedUniformsSize = (sizeof(Uniforms) & ~0xFF) + 0x100; } - (void)drawInMTKView:(nonnull MTKView*)view { - renderer_.Render(); + renderer_->Render(); /// Per frame updates here dispatch_semaphore_wait(_inFlightSemaphore, DISPATCH_TIME_FOREVER); @@ -301,7 +303,7 @@ static const size_t kAlignedUniformsSize = (sizeof(Uniforms) & ~0xFF) + 0x100; } - (void)mtkView:(nonnull MTKView*)view drawableSizeWillChange:(CGSize)size { - renderer_.SurfaceSizeDidChange({size.width, size.height}); + renderer_->SurfaceSizeDidChange({size.width, size.height}); float aspect = size.width / (float)size.height; _projectionMatrix = matrix_perspective_right_hand(65.0f * (M_PI / 180.0f), diff --git a/engine/src/flutter/impeller/host/shaders_location.cc b/engine/src/flutter/impeller/host/shaders_location.cc index 3e9fb5518ca..6ce60a7ef6c 100644 --- a/engine/src/flutter/impeller/host/shaders_location.cc +++ b/engine/src/flutter/impeller/host/shaders_location.cc @@ -9,16 +9,16 @@ namespace impeller { -std::optional ImpellerShadersLocation(std::string library_name) { - auto executable_directory = fml::paths::GetExecutableDirectoryPath(); - - if (!executable_directory.first) { - FML_LOG(ERROR) << "Shaders directory could not be found."; - return std::nullopt; +std::string ImpellerShadersDirectory() { + auto path_result = fml::paths::GetExecutableDirectoryPath(); + if (!path_result.first) { + return {}; } + return fml::paths::JoinPaths({path_result.second, "shaders"}); +} - auto path = fml::paths::JoinPaths( - {executable_directory.second, "shaders", library_name}); +std::optional ImpellerShadersLocation(std::string library_name) { + auto path = fml::paths::JoinPaths({ImpellerShadersDirectory(), library_name}); if (!fml::IsFile(path)) { FML_LOG(ERROR) << "The shader library does not exist: " << path; diff --git a/engine/src/flutter/impeller/host/shaders_location.h b/engine/src/flutter/impeller/host/shaders_location.h index f449810835e..cd26132f127 100644 --- a/engine/src/flutter/impeller/host/shaders_location.h +++ b/engine/src/flutter/impeller/host/shaders_location.h @@ -7,6 +7,8 @@ namespace impeller { +std::string ImpellerShadersDirectory(); + std::optional ImpellerShadersLocation(std::string library_name); } // namespace impeller diff --git a/engine/src/flutter/impeller/impeller/BUILD.gn b/engine/src/flutter/impeller/impeller/BUILD.gn index aa4ff9845b0..e8b1abe59d2 100644 --- a/engine/src/flutter/impeller/impeller/BUILD.gn +++ b/engine/src/flutter/impeller/impeller/BUILD.gn @@ -23,6 +23,10 @@ source_set("impeller") { cflags_objc = flutter_cflags_objc_arc cflags_objcc = flutter_cflags_objcc_arc + if (is_clang) { + cflags_cc = [ "-Wno-unused-private-field" ] + } + include_dirs = [ "entity", "geometry", @@ -45,6 +49,8 @@ source_set("impeller") { "compositor/shader_library.mm", "compositor/surface.h", "compositor/surface.mm", + "compositor/vertex_descriptor.h", + "compositor/vertex_descriptor.mm", ] geometry_sources = [ diff --git a/engine/src/flutter/impeller/impeller/compositor/context.h b/engine/src/flutter/impeller/impeller/compositor/context.h index 163239a7c34..dc007ba4d7e 100644 --- a/engine/src/flutter/impeller/impeller/compositor/context.h +++ b/engine/src/flutter/impeller/impeller/compositor/context.h @@ -6,13 +6,17 @@ #include +#include + #include "flutter/fml/macros.h" namespace impeller { +class ShaderLibrary; + class Context { public: - Context(); + Context(std::string shaders_directory); ~Context(); @@ -22,10 +26,13 @@ class Context { id GetTransferQueue() const; + std::shared_ptr GetShaderLibrary() const; + private: - id device_; - id render_queue_; - id transfer_queue_; + id device_ = nullptr; + id render_queue_ = nullptr; + id transfer_queue_ = nullptr; + std::shared_ptr shader_library_; bool is_valid_ = false; FML_DISALLOW_COPY_AND_ASSIGN(Context); diff --git a/engine/src/flutter/impeller/impeller/compositor/context.mm b/engine/src/flutter/impeller/impeller/compositor/context.mm index e64025f84c0..702e9a4ffa1 100644 --- a/engine/src/flutter/impeller/impeller/compositor/context.mm +++ b/engine/src/flutter/impeller/impeller/compositor/context.mm @@ -5,14 +5,19 @@ #include "context.h" #include "flutter/fml/logging.h" +#include "flutter/fml/paths.h" +#include "impeller/compositor/shader_library.h" namespace impeller { -Context::Context() : device_(::MTLCreateSystemDefaultDevice()) { +Context::Context(std::string shaders_directory) + : device_(::MTLCreateSystemDefaultDevice()) { + // Setup device. if (!device_) { return; } + // Setup command queues. render_queue_ = device_.newCommandQueue; transfer_queue_ = device_.newCommandQueue; @@ -23,6 +28,25 @@ Context::Context() : device_(::MTLCreateSystemDefaultDevice()) { render_queue_.label = @"Impeller Render Queue"; transfer_queue_.label = @"Impeller Transfer Queue"; + // Setup the shader library. + { + NSError* shader_library_error = nil; + auto shader_library_path = + fml::paths::JoinPaths({shaders_directory, "impeller.metallib"}); + id library = + [device_ newLibraryWithFile:@(shader_library_path.c_str()) + error:&shader_library_error]; + if (!library) { + FML_LOG(ERROR) << "Could not create shader library: " + << shader_library_error.localizedDescription.UTF8String; + return; + } + + // std::make_shared disallowed because of private friend ctor. + shader_library_ = + std::shared_ptr(new ShaderLibrary(library)); + } + is_valid_ = true; } diff --git a/engine/src/flutter/impeller/impeller/compositor/pipeline_builder.h b/engine/src/flutter/impeller/impeller/compositor/pipeline_builder.h index d2e1c7002e0..0afa12fdb44 100644 --- a/engine/src/flutter/impeller/impeller/compositor/pipeline_builder.h +++ b/engine/src/flutter/impeller/impeller/compositor/pipeline_builder.h @@ -4,8 +4,12 @@ #pragma once +#include + #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 { @@ -15,7 +19,17 @@ class PipelineBuilder { ~PipelineBuilder(); - PipelineDescriptor Build() const; + PipelineBuilder& SetLabel(); + + PipelineBuilder& SetSampleCountCount(size_t samples); + + PipelineBuilder& SetVertexFunction(std::shared_ptr function); + + PipelineBuilder& SetFragmentFunction( + std::shared_ptr function); + + PipelineBuilder& SetVertexDescriptor( + std::shared_ptr vertex_descriptor); private: FML_DISALLOW_COPY_AND_ASSIGN(PipelineBuilder); diff --git a/engine/src/flutter/impeller/impeller/compositor/renderer.h b/engine/src/flutter/impeller/impeller/compositor/renderer.h index 8fc32a5e89d..7765af8764e 100644 --- a/engine/src/flutter/impeller/impeller/compositor/renderer.h +++ b/engine/src/flutter/impeller/impeller/compositor/renderer.h @@ -15,7 +15,7 @@ namespace impeller { class Renderer { public: - Renderer(); + Renderer(std::string shaders_directory); ~Renderer(); diff --git a/engine/src/flutter/impeller/impeller/compositor/renderer.mm b/engine/src/flutter/impeller/impeller/compositor/renderer.mm index 5d5b8ac45af..8ff3f03f53f 100644 --- a/engine/src/flutter/impeller/impeller/compositor/renderer.mm +++ b/engine/src/flutter/impeller/impeller/compositor/renderer.mm @@ -8,8 +8,8 @@ namespace impeller { -Renderer::Renderer() - : context_(std::make_shared()), +Renderer::Renderer(std::string shaders_directory) + : context_(std::make_shared(std::move(shaders_directory))), surface_(std::make_unique(context_)) { if (!context_->IsValid()) { return; diff --git a/engine/src/flutter/impeller/impeller/compositor/shader_library.h b/engine/src/flutter/impeller/impeller/compositor/shader_library.h index 6d62e86a973..dede6505e29 100644 --- a/engine/src/flutter/impeller/impeller/compositor/shader_library.h +++ b/engine/src/flutter/impeller/impeller/compositor/shader_library.h @@ -4,17 +4,53 @@ #pragma once +#include + +#include +#include + #include "flutter/fml/macros.h" namespace impeller { -class ShaderLibrary { - public: - ShaderLibrary(); +class Context; - ~ShaderLibrary(); +enum class ShaderStage { + kVertex, + kFragment, +}; + +class ShaderFunction { + public: + ~ShaderFunction(); + + ShaderStage GetStage() const; private: + friend class ShaderLibrary; + + id function_ = nullptr; + ShaderStage stage_; + + ShaderFunction(id function, ShaderStage stage); + + FML_DISALLOW_COPY_AND_ASSIGN(ShaderFunction); +}; + +class ShaderLibrary { + public: + ~ShaderLibrary(); + + std::shared_ptr GetFunction(const std::string& name, + ShaderStage stage); + + private: + friend class Context; + + id library_ = nullptr; + + ShaderLibrary(id library); + FML_DISALLOW_COPY_AND_ASSIGN(ShaderLibrary); }; diff --git a/engine/src/flutter/impeller/impeller/compositor/shader_library.mm b/engine/src/flutter/impeller/impeller/compositor/shader_library.mm index e69de29bb2d..821ebc50d88 100644 --- a/engine/src/flutter/impeller/impeller/compositor/shader_library.mm +++ b/engine/src/flutter/impeller/impeller/compositor/shader_library.mm @@ -0,0 +1,32 @@ +// 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/shader_library.h" + +namespace impeller { + +ShaderFunction::ShaderFunction(id function, ShaderStage stage) + : function_(function), stage_(stage) {} + +ShaderFunction::~ShaderFunction() = default; + +ShaderStage ShaderFunction::GetStage() const { + return stage_; +} + +ShaderLibrary::ShaderLibrary(id library) : library_(library) {} + +ShaderLibrary::~ShaderLibrary() = default; + +std::shared_ptr ShaderLibrary::GetFunction( + const std::string& name, + ShaderStage stage) { + auto function = [library_ newFunctionWithName:@(name.c_str())]; + if (!function) { + return nullptr; + } + return std::shared_ptr(new ShaderFunction(function, stage)); +} + +} // namespace impeller diff --git a/engine/src/flutter/impeller/impeller/compositor/surface.h b/engine/src/flutter/impeller/impeller/compositor/surface.h index a172a0e6b30..fed78ce1528 100644 --- a/engine/src/flutter/impeller/impeller/compositor/surface.h +++ b/engine/src/flutter/impeller/impeller/compositor/surface.h @@ -25,7 +25,7 @@ class Surface { private: std::shared_ptr context_; - dispatch_semaphore_t frames_in_flight_sema_; + dispatch_semaphore_t frames_in_flight_sema_ = nullptr; bool is_valid_ = false; FML_DISALLOW_COPY_AND_ASSIGN(Surface); diff --git a/engine/src/flutter/impeller/impeller/compositor/vertex_descriptor.h b/engine/src/flutter/impeller/impeller/compositor/vertex_descriptor.h new file mode 100644 index 00000000000..bda80d5a19e --- /dev/null +++ b/engine/src/flutter/impeller/impeller/compositor/vertex_descriptor.h @@ -0,0 +1,21 @@ +// 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" + +namespace impeller { + +class VertexDescriptor { + public: + VertexDescriptor(); + + ~VertexDescriptor(); + + private: + FML_DISALLOW_COPY_AND_ASSIGN(VertexDescriptor); +}; + +} // namespace impeller diff --git a/engine/src/flutter/impeller/impeller/compositor/vertex_descriptor.mm b/engine/src/flutter/impeller/impeller/compositor/vertex_descriptor.mm new file mode 100644 index 00000000000..f146a9265cb --- /dev/null +++ b/engine/src/flutter/impeller/impeller/compositor/vertex_descriptor.mm @@ -0,0 +1,13 @@ +// 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/vertex_descriptor.h" + +namespace impeller { + +VertexDescriptor::VertexDescriptor() = default; + +VertexDescriptor::~VertexDescriptor() = default; + +} // namespace impeller