| // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <memory> |
| |
| #include "egl_stuff.h" |
| #include "main.h" |
| #include "xlib_window.h" |
| |
| std::unique_ptr<GLInterface> g_main_gl_interface; |
| |
| GLInterface* GLInterface::Create() { |
| return new EGLInterface; |
| } |
| |
| bool EGLInterface::Init() { |
| if (!XlibInit()) |
| return false; |
| |
| EGLNativeWindowType native_window = |
| static_cast<EGLNativeWindowType>(g_xlib_window); |
| surface_ = eglCreateWindowSurface(display_, config_, native_window, NULL); |
| CheckError(); |
| |
| context_ = CreateContext(); |
| CheckError(); |
| |
| eglMakeCurrent(display_, surface_, surface_, context_); |
| CheckError(); |
| |
| eglQuerySurface(display_, surface_, EGL_WIDTH, &g_width); |
| eglQuerySurface(display_, surface_, EGL_HEIGHT, &g_height); |
| |
| return true; |
| } |
| |
| void EGLInterface::Cleanup() { |
| eglMakeCurrent(display_, NULL, NULL, NULL); |
| DeleteContext(context_); |
| eglDestroySurface(display_, surface_); |
| } |
| |
| XVisualInfo* EGLInterface::GetXVisual() { |
| if (!config_) { |
| EGLint attribs[] = {EGL_RED_SIZE, 1, |
| EGL_GREEN_SIZE, 1, |
| EGL_BLUE_SIZE, 1, |
| EGL_DEPTH_SIZE, 1, |
| EGL_STENCIL_SIZE, 1, |
| EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
| EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
| EGL_NONE}; |
| |
| EGLNativeDisplayType native_display = |
| static_cast<EGLNativeDisplayType>(g_xlib_display); |
| |
| display_ = eglGetDisplay(native_display); |
| CheckError(); |
| |
| eglInitialize(display_, NULL, NULL); |
| CheckError(); |
| |
| EGLint num_configs = -1; |
| eglGetConfigs(display_, NULL, 0, &num_configs); |
| CheckError(); |
| |
| eglChooseConfig(display_, attribs, &config_, 1, &num_configs); |
| CheckError(); |
| } |
| |
| // TODO: for some reason on some systems EGL_NATIVE_VISUAL_ID returns an ID |
| // that XVisualIDFromVisual cannot find. Use default visual until this is |
| // resolved. |
| #if 0 |
| EGLint visual_id; |
| eglGetConfigAttrib(display_, config_, EGL_NATIVE_VISUAL_ID, &visual_id); |
| CheckError(); |
| XVisualInfo vinfo_template; |
| vinfo_template.visualid = static_cast<VisualID>(visual_id); |
| #else |
| XVisualInfo vinfo_template; |
| vinfo_template.visualid = XVisualIDFromVisual( |
| DefaultVisual(g_xlib_display, DefaultScreen(g_xlib_display))); |
| #endif |
| |
| int nitems = 0; |
| XVisualInfo* ret = |
| XGetVisualInfo(g_xlib_display, VisualIDMask, &vinfo_template, &nitems); |
| CHECK(nitems == 1); |
| return ret; |
| } |
| |
| void EGLInterface::SwapBuffers() { |
| eglSwapBuffers(display_, surface_); |
| } |
| |
| bool EGLInterface::SwapInterval(int interval) { |
| return (eglSwapInterval(display_, interval) == EGL_TRUE); |
| } |
| |
| bool EGLInterface::MakeCurrent(const GLContext& context) { |
| return eglMakeCurrent(display_, surface_, surface_, context); |
| } |
| |
| const GLContext EGLInterface::CreateContext() { |
| EGLint attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; |
| CHECK(display_ != EGL_NO_DISPLAY); |
| CHECK(config_); |
| return eglCreateContext(display_, config_, NULL, attribs); |
| } |
| |
| void EGLInterface::CheckError() { |
| CHECK_EQ(eglGetError(), EGL_SUCCESS); |
| } |
| |
| void EGLInterface::DeleteContext(const GLContext& context) { |
| eglDestroyContext(display_, context); |
| } |
| |
| void EGLInterface::TerminateGL() { |
| eglDestroySurface(display_, surface_); |
| eglTerminate(display_); |
| } |