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 
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"
28 #include "impeller/renderer/mtl/compute_shaders.h"
29 
30 namespace impeller {
31 
33  CAMetalLayer* metal_layer = nil;
34 };
35 
36 static std::vector<std::shared_ptr<fml::Mapping>>
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 
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  std::optional<PixelFormat> wide_gamut_format = std::nullopt;
80  if (switches.enable_wide_gamut) {
81  wide_gamut_format = PixelFormat::kB10G10R10A10XR;
82  }
83  auto context = ContextMTL::Create(
85  is_gpu_disabled_sync_switch_, "Playground Library", wide_gamut_format);
86  if (!context) {
87  return;
88  }
89  NSWindow* cocoa_window = ::glfwGetCocoaWindow(window);
90  if (cocoa_window == nil) {
91  return;
92  }
93  data_->metal_layer = [CAMetalLayer layer];
94  data_->metal_layer.device = ContextMTL::Cast(*context).GetMTLDevice();
95  data_->metal_layer.pixelFormat =
96  ToMTLPixelFormat(context->GetCapabilities()->GetDefaultColorFormat());
97  data_->metal_layer.framebufferOnly = NO;
98  cocoa_window.contentView.layer = data_->metal_layer;
99  cocoa_window.contentView.wantsLayer = YES;
100 
101  handle_.reset(window);
102  context_ = std::move(context);
103  swapchain_transients_ = std::make_shared<SwapchainTransientsMTL>(
104  context_->GetResourceAllocator());
105 }
106 
108 
109 std::shared_ptr<Context> PlaygroundImplMTL::GetContext() const {
110  return context_;
111 }
112 
113 // |PlaygroundImpl|
114 PlaygroundImpl::WindowHandle PlaygroundImplMTL::GetWindowHandle() const {
115  return handle_.get();
116 }
117 
118 // |PlaygroundImpl|
119 std::unique_ptr<Surface> PlaygroundImplMTL::AcquireSurfaceFrame(
120  std::shared_ptr<Context> context) {
121  if (!data_->metal_layer) {
122  return nullptr;
123  }
124 
125  const auto layer_size = data_->metal_layer.bounds.size;
126  const auto scale = GetContentScale();
127  data_->metal_layer.drawableSize =
128  CGSizeMake(layer_size.width * scale.x, layer_size.height * scale.y);
129 
130  auto drawable =
131  SurfaceMTL::GetMetalDrawableAndValidate(context, data_->metal_layer);
132  return SurfaceMTL::MakeFromMetalLayerDrawable(context, drawable,
133  swapchain_transients_);
134 }
135 
137  const std::shared_ptr<Capabilities>& capabilities) {
138  context_->SetCapabilities(capabilities);
139  return fml::Status();
140 }
141 
142 void PlaygroundImplMTL::SetGPUDisabled(bool disabled) const {
143  is_gpu_disabled_sync_switch_->SetSwitch(disabled);
144 }
145 
146 } // namespace impeller
static ContextMTL & Cast(Context &base)
Definition: backend_cast.h:13
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:232
id< MTLDevice > GetMTLDevice() const
Definition: context_mtl.mm:364
Vector2 GetContentScale() const
fml::Status SetCapabilities(const std::shared_ptr< Capabilities > &capabilities) override
PlaygroundImplMTL(PlaygroundSwitches switches)
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
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
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:161
static std::vector< std::shared_ptr< fml::Mapping > > ShaderLibraryMappingsForPlayground()
constexpr MTLPixelFormat ToMTLPixelFormat(PixelFormat format)
Definition: formats_mtl.h:76
Definition: comparable.h:95