EchoMap
2026-07-25 6d3977c
An experimental cross-platform digital signal processing application for sound-source localisation.
Toggle main menu visibility
Loading...
Searching...
No Matches
SurfaceFactory.cpp
Go to the documentation of this file.
1
7
8
#include "
SurfaceFactory.hpp
"
9
10
#include <GLFW/glfw3.h>
11
12
#if defined(_WIN32)
13
#define GLFW_EXPOSE_NATIVE_WIN32 1
14
#define GOT_SUPPORTED_PLATFORM
15
#endif
16
17
#if defined(__APPLE__)
18
#define GLFW_EXPOSE_NATIVE_COCOA 1
19
#define GOT_SUPPORTED_PLATFORM
20
#endif
21
22
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
23
#define GLFW_EXPOSE_NATIVE_X11 1
24
#define GLFW_EXPOSE_NATIVE_WAYLAND 1
25
#define GOT_SUPPORTED_PLATFORM
26
#endif
27
28
#if defined(__EMSCRIPTEN__)
29
#define GOT_SUPPORTED_PLATFORM
30
#endif
31
32
#if !defined(GOT_SUPPORTED_PLATFORM)
33
#error "No supported platforms for the SurfaceFactory."
34
#error "Supported platforms are: Emscripten; Wayland; X11; Win32; Cocoa (Apple)."
35
#endif
36
37
#if !defined(__EMSCRIPTEN__)
38
#include <GLFW/glfw3native.h>
39
#endif
40
41
#if defined(__APPLE__)
42
43
// If we're on an Apple platform, define C++ shims to despatch messages through the Objective-C interface.
44
45
#include <objc/message.h>
46
#include <objc/objc.h>
47
#include <objc/runtime.h>
48
49
namespace
50
{
51
52
template
<
typename
T,
typename
... Args>
53
T objc_call(
id
obj,
const
char
*
const
sel, Args... args) {
54
using
FuncPtr = T (*)(id, SEL, Args...);
55
return
reinterpret_cast<
FuncPtr
>
(objc_msgSend)(obj, sel_registerName(sel), args...);
56
}
57
58
template
<
typename
T,
typename
... Args>
59
T objc_call(
const
char
*clazz,
const
char
*
const
sel, Args... args) {
60
return
objc_call<T>(
reinterpret_cast<
id
>
(objc_getClass(clazz)), sel, args...);
61
}
62
63
}
64
65
#endif
66
67
namespace
echomap
68
{
69
70
wgpu::Surface
SurfaceFactory::create_surface
(
71
const
wgpu::Instance& instance,
72
GLFWwindow* window
73
)
74
{
75
const
auto
chainedDescriptor =
get_surface_descriptor
(window);
76
if
(chainedDescriptor ==
nullptr
)
77
throw
std::runtime_error
(
"Could not create and bind a Surface to the given window."
);
78
79
wgpu::SurfaceDescriptor descriptor;
80
descriptor.nextInChain = chainedDescriptor.get();
81
82
return
instance.CreateSurface(&descriptor);
83
}
84
85
std::unique_ptr<wgpu::ChainedStruct>
SurfaceFactory::get_surface_descriptor
(
86
GLFWwindow*
const
window
87
)
88
{
89
// Verify that the window is valid in the runtime.
90
if
(glfwGetWindowAttrib(window, GLFW_CLIENT_API) != GLFW_NO_API)
91
return
nullptr
;
92
93
#if defined(__EMSCRIPTEN__)
94
auto
desc =
std::make_unique<wgpu::EmscriptenSurfaceSourceCanvasHTMLSelector>
();
95
desc->selector =
"#canvas"
;
96
return
desc;
97
#else
98
// Use the GLFW_EXPOSE_NATIVE_* flags to determine which GLFW platforms we can handle.
99
100
// ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
101
switch
(glfwGetPlatform()) {
102
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
103
case
GLFW_PLATFORM_WAYLAND: {
104
auto
desc =
std::make_unique<wgpu::SurfaceSourceWaylandSurface>
();
105
desc->display = glfwGetWaylandDisplay();
106
desc->surface = glfwGetWaylandWindow(window);
107
return
desc;
108
}
109
#endif
110
#if defined(GLFW_EXPOSE_NATIVE_X11)
111
case
GLFW_PLATFORM_X11: {
112
auto
desc =
std::make_unique<wgpu::SurfaceSourceXlibWindow>
();
113
desc->display = glfwGetX11Display();
114
desc->window = glfwGetX11Window(window);
115
return
desc;
116
}
117
#endif
118
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
119
case
GLFW_PLATFORM_WIN32: {
120
auto
desc =
std::make_unique<wgpu::SurfaceSourceWindowsHWND>
();
121
desc->hwnd = glfwGetWin32Window(window);
122
desc->hinstance = GetModuleHandle(
nullptr
);
123
return
desc;
124
}
125
#endif
126
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
127
case
GLFW_PLATFORM_COCOA: {
128
/*
129
* On Apple platforms, more work is required to configure the Metal layer on the Cocoa Surface through the
130
* Objective-C messaging APIs.
131
*/
132
auto
ns_window = glfwGetCocoaWindow(window);
133
CFRetain(ns_window);
134
135
auto
view = objc_call<id>(ns_window,
"contentView"
);
136
CFRetain(view);
137
138
objc_call<void, BOOL>(view,
"setWantsLayer:"
, YES);
139
auto
layer = objc_call<id>(
"CAMetalLayer"
,
"layer"
);
140
auto
scale_factor = objc_call<CGFloat>(ns_window,
"backingScaleFactor"
);
141
objc_call<void, CGFloat>(layer,
"setContentsScale:"
, scale_factor);
142
objc_call<void, id>(view,
"setLayer:"
, layer);
143
144
auto
desc =
std::make_unique<wgpu::SurfaceSourceMetalLayer>
();
145
desc->layer = layer;
146
CFRelease(view);
147
CFRelease(ns_window);
148
149
return
desc;
150
}
151
#endif
152
}
153
#endif
154
155
// No handlers were enabled. This should be caught be a compile-time check.
156
// ReSharper disable once CppDFAUnreachableCode
157
return
nullptr
;
158
}
159
160
}
// namespace echomap
SurfaceFactory.hpp
EchoMap WebGPU-GLFW Surface factory specification.
echomap::SurfaceFactory::create_surface
static wgpu::Surface create_surface(const wgpu::Instance &instance, GLFWwindow *window)
Creates and binds a Surface to the given GLFW window.
Definition
SurfaceFactory.cpp:70
echomap::SurfaceFactory::get_surface_descriptor
static std::unique_ptr< wgpu::ChainedStruct > get_surface_descriptor(GLFWwindow *window)
Produce an owning container of the WebGPU Surface descriptor for the given GLFW window.
Definition
SurfaceFactory.cpp:85
std::make_unique
T make_unique(T... args)
echomap
The main EchoMap outermost namespace for all non-exported symbols.
Definition
ActionController.hpp:20
std::runtime_error
std::unique_ptr
src
platform
SurfaceFactory.cpp
Generated by
1.17.0