• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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 
5 #define WAFFLE_API_VERSION 0x0106
6 
7 #include <memory>
8 
9 #include <stdio.h>
10 #include "main.h"
11 #include "utils.h"
12 #include "waffle_stuff.h"
13 
14 GLint g_width = WINDOW_WIDTH;
15 GLint g_height = WINDOW_HEIGHT;
16 
17 std::unique_ptr<GLInterface> g_main_gl_interface;
18 
19 #ifdef USE_OPENGL
20 namespace gl {
21 #define F(fun, type) type fun = NULL;
22 LIST_PROC_FUNCTIONS(F)
23 #undef F
24 };
25 #define GL_API WAFFLE_CONTEXT_OPENGL
26 #else
27 #define GL_API WAFFLE_CONTEXT_OPENGL_ES2
28 #endif
29 
30 #define ID_PLATFORM_GLX 1
31 #define ID_PLATFORM_X11_EGL 2
32 #define ID_PLATFORM_NULL 3
33 
34 #define CONCAT(a, b) a##b
35 #define PLATFORM_ID(x) CONCAT(ID_, x)
36 #define PLATFORM_ENUM(x) CONCAT(WAFFLE_, x)
37 #define THIS_IS(x) PLATFORM_ID(x) == PLATFORM_ID(PLATFORM)
38 
39 #if THIS_IS(PLATFORM_GLX)
40 #include "waffle_glx.h"
41 #elif THIS_IS(PLATFORM_X11_EGL)
42 #include "waffle_x11_egl.h"
43 #elif THIS_IS(PLATFORM_NULL)
44 #include "waffle_null.h"
45 #else
46 #error "Compile with -DPLATFORM=PLATFORM_<x> where <x> is NULL, GLX or X11_EGL."
47 #endif
48 
49 #define WAFFLE_CHECK_ERROR \
50   do {                     \
51     CHECK(WaffleOK());     \
52   } while (0)
53 
Create()54 GLInterface* GLInterface::Create() {
55   return new WaffleInterface;
56 }
57 
WaffleOK()58 static bool WaffleOK() {
59   const waffle_error_info* info = waffle_error_get_info();
60   if (info->code == WAFFLE_NO_ERROR)
61     return true;
62   printf("# Error: %s: %s\n", waffle_error_to_string(info->code),
63          info->message);
64   return false;
65 }
66 
GetSurfaceSize(GLint * width,GLint * height)67 void WaffleInterface::GetSurfaceSize(GLint* width, GLint* height) {
68   union waffle_native_window* nw = waffle_window_get_native(surface_);
69 
70 #if THIS_IS(PLATFORM_NULL)
71   *width = nw->null->width;
72   *height = nw->null->height;
73 #elif THIS_IS(PLATFORM_GLX)
74   unsigned w, h;
75 #if 0
76   // doesn't work with mesa - https://bugs.freedesktop.org/show_bug.cgi?id=54080
77   glXQueryDrawable(nw->glx->xlib_display, nw->glx->xlib_window, GLX_WIDTH, &w);
78   glXQueryDrawable(nw->glx->xlib_display, nw->glx->xlib_window, GLX_HEIGHT, &h);
79 #else
80   Window root;
81   int x, y;
82   unsigned bd, depth;
83   XGetGeometry(nw->glx->xlib_display, nw->glx->xlib_window, &root, &x, &y, &w,
84                &h, &bd, &depth);
85 #endif
86   *width = w;
87   *height = h;
88 #elif THIS_IS(PLATFORM_X11_EGL)
89   EGLint w, h;
90   eglQuerySurface(nw->x11_egl->display.egl_display, nw->x11_egl->egl_surface,
91                   EGL_WIDTH, &w);
92   eglQuerySurface(nw->x11_egl->display.egl_display, nw->x11_egl->egl_surface,
93                   EGL_HEIGHT, &h);
94   *width = w;
95   *height = h;
96 #else
97 #error "Compile with -DPLATFORM=PLATFORM_<x> where <x> is NULL, GLX or X11_EGL."
98 #endif
99 
100   free(nw);
101 }
102 
InitOnce()103 void WaffleInterface::InitOnce() {
104   // Prevent multiple initializations.
105   if (surface_)
106     return;
107 
108   int32_t initAttribs[] = {WAFFLE_PLATFORM, PLATFORM_ENUM(PLATFORM), 0};
109 
110   waffle_init(initAttribs);
111   WAFFLE_CHECK_ERROR;
112 
113   display_ = waffle_display_connect(NULL);
114   WAFFLE_CHECK_ERROR;
115 
116   int32_t configAttribs[] = {WAFFLE_CONTEXT_API, GL_API,
117                              WAFFLE_RED_SIZE, 1,
118                              WAFFLE_GREEN_SIZE, 1,
119                              WAFFLE_BLUE_SIZE, 1,
120                              WAFFLE_ALPHA_SIZE, 1,
121                              WAFFLE_DEPTH_SIZE, 1,
122                              WAFFLE_STENCIL_SIZE, 1,
123                              WAFFLE_DOUBLE_BUFFERED, true,
124                              0};
125 
126   config_ = waffle_config_choose(display_, configAttribs);
127   WAFFLE_CHECK_ERROR;
128 
129   if (g_width == -1 && g_height == -1) {
130     const intptr_t attrib[] = {WAFFLE_WINDOW_FULLSCREEN, 1, 0};
131     surface_ = waffle_window_create2(config_, attrib);
132     GetSurfaceSize(&g_width, &g_height);
133   } else {
134     surface_ = waffle_window_create(config_, g_width, g_height);
135   }
136   WAFFLE_CHECK_ERROR;
137 
138   waffle_window_show(surface_);
139   WAFFLE_CHECK_ERROR;
140 }
141 
Init()142 bool WaffleInterface::Init() {
143   InitOnce();
144 
145   context_ = CreateContext();
146   CHECK(context_);
147 
148   waffle_make_current(display_, surface_, context_);
149   WAFFLE_CHECK_ERROR;
150 
151 #if defined(USE_OPENGL)
152 #define F(fun, type) \
153   fun = reinterpret_cast<type>(waffle_get_proc_address(#fun));
154   LIST_PROC_FUNCTIONS(F)
155 #undef F
156 #endif
157 
158   return true;
159 }
160 
Cleanup()161 void WaffleInterface::Cleanup() {
162   waffle_make_current(display_, NULL, NULL);
163   WAFFLE_CHECK_ERROR;
164 
165   waffle_context_destroy(context_);
166   WAFFLE_CHECK_ERROR;
167 }
168 
SwapBuffers()169 void WaffleInterface::SwapBuffers() {
170   waffle_window_swap_buffers(surface_);
171   WAFFLE_CHECK_ERROR;
172 }
173 
SwapInterval(int interval)174 bool WaffleInterface::SwapInterval(int interval) {
175   return false;
176 }
177 
MakeCurrent(const GLContext & context)178 bool WaffleInterface::MakeCurrent(const GLContext& context) {
179   return waffle_make_current(display_, surface_, context);
180 }
181 
CreateContext()182 const GLContext WaffleInterface::CreateContext() {
183   return waffle_context_create(config_, NULL);
184 }
185 
CheckError()186 void WaffleInterface::CheckError() {}
187 
DeleteContext(const GLContext & context)188 void WaffleInterface::DeleteContext(const GLContext& context) {
189   waffle_context_destroy(context);
190   WAFFLE_CHECK_ERROR;
191 }
192