surfman/platform/generic/multi/
connection.rs1use super::device::{Adapter, Device, NativeDevice};
6use super::surface::NativeWidget;
7use crate::connection::Connection as ConnectionInterface;
8use crate::device::Device as DeviceInterface;
9use crate::Error;
10use crate::GLApi;
11
12use euclid::default::Size2D;
13
14use std::os::raw::c_void;
15
16pub enum Connection<Def, Alt>
18where
19 Def: DeviceInterface,
20 Alt: DeviceInterface,
21 Def::Connection: ConnectionInterface,
22 Alt::Connection: ConnectionInterface,
23{
24 Default(Def::Connection),
26 Alternate(Alt::Connection),
28}
29
30impl<Def, Alt> Clone for Connection<Def, Alt>
31where
32 Def: DeviceInterface,
33 Alt: DeviceInterface,
34 Def::Connection: Clone,
35 Alt::Connection: Clone,
36{
37 fn clone(&self) -> Self {
38 match self {
39 Connection::Default(ref connection) => Connection::Default(connection.clone()),
40 Connection::Alternate(ref connection) => Connection::Alternate(connection.clone()),
41 }
42 }
43}
44
45pub enum NativeConnection<Def, Alt>
47where
48 Def: DeviceInterface,
49 Alt: DeviceInterface,
50 Def::Connection: ConnectionInterface,
51 Alt::Connection: ConnectionInterface,
52{
53 Default(<Def::Connection as ConnectionInterface>::NativeConnection),
55 Alternate(<Alt::Connection as ConnectionInterface>::NativeConnection),
57}
58
59impl<Def, Alt> Connection<Def, Alt>
60where
61 Def: DeviceInterface,
62 Alt: DeviceInterface,
63 Def::Connection: ConnectionInterface<Device = Def>,
64 Alt::Connection: ConnectionInterface<Device = Alt>,
65{
66 #[inline]
68 pub fn new() -> Result<Connection<Def, Alt>, Error> {
69 match <Def::Connection>::new() {
70 Ok(connection) => Ok(Connection::Default(connection)),
71 Err(_) => <Alt::Connection>::new().map(Connection::Alternate),
72 }
73 }
74
75 pub fn native_connection(&self) -> NativeConnection<Def, Alt> {
77 match *self {
78 Connection::Default(ref connection) => {
79 NativeConnection::Default(connection.native_connection())
80 }
81 Connection::Alternate(ref connection) => {
82 NativeConnection::Alternate(connection.native_connection())
83 }
84 }
85 }
86
87 pub fn gl_api(&self) -> GLApi {
89 match *self {
90 Connection::Default(ref connection) => connection.gl_api(),
91 Connection::Alternate(ref connection) => connection.gl_api(),
92 }
93 }
94
95 pub fn create_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
99 match *self {
100 Connection::Default(ref connection) => {
101 connection.create_adapter().map(Adapter::Default)
102 }
103 Connection::Alternate(ref connection) => {
104 connection.create_adapter().map(Adapter::Alternate)
105 }
106 }
107 }
108
109 pub fn create_hardware_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
111 match *self {
112 Connection::Default(ref connection) => {
113 connection.create_hardware_adapter().map(Adapter::Default)
114 }
115 Connection::Alternate(ref connection) => {
116 connection.create_hardware_adapter().map(Adapter::Alternate)
117 }
118 }
119 }
120
121 pub fn create_low_power_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
123 match *self {
124 Connection::Default(ref connection) => {
125 connection.create_low_power_adapter().map(Adapter::Default)
126 }
127 Connection::Alternate(ref connection) => connection
128 .create_low_power_adapter()
129 .map(Adapter::Alternate),
130 }
131 }
132
133 pub fn create_software_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
135 match *self {
136 Connection::Default(ref connection) => {
137 connection.create_software_adapter().map(Adapter::Default)
138 }
139 Connection::Alternate(ref connection) => {
140 connection.create_software_adapter().map(Adapter::Alternate)
141 }
142 }
143 }
144
145 pub fn create_device(&self, adapter: &Adapter<Def, Alt>) -> Result<Device<Def, Alt>, Error> {
149 match (self, adapter) {
150 (Connection::Default(connection), Adapter::Default(adapter)) => {
151 connection.create_device(adapter).map(Device::Default)
152 }
153 (Connection::Alternate(connection), Adapter::Alternate(adapter)) => {
154 connection.create_device(adapter).map(Device::Alternate)
155 }
156 _ => Err(Error::IncompatibleAdapter),
157 }
158 }
159
160 #[inline]
162 pub unsafe fn create_device_from_native_device(
163 &self,
164 native_device: NativeDevice<Def, Alt>,
165 ) -> Result<Device<Def, Alt>, Error> {
166 match self {
167 Connection::Default(connection) => match native_device {
168 NativeDevice::Default(native_device) => connection
169 .create_device_from_native_device(native_device)
170 .map(Device::Default),
171 _ => Err(Error::IncompatibleNativeDevice),
172 },
173 Connection::Alternate(connection) => match native_device {
174 NativeDevice::Alternate(native_device) => connection
175 .create_device_from_native_device(native_device)
176 .map(Device::Alternate),
177 _ => Err(Error::IncompatibleNativeDevice),
178 },
179 }
180 }
181
182 #[cfg(feature = "sm-raw-window-handle-05")]
184 pub fn from_raw_display_handle(
185 raw_handle: rwh_05::RawDisplayHandle,
186 ) -> Result<Connection<Def, Alt>, Error> {
187 match <Def::Connection>::from_raw_display_handle(raw_handle) {
188 Ok(connection) => Ok(Connection::Default(connection)),
189 Err(_) => {
190 <Alt::Connection>::from_raw_display_handle(raw_handle).map(Connection::Alternate)
191 }
192 }
193 }
194
195 #[cfg(feature = "sm-raw-window-handle-06")]
197 pub fn from_display_handle(
198 handle: rwh_06::DisplayHandle,
199 ) -> Result<Connection<Def, Alt>, Error> {
200 match <Def::Connection>::from_display_handle(handle) {
201 Ok(connection) => Ok(Connection::Default(connection)),
202 Err(_) => <Alt::Connection>::from_display_handle(handle).map(Connection::Alternate),
203 }
204 }
205
206 pub unsafe fn create_native_widget_from_ptr(
208 &self,
209 raw: *mut c_void,
210 size: Size2D<i32>,
211 ) -> NativeWidget<Def, Alt> {
212 match *self {
213 Connection::Default(ref connection) => {
214 NativeWidget::Default(connection.create_native_widget_from_ptr(raw, size))
215 }
216 Connection::Alternate(ref connection) => {
217 NativeWidget::Alternate(connection.create_native_widget_from_ptr(raw, size))
218 }
219 }
220 }
221
222 #[cfg(feature = "sm-raw-window-handle-05")]
224 pub fn create_native_widget_from_raw_window_handle(
225 &self,
226 raw_handle: rwh_05::RawWindowHandle,
227 size: Size2D<i32>,
228 ) -> Result<NativeWidget<Def, Alt>, Error> {
229 match *self {
230 Connection::Default(ref connection) => connection
231 .create_native_widget_from_raw_window_handle(raw_handle, size)
232 .map(NativeWidget::Default),
233 Connection::Alternate(ref connection) => connection
234 .create_native_widget_from_raw_window_handle(raw_handle, size)
235 .map(NativeWidget::Alternate),
236 }
237 }
238
239 #[cfg(feature = "sm-raw-window-handle-06")]
241 pub fn create_native_widget_from_window_handle(
242 &self,
243 handle: rwh_06::WindowHandle,
244 size: Size2D<i32>,
245 ) -> Result<NativeWidget<Def, Alt>, Error> {
246 match *self {
247 Connection::Default(ref connection) => connection
248 .create_native_widget_from_window_handle(handle, size)
249 .map(NativeWidget::Default),
250 Connection::Alternate(ref connection) => connection
251 .create_native_widget_from_window_handle(handle, size)
252 .map(NativeWidget::Alternate),
253 }
254 }
255}
256
257impl<Def, Alt> ConnectionInterface for Connection<Def, Alt>
258where
259 Def: DeviceInterface,
260 Alt: DeviceInterface,
261 Def::Connection: ConnectionInterface<Device = Def>,
262 Alt::Connection: ConnectionInterface<Device = Alt>,
263{
264 type Adapter = Adapter<Def, Alt>;
265 type Device = Device<Def, Alt>;
266 type NativeConnection = NativeConnection<Def, Alt>;
267 type NativeDevice = NativeDevice<Def, Alt>;
268 type NativeWidget = NativeWidget<Def, Alt>;
269
270 #[inline]
271 fn new() -> Result<Connection<Def, Alt>, Error> {
272 Connection::new()
273 }
274
275 #[inline]
276 fn native_connection(&self) -> NativeConnection<Def, Alt> {
277 Connection::native_connection(self)
278 }
279
280 #[inline]
281 fn gl_api(&self) -> GLApi {
282 Connection::gl_api(self)
283 }
284
285 #[inline]
286 fn create_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
287 Connection::create_adapter(self)
288 }
289
290 #[inline]
291 fn create_hardware_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
292 Connection::create_hardware_adapter(self)
293 }
294
295 #[inline]
296 fn create_low_power_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
297 Connection::create_low_power_adapter(self)
298 }
299
300 #[inline]
301 fn create_software_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
302 Connection::create_software_adapter(self)
303 }
304
305 #[inline]
306 fn create_device(&self, adapter: &Adapter<Def, Alt>) -> Result<Device<Def, Alt>, Error> {
307 Connection::create_device(self, adapter)
308 }
309
310 #[inline]
311 unsafe fn create_device_from_native_device(
312 &self,
313 native_device: NativeDevice<Def, Alt>,
314 ) -> Result<Device<Def, Alt>, Error> {
315 Connection::create_device_from_native_device(self, native_device)
316 }
317
318 #[cfg(feature = "sm-raw-window-handle-05")]
319 fn from_raw_display_handle(
320 raw_handle: rwh_05::RawDisplayHandle,
321 ) -> Result<Connection<Def, Alt>, Error> {
322 Connection::from_raw_display_handle(raw_handle)
323 }
324
325 #[cfg(feature = "sm-raw-window-handle-06")]
326 fn from_display_handle(handle: rwh_06::DisplayHandle) -> Result<Connection<Def, Alt>, Error> {
327 Connection::from_display_handle(handle)
328 }
329
330 #[inline]
331 unsafe fn create_native_widget_from_ptr(
332 &self,
333 raw: *mut c_void,
334 size: Size2D<i32>,
335 ) -> NativeWidget<Def, Alt> {
336 Connection::create_native_widget_from_ptr(self, raw, size)
337 }
338
339 #[cfg(feature = "sm-raw-window-handle-05")]
340 fn create_native_widget_from_raw_window_handle(
341 &self,
342 raw_handle: rwh_05::RawWindowHandle,
343 size: Size2D<i32>,
344 ) -> Result<Self::NativeWidget, Error> {
345 Connection::create_native_widget_from_raw_window_handle(self, raw_handle, size)
346 }
347
348 #[cfg(feature = "sm-raw-window-handle-06")]
349 fn create_native_widget_from_window_handle(
350 &self,
351 handle: rwh_06::WindowHandle,
352 size: Size2D<i32>,
353 ) -> Result<Self::NativeWidget, Error> {
354 Connection::create_native_widget_from_window_handle(self, handle, size)
355 }
356}