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