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 ;
154pub 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.
3323pub 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