Skip to main content

surfman/
macros.rs

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