@@ -574,7 +574,6 @@ impl Inner {
574574 } )
575575 . unwrap ( ) ;
576576
577- let needs_robustness = true ;
578577 let mut khr_context_flags = 0 ;
579578 let supports_khr_context = display_extensions. contains ( "EGL_KHR_create_context" ) ;
580579
@@ -611,53 +610,108 @@ impl Inner {
611610 log:: debug!( "\t EGL context: -debug" ) ;
612611 }
613612 }
614- if needs_robustness {
615- //Note: the core version can fail if robustness is not supported
616- // (regardless of whether the extension is supported!).
617- // In fact, Angle does precisely that awful behavior, so we don't try it there.
618- if version >= ( 1 , 5 ) && !display_extensions. contains ( "EGL_ANGLE_" ) {
619- log:: debug!( "\t EGL context: +robust access" ) ;
620- context_attributes. push ( khronos_egl:: CONTEXT_OPENGL_ROBUST_ACCESS ) ;
621- context_attributes. push ( khronos_egl:: TRUE as _ ) ;
622- } else if display_extensions. contains ( "EGL_EXT_create_context_robustness" ) {
623- log:: debug!( "\t EGL context: +robust access EXT" ) ;
624- context_attributes. push ( EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT ) ;
625- context_attributes. push ( khronos_egl:: TRUE as _ ) ;
626- } else {
627- //Note: we aren't trying `EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR`
628- // because it's for desktop GL only, not GLES.
629- log:: warn!( "\t EGL context: -robust access" ) ;
630- }
631- }
613+
632614 if khr_context_flags != 0 {
633615 context_attributes. push ( EGL_CONTEXT_FLAGS_KHR ) ;
634616 context_attributes. push ( khr_context_flags) ;
635617 }
636- context_attributes. push ( khronos_egl:: NONE ) ;
637618
638619 gl_context_attributes. extend ( & context_attributes) ;
639620 gles_context_attributes. extend ( & context_attributes) ;
640621
641- let context = if supports_opengl {
642- egl. create_context ( display, config, None , & gl_context_attributes)
643- . or_else ( |_| {
644- egl. bind_api ( khronos_egl:: OPENGL_ES_API ) . unwrap ( ) ;
622+ let context = {
623+ enum Robustness {
624+ Core ,
625+ Ext ,
626+ }
627+
628+ let mut robustness = if version >= ( 1 , 5 ) {
629+ Some ( Robustness :: Core )
630+ } else if display_extensions. contains ( "EGL_EXT_create_context_robustness" ) {
631+ Some ( Robustness :: Ext )
632+ } else {
633+ None
634+ } ;
635+
636+ loop {
637+ let robustness_attributes = match robustness {
638+ Some ( Robustness :: Core ) => {
639+ vec ! [
640+ khronos_egl:: CONTEXT_OPENGL_ROBUST_ACCESS ,
641+ khronos_egl:: TRUE as _,
642+ khronos_egl:: NONE ,
643+ ]
644+ }
645+ Some ( Robustness :: Ext ) => {
646+ vec ! [
647+ EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT ,
648+ khronos_egl:: TRUE as _,
649+ khronos_egl:: NONE ,
650+ ]
651+ }
652+ None => vec ! [ khronos_egl:: NONE ] ,
653+ } ;
654+
655+ let mut gl_context_attributes = gl_context_attributes. clone ( ) ;
656+ gl_context_attributes. extend ( & robustness_attributes) ;
657+
658+ let mut gles_context_attributes = gles_context_attributes. clone ( ) ;
659+ gles_context_attributes. extend ( & robustness_attributes) ;
660+
661+ let result = if supports_opengl {
662+ egl. create_context ( display, config, None , & gl_context_attributes)
663+ . or_else ( |_| {
664+ egl. bind_api ( khronos_egl:: OPENGL_ES_API ) . unwrap ( ) ;
665+ egl. create_context ( display, config, None , & gles_context_attributes)
666+ } )
667+ } else {
645668 egl. create_context ( display, config, None , & gles_context_attributes)
646- } )
647- . map_err ( |e| {
648- crate :: InstanceError :: with_source (
649- String :: from ( "unable to create OpenGL or GLES 3.x context" ) ,
650- e,
651- )
652- } )
653- } else {
654- egl. create_context ( display, config, None , & gles_context_attributes)
655- . map_err ( |e| {
656- crate :: InstanceError :: with_source (
657- String :: from ( "unable to create GLES 3.x context" ) ,
658- e,
659- )
660- } )
669+ } ;
670+
671+ match ( result, robustness) {
672+ // We have a context at the requested robustness level
673+ ( Ok ( _) , robustness) => {
674+ match robustness {
675+ Some ( Robustness :: Core ) => {
676+ log:: debug!( "\t EGL context: +robust access" ) ;
677+ }
678+ Some ( Robustness :: Ext ) => {
679+ log:: debug!( "\t EGL context: +robust access EXT" ) ;
680+ }
681+ None => {
682+ log:: debug!( "\t EGL context: -robust access" ) ;
683+ }
684+ }
685+
686+ break result;
687+ }
688+
689+ // BadAttribute could mean that context creation is not supported at the requested robustness level
690+ // We try the next robustness level.
691+ ( Err ( khronos_egl:: Error :: BadAttribute ) , Some ( r) ) => {
692+ // Trying EXT robustness if Core robustness is not working
693+ // and EXT robustness is supported.
694+ robustness = if matches ! ( r, Robustness :: Core )
695+ && display_extensions. contains ( "EGL_EXT_create_context_robustness" )
696+ {
697+ Some ( Robustness :: Ext )
698+ } else {
699+ None
700+ } ;
701+
702+ continue ;
703+ }
704+
705+ // Any other error, or depleted robustness levels, we give up.
706+ _ => break result,
707+ }
708+ }
709+ . map_err ( |e| {
710+ crate :: InstanceError :: with_source (
711+ String :: from ( "unable to create OpenGL or GLES 3.x context" ) ,
712+ e,
713+ )
714+ } )
661715 } ?;
662716
663717 // Testing if context can be binded without surface
0 commit comments