// 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_);
}