surfman/
macros.rs

1// surfman/surfman/src/macros.rs
2//
3//! A macro for use in the top-level crate.
4
5/// When using `surfman`, you should place this macro at the top of your crate, like so:
6///
7/// ```ignore
8/// use surfman::macros::declare_surfman;
9///
10/// declare_surfman!();
11///
12/// fn main() { ... }
13/// ```
14///
15/// On Windows, this macro exports various linker flags that the GPU drivers look at to determine
16/// whether to use the integrated or discrete GPU. If you don't use this macro, `surfman` should
17/// still work, but you may get the wrong GPU.
18#[macro_export]
19macro_rules! declare_surfman {
20    () => {
21        #[cfg(target_os = "windows")]
22        #[link_section = ".drectve"]
23        #[no_mangle]
24        pub static _SURFMAN_LINK_ARGS: [u8; 74] =
25            *b" /export:NvOptimusEnablement /export:AmdPowerXpressRequestHighPerformance ";
26        #[cfg(target_os = "windows")]
27        #[no_mangle]
28        pub static mut NvOptimusEnablement: i32 = 1;
29        #[cfg(target_os = "windows")]
30        #[no_mangle]
31        pub static mut AmdPowerXpressRequestHighPerformance: i32 = 1;
32    };
33}
34
35/// Internal macro used for generating implementations of the `Connection` and `Device` traits.
36macro_rules! implement_interfaces {
37    () => {
38        mod implementation {
39            use super::connection::{Connection, NativeConnection};
40            use super::context::{Context, ContextDescriptor, NativeContext};
41            use super::device::{Adapter, Device, NativeDevice};
42            use super::surface::{NativeWidget, Surface, SurfaceTexture};
43            use euclid::default::Size2D;
44            use glow::Texture;
45            use std::os::raw::c_void;
46            use $crate::connection::Connection as ConnectionInterface;
47            use $crate::device::Device as DeviceInterface;
48            use $crate::info::GLApi;
49            use $crate::Error;
50            use $crate::{ContextAttributes, ContextID, SurfaceAccess, SurfaceInfo, SurfaceType};
51
52            impl ConnectionInterface for Connection {
53                type Adapter = Adapter;
54                type Device = Device;
55                type NativeConnection = NativeConnection;
56                type NativeDevice = NativeDevice;
57                type NativeWidget = NativeWidget;
58
59                #[inline]
60                fn new() -> Result<Connection, Error> {
61                    Connection::new()
62                }
63
64                #[inline]
65                fn native_connection(&self) -> Self::NativeConnection {
66                    Connection::native_connection(self)
67                }
68
69                #[inline]
70                fn gl_api(&self) -> GLApi {
71                    Connection::gl_api(self)
72                }
73
74                #[inline]
75                fn create_adapter(&self) -> Result<Self::Adapter, Error> {
76                    Connection::create_adapter(self)
77                }
78
79                #[inline]
80                fn create_hardware_adapter(&self) -> Result<Self::Adapter, Error> {
81                    Connection::create_hardware_adapter(self)
82                }
83
84                #[inline]
85                fn create_low_power_adapter(&self) -> Result<Self::Adapter, Error> {
86                    Connection::create_low_power_adapter(self)
87                }
88
89                #[inline]
90                fn create_software_adapter(&self) -> Result<Self::Adapter, Error> {
91                    Connection::create_software_adapter(self)
92                }
93
94                #[inline]
95                fn create_device(&self, adapter: &Adapter) -> Result<Self::Device, Error> {
96                    Connection::create_device(self, adapter)
97                }
98
99                #[inline]
100                unsafe fn create_device_from_native_device(
101                    &self,
102                    native_device: Self::NativeDevice,
103                ) -> Result<Device, Error> {
104                    Connection::create_device_from_native_device(self, native_device)
105                }
106
107                #[inline]
108                #[cfg(feature = "sm-raw-window-handle-05")]
109                fn from_raw_display_handle(
110                    raw_handle: rwh_05::RawDisplayHandle,
111                ) -> Result<Connection, Error> {
112                    Connection::from_raw_display_handle(raw_handle)
113                }
114
115                #[inline]
116                #[cfg(feature = "sm-raw-window-handle-06")]
117                fn from_display_handle(handle: rwh_06::DisplayHandle) -> Result<Connection, Error> {
118                    Connection::from_display_handle(handle)
119                }
120
121                #[inline]
122                unsafe fn create_native_widget_from_ptr(
123                    &self,
124                    raw: *mut c_void,
125                    size: Size2D<i32>,
126                ) -> Self::NativeWidget {
127                    Connection::create_native_widget_from_ptr(self, raw, size)
128                }
129
130                #[inline]
131                #[cfg(feature = "sm-raw-window-handle-05")]
132                fn create_native_widget_from_raw_window_handle(
133                    &self,
134                    window: rwh_05::RawWindowHandle,
135                    size: Size2D<i32>,
136                ) -> Result<Self::NativeWidget, Error> {
137                    Connection::create_native_widget_from_raw_window_handle(self, window, size)
138                }
139
140                #[inline]
141                #[cfg(feature = "sm-raw-window-handle-06")]
142                fn create_native_widget_from_window_handle(
143                    &self,
144                    window: rwh_06::WindowHandle,
145                    size: Size2D<i32>,
146                ) -> Result<Self::NativeWidget, Error> {
147                    Connection::create_native_widget_from_window_handle(self, window, size)
148                }
149            }
150
151            impl DeviceInterface for Device {
152                type Connection = Connection;
153                type Context = Context;
154                type ContextDescriptor = ContextDescriptor;
155                type NativeContext = NativeContext;
156                type Surface = Surface;
157                type SurfaceTexture = SurfaceTexture;
158
159                // device.rs
160
161                /// Returns the native device associated with this device.
162                #[inline]
163                fn native_device(&self) -> <Self::Connection as ConnectionInterface>::NativeDevice {
164                    Device::native_device(self)
165                }
166
167                #[inline]
168                fn connection(&self) -> Connection {
169                    Device::connection(self)
170                }
171
172                #[inline]
173                fn adapter(&self) -> Adapter {
174                    Device::adapter(self)
175                }
176
177                #[inline]
178                fn gl_api(&self) -> GLApi {
179                    Device::gl_api(self)
180                }
181
182                // context.rs
183
184                #[inline]
185                fn create_context_descriptor(
186                    &self,
187                    attributes: &ContextAttributes,
188                ) -> Result<Self::ContextDescriptor, Error> {
189                    Device::create_context_descriptor(self, attributes)
190                }
191
192                #[inline]
193                fn create_context(
194                    &mut self,
195                    descriptor: &Self::ContextDescriptor,
196                    share_with: Option<&Self::Context>,
197                ) -> Result<Self::Context, Error> {
198                    Device::create_context(self, descriptor, share_with)
199                }
200
201                #[inline]
202                unsafe fn create_context_from_native_context(
203                    &self,
204                    native_context: Self::NativeContext,
205                ) -> Result<Self::Context, Error> {
206                    Device::create_context_from_native_context(self, native_context)
207                }
208
209                #[inline]
210                fn destroy_context(&self, context: &mut Self::Context) -> Result<(), Error> {
211                    Device::destroy_context(self, context)
212                }
213
214                #[inline]
215                fn context_descriptor(&self, context: &Self::Context) -> Self::ContextDescriptor {
216                    Device::context_descriptor(self, context)
217                }
218
219                #[inline]
220                fn make_context_current(&self, context: &Self::Context) -> Result<(), Error> {
221                    Device::make_context_current(self, context)
222                }
223
224                #[inline]
225                fn make_no_context_current(&self) -> Result<(), Error> {
226                    Device::make_no_context_current(self)
227                }
228
229                #[inline]
230                fn context_descriptor_attributes(
231                    &self,
232                    context_descriptor: &Self::ContextDescriptor,
233                ) -> ContextAttributes {
234                    Device::context_descriptor_attributes(self, context_descriptor)
235                }
236
237                #[inline]
238                fn get_proc_address(
239                    &self,
240                    context: &Self::Context,
241                    symbol_name: &str,
242                ) -> *const c_void {
243                    Device::get_proc_address(self, context, symbol_name)
244                }
245
246                #[inline]
247                fn bind_surface_to_context(
248                    &self,
249                    context: &mut Self::Context,
250                    surface: Self::Surface,
251                ) -> Result<(), (Error, Self::Surface)> {
252                    Device::bind_surface_to_context(self, context, surface)
253                }
254
255                #[inline]
256                fn unbind_surface_from_context(
257                    &self,
258                    context: &mut Self::Context,
259                ) -> Result<Option<Self::Surface>, Error> {
260                    Device::unbind_surface_from_context(self, context)
261                }
262
263                #[inline]
264                fn context_id(&self, context: &Self::Context) -> ContextID {
265                    Device::context_id(self, context)
266                }
267
268                #[inline]
269                fn context_surface_info(
270                    &self,
271                    context: &Self::Context,
272                ) -> Result<Option<SurfaceInfo>, Error> {
273                    Device::context_surface_info(self, context)
274                }
275
276                #[inline]
277                fn native_context(&self, context: &Self::Context) -> Self::NativeContext {
278                    Device::native_context(self, context)
279                }
280
281                // surface.rs
282
283                #[inline]
284                fn create_surface(
285                    &mut self,
286                    context: &Self::Context,
287                    surface_access: SurfaceAccess,
288                    surface_type: SurfaceType<NativeWidget>,
289                ) -> Result<Self::Surface, Error> {
290                    Device::create_surface(self, context, surface_access, surface_type)
291                }
292
293                #[inline]
294                fn create_surface_texture(
295                    &self,
296                    context: &mut Self::Context,
297                    surface: Self::Surface,
298                ) -> Result<Self::SurfaceTexture, (Error, Self::Surface)> {
299                    Device::create_surface_texture(self, context, surface)
300                }
301
302                #[inline]
303                fn destroy_surface(
304                    &self,
305                    context: &mut Self::Context,
306                    surface: &mut Self::Surface,
307                ) -> Result<(), Error> {
308                    Device::destroy_surface(self, context, surface)
309                }
310
311                #[inline]
312                fn destroy_surface_texture(
313                    &self,
314                    context: &mut Self::Context,
315                    surface_texture: Self::SurfaceTexture,
316                ) -> Result<Self::Surface, (Error, Self::SurfaceTexture)> {
317                    Device::destroy_surface_texture(self, context, surface_texture)
318                }
319
320                #[inline]
321                fn surface_gl_texture_target(&self) -> u32 {
322                    Device::surface_gl_texture_target(self)
323                }
324
325                #[inline]
326                fn present_surface(
327                    &self,
328                    context: &Self::Context,
329                    surface: &mut Self::Surface,
330                ) -> Result<(), Error> {
331                    Device::present_surface(self, context, surface)
332                }
333
334                #[inline]
335                fn resize_surface(
336                    &self,
337                    context: &Context,
338                    surface: &mut Surface,
339                    size: Size2D<i32>,
340                ) -> Result<(), Error> {
341                    Device::resize_surface(self, context, surface, size)
342                }
343
344                #[inline]
345                fn surface_info(&self, surface: &Self::Surface) -> SurfaceInfo {
346                    Device::surface_info(self, surface)
347                }
348
349                #[inline]
350                fn surface_texture_object(
351                    &self,
352                    surface_texture: &Self::SurfaceTexture,
353                ) -> Option<Texture> {
354                    Device::surface_texture_object(self, surface_texture)
355                }
356            }
357        }
358    };
359}
360
361pub(crate) use implement_interfaces;