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;
38            use super::context::{Context, ContextDescriptor};
39            use super::device::{Adapter, Device};
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 NativeWidget = NativeWidget;
54
55                #[inline]
56                fn new() -> Result<Connection, Error> {
57                    Connection::new()
58                }
59
60                #[inline]
61                fn gl_api(&self) -> GLApi {
62                    Connection::gl_api(self)
63                }
64
65                #[inline]
66                fn create_adapter(&self) -> Result<Self::Adapter, Error> {
67                    Connection::create_adapter(self)
68                }
69
70                #[inline]
71                fn create_hardware_adapter(&self) -> Result<Self::Adapter, Error> {
72                    Connection::create_hardware_adapter(self)
73                }
74
75                #[inline]
76                fn create_low_power_adapter(&self) -> Result<Self::Adapter, Error> {
77                    Connection::create_low_power_adapter(self)
78                }
79
80                #[inline]
81                fn create_software_adapter(&self) -> Result<Self::Adapter, Error> {
82                    Connection::create_software_adapter(self)
83                }
84
85                #[inline]
86                fn create_device(&self, adapter: &Adapter) -> Result<Self::Device, Error> {
87                    Connection::create_device(self, adapter)
88                }
89
90                #[inline]
91                fn from_display_handle(
92                    handle: raw_window_handle::DisplayHandle,
93                ) -> Result<Connection, Error> {
94                    Connection::from_display_handle(handle)
95                }
96
97                #[inline]
98                unsafe fn create_native_widget_from_ptr(
99                    &self,
100                    raw: *mut c_void,
101                    size: Size2D<i32>,
102                ) -> Self::NativeWidget {
103                    Connection::create_native_widget_from_ptr(self, raw, size)
104                }
105
106                #[inline]
107                fn create_native_widget_from_window_handle(
108                    &self,
109                    window: raw_window_handle::WindowHandle,
110                    size: Size2D<i32>,
111                ) -> Result<Self::NativeWidget, Error> {
112                    Connection::create_native_widget_from_window_handle(self, window, size)
113                }
114            }
115
116            impl DeviceInterface for Device {
117                type Connection = Connection;
118                type Context = Context;
119                type ContextDescriptor = ContextDescriptor;
120                type Surface = Surface;
121                type SurfaceTexture = SurfaceTexture;
122
123                // device.rs
124
125                #[inline]
126                fn connection(&self) -> Connection {
127                    Device::connection(self)
128                }
129
130                #[inline]
131                fn adapter(&self) -> Adapter {
132                    Device::adapter(self)
133                }
134
135                #[inline]
136                fn gl_api(&self) -> GLApi {
137                    Device::gl_api(self)
138                }
139
140                // context.rs
141
142                #[inline]
143                fn create_context_descriptor(
144                    &self,
145                    attributes: &ContextAttributes,
146                ) -> Result<Self::ContextDescriptor, Error> {
147                    Device::create_context_descriptor(self, attributes)
148                }
149
150                #[inline]
151                fn create_context(
152                    &self,
153                    descriptor: &Self::ContextDescriptor,
154                    share_with: Option<&Self::Context>,
155                ) -> Result<Self::Context, Error> {
156                    Device::create_context(self, descriptor, share_with)
157                }
158
159                #[inline]
160                fn destroy_context(&self, context: &mut Self::Context) -> Result<(), Error> {
161                    Device::destroy_context(self, context)
162                }
163
164                #[inline]
165                fn context_descriptor(&self, context: &Self::Context) -> Self::ContextDescriptor {
166                    Device::context_descriptor(self, context)
167                }
168
169                #[inline]
170                fn make_context_current(&self, context: &Self::Context) -> Result<(), Error> {
171                    Device::make_context_current(self, context)
172                }
173
174                #[inline]
175                fn make_no_context_current(&self) -> Result<(), Error> {
176                    Device::make_no_context_current(self)
177                }
178
179                #[inline]
180                fn context_descriptor_attributes(
181                    &self,
182                    context_descriptor: &Self::ContextDescriptor,
183                ) -> ContextAttributes {
184                    Device::context_descriptor_attributes(self, context_descriptor)
185                }
186
187                #[inline]
188                fn get_proc_address(
189                    &self,
190                    context: &Self::Context,
191                    symbol_name: &str,
192                ) -> *const c_void {
193                    Device::get_proc_address(self, context, symbol_name)
194                }
195
196                #[inline]
197                fn bind_surface_to_context(
198                    &self,
199                    context: &mut Self::Context,
200                    surface: Self::Surface,
201                ) -> Result<(), (Error, Self::Surface)> {
202                    Device::bind_surface_to_context(self, context, surface)
203                }
204
205                #[inline]
206                fn unbind_surface_from_context(
207                    &self,
208                    context: &mut Self::Context,
209                ) -> Result<Option<Self::Surface>, Error> {
210                    Device::unbind_surface_from_context(self, context)
211                }
212
213                #[inline]
214                fn context_id(&self, context: &Self::Context) -> ContextID {
215                    Device::context_id(self, context)
216                }
217
218                #[inline]
219                fn context_surface_info(
220                    &self,
221                    context: &Self::Context,
222                ) -> Result<Option<SurfaceInfo>, Error> {
223                    Device::context_surface_info(self, context)
224                }
225
226                // surface.rs
227
228                #[inline]
229                fn create_surface(
230                    &self,
231                    context: &Self::Context,
232                    surface_access: SurfaceAccess,
233                    surface_type: SurfaceType<NativeWidget>,
234                ) -> Result<Self::Surface, Error> {
235                    Device::create_surface(self, context, surface_access, surface_type)
236                }
237
238                #[inline]
239                fn create_surface_texture(
240                    &self,
241                    context: &mut Self::Context,
242                    surface: Self::Surface,
243                ) -> Result<Self::SurfaceTexture, (Error, Self::Surface)> {
244                    Device::create_surface_texture(self, context, surface)
245                }
246
247                #[inline]
248                fn destroy_surface(
249                    &self,
250                    context: &mut Self::Context,
251                    surface: &mut Self::Surface,
252                ) -> Result<(), Error> {
253                    Device::destroy_surface(self, context, surface)
254                }
255
256                #[inline]
257                fn destroy_surface_texture(
258                    &self,
259                    context: &mut Self::Context,
260                    surface_texture: Self::SurfaceTexture,
261                ) -> Result<Self::Surface, (Error, Self::SurfaceTexture)> {
262                    Device::destroy_surface_texture(self, context, surface_texture)
263                }
264
265                #[inline]
266                fn surface_gl_texture_target(&self) -> u32 {
267                    Device::surface_gl_texture_target(self)
268                }
269
270                #[inline]
271                fn present_bound_surface(&self, context: &mut Self::Context) -> Result<(), Error> {
272                    Device::present_bound_surface(self, context)
273                }
274
275                #[inline]
276                fn present_surface(
277                    &self,
278                    context: &Self::Context,
279                    surface: &mut Self::Surface,
280                ) -> Result<(), Error> {
281                    Device::present_surface(self, context, surface)
282                }
283
284                #[inline]
285                fn resize_bound_surface(
286                    &self,
287                    context: &mut Context,
288                    size: Size2D<i32>,
289                ) -> Result<(), Error> {
290                    Device::resize_bound_surface(self, context, size)
291                }
292
293                #[inline]
294                fn resize_surface(
295                    &self,
296                    context: &Context,
297                    surface: &mut Surface,
298                    size: Size2D<i32>,
299                ) -> Result<(), Error> {
300                    Device::resize_surface(self, context, surface, size)
301                }
302
303                #[inline]
304                fn surface_info(&self, surface: &Self::Surface) -> SurfaceInfo {
305                    Device::surface_info(self, surface)
306                }
307
308                #[inline]
309                fn surface_texture_object(
310                    &self,
311                    surface_texture: &Self::SurfaceTexture,
312                ) -> Option<Texture> {
313                    Device::surface_texture_object(self, surface_texture)
314                }
315            }
316        }
317    };
318}
319
320pub(crate) use implement_interfaces;