• 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 "base/logging.h"
10 #include "main.h"
11 #include "waffle_stuff.h"
12 #include <stdio.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 do { CHECK(WaffleOK()); } while (0)
50 
Create()51 GLInterface* GLInterface::Create() {
52   return new WaffleInterface;
53 }
54 
WaffleOK()55 static bool WaffleOK() {
56   const waffle_error_info *info = waffle_error_get_info();
57   if (info->code == WAFFLE_NO_ERROR)
58     return true;
59   printf("# Error: %s: %s\n",
60          waffle_error_to_string(info->code),
61          info->message);
62   return false;
63 }
64 
GetSurfaceSize(GLint * width,GLint * height)65 void WaffleInterface::GetSurfaceSize(GLint *width, GLint *height) {
66   union waffle_native_window *nw = waffle_window_get_native(surface_);
67 
68 #if THIS_IS(PLATFORM_NULL)
69   *width = nw->null->width;
70   *height = nw->null->height;
71 #elif THIS_IS(PLATFORM_GLX)
72   unsigned w, h;
73 #if 0
74   // doesn't work with mesa - https://bugs.freedesktop.org/show_bug.cgi?id=54080
75   glXQueryDrawable(nw->glx->xlib_display, nw->glx->xlib_window, GLX_WIDTH, &w);
76   glXQueryDrawable(nw->glx->xlib_display, nw->glx->xlib_window, GLX_HEIGHT, &h);
77 #else
78    Window root;
79    int x, y;
80    unsigned bd, depth;
81    XGetGeometry(nw->glx->xlib_display, nw->glx->xlib_window,
82                 &root, &x, &y, &w, &h, &bd, &depth);
83 #endif
84   *width = w;
85   *height = h;
86 #elif THIS_IS(PLATFORM_X11_EGL)
87   EGLint w, h;
88   eglQuerySurface(nw->x11_egl->display.egl_display, nw->x11_egl->egl_surface,
89                   EGL_WIDTH, &w);
90   eglQuerySurface(nw->x11_egl->display.egl_display, nw->x11_egl->egl_surface,
91                   EGL_HEIGHT, &h);
92   *width = w;
93   *height = h;
94 #else
95 #error "Compile with -DPLATFORM=PLATFORM_<x> where <x> is NULL, GLX or X11_EGL."
96 #endif
97 
98   free(nw);
99 }
100 
InitOnce()101 void WaffleInterface::InitOnce() {
102   // Prevent multiple initializations.
103   if (surface_)
104     return;
105 
106   int32_t initAttribs[] = {
107     WAFFLE_PLATFORM, PLATFORM_ENUM(PLATFORM),
108     0
109   };
110 
111   waffle_init(initAttribs);
112   WAFFLE_CHECK_ERROR;
113 
114   display_ = waffle_display_connect(NULL);
115   WAFFLE_CHECK_ERROR;
116 
117   int32_t configAttribs[] = {
118     WAFFLE_CONTEXT_API,     GL_API,
119     WAFFLE_RED_SIZE,        1,
120     WAFFLE_GREEN_SIZE,      1,
121     WAFFLE_BLUE_SIZE,       1,
122     WAFFLE_ALPHA_SIZE,      1,
123     WAFFLE_DEPTH_SIZE,      1,
124     WAFFLE_STENCIL_SIZE,    1,
125     WAFFLE_DOUBLE_BUFFERED, true,
126     0
127   };
128 
129   config_ = waffle_config_choose(display_, configAttribs);
130   WAFFLE_CHECK_ERROR;
131 
132   if (g_width == -1 && g_height == -1) {
133     const intptr_t attrib[] = {
134       WAFFLE_WINDOW_FULLSCREEN, 1,
135       0
136     };
137     surface_ = waffle_window_create2(config_, attrib);
138     GetSurfaceSize(&g_width, &g_height);
139   } else {
140     surface_ = waffle_window_create(config_, g_width, g_height);
141   }
142   WAFFLE_CHECK_ERROR;
143 
144   waffle_window_show(surface_);
145   WAFFLE_CHECK_ERROR;
146 }
147 
Init()148 bool WaffleInterface::Init() {
149   InitOnce();
150 
151   context_ = CreateContext();
152   CHECK(context_);
153 
154   waffle_make_current(display_, surface_, context_);
155   WAFFLE_CHECK_ERROR;
156 
157 #if defined(USE_OPENGL)
158 #define F(fun, type) fun = reinterpret_cast<type>(waffle_get_proc_address(#fun));
159   LIST_PROC_FUNCTIONS(F)
160 #undef F
161 #endif
162 
163   return true;
164 }
165 
Cleanup()166 void WaffleInterface::Cleanup() {
167   waffle_make_current(display_, NULL, NULL);
168   WAFFLE_CHECK_ERROR;
169 
170   waffle_context_destroy(context_);
171   WAFFLE_CHECK_ERROR;
172 }
173 
SwapBuffers()174 void WaffleInterface::SwapBuffers() {
175   waffle_window_swap_buffers(surface_);
176   WAFFLE_CHECK_ERROR;
177 }
178 
SwapInterval(int interval)179 bool WaffleInterface::SwapInterval(int interval) {
180   return false;
181 }
182 
MakeCurrent(const GLContext & context)183 bool WaffleInterface::MakeCurrent(const GLContext& context) {
184   return waffle_make_current(display_, surface_, context);
185 }
186 
CreateContext()187 const GLContext WaffleInterface::CreateContext() {
188   return waffle_context_create(config_, NULL);
189 }
190 
CheckError()191 void WaffleInterface::CheckError() {
192 }
193 
DeleteContext(const GLContext & context)194 void WaffleInterface::DeleteContext(const GLContext& context) {
195   waffle_context_destroy(context);
196   WAFFLE_CHECK_ERROR;
197 }
198