Skip to content

Commit af6cbf5

Browse files
authored
Merge most impl Device blocks in src/x11 (#378)
This change just moves code and adjust imports. It was very previously difficult to know where any particular `Device` method was implemented. This will also make it easier to eliminate `macros.rs`, necessary to implement the new version of the API. The downside is that now much of the implementation is gathered into the `device.rs` files, but these usually do not go beyond 1500 lines. Further changes to the API will eliminate many lines of code and spread the logic more equally between files. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
1 parent b678c3f commit af6cbf5

3 files changed

Lines changed: 438 additions & 448 deletions

File tree

src/x11/context.rs

Lines changed: 2 additions & 237 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,8 @@
11
//! OpenGL rendering contexts on X11 via EGL.
22
3-
use euclid::default::Size2D;
4-
5-
use super::device::Device;
6-
use super::surface::Surface;
7-
use crate::base::egl::context::{self, CurrentContextGuard, EGLBackedContext};
8-
use crate::context::ContextID;
9-
use crate::egl;
10-
use crate::egl::types::EGLint;
11-
use crate::{ContextAttributes, Error, Gl, SurfaceInfo};
12-
13-
use std::os::raw::c_void;
14-
3+
use crate::base::egl::context::EGLBackedContext;
154
pub use crate::base::egl::context::{ContextDescriptor, NativeContext};
5+
use crate::Gl;
166

177
/// Represents an OpenGL rendering context.
188
///
@@ -31,228 +21,3 @@ pub use crate::base::egl::context::{ContextDescriptor, NativeContext};
3121
///
3222
/// A context must be explicitly destroyed with `destroy_context()`, or a panic will occur.
3323
pub struct Context(pub(crate) EGLBackedContext, pub(crate) Gl);
34-
35-
impl Device {
36-
/// Creates a context descriptor with the given attributes.
37-
///
38-
/// Context descriptors are local to this device.
39-
#[inline]
40-
pub fn create_context_descriptor(
41-
&self,
42-
attributes: &ContextAttributes,
43-
) -> Result<ContextDescriptor, Error> {
44-
// Set environment variables as appropriate.
45-
self.adapter.set_environment_variables();
46-
47-
unsafe {
48-
ContextDescriptor::new(
49-
self.native_connection.egl_display,
50-
attributes,
51-
&[
52-
egl::SURFACE_TYPE as EGLint,
53-
egl::WINDOW_BIT as EGLint,
54-
egl::RENDERABLE_TYPE as EGLint,
55-
egl::OPENGL_BIT as EGLint,
56-
],
57-
)
58-
}
59-
}
60-
61-
/// Creates a new OpenGL context.
62-
///
63-
/// The context initially has no surface attached. Until a surface is bound to it, rendering
64-
/// commands will fail or have no effect.
65-
#[inline]
66-
pub fn create_context(
67-
&self,
68-
descriptor: &ContextDescriptor,
69-
share_with: Option<&Context>,
70-
) -> Result<Context, Error> {
71-
unsafe {
72-
let context = EGLBackedContext::new(
73-
self.native_connection.egl_display,
74-
descriptor,
75-
share_with.map(|ctx| &ctx.0),
76-
self.gl_api(),
77-
)?;
78-
context.make_current(self.native_connection.egl_display)?;
79-
Ok(Context(
80-
context,
81-
Gl::from_loader_function(context::get_proc_address),
82-
))
83-
}
84-
}
85-
86-
/// Wraps an `EGLContext` in a native context and returns it.
87-
///
88-
/// The context is not retained, as there is no way to do this in the EGL API. Therefore,
89-
/// it is the caller's responsibility to ensure that the returned `Context` object remains
90-
/// alive as long as the `EGLContext` is.
91-
#[inline]
92-
pub unsafe fn create_context_from_native_context(
93-
&self,
94-
native_context: NativeContext,
95-
) -> Result<Context, Error> {
96-
Ok(Context(
97-
EGLBackedContext::from_native_context(native_context),
98-
Gl::from_loader_function(context::get_proc_address),
99-
))
100-
}
101-
102-
/// Destroys a context.
103-
///
104-
/// The context must have been created on this device.
105-
pub fn destroy_context(&self, context: &mut Context) -> Result<(), Error> {
106-
if let Ok(Some(mut surface)) = self.unbind_surface_from_context(context) {
107-
self.destroy_surface(context, &mut surface)?;
108-
}
109-
110-
unsafe {
111-
context.0.destroy(self.native_connection.egl_display);
112-
Ok(())
113-
}
114-
}
115-
116-
/// Given a context, returns its underlying EGL context and attached surfaces.
117-
#[inline]
118-
pub fn native_context(&self, context: &Context) -> NativeContext {
119-
context.0.native_context()
120-
}
121-
122-
/// Returns the descriptor that this context was created with.
123-
#[inline]
124-
pub fn context_descriptor(&self, context: &Context) -> ContextDescriptor {
125-
unsafe {
126-
ContextDescriptor::from_egl_context(
127-
&context.1,
128-
self.native_connection.egl_display,
129-
context.0.egl_context,
130-
)
131-
}
132-
}
133-
134-
/// Makes the context the current OpenGL context for this thread.
135-
///
136-
/// After calling this function, it is valid to use OpenGL rendering commands.
137-
#[inline]
138-
pub fn make_context_current(&self, context: &Context) -> Result<(), Error> {
139-
unsafe { context.0.make_current(self.native_connection.egl_display) }
140-
}
141-
142-
/// Removes the current OpenGL context from this thread.
143-
///
144-
/// After calling this function, OpenGL rendering commands will fail until a new context is
145-
/// made current.
146-
#[inline]
147-
pub fn make_no_context_current(&self) -> Result<(), Error> {
148-
unsafe { context::make_no_context_current(self.native_connection.egl_display) }
149-
}
150-
151-
#[inline]
152-
pub(crate) fn temporarily_make_context_current(
153-
&self,
154-
context: &Context,
155-
) -> Result<CurrentContextGuard, Error> {
156-
let guard = CurrentContextGuard::new();
157-
self.make_context_current(context)?;
158-
Ok(guard)
159-
}
160-
161-
/// Returns the attributes that the context descriptor was created with.
162-
#[inline]
163-
pub fn context_descriptor_attributes(
164-
&self,
165-
context_descriptor: &ContextDescriptor,
166-
) -> ContextAttributes {
167-
unsafe { context_descriptor.attributes(self.native_connection.egl_display) }
168-
}
169-
170-
/// Fetches the address of an OpenGL function associated with this context.
171-
///
172-
/// OpenGL functions are local to a context. You should not use OpenGL functions on one context
173-
/// with any other context.
174-
///
175-
/// This method is typically used with a function like `gl::load_with()` from the `gl` crate to
176-
/// load OpenGL function pointers.
177-
#[inline]
178-
pub fn get_proc_address(&self, _: &Context, symbol_name: &str) -> *const c_void {
179-
context::get_proc_address(symbol_name)
180-
}
181-
182-
/// Attaches a surface to a context for rendering.
183-
///
184-
/// This function takes ownership of the surface. The surface must have been created with this
185-
/// context, or an `IncompatibleSurface` error is returned.
186-
///
187-
/// If this function is called with a surface already bound, a `SurfaceAlreadyBound` error is
188-
/// returned. To avoid this error, first unbind the existing surface with
189-
/// `unbind_surface_from_context`.
190-
///
191-
/// If an error is returned, the surface is returned alongside it.
192-
#[inline]
193-
pub fn bind_surface_to_context(
194-
&self,
195-
context: &mut Context,
196-
surface: Surface,
197-
) -> Result<(), (Error, Surface)> {
198-
unsafe {
199-
context
200-
.0
201-
.bind_surface(self.native_connection.egl_display, surface.0)
202-
.map_err(|(err, surface)| (err, Surface(surface)))
203-
}
204-
}
205-
206-
/// Removes and returns any attached surface from this context.
207-
///
208-
/// Any pending OpenGL commands targeting this surface will be automatically flushed, so the
209-
/// surface is safe to read from immediately when this function returns.
210-
pub fn unbind_surface_from_context(
211-
&self,
212-
context: &mut Context,
213-
) -> Result<Option<Surface>, Error> {
214-
unsafe {
215-
context
216-
.0
217-
.unbind_surface(&context.1, self.native_connection.egl_display)
218-
.map(|maybe_surface| maybe_surface.map(Surface))
219-
}
220-
}
221-
222-
/// Displays the contents of the currently bound surface to the screen, if
223-
/// it is a widget surface.
224-
///
225-
/// Widget surfaces are internally double-buffered, so changes to them don't
226-
/// show up in their associated widgets until this method is called.
227-
pub fn present_bound_surface(&self, context: &mut Context) -> Result<(), Error> {
228-
context
229-
.0
230-
.present_bound_surface(self.native_connection.egl_display)
231-
}
232-
233-
/// If the currently bound surface is a widget surface, resize it,
234-
pub fn resize_bound_surface(
235-
&self,
236-
context: &mut Context,
237-
size: Size2D<i32>,
238-
) -> Result<(), Error> {
239-
context.0.resize_bound_surface(size)
240-
}
241-
242-
/// Returns a unique ID representing a context.
243-
///
244-
/// This ID is unique to all currently-allocated contexts. If you destroy a context and create
245-
/// a new one, the new context might have the same ID as the destroyed one.
246-
#[inline]
247-
pub fn context_id(&self, context: &Context) -> ContextID {
248-
context.0.id
249-
}
250-
251-
/// Returns various information about the surface attached to a context.
252-
///
253-
/// This includes, most notably, the OpenGL framebuffer object needed to render to the surface.
254-
#[inline]
255-
pub fn context_surface_info(&self, context: &Context) -> Result<Option<SurfaceInfo>, Error> {
256-
context.0.surface_info()
257-
}
258-
}

0 commit comments

Comments
 (0)