4 #include <android/native_window.h>
7 #include "window_private.h"
14 struct GLContext::Private
21 void attach(WindowHandle);
26 void GLContext::platform_init(const GLOptions &opts)
28 EGLDisplay egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
29 if(egl_display==EGL_NO_DISPLAY)
30 throw runtime_error("no egl display");
32 if(!eglInitialize(egl_display, 0, 0))
33 throw runtime_error("could not initialize egl");
37 attribs.push_back(EGL_COLOR_BUFFER_TYPE);
38 attribs.push_back(EGL_RGB_BUFFER);
39 attribs.push_back(EGL_RENDERABLE_TYPE);
40 attribs.push_back(EGL_OPENGL_ES2_BIT);
41 attribs.push_back(EGL_SURFACE_TYPE);
42 attribs.push_back(EGL_WINDOW_BIT);
43 attribs.push_back(EGL_DEPTH_SIZE);
48 attribs.push_back(EGL_ALPHA_SIZE);
54 attribs.push_back(EGL_STENCIL_SIZE);
58 if(opts.multisample>0)
60 attribs.push_back(EGL_SAMPLE_BUFFERS);
62 attribs.push_back(EGL_SAMPLES);
63 attribs.push_back(opts.multisample);
66 attribs.push_back(EGL_NONE);
70 if(!eglChooseConfig(egl_display, &attribs.front(), &config, 1, &num_configs))
72 eglTerminate(egl_display);
73 throw unsupported_gl_mode(opts);
77 priv->display = egl_display;
78 priv->config = config;
80 /* Must wait for the window to be available, because the calling code
81 expects GL to be usable after creation of the context. */
82 WindowHandle native_window;
83 const Window::Private &window_priv = window.get_private();
84 while(!(native_window = window_priv.window))
88 eglGetConfigAttrib(priv->display, config, EGL_NATIVE_VISUAL_ID, &format);
89 ANativeWindow_setBuffersGeometry(native_window, 0, 0, format);
91 priv->surface = eglCreateWindowSurface(priv->display, config, native_window, 0);
93 eglBindAPI(EGL_OPENGL_ES_API);
94 int context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
95 priv->context = eglCreateContext(priv->display, config, 0, context_attribs);
97 eglMakeCurrent(priv->display, priv->surface, priv->surface, priv->context);
99 window_priv.signal_window_acquired.connect(sigc::mem_fun(priv, &Private::attach));
100 window_priv.signal_window_lost.connect(sigc::mem_fun(priv, &Private::detach));
103 GLContext::~GLContext()
105 eglDestroyContext(priv->display, priv->context);
106 if(priv->surface!=EGL_NO_SURFACE)
107 eglDestroySurface(priv->display, priv->surface);
108 eglTerminate(priv->display);
112 void GLContext::swap_buffers()
114 eglSwapBuffers(priv->display, priv->surface);
117 void GLContext::window_resized(unsigned, unsigned)
121 void GLContext::Private::attach(WindowHandle native_window)
123 surface = eglCreateWindowSurface(display, config, native_window, 0);
124 eglMakeCurrent(display, surface, surface, context);
127 void GLContext::Private::detach()
129 eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
130 eglDestroySurface(display, surface);
133 } // namespace Graphics