| Flutter Impeller |

playground_impl_mtl.mm
Go to the documentation of this file.
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/playground/backend/metal/playground_impl_mtl.h"
6 #include "impeller/renderer/backend/metal/swapchain_transients_mtl.h"
7
8 #define GLFW_INCLUDE_NONE
9 #import "third_party/glfw/include/GLFW/glfw3.h"
10
11 #define GLFW_EXPOSE_NATIVE_COCOA
12 #import "third_party/glfw/include/GLFW/glfw3native.h"
13
14 #include <Metal/Metal.h>
15 #include <QuartzCore/QuartzCore.h>
16
17 #include "flutter/fml/mapping.h"
18 #include "impeller/entity/mtl/entity_shaders.h"
19 #include "impeller/entity/mtl/framebuffer_blend_shaders.h"
20 #include "impeller/entity/mtl/modern_shaders.h"
21 #include "impeller/fixtures/mtl/fixtures_shaders.h"
22 #include "impeller/fixtures/mtl/modern_fixtures_shaders.h"
23 #include "impeller/playground/imgui/mtl/imgui_shaders.h"
24 #include "impeller/renderer/backend/metal/context_mtl.h"
25 #include "impeller/renderer/backend/metal/formats_mtl.h"
26 #include "impeller/renderer/backend/metal/surface_mtl.h"
27 #include "impeller/renderer/backend/metal/texture_mtl.h"
28 #include "impeller/renderer/mtl/compute_shaders.h"
29
30 namespace impeller {
31
32 struct PlaygroundImplMTL::Data {
33 CAMetalLayer* metal_layer = nil;
34 };
35
36 static std::vector<std::shared_ptr<fml::Mapping>>
37 ShaderLibraryMappingsForPlayground() {
38 return {std::make_shared<fml::NonOwnedMapping>(
39 impeller_entity_shaders_data, impeller_entity_shaders_length),
40 std::make_shared<fml::NonOwnedMapping>(
41 impeller_modern_shaders_data, impeller_modern_shaders_length),
42 std::make_shared<fml::NonOwnedMapping>(
43 impeller_framebuffer_blend_shaders_data,
44 impeller_framebuffer_blend_shaders_length),
45 std::make_shared<fml::NonOwnedMapping>(
46 impeller_fixtures_shaders_data, impeller_fixtures_shaders_length),
47 std::make_shared<fml::NonOwnedMapping>(
48 impeller_modern_fixtures_shaders_data,
49 impeller_modern_fixtures_shaders_length),
50 std::make_shared<fml::NonOwnedMapping>(impeller_imgui_shaders_data,
51 impeller_imgui_shaders_length),
52 std::make_shared<fml::NonOwnedMapping>(
53 impeller_compute_shaders_data, impeller_compute_shaders_length)
54
55 };
56 }
57
58 void PlaygroundImplMTL::DestroyWindowHandle(WindowHandle handle) {
59 if (!handle) {
60 return;
61 }
62 ::glfwDestroyWindow(reinterpret_cast<GLFWwindow*>(handle));
63 }
64
65 PlaygroundImplMTL::PlaygroundImplMTL(PlaygroundSwitches switches)
66 : PlaygroundImpl(switches),
67 handle_(nullptr, &DestroyWindowHandle),
68 data_(std::make_unique<Data>()),
69 concurrent_loop_(fml::ConcurrentMessageLoop::Create()),
70 is_gpu_disabled_sync_switch_(new fml::SyncSwitch(false)) {
71 ::glfwDefaultWindowHints();
72 ::glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
73 ::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
74 auto window = ::glfwCreateWindow(1, 1, "Test", nullptr, nullptr);
75 if (!window) {
76 return;
77 }
78
79 auto context = ContextMTL::Create(
80 switches.flags, ShaderLibraryMappingsForPlayground(),
81 is_gpu_disabled_sync_switch_, "Playground Library",
82 switches.enable_wide_gamut
83 ? std::optional<PixelFormat>(PixelFormat::kB10G10R10A10XR)
84 : std::nullopt);
85 if (!context) {
86 return;
87 }
88 NSWindow* cocoa_window = ::glfwGetCocoaWindow(window);
89 if (cocoa_window == nil) {
90 return;
91 }
92 data_->metal_layer = [CAMetalLayer layer];
93 data_->metal_layer.device = ContextMTL::Cast(*context).GetMTLDevice();
94 data_->metal_layer.pixelFormat =
95 ToMTLPixelFormat(context->GetCapabilities()->GetDefaultColorFormat());
96 data_->metal_layer.framebufferOnly = NO;
97 cocoa_window.contentView.layer = data_->metal_layer;
98 cocoa_window.contentView.wantsLayer = YES;
99
100 handle_.reset(window);
101 context_ = std::move(context);
102 swapchain_transients_ = std::make_shared<SwapchainTransientsMTL>(
103 context_->GetResourceAllocator());
104 }
105
106 PlaygroundImplMTL::~PlaygroundImplMTL() = default;
107
108 std::shared_ptr<Context> PlaygroundImplMTL::GetContext() const {
109 return context_;
110 }
111
112 // |PlaygroundImpl|
113 PlaygroundImpl::WindowHandle PlaygroundImplMTL::GetWindowHandle() const {
114 return handle_.get();
115 }
116
117 // |PlaygroundImpl|
118 std::unique_ptr<Surface> PlaygroundImplMTL::AcquireSurfaceFrame(
119 std::shared_ptr<Context> context) {
120 if (!data_->metal_layer) {
121 return nullptr;
122 }
123
124 const auto layer_size = data_->metal_layer.bounds.size;
125 const auto scale = GetContentScale();
126 data_->metal_layer.drawableSize =
127 CGSizeMake(layer_size.width * scale.x, layer_size.height * scale.y);
128
129 auto drawable =
130 SurfaceMTL::GetMetalDrawableAndValidate(context, data_->metal_layer);
131 return SurfaceMTL::MakeFromMetalLayerDrawable(context, drawable,
132 swapchain_transients_);
133 }
134
135 fml::Status PlaygroundImplMTL::SetCapabilities(
136 const std::shared_ptr<Capabilities>& capabilities) {
137 context_->SetCapabilities(capabilities);
138 return fml::Status();
139 }
140
141 } // namespace impeller
impeller::BackendCast< ContextMTL, Context >::Cast
static ContextMTL & Cast(Context &base)
Definition: backend_cast.h:13
impeller::ContextMTL::Create
static std::shared_ptr< ContextMTL > Create(const Flags &flags, const std::vector< std::string > &shader_library_paths, std::shared_ptr< const fml::SyncSwitch > is_gpu_disabled_sync_switch)
Definition: context_mtl.mm:239
impeller::ContextMTL::GetMTLDevice
id< MTLDevice > GetMTLDevice() const
Definition: context_mtl.mm:371
impeller::PlaygroundImpl
Definition: playground_impl.h:18
impeller::PlaygroundImpl::GetContentScale
Vector2 GetContentScale() const
Definition: playground_impl.cc:60
impeller::PlaygroundImpl::WindowHandle
void * WindowHandle
Definition: playground_impl.h:25
impeller::PlaygroundImplMTL::~PlaygroundImplMTL
~PlaygroundImplMTL()
impeller::PlaygroundImplMTL::SetCapabilities
fml::Status SetCapabilities(const std::shared_ptr< Capabilities > &capabilities) override
Definition: playground_impl_mtl.mm:135
impeller::PlaygroundImplMTL::PlaygroundImplMTL
PlaygroundImplMTL(PlaygroundSwitches switches)
Definition: playground_impl_mtl.mm:65
impeller::SurfaceMTL::MakeFromMetalLayerDrawable
static std::unique_ptr< SurfaceMTL > MakeFromMetalLayerDrawable(const std::shared_ptr< Context > &context, id< CAMetalDrawable > drawable, const std::shared_ptr< SwapchainTransientsMTL > &transients, std::optional< IRect > clip_rect=std::nullopt)
Definition: surface_mtl.mm:113
impeller::SurfaceMTL::GetMetalDrawableAndValidate
static id< CAMetalDrawable > GetMetalDrawableAndValidate(const std::shared_ptr< Context > &context, CAMetalLayer *layer)
Wraps the current drawable of the given Metal layer to create a surface Impeller can render to....
Definition: surface_mtl.mm:29
formats_mtl.h
fml
Definition: metal_screenshot.h:16
impeller::interop::Create
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:161
impeller
Definition: allocation.cc:12
impeller::PixelFormat::kB10G10R10A10XR
@ kB10G10R10A10XR
impeller::ShaderLibraryMappingsForPlayground
static std::vector< std::shared_ptr< fml::Mapping > > ShaderLibraryMappingsForPlayground()
Definition: playground_impl_gles.cc:106
impeller::ToMTLPixelFormat
constexpr MTLPixelFormat ToMTLPixelFormat(PixelFormat format)
Definition: formats_mtl.h:76
std
Definition: comparable.h:95
playground_impl_mtl.h
context_mtl.h
surface_mtl.h
scale
const Scalar scale
Definition: stroke_path_geometry.cc:319
impeller::PlaygroundImplMTL::Data
Definition: playground_impl_mtl.mm:32
impeller::PlaygroundImplMTL::Data::metal_layer
CAMetalLayer * metal_layer
Definition: playground_impl_mtl.mm:33
impeller::PlaygroundSwitches
Definition: switches.h:16
impeller::PlaygroundSwitches::flags
Flags flags
Definition: switches.h:38
impeller::PlaygroundSwitches::enable_wide_gamut
bool enable_wide_gamut
Definition: switches.h:36
swapchain_transients_mtl.h
texture_mtl.h