1use super::device::{Adapter, Device};
4use super::surface::NativeWidget;
5use crate::connection::Connection as ConnectionInterface;
6use crate::device::Device as DeviceInterface;
7use crate::Error;
8use crate::GLApi;
9
10use euclid::default::Size2D;
11
12use std::os::raw::c_void;
13
14pub enum Connection<Def, Alt>
16where
17 Def: DeviceInterface,
18 Alt: DeviceInterface,
19 Def::Connection: ConnectionInterface,
20 Alt::Connection: ConnectionInterface,
21{
22 Default(Def::Connection),
24 Alternate(Alt::Connection),
26}
27
28impl<Def, Alt> Clone for Connection<Def, Alt>
29where
30 Def: DeviceInterface,
31 Alt: DeviceInterface,
32 Def::Connection: Clone,
33 Alt::Connection: Clone,
34{
35 fn clone(&self) -> Self {
36 match self {
37 Connection::Default(ref connection) => Connection::Default(connection.clone()),
38 Connection::Alternate(ref connection) => Connection::Alternate(connection.clone()),
39 }
40 }
41}
42
43impl<Def, Alt> Connection<Def, Alt>
44where
45 Def: DeviceInterface,
46 Alt: DeviceInterface,
47 Def::Connection: ConnectionInterface<Device = Def>,
48 Alt::Connection: ConnectionInterface<Device = Alt>,
49{
50 #[inline]
52 pub fn new() -> Result<Connection<Def, Alt>, Error> {
53 match <Def::Connection>::new() {
54 Ok(connection) => Ok(Connection::Default(connection)),
55 Err(_) => <Alt::Connection>::new().map(Connection::Alternate),
56 }
57 }
58
59 pub fn gl_api(&self) -> GLApi {
61 match *self {
62 Connection::Default(ref connection) => connection.gl_api(),
63 Connection::Alternate(ref connection) => connection.gl_api(),
64 }
65 }
66
67 pub fn create_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
71 match *self {
72 Connection::Default(ref connection) => {
73 connection.create_adapter().map(Adapter::Default)
74 }
75 Connection::Alternate(ref connection) => {
76 connection.create_adapter().map(Adapter::Alternate)
77 }
78 }
79 }
80
81 pub fn create_hardware_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
83 match *self {
84 Connection::Default(ref connection) => {
85 connection.create_hardware_adapter().map(Adapter::Default)
86 }
87 Connection::Alternate(ref connection) => {
88 connection.create_hardware_adapter().map(Adapter::Alternate)
89 }
90 }
91 }
92
93 pub fn create_low_power_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
95 match *self {
96 Connection::Default(ref connection) => {
97 connection.create_low_power_adapter().map(Adapter::Default)
98 }
99 Connection::Alternate(ref connection) => connection
100 .create_low_power_adapter()
101 .map(Adapter::Alternate),
102 }
103 }
104
105 pub fn create_software_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
107 match *self {
108 Connection::Default(ref connection) => {
109 connection.create_software_adapter().map(Adapter::Default)
110 }
111 Connection::Alternate(ref connection) => {
112 connection.create_software_adapter().map(Adapter::Alternate)
113 }
114 }
115 }
116
117 pub fn create_device(&self, adapter: &Adapter<Def, Alt>) -> Result<Device<Def, Alt>, Error> {
121 match (self, adapter) {
122 (Connection::Default(connection), Adapter::Default(adapter)) => {
123 connection.create_device(adapter).map(Device::Default)
124 }
125 (Connection::Alternate(connection), Adapter::Alternate(adapter)) => {
126 connection.create_device(adapter).map(Device::Alternate)
127 }
128 _ => Err(Error::IncompatibleAdapter),
129 }
130 }
131
132 pub fn from_display_handle(
134 handle: raw_window_handle::DisplayHandle,
135 ) -> Result<Connection<Def, Alt>, Error> {
136 match <Def::Connection>::from_display_handle(handle) {
137 Ok(connection) => Ok(Connection::Default(connection)),
138 Err(_) => <Alt::Connection>::from_display_handle(handle).map(Connection::Alternate),
139 }
140 }
141
142 pub unsafe fn create_native_widget_from_ptr(
144 &self,
145 raw: *mut c_void,
146 size: Size2D<i32>,
147 ) -> NativeWidget<Def, Alt> {
148 match *self {
149 Connection::Default(ref connection) => {
150 NativeWidget::Default(connection.create_native_widget_from_ptr(raw, size))
151 }
152 Connection::Alternate(ref connection) => {
153 NativeWidget::Alternate(connection.create_native_widget_from_ptr(raw, size))
154 }
155 }
156 }
157
158 pub fn create_native_widget_from_window_handle(
160 &self,
161 handle: raw_window_handle::WindowHandle,
162 size: Size2D<i32>,
163 ) -> Result<NativeWidget<Def, Alt>, Error> {
164 match *self {
165 Connection::Default(ref connection) => connection
166 .create_native_widget_from_window_handle(handle, size)
167 .map(NativeWidget::Default),
168 Connection::Alternate(ref connection) => connection
169 .create_native_widget_from_window_handle(handle, size)
170 .map(NativeWidget::Alternate),
171 }
172 }
173}
174
175impl<Def, Alt> ConnectionInterface for Connection<Def, Alt>
176where
177 Def: DeviceInterface,
178 Alt: DeviceInterface,
179 Def::Connection: ConnectionInterface<Device = Def>,
180 Alt::Connection: ConnectionInterface<Device = Alt>,
181{
182 type Adapter = Adapter<Def, Alt>;
183 type Device = Device<Def, Alt>;
184 type NativeWidget = NativeWidget<Def, Alt>;
185
186 #[inline]
187 fn new() -> Result<Connection<Def, Alt>, Error> {
188 Connection::new()
189 }
190
191 #[inline]
192 fn gl_api(&self) -> GLApi {
193 Connection::gl_api(self)
194 }
195
196 #[inline]
197 fn create_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
198 Connection::create_adapter(self)
199 }
200
201 #[inline]
202 fn create_hardware_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
203 Connection::create_hardware_adapter(self)
204 }
205
206 #[inline]
207 fn create_low_power_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
208 Connection::create_low_power_adapter(self)
209 }
210
211 #[inline]
212 fn create_software_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
213 Connection::create_software_adapter(self)
214 }
215
216 #[inline]
217 fn create_device(&self, adapter: &Adapter<Def, Alt>) -> Result<Device<Def, Alt>, Error> {
218 Connection::create_device(self, adapter)
219 }
220
221 fn from_display_handle(
222 handle: raw_window_handle::DisplayHandle,
223 ) -> Result<Connection<Def, Alt>, Error> {
224 Connection::from_display_handle(handle)
225 }
226
227 #[inline]
228 unsafe fn create_native_widget_from_ptr(
229 &self,
230 raw: *mut c_void,
231 size: Size2D<i32>,
232 ) -> NativeWidget<Def, Alt> {
233 Connection::create_native_widget_from_ptr(self, raw, size)
234 }
235
236 fn create_native_widget_from_window_handle(
237 &self,
238 handle: raw_window_handle::WindowHandle,
239 size: Size2D<i32>,
240 ) -> Result<Self::NativeWidget, Error> {
241 Connection::create_native_widget_from_window_handle(self, handle, size)
242 }
243}