This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
Expand file tree
/
Copy pathplayground_impl_mtl.mm
More file actions
127 lines (108 loc) · 4.5 KB
/
playground_impl_mtl.mm
File metadata and controls
127 lines (108 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// 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/playground/backend/metal/playground_impl_mtl.h"
#define GLFW_INCLUDE_NONE
#import "third_party/glfw/include/GLFW/glfw3.h"
#define GLFW_EXPOSE_NATIVE_COCOA
#import "third_party/glfw/include/GLFW/glfw3native.h"
#include <Metal/Metal.h>
#include <QuartzCore/QuartzCore.h>
#include "flutter/fml/mapping.h"
#include "impeller/entity/mtl/entity_shaders.h"
#include "impeller/entity/mtl/framebuffer_blend_shaders.h"
#include "impeller/entity/mtl/modern_shaders.h"
#include "impeller/fixtures/mtl/fixtures_shaders.h"
#include "impeller/playground/imgui/mtl/imgui_shaders.h"
#include "impeller/renderer/backend/metal/context_mtl.h"
#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/renderer/mtl/compute_shaders.h"
#include "impeller/scene/shaders/mtl/scene_shaders.h"
namespace impeller {
struct PlaygroundImplMTL::Data {
CAMetalLayer* metal_layer = nil;
};
static std::vector<std::shared_ptr<fml::Mapping>>
ShaderLibraryMappingsForPlayground() {
return {std::make_shared<fml::NonOwnedMapping>(
impeller_entity_shaders_data, impeller_entity_shaders_length),
std::make_shared<fml::NonOwnedMapping>(
impeller_modern_shaders_data, impeller_modern_shaders_length),
std::make_shared<fml::NonOwnedMapping>(
impeller_framebuffer_blend_shaders_data,
impeller_framebuffer_blend_shaders_length),
std::make_shared<fml::NonOwnedMapping>(
impeller_fixtures_shaders_data, 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),
std::make_shared<fml::NonOwnedMapping>(
impeller_compute_shaders_data, impeller_compute_shaders_length)
};
}
void PlaygroundImplMTL::DestroyWindowHandle(WindowHandle handle) {
if (!handle) {
return;
}
::glfwDestroyWindow(reinterpret_cast<GLFWwindow*>(handle));
}
PlaygroundImplMTL::PlaygroundImplMTL(PlaygroundSwitches switches)
: PlaygroundImpl(switches),
handle_(nullptr, &DestroyWindowHandle),
data_(std::make_unique<Data>()),
concurrent_loop_(fml::ConcurrentMessageLoop::Create()),
is_gpu_disabled_sync_switch_(new fml::SyncSwitch(false)) {
::glfwDefaultWindowHints();
::glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
::glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
auto window = ::glfwCreateWindow(1, 1, "Test", nullptr, nullptr);
if (!window) {
return;
}
auto worker_task_runner = concurrent_loop_->GetTaskRunner();
auto context = ContextMTL::Create(
ShaderLibraryMappingsForPlayground(), worker_task_runner,
is_gpu_disabled_sync_switch_, "Playground Library");
if (!context) {
return;
}
NSWindow* cocoa_window = ::glfwGetCocoaWindow(window);
if (cocoa_window == nil) {
return;
}
data_->metal_layer = [CAMetalLayer layer];
data_->metal_layer.device = ContextMTL::Cast(*context).GetMTLDevice();
data_->metal_layer.pixelFormat =
ToMTLPixelFormat(context->GetCapabilities()->GetDefaultColorFormat());
data_->metal_layer.framebufferOnly = NO;
cocoa_window.contentView.layer = data_->metal_layer;
cocoa_window.contentView.wantsLayer = YES;
handle_.reset(window);
context_ = std::move(context);
}
PlaygroundImplMTL::~PlaygroundImplMTL() = default;
std::shared_ptr<Context> PlaygroundImplMTL::GetContext() const {
return context_;
}
// |PlaygroundImpl|
PlaygroundImpl::WindowHandle PlaygroundImplMTL::GetWindowHandle() const {
return handle_.get();
}
// |PlaygroundImpl|
std::unique_ptr<Surface> PlaygroundImplMTL::AcquireSurfaceFrame(
std::shared_ptr<Context> context) {
if (!data_->metal_layer) {
return nullptr;
}
const auto layer_size = data_->metal_layer.bounds.size;
const auto scale = GetContentScale();
data_->metal_layer.drawableSize =
CGSizeMake(layer_size.width * scale.x, layer_size.height * scale.y);
auto drawable =
SurfaceMTL::GetMetalDrawableAndValidate(context, data_->metal_layer);
return SurfaceMTL::WrapCurrentMetalLayerDrawable(context, drawable);
}
} // namespace impeller