@@ -13,6 +13,7 @@ use crate::egl::types::{EGLConfig, EGLContext, EGLDisplay, EGLSurface, EGLint};
13
13
use crate :: surface:: Framebuffer ;
14
14
use crate :: { ContextAttributeFlags , ContextAttributes , ContextID , Error , GLApi , GLVersion } ;
15
15
use crate :: { Gl , SurfaceInfo } ;
16
+ use glow:: HasContext ;
16
17
17
18
use std:: ffi:: CString ;
18
19
use std:: mem;
@@ -27,6 +28,7 @@ const RGB_CHANNEL_BIT_DEPTH: EGLint = 8;
27
28
pub ( crate ) struct EGLBackedContext {
28
29
pub ( crate ) egl_context : EGLContext ,
29
30
pub ( crate ) id : ContextID ,
31
+ pbuffer : EGLSurface ,
30
32
framebuffer : Framebuffer < EGLBackedSurface , ExternalEGLSurfaces > ,
31
33
context_is_owned : bool ,
32
34
}
@@ -101,12 +103,16 @@ impl EGLBackedContext {
101
103
gl_api,
102
104
) ?;
103
105
106
+ // Create a dummy pbuffer.
107
+ let pbuffer = create_dummy_pbuffer ( egl_display, egl_context) . unwrap_or ( egl:: NO_SURFACE ) ;
108
+
104
109
// Wrap and return it.
105
110
let context = EGLBackedContext {
106
111
egl_context,
107
112
id : * next_context_id,
108
113
framebuffer : Framebuffer :: None ,
109
114
context_is_owned : true ,
115
+ pbuffer,
110
116
} ;
111
117
next_context_id. 0 += 1 ;
112
118
Ok ( context)
@@ -122,13 +128,20 @@ impl EGLBackedContext {
122
128
read : native_context. egl_read_surface ,
123
129
} ) ,
124
130
context_is_owned : false ,
131
+ pbuffer : egl:: NO_SURFACE ,
125
132
} ;
126
133
next_context_id. 0 += 1 ;
127
134
context
128
135
}
129
136
130
137
pub ( crate ) unsafe fn destroy ( & mut self , egl_display : EGLDisplay ) {
131
138
EGL_FUNCTIONS . with ( |egl| {
139
+ if self . pbuffer != egl:: NO_SURFACE {
140
+ let result = egl. DestroySurface ( egl_display, self . pbuffer ) ;
141
+ assert_ne ! ( result, egl:: FALSE ) ;
142
+ self . pbuffer = egl:: NO_SURFACE ;
143
+ }
144
+
132
145
egl. MakeCurrent (
133
146
egl_display,
134
147
egl:: NO_SURFACE ,
@@ -163,7 +176,10 @@ impl EGLBackedContext {
163
176
let egl_surfaces = match self . framebuffer {
164
177
Framebuffer :: Surface ( ref surface) => surface. egl_surfaces ( ) ,
165
178
Framebuffer :: External ( ref surfaces) => ( * surfaces) . clone ( ) ,
166
- Framebuffer :: None => ExternalEGLSurfaces :: default ( ) ,
179
+ Framebuffer :: None => ExternalEGLSurfaces {
180
+ draw : self . pbuffer ,
181
+ read : self . pbuffer ,
182
+ } ,
167
183
} ;
168
184
169
185
EGL_FUNCTIONS . with ( |egl| {
@@ -214,6 +230,9 @@ impl EGLBackedContext {
214
230
gl : & Gl ,
215
231
egl_display : EGLDisplay ,
216
232
) -> Result < Option < EGLBackedSurface > , Error > {
233
+ // Flush to avoid races on Mesa/Intel and possibly other GPUs.
234
+ gl. flush ( ) ;
235
+
217
236
match self . framebuffer {
218
237
Framebuffer :: None => return Ok ( None ) ,
219
238
Framebuffer :: Surface ( _) => { }
@@ -382,29 +401,20 @@ impl ContextDescriptor {
382
401
} )
383
402
}
384
403
385
- pub ( crate ) unsafe fn from_egl_context < F > (
386
- get_proc_address : F ,
404
+ pub ( crate ) unsafe fn from_egl_context (
405
+ gl : & Gl ,
387
406
egl_display : EGLDisplay ,
388
407
egl_context : EGLContext ,
389
- ) -> ContextDescriptor
390
- where
391
- F : FnMut ( & str ) -> * const c_void ,
392
- {
408
+ ) -> ContextDescriptor {
393
409
let egl_config_id = get_context_attr ( egl_display, egl_context, egl:: CONFIG_ID as EGLint ) ;
410
+ let gl_version = GLVersion :: current ( & gl) ;
411
+ let compatibility_profile = context:: current_context_uses_compatibility_profile ( & gl) ;
394
412
395
- EGL_FUNCTIONS . with ( |egl| {
396
- let _guard = CurrentContextGuard :: new ( ) ;
397
- egl. MakeCurrent ( egl_display, egl:: NO_SURFACE , egl:: NO_SURFACE , egl_context) ;
398
- let gl = unsafe { Gl :: from_loader_function ( get_proc_address) } ;
399
- let gl_version = GLVersion :: current ( & gl) ;
400
- let compatibility_profile = context:: current_context_uses_compatibility_profile ( & gl) ;
401
-
402
- ContextDescriptor {
403
- egl_config_id,
404
- gl_version,
405
- compatibility_profile,
406
- }
407
- } )
413
+ ContextDescriptor {
414
+ egl_config_id,
415
+ gl_version,
416
+ compatibility_profile,
417
+ }
408
418
}
409
419
410
420
#[ allow( dead_code) ]
@@ -609,7 +619,7 @@ pub(crate) fn get_proc_address(symbol_name: &str) -> *const c_void {
609
619
pub ( crate ) unsafe fn create_dummy_pbuffer (
610
620
egl_display : EGLDisplay ,
611
621
egl_context : EGLContext ,
612
- ) -> EGLSurface {
622
+ ) -> Option < EGLSurface > {
613
623
let egl_config_id = get_context_attr ( egl_display, egl_context, egl:: CONFIG_ID as EGLint ) ;
614
624
let egl_config = egl_config_from_id ( egl_display, egl_config_id) ;
615
625
@@ -627,7 +637,10 @@ pub(crate) unsafe fn create_dummy_pbuffer(
627
637
EGL_FUNCTIONS . with ( |egl| {
628
638
let pbuffer =
629
639
egl. CreatePbufferSurface ( egl_display, egl_config, pbuffer_attributes. as_ptr ( ) ) ;
630
- assert_ne ! ( pbuffer, egl:: NO_SURFACE ) ;
631
- pbuffer
640
+ if pbuffer == egl:: NO_SURFACE {
641
+ None
642
+ } else {
643
+ Some ( pbuffer)
644
+ }
632
645
} )
633
646
}
0 commit comments