1use super::context::Context;
6use super::device::Device;
7use crate::connection::Connection as ConnectionInterface;
8use crate::device::Device as DeviceInterface;
9use crate::{Error, SurfaceAccess, SurfaceInfo, SurfaceType};
10use euclid::default::Size2D;
11use glow::Texture;
12
13use std::fmt::{self, Debug, Formatter};
14
15pub enum Surface<Def, Alt>
32where
33 Def: DeviceInterface,
34 Alt: DeviceInterface,
35{
36 Default(Def::Surface),
38 Alternate(Alt::Surface),
40}
41
42pub enum SurfaceTexture<Def, Alt>
52where
53 Def: DeviceInterface,
54 Alt: DeviceInterface,
55{
56 Default(Def::SurfaceTexture),
58 Alternate(Alt::SurfaceTexture),
60}
61
62pub enum NativeWidget<Def, Alt>
64where
65 Def: DeviceInterface,
66 Alt: DeviceInterface,
67{
68 Default(<Def::Connection as ConnectionInterface>::NativeWidget),
70 Alternate(<Alt::Connection as ConnectionInterface>::NativeWidget),
72}
73
74impl<Def, Alt> Debug for Surface<Def, Alt>
75where
76 Def: DeviceInterface,
77 Alt: DeviceInterface,
78{
79 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
80 write!(f, "Surface")
81 }
82}
83
84impl<Def, Alt> Debug for SurfaceTexture<Def, Alt>
85where
86 Def: DeviceInterface,
87 Alt: DeviceInterface,
88{
89 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
90 write!(f, "SurfaceTexture")
91 }
92}
93
94impl<Def, Alt> Device<Def, Alt>
95where
96 Def: DeviceInterface,
97 Alt: DeviceInterface,
98{
99 pub fn create_surface(
104 &mut self,
105 context: &Context<Def, Alt>,
106 surface_access: SurfaceAccess,
107 surface_type: SurfaceType<NativeWidget<Def, Alt>>,
108 ) -> Result<Surface<Def, Alt>, Error> {
109 match (&mut *self, context) {
110 (&mut Device::Default(ref mut device), Context::Default(context)) => {
111 let surface_type = match surface_type {
112 SurfaceType::Generic { size } => SurfaceType::Generic { size },
113 SurfaceType::Widget {
114 native_widget: NativeWidget::Default(native_widget),
115 } => SurfaceType::Widget { native_widget },
116 SurfaceType::Widget { native_widget: _ } => {
117 return Err(Error::IncompatibleNativeWidget)
118 }
119 };
120 device
121 .create_surface(context, surface_access, surface_type)
122 .map(Surface::Default)
123 }
124 (&mut Device::Alternate(ref mut device), Context::Alternate(context)) => {
125 let surface_type = match surface_type {
126 SurfaceType::Generic { size } => SurfaceType::Generic { size },
127 SurfaceType::Widget {
128 native_widget: NativeWidget::Alternate(native_widget),
129 } => SurfaceType::Widget { native_widget },
130 SurfaceType::Widget { native_widget: _ } => {
131 return Err(Error::IncompatibleNativeWidget)
132 }
133 };
134 device
135 .create_surface(context, surface_access, surface_type)
136 .map(Surface::Alternate)
137 }
138 _ => Err(Error::IncompatibleContext),
139 }
140 }
141
142 pub fn create_surface_texture(
153 &self,
154 context: &mut Context<Def, Alt>,
155 surface: Surface<Def, Alt>,
156 ) -> Result<SurfaceTexture<Def, Alt>, (Error, Surface<Def, Alt>)> {
157 match (self, &mut *context) {
158 (Device::Default(device), &mut Context::Default(ref mut context)) => match surface {
159 Surface::Default(surface) => {
160 match device.create_surface_texture(context, surface) {
161 Ok(surface_texture) => Ok(SurfaceTexture::Default(surface_texture)),
162 Err((err, surface)) => Err((err, Surface::Default(surface))),
163 }
164 }
165 _ => Err((Error::IncompatibleSurface, surface)),
166 },
167 (Device::Alternate(device), &mut Context::Alternate(ref mut context)) => {
168 match surface {
169 Surface::Alternate(surface) => {
170 match device.create_surface_texture(context, surface) {
171 Ok(surface_texture) => Ok(SurfaceTexture::Alternate(surface_texture)),
172 Err((err, surface)) => Err((err, Surface::Alternate(surface))),
173 }
174 }
175 _ => Err((Error::IncompatibleSurface, surface)),
176 }
177 }
178 _ => Err((Error::IncompatibleContext, surface)),
179 }
180 }
181
182 pub fn destroy_surface(
190 &self,
191 context: &mut Context<Def, Alt>,
192 surface: &mut Surface<Def, Alt>,
193 ) -> Result<(), Error> {
194 match (self, &mut *context) {
195 (Device::Default(device), &mut Context::Default(ref mut context)) => match *surface {
196 Surface::Default(ref mut surface) => device.destroy_surface(context, surface),
197 _ => Err(Error::IncompatibleSurface),
198 },
199 (Device::Alternate(device), &mut Context::Alternate(ref mut context)) => match *surface
200 {
201 Surface::Alternate(ref mut surface) => device.destroy_surface(context, surface),
202 _ => Err(Error::IncompatibleSurface),
203 },
204 _ => Err(Error::IncompatibleContext),
205 }
206 }
207
208 pub fn destroy_surface_texture(
216 &self,
217 context: &mut Context<Def, Alt>,
218 surface_texture: SurfaceTexture<Def, Alt>,
219 ) -> Result<Surface<Def, Alt>, (Error, SurfaceTexture<Def, Alt>)> {
220 match (self, &mut *context) {
221 (Device::Default(device), &mut Context::Default(ref mut context)) => {
222 match surface_texture {
223 SurfaceTexture::Default(surface_texture) => {
224 match device.destroy_surface_texture(context, surface_texture) {
225 Ok(surface) => Ok(Surface::Default(surface)),
226 Err((err, surface_texture)) => {
227 Err((err, SurfaceTexture::Default(surface_texture)))
228 }
229 }
230 }
231 _ => Err((Error::IncompatibleSurfaceTexture, surface_texture)),
232 }
233 }
234 (Device::Alternate(device), &mut Context::Alternate(ref mut context)) => {
235 match surface_texture {
236 SurfaceTexture::Alternate(surface_texture) => {
237 match device.destroy_surface_texture(context, surface_texture) {
238 Ok(surface) => Ok(Surface::Alternate(surface)),
239 Err((err, surface_texture)) => {
240 Err((err, SurfaceTexture::Alternate(surface_texture)))
241 }
242 }
243 }
244 _ => Err((Error::IncompatibleSurfaceTexture, surface_texture)),
245 }
246 }
247 _ => Err((Error::IncompatibleContext, surface_texture)),
248 }
249 }
250
251 pub fn present_surface(
259 &self,
260 context: &Context<Def, Alt>,
261 surface: &mut Surface<Def, Alt>,
262 ) -> Result<(), Error> {
263 match (self, context) {
264 (Device::Default(device), Context::Default(context)) => match *surface {
265 Surface::Default(ref mut surface) => device.present_surface(context, surface),
266 _ => Err(Error::IncompatibleSurface),
267 },
268 (Device::Alternate(device), Context::Alternate(context)) => match *surface {
269 Surface::Alternate(ref mut surface) => device.present_surface(context, surface),
270 _ => Err(Error::IncompatibleSurface),
271 },
272 _ => Err(Error::IncompatibleContext),
273 }
274 }
275
276 pub fn resize_surface(
278 &self,
279 context: &Context<Def, Alt>,
280 surface: &mut Surface<Def, Alt>,
281 size: Size2D<i32>,
282 ) -> Result<(), Error> {
283 match (self, context) {
284 (Device::Default(device), Context::Default(context)) => match *surface {
285 Surface::Default(ref mut surface) => device.resize_surface(context, surface, size),
286 _ => Err(Error::IncompatibleSurface),
287 },
288 (Device::Alternate(device), Context::Alternate(context)) => match *surface {
289 Surface::Alternate(ref mut surface) => {
290 device.resize_surface(context, surface, size)
291 }
292 _ => Err(Error::IncompatibleSurface),
293 },
294 _ => Err(Error::IncompatibleContext),
295 }
296 }
297
298 #[inline]
302 pub fn surface_gl_texture_target(&self) -> u32 {
303 match *self {
304 Device::Default(ref device) => device.surface_gl_texture_target(),
305 Device::Alternate(ref device) => device.surface_gl_texture_target(),
306 }
307 }
308
309 pub fn surface_info(&self, surface: &Surface<Def, Alt>) -> SurfaceInfo {
316 match (self, surface) {
317 (Device::Default(device), Surface::Default(ref surface)) => {
318 device.surface_info(surface)
319 }
320 (Device::Alternate(device), Surface::Alternate(ref surface)) => {
321 device.surface_info(surface)
322 }
323 _ => panic!("Incompatible context!"),
324 }
325 }
326
327 pub fn surface_texture_object(
331 &self,
332 surface_texture: &SurfaceTexture<Def, Alt>,
333 ) -> Option<Texture> {
334 match (self, surface_texture) {
335 (Device::Default(device), SurfaceTexture::Default(ref surface_texture)) => {
336 device.surface_texture_object(surface_texture)
337 }
338 (Device::Alternate(device), SurfaceTexture::Alternate(ref surface_texture)) => {
339 device.surface_texture_object(surface_texture)
340 }
341 _ => panic!("Incompatible context!"),
342 }
343 }
344}