Skip to content

Commit 53e5509

Browse files
authored
Merge most impl Device blocks in src/mesa_surfaceless (#375)
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 faaa35c commit 53e5509

3 files changed

Lines changed: 397 additions & 405 deletions

File tree

src/mesa_surfaceless/context.rs

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

0 commit comments

Comments
 (0)