1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Use of EGL to implement Gamnit on GNU/Linux and Android
20 import gamnit
::display
22 redef class GamnitDisplay
25 var egl_display
: EGLDisplay is noautoinit
28 var egl_context
: EGLContext is noautoinit
30 # The EGL surface for the window
31 var window_surface
: EGLSurface is noautoinit
33 # The selected EGL configuration
34 var egl_config
: EGLConfig is noautoinit
36 # Setup the EGL display for the given `native_display`
37 protected fun setup_egl_display
(native_display
: Pointer)
39 var egl_display
= new EGLDisplay(native_display
)
40 assert egl_display
.is_valid
else print
"new EGL display is not valid"
42 egl_display
.initialize
43 assert egl_display
.is_valid
else print
"EGL initialize error: {egl_display.error}"
45 self.egl_display
= egl_display
48 # Select an EGL config
49 protected fun select_egl_config
(red
, green
, blue
, alpha
, depth
, stencil
, sample
: Int)
51 var config_chooser
= new EGLConfigChooser
52 config_chooser
.renderable_type_egl
53 config_chooser
.surface_type_egl
54 config_chooser
.red_size
= red
55 config_chooser
.green_size
= green
56 config_chooser
.blue_size
= blue
57 if alpha
> 0 then config_chooser
.alpha_size
= alpha
58 if depth
> 0 then config_chooser
.depth_size
= depth
59 if stencil
> 0 then config_chooser
.stencil_size
= stencil
60 if sample
> 0 then config_chooser
.sample_buffers
= sample
63 var configs
= config_chooser
.choose
(egl_display
)
64 assert configs
!= null else print
"Choosing EGL config failed: {egl_display.error}"
65 assert not configs
.is_empty
else print
"Found no EGL config"
68 print
"EGL available configurations:"
69 for config
in configs
do
70 var attribs
= config
.attribs
(egl_display
)
71 print
"* Conformant to: {attribs.conformant}"
72 print
" Caveats: {attribs.caveat}"
73 print
" Size of RGBA: {attribs.red_size} {attribs.green_size} {attribs.blue_size} {attribs.alpha_size}"
74 print
" Buffer, depth, stencil: {attribs.buffer_size} {attribs.depth_size} {attribs.stencil_size}"
78 # We use the first one, it is recommended
79 self.egl_config
= configs
.first
82 # Setup the EGL context for the given `native_window`
83 protected fun setup_egl_context
(native_window
: Pointer)
85 var window_surface
= egl_display
.create_window_surface
(egl_config
, native_window
, [0])
86 assert window_surface
.is_ok
else print
"Creating EGL window surface failed: {egl_display.error}"
87 self.window_surface
= window_surface
89 egl_context
= egl_display
.create_context
(egl_config
)
90 assert egl_context
.is_ok
else print
"Creating EGL context failed: {egl_display.error}"
92 var make_current_res
= egl_display
.make_current
(window_surface
, window_surface
, egl_context
)
93 assert make_current_res
else print
"Creating EGL make current failed: {egl_display.error}"
95 # TODO make the API selection configurable per platform
96 assert egl_bind_opengl_es_api
else print
"EGL bind API failed: {egl_display.error}"
99 redef fun width
do return window_surface
.attribs
(egl_display
).width
101 redef fun height
do return window_surface
.attribs
(egl_display
).height
103 # Close the EGL context
106 egl_display
.make_current
(new EGLSurface.none
, new EGLSurface.none
, new EGLContext.none
)
107 egl_display
.destroy_context
(egl_context
)
108 egl_display
.destroy_surface
(window_surface
)
113 egl_display
.swap_buffers
(window_surface
)