surfman/platform/generic/multi/
context.rs1use super::device::Device;
6use super::surface::Surface;
7use crate::device::Device as DeviceInterface;
8use crate::{ContextAttributes, ContextID, Error, SurfaceInfo};
9
10use std::os::raw::c_void;
11
12pub enum Context<Def, Alt>
29where
30 Def: DeviceInterface,
31 Alt: DeviceInterface,
32{
33 Default(Def::Context),
35 Alternate(Alt::Context),
37}
38
39#[derive(Clone)]
43pub enum ContextDescriptor<Def, Alt>
44where
45 Def: DeviceInterface,
46 Alt: DeviceInterface,
47{
48 Default(Def::ContextDescriptor),
50 Alternate(Alt::ContextDescriptor),
52}
53
54pub enum NativeContext<Def, Alt>
56where
57 Def: DeviceInterface,
58 Alt: DeviceInterface,
59{
60 Default(Def::NativeContext),
62 Alternate(Alt::NativeContext),
64}
65
66impl<Def, Alt> Device<Def, Alt>
67where
68 Def: DeviceInterface,
69 Alt: DeviceInterface,
70{
71 pub fn create_context_descriptor(
75 &self,
76 attributes: &ContextAttributes,
77 ) -> Result<ContextDescriptor<Def, Alt>, Error> {
78 match *self {
79 Device::Default(ref device) => device
80 .create_context_descriptor(attributes)
81 .map(ContextDescriptor::Default),
82 Device::Alternate(ref device) => device
83 .create_context_descriptor(attributes)
84 .map(ContextDescriptor::Alternate),
85 }
86 }
87
88 pub fn create_context(
93 &mut self,
94 descriptor: &ContextDescriptor<Def, Alt>,
95 share_with: Option<&Context<Def, Alt>>,
96 ) -> Result<Context<Def, Alt>, Error> {
97 match (&mut *self, descriptor) {
98 (&mut Device::Default(ref mut device), ContextDescriptor::Default(descriptor)) => {
99 let shared = match share_with {
100 Some(Context::Default(other)) => Some(other),
101 Some(_) => {
102 return Err(Error::IncompatibleSharedContext);
103 }
104 None => None,
105 };
106 device
107 .create_context(descriptor, shared)
108 .map(Context::Default)
109 }
110 (&mut Device::Alternate(ref mut device), ContextDescriptor::Alternate(descriptor)) => {
111 let shared = match share_with {
112 Some(Context::Alternate(other)) => Some(other),
113 Some(_) => {
114 return Err(Error::IncompatibleSharedContext);
115 }
116 None => None,
117 };
118 device
119 .create_context(descriptor, shared)
120 .map(Context::Alternate)
121 }
122 _ => Err(Error::IncompatibleContextDescriptor),
123 }
124 }
125
126 pub unsafe fn create_context_from_native_context(
128 &self,
129 native_context: NativeContext<Def, Alt>,
130 ) -> Result<Context<Def, Alt>, Error> {
131 match self {
132 Device::Default(device) => match native_context {
133 NativeContext::Default(native_context) => device
134 .create_context_from_native_context(native_context)
135 .map(Context::Default),
136 _ => Err(Error::IncompatibleNativeContext),
137 },
138 Device::Alternate(device) => match native_context {
139 NativeContext::Alternate(native_context) => device
140 .create_context_from_native_context(native_context)
141 .map(Context::Alternate),
142 _ => Err(Error::IncompatibleNativeContext),
143 },
144 }
145 }
146
147 pub fn destroy_context(&self, context: &mut Context<Def, Alt>) -> Result<(), Error> {
151 match (self, &mut *context) {
152 (Device::Default(device), &mut Context::Default(ref mut context)) => {
153 device.destroy_context(context)
154 }
155 (Device::Alternate(device), &mut Context::Alternate(ref mut context)) => {
156 device.destroy_context(context)
157 }
158 _ => Err(Error::IncompatibleContext),
159 }
160 }
161
162 pub fn native_context(&self, context: &Context<Def, Alt>) -> NativeContext<Def, Alt> {
164 match (self, context) {
165 (Device::Default(device), Context::Default(context)) => {
166 NativeContext::Default(device.native_context(context))
167 }
168 (Device::Alternate(device), Context::Alternate(context)) => {
169 NativeContext::Alternate(device.native_context(context))
170 }
171 _ => panic!("Incompatible context!"),
172 }
173 }
174
175 pub fn context_descriptor(&self, context: &Context<Def, Alt>) -> ContextDescriptor<Def, Alt> {
177 match (self, context) {
178 (Device::Default(device), Context::Default(context)) => {
179 ContextDescriptor::Default(device.context_descriptor(context))
180 }
181 (Device::Alternate(device), Context::Alternate(context)) => {
182 ContextDescriptor::Alternate(device.context_descriptor(context))
183 }
184 _ => panic!("Incompatible context!"),
185 }
186 }
187
188 pub fn make_context_current(&self, context: &Context<Def, Alt>) -> Result<(), Error> {
192 match (self, context) {
193 (Device::Default(device), Context::Default(context)) => {
194 device.make_context_current(context)
195 }
196 (Device::Alternate(device), Context::Alternate(context)) => {
197 device.make_context_current(context)
198 }
199 _ => Err(Error::IncompatibleContext),
200 }
201 }
202
203 pub fn make_no_context_current(&self) -> Result<(), Error> {
208 match self {
209 Device::Default(device) => device.make_no_context_current(),
210 Device::Alternate(device) => device.make_no_context_current(),
211 }
212 }
213
214 pub fn bind_surface_to_context(
225 &self,
226 context: &mut Context<Def, Alt>,
227 surface: Surface<Def, Alt>,
228 ) -> Result<(), (Error, Surface<Def, Alt>)> {
229 match (self, &mut *context) {
230 (Device::Default(device), &mut Context::Default(ref mut context)) => match surface {
231 Surface::Default(surface) => device
232 .bind_surface_to_context(context, surface)
233 .map_err(|(err, surface)| (err, Surface::Default(surface))),
234 _ => Err((Error::IncompatibleSurface, surface)),
235 },
236 (Device::Alternate(device), &mut Context::Alternate(ref mut context)) => {
237 match surface {
238 Surface::Alternate(surface) => device
239 .bind_surface_to_context(context, surface)
240 .map_err(|(err, surface)| (err, Surface::Alternate(surface))),
241 _ => Err((Error::IncompatibleSurface, surface)),
242 }
243 }
244 _ => Err((Error::IncompatibleContext, surface)),
245 }
246 }
247
248 pub fn unbind_surface_from_context(
253 &self,
254 context: &mut Context<Def, Alt>,
255 ) -> Result<Option<Surface<Def, Alt>>, Error> {
256 match (self, &mut *context) {
257 (Device::Default(device), &mut Context::Default(ref mut context)) => device
258 .unbind_surface_from_context(context)
259 .map(|surface| surface.map(Surface::Default)),
260 (Device::Alternate(device), &mut Context::Alternate(ref mut context)) => device
261 .unbind_surface_from_context(context)
262 .map(|surface| surface.map(Surface::Alternate)),
263 _ => Err(Error::IncompatibleContext),
264 }
265 }
266
267 pub fn context_descriptor_attributes(
269 &self,
270 context_descriptor: &ContextDescriptor<Def, Alt>,
271 ) -> ContextAttributes {
272 match (self, context_descriptor) {
273 (Device::Default(device), ContextDescriptor::Default(context_descriptor)) => {
274 device.context_descriptor_attributes(context_descriptor)
275 }
276 (Device::Alternate(device), ContextDescriptor::Alternate(context_descriptor)) => {
277 device.context_descriptor_attributes(context_descriptor)
278 }
279 _ => panic!("Incompatible context!"),
280 }
281 }
282
283 pub fn get_proc_address(
291 &self,
292 context: &Context<Def, Alt>,
293 symbol_name: &str,
294 ) -> *const c_void {
295 match (self, context) {
296 (Device::Default(device), Context::Default(context)) => {
297 device.get_proc_address(context, symbol_name)
298 }
299 (Device::Alternate(device), Context::Alternate(context)) => {
300 device.get_proc_address(context, symbol_name)
301 }
302 _ => panic!("Incompatible context!"),
303 }
304 }
305
306 pub fn context_id(&self, context: &Context<Def, Alt>) -> ContextID {
311 match (self, context) {
312 (Device::Default(device), Context::Default(context)) => device.context_id(context),
313 (Device::Alternate(device), Context::Alternate(context)) => device.context_id(context),
314 _ => panic!("Incompatible context!"),
315 }
316 }
317
318 pub fn context_surface_info(
322 &self,
323 context: &Context<Def, Alt>,
324 ) -> Result<Option<SurfaceInfo>, Error> {
325 match (self, context) {
326 (Device::Default(device), Context::Default(context)) => {
327 device.context_surface_info(context)
328 }
329 (Device::Alternate(device), Context::Alternate(context)) => {
330 device.context_surface_info(context)
331 }
332 _ => Err(Error::IncompatibleContext),
333 }
334 }
335}