1// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4#include "egl_stuff.h"
5#include "main.h"
6#include "xlib_window.h"
7
8scoped_ptr<GLInterface> g_main_gl_interface;
9
10GLInterface* GLInterface::Create() {
11  return new EGLInterface;
12}
13
14bool EGLInterface::Init() {
15  if (!XlibInit())
16    return false;
17
18  EGLNativeWindowType native_window =
19      static_cast<EGLNativeWindowType>(g_xlib_window);
20  surface_ = eglCreateWindowSurface(display_, config_, native_window, NULL);
21  CheckError();
22
23  context_ = CreateContext();
24  CheckError();
25
26  eglMakeCurrent(display_, surface_, surface_, context_);
27  CheckError();
28
29  eglQuerySurface(display_, surface_, EGL_WIDTH, &g_width);
30  eglQuerySurface(display_, surface_, EGL_HEIGHT, &g_height);
31
32  return true;
33}
34
35void EGLInterface::Cleanup() {
36  eglMakeCurrent(display_, NULL, NULL, NULL);
37  DeleteContext(context_);
38  eglDestroySurface(display_, surface_);
39}
40
41XVisualInfo* EGLInterface::GetXVisual() {
42  if (!config_) {
43    EGLint attribs[] = {
44      EGL_RED_SIZE, 1,
45      EGL_GREEN_SIZE, 1,
46      EGL_BLUE_SIZE, 1,
47      EGL_DEPTH_SIZE, 1,
48      EGL_STENCIL_SIZE, 1,
49      EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
50      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
51      EGL_NONE
52    };
53
54    EGLNativeDisplayType native_display =
55      static_cast<EGLNativeDisplayType>(g_xlib_display);
56
57    display_ = eglGetDisplay(native_display);
58    CheckError();
59
60    eglInitialize(display_, NULL, NULL);
61    CheckError();
62
63    EGLint num_configs = -1;
64    eglGetConfigs(display_, NULL, 0, &num_configs);
65    CheckError();
66
67    eglChooseConfig(display_, attribs, &config_, 1, &num_configs);
68    CheckError();
69  }
70
71  // TODO: for some reason on some systems EGL_NATIVE_VISUAL_ID returns an ID
72  // that XVisualIDFromVisual cannot find.  Use default visual until this is
73  // resolved.
74#if 0
75  EGLint visual_id;
76  eglGetConfigAttrib(display_, config_, EGL_NATIVE_VISUAL_ID, &visual_id);
77  CheckError();
78  XVisualInfo vinfo_template;
79  vinfo_template.visualid = static_cast<VisualID>(visual_id);
80#else
81  XVisualInfo vinfo_template;
82  vinfo_template.visualid = XVisualIDFromVisual(DefaultVisual(
83      g_xlib_display, DefaultScreen(g_xlib_display)));
84#endif
85
86  int nitems = 0;
87  XVisualInfo* ret = XGetVisualInfo(g_xlib_display, VisualIDMask,
88                                    &vinfo_template, &nitems);
89  CHECK(nitems == 1);
90  return ret;
91}
92
93void EGLInterface::SwapBuffers() {
94  eglSwapBuffers(display_, surface_);
95}
96
97bool EGLInterface::SwapInterval(int interval) {
98  return (eglSwapInterval(display_, interval) == EGL_TRUE);
99}
100
101bool EGLInterface::MakeCurrent(const GLContext& context) {
102  return eglMakeCurrent(display_, surface_, surface_, context);
103}
104
105const GLContext EGLInterface::CreateContext() {
106  EGLint attribs[] = {
107    EGL_CONTEXT_CLIENT_VERSION, 2,
108    EGL_NONE
109  };
110  CHECK(display_ != EGL_NO_DISPLAY);
111  CHECK(config_);
112  return eglCreateContext(display_, config_, NULL, attribs);
113}
114
115void EGLInterface::CheckError() {
116  CHECK_EQ(eglGetError(), EGL_SUCCESS);
117}
118
119void EGLInterface::DeleteContext(const GLContext& context) {
120  eglDestroyContext(display_, context);
121}
122
123void EGLInterface::TerminateGL() {
124  eglDestroySurface(display_, surface_);
125  eglTerminate(display_);
126}
127