Skip to content

Commit 21569bd

Browse files
committed
Merge most impl Device blocks
It was very difficult to know where any particular `Device` method was implemented. This will make it easier to eliminate `macros.rs, necessary to implement the new version of the API. Signed-off-by: Martin Robinson <mrobinson@abandonedwig.info>
1 parent 9eaf3fc commit 21569bd

20 files changed

Lines changed: 4288 additions & 4308 deletions

File tree

src/angle/context.rs

Lines changed: 0 additions & 368 deletions
Original file line numberDiff line numberDiff line change
@@ -54,371 +54,3 @@ impl Drop for Context {
5454
}
5555
}
5656
}
57-
58-
impl Device {
59-
/// Creates a context descriptor with the given attributes.
60-
///
61-
/// Context descriptors are local to this device.
62-
#[inline]
63-
pub fn create_context_descriptor(
64-
&self,
65-
attributes: &ContextAttributes,
66-
) -> Result<ContextDescriptor, Error> {
67-
unsafe {
68-
ContextDescriptor::new(
69-
self.egl_display,
70-
attributes,
71-
&[
72-
egl::BIND_TO_TEXTURE_RGBA as EGLint,
73-
1 as EGLint,
74-
egl::SURFACE_TYPE as EGLint,
75-
egl::PBUFFER_BIT as EGLint,
76-
egl::RENDERABLE_TYPE as EGLint,
77-
egl::OPENGL_ES2_BIT as EGLint,
78-
],
79-
)
80-
}
81-
}
82-
83-
/// Creates a new OpenGL context.
84-
///
85-
/// The context initially has no surface attached. Until a surface is bound to it, rendering
86-
/// commands will fail or have no effect.
87-
pub fn create_context(
88-
&self,
89-
descriptor: &ContextDescriptor,
90-
share_with: Option<&Context>,
91-
) -> Result<Context, Error> {
92-
let (egl_context, id) = {
93-
let mut next_context_id_lock = CREATE_CONTEXT_MUTEX.lock().unwrap();
94-
let egl_context = unsafe {
95-
context::create_context(
96-
self.egl_display,
97-
descriptor,
98-
share_with.map_or(egl::NO_CONTEXT, |ctx| ctx.egl_context),
99-
self.gl_api(),
100-
)?
101-
};
102-
next_context_id_lock.0 += 1;
103-
(egl_context, *next_context_id_lock)
104-
};
105-
106-
unsafe {
107-
EGL_FUNCTIONS.with(|egl| {
108-
let result = egl.MakeCurrent(
109-
self.egl_display,
110-
egl::NO_SURFACE,
111-
egl::NO_SURFACE,
112-
egl_context,
113-
);
114-
if result == egl::FALSE {
115-
return Err(Error::MakeCurrentFailed(
116-
egl.GetError().to_windowing_api_error(),
117-
));
118-
}
119-
Ok(())
120-
})?;
121-
}
122-
123-
let context = Context {
124-
egl_context,
125-
id,
126-
framebuffer: Framebuffer::None,
127-
context_is_owned: true,
128-
gl: unsafe { Gl::from_loader_function(context::get_proc_address) },
129-
};
130-
Ok(context)
131-
}
132-
133-
/// Wraps a native `EGLContext` in a context object.
134-
///
135-
/// The underlying `EGLContext` is not retained, as there is no way to do this in the EGL API.
136-
/// Therefore, it is the caller's responsibility to keep it alive as long as this `Context`
137-
/// remains alive.
138-
pub unsafe fn create_context_from_native_context(
139-
&self,
140-
native_context: NativeContext,
141-
) -> Result<Context, Error> {
142-
let mut next_context_id = CREATE_CONTEXT_MUTEX.lock().unwrap();
143-
144-
// Create the context.
145-
let context = Context {
146-
egl_context: native_context.egl_context,
147-
id: *next_context_id,
148-
framebuffer: Framebuffer::External(ExternalEGLSurfaces {
149-
draw: native_context.egl_draw_surface,
150-
read: native_context.egl_read_surface,
151-
}),
152-
context_is_owned: false,
153-
gl: Gl::from_loader_function(context::get_proc_address),
154-
};
155-
next_context_id.0 += 1;
156-
157-
Ok(context)
158-
}
159-
160-
/// Destroys a context.
161-
///
162-
/// The context must have been created on this device.
163-
pub fn destroy_context(&self, context: &mut Context) -> Result<(), Error> {
164-
if context.egl_context == egl::NO_CONTEXT {
165-
return Ok(());
166-
}
167-
168-
if let Ok(Some(mut surface)) = self.unbind_surface_from_context(context) {
169-
self.destroy_surface(context, &mut surface)?;
170-
}
171-
172-
EGL_FUNCTIONS.with(|egl| unsafe {
173-
egl.MakeCurrent(
174-
self.egl_display,
175-
egl::NO_SURFACE,
176-
egl::NO_SURFACE,
177-
egl::NO_CONTEXT,
178-
);
179-
180-
if context.context_is_owned {
181-
let result = egl.DestroyContext(self.egl_display, context.egl_context);
182-
assert_ne!(result, egl::FALSE);
183-
}
184-
185-
context.egl_context = egl::NO_CONTEXT;
186-
});
187-
188-
Ok(())
189-
}
190-
191-
/// Returns the descriptor that this context was created with.
192-
pub fn context_descriptor(&self, context: &Context) -> ContextDescriptor {
193-
unsafe {
194-
ContextDescriptor::from_egl_context(&context.gl, self.egl_display, context.egl_context)
195-
}
196-
}
197-
198-
/// Makes the context the current OpenGL context for this thread.
199-
///
200-
/// After calling this function, it is valid to use OpenGL rendering commands.
201-
pub fn make_context_current(&self, context: &Context) -> Result<(), Error> {
202-
unsafe {
203-
let (egl_draw_surface, egl_read_surface) = match context.framebuffer {
204-
Framebuffer::Surface(ref surface) => (surface.egl_surface, surface.egl_surface),
205-
Framebuffer::None => (egl::NO_SURFACE, egl::NO_SURFACE),
206-
Framebuffer::External(ref surfaces) => (surfaces.draw, surfaces.read),
207-
};
208-
209-
EGL_FUNCTIONS.with(|egl| {
210-
let result = egl.MakeCurrent(
211-
self.egl_display,
212-
egl_draw_surface,
213-
egl_read_surface,
214-
context.egl_context,
215-
);
216-
if result == egl::FALSE {
217-
let err = egl.GetError().to_windowing_api_error();
218-
return Err(Error::MakeCurrentFailed(err));
219-
}
220-
Ok(())
221-
})
222-
}
223-
}
224-
225-
/// Removes the current OpenGL context from this thread.
226-
///
227-
/// After calling this function, OpenGL rendering commands will fail until a new context is
228-
/// made current.
229-
pub fn make_no_context_current(&self) -> Result<(), Error> {
230-
unsafe { context::make_no_context_current(self.egl_display) }
231-
}
232-
233-
pub(crate) fn temporarily_make_context_current(
234-
&self,
235-
context: &Context,
236-
) -> Result<CurrentContextGuard, Error> {
237-
let guard = CurrentContextGuard::new();
238-
self.make_context_current(context)?;
239-
Ok(guard)
240-
}
241-
242-
pub(crate) fn context_is_current(&self, context: &Context) -> bool {
243-
EGL_FUNCTIONS.with(|egl| unsafe { egl.GetCurrentContext() == context.egl_context })
244-
}
245-
246-
/// Returns the attributes that the context descriptor was created with.
247-
#[inline]
248-
pub fn context_descriptor_attributes(
249-
&self,
250-
context_descriptor: &ContextDescriptor,
251-
) -> ContextAttributes {
252-
unsafe { context_descriptor.attributes(self.egl_display) }
253-
}
254-
255-
/// Fetches the address of an OpenGL function associated with this context.
256-
///
257-
/// OpenGL functions are local to a context. You should not use OpenGL functions on one context
258-
/// with any other context.
259-
///
260-
/// This method is typically used with a function like `gl::load_with()` from the `gl` crate to
261-
/// load OpenGL function pointers.
262-
#[inline]
263-
pub fn get_proc_address(&self, _: &Context, symbol_name: &str) -> *const c_void {
264-
context::get_proc_address(symbol_name)
265-
}
266-
267-
#[inline]
268-
pub(crate) fn context_descriptor_to_egl_config(
269-
&self,
270-
context_descriptor: &ContextDescriptor,
271-
) -> EGLConfig {
272-
unsafe { context::egl_config_from_id(self.egl_display, context_descriptor.egl_config_id) }
273-
}
274-
275-
/// Attaches a surface to a context for rendering.
276-
///
277-
/// This function takes ownership of the surface. The surface must have been created with this
278-
/// context, or an `IncompatibleSurface` error is returned.
279-
///
280-
/// If this function is called with a surface already bound, a `SurfaceAlreadyBound` error is
281-
/// returned. To avoid this error, first unbind the existing surface with
282-
/// `unbind_surface_from_context`.
283-
///
284-
/// If an error is returned, the surface is returned alongside it.
285-
pub fn bind_surface_to_context(
286-
&self,
287-
context: &mut Context,
288-
surface: Surface,
289-
) -> Result<(), (Error, Surface)> {
290-
if context.id != surface.context_id {
291-
return Err((Error::IncompatibleSurface, surface));
292-
}
293-
294-
match context.framebuffer {
295-
Framebuffer::None => {}
296-
Framebuffer::External(_) => return Err((Error::ExternalRenderTarget, surface)),
297-
Framebuffer::Surface(_) => return Err((Error::SurfaceAlreadyBound, surface)),
298-
}
299-
300-
// If the surface is synchronized with GLFinish, then finish.
301-
// FIXME(pcwalton): Is this necessary and sufficient?
302-
if surface.uses_gl_finish() {
303-
if let Ok(_guard) = self.temporarily_make_context_current(context) {
304-
unsafe {
305-
context.gl.finish();
306-
}
307-
}
308-
}
309-
310-
let is_current = self.context_is_current(context);
311-
312-
match surface.win32_objects {
313-
Win32Objects::Pbuffer {
314-
synchronization: Synchronization::KeyedMutex(ref keyed_mutex),
315-
..
316-
} => unsafe {
317-
let result = keyed_mutex.AcquireSync(0, INFINITE);
318-
assert_eq!(result, S_OK);
319-
},
320-
_ => {}
321-
}
322-
323-
context.framebuffer = Framebuffer::Surface(surface);
324-
325-
if is_current {
326-
// We need to make ourselves current again, because the surface changed.
327-
drop(self.make_context_current(context));
328-
}
329-
330-
Ok(())
331-
}
332-
333-
/// Removes and returns any attached surface from this context.
334-
///
335-
/// Any pending OpenGL commands targeting this surface will be automatically flushed, so the
336-
/// surface is safe to read from immediately when this function returns.
337-
pub fn unbind_surface_from_context(
338-
&self,
339-
context: &mut Context,
340-
) -> Result<Option<Surface>, Error> {
341-
match context.framebuffer {
342-
Framebuffer::None => return Ok(None),
343-
Framebuffer::External(_) => return Err(Error::ExternalRenderTarget),
344-
Framebuffer::Surface(_) => {}
345-
}
346-
347-
let surface = match mem::replace(&mut context.framebuffer, Framebuffer::None) {
348-
Framebuffer::Surface(surface) => surface,
349-
Framebuffer::None | Framebuffer::External(_) => unreachable!(),
350-
};
351-
352-
match surface.win32_objects {
353-
Win32Objects::Pbuffer {
354-
synchronization: Synchronization::KeyedMutex(ref keyed_mutex),
355-
..
356-
} => unsafe {
357-
let result = keyed_mutex.ReleaseSync(0);
358-
assert_eq!(result, S_OK);
359-
},
360-
_ => {}
361-
}
362-
363-
Ok(Some(surface))
364-
}
365-
366-
/// Displays the contents of the currently bound surface to the screen, if
367-
/// it is a widget surface.
368-
///
369-
/// Widget surfaces are internally double-buffered, so changes to them don't
370-
/// show up in their associated widgets until this method is called.
371-
pub fn present_bound_surface(&self, context: &mut Context) -> Result<(), Error> {
372-
match &context.framebuffer {
373-
Framebuffer::Surface(surface) => surface.present(self),
374-
_ => Ok(()),
375-
}
376-
}
377-
378-
/// If the currently bound surface is a widget surface, resize it,
379-
pub fn resize_bound_surface(
380-
&self,
381-
context: &mut Context,
382-
size: Size2D<i32>,
383-
) -> Result<(), Error> {
384-
if let Framebuffer::Surface(surface) = &mut context.framebuffer {
385-
surface.resize(size);
386-
}
387-
Ok(())
388-
}
389-
390-
/// Returns a unique ID representing a context.
391-
///
392-
/// This ID is unique to all currently-allocated contexts. If you destroy a context and create
393-
/// a new one, the new context might have the same ID as the destroyed one.
394-
#[inline]
395-
pub fn context_id(&self, context: &Context) -> ContextID {
396-
context.id
397-
}
398-
399-
/// Returns various information about the surface attached to a context.
400-
///
401-
/// This includes, most notably, the OpenGL framebuffer object needed to render to the surface.
402-
pub fn context_surface_info(&self, context: &Context) -> Result<Option<SurfaceInfo>, Error> {
403-
match context.framebuffer {
404-
Framebuffer::None => Ok(None),
405-
Framebuffer::External(_) => Err(Error::ExternalRenderTarget),
406-
Framebuffer::Surface(ref surface) => Ok(Some(self.surface_info(surface))),
407-
}
408-
}
409-
410-
/// Given a context, returns its underlying EGL context and attached surfaces.
411-
pub fn native_context(&self, context: &Context) -> NativeContext {
412-
let (egl_draw_surface, egl_read_surface) = match context.framebuffer {
413-
Framebuffer::Surface(Surface { egl_surface, .. }) => (egl_surface, egl_surface),
414-
Framebuffer::External(ExternalEGLSurfaces { draw, read }) => (draw, read),
415-
Framebuffer::None => (egl::NO_SURFACE, egl::NO_SURFACE),
416-
};
417-
418-
NativeContext {
419-
egl_context: context.egl_context,
420-
egl_draw_surface,
421-
egl_read_surface,
422-
}
423-
}
424-
}

0 commit comments

Comments
 (0)