36e1277a2e0fe74a6a0ef19163181ad2fc236ce4
[mesa.git] / src / egl / drivers / haiku / egl_haiku.cpp
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2014 Adrián Arroyo Calle <adrian.arroyocalle@gmail.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <errno.h>
26 #include <dlfcn.h>
27 #include <stdint.h>
28 #include <stdio.h>
29
30 #include "loader.h"
31 #include "eglconfig.h"
32 #include "eglcontext.h"
33 #include "egldisplay.h"
34 #include "egldriver.h"
35 #include "eglcurrent.h"
36 #include "egllog.h"
37 #include "eglsurface.h"
38 #include "eglimage.h"
39 #include "egltypedefs.h"
40
41 #include <InterfaceKit.h>
42 #include <OpenGLKit.h>
43
44
45 #define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
46
47 #ifdef DEBUG
48 # define TRACE(x...) printf("egl_haiku: " x)
49 # define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
50 #else
51 # define TRACE(x...)
52 # define CALLED()
53 #endif
54 #define ERROR(x...) printf("egl_haiku: " x)
55
56
57 _EGL_DRIVER_STANDARD_TYPECASTS(haiku_egl)
58
59
60 struct haiku_egl_driver
61 {
62 _EGLDriver base;
63
64 void *handle;
65 _EGLProc (*get_proc_address)(const char *procname);
66 void (*glFlush)(void);
67 };
68
69 struct haiku_egl_config
70 {
71 _EGLConfig base;
72 };
73
74 struct haiku_egl_context
75 {
76 _EGLContext ctx;
77 };
78
79 struct haiku_egl_surface
80 {
81 _EGLSurface surf;
82 BGLView* gl;
83 };
84
85
86 static void
87 haiku_log(EGLint level, const char *msg)
88 {
89 switch (level) {
90 case _EGL_DEBUG:
91 fprintf(stderr,"%s", msg);
92 break;
93 case _EGL_INFO:
94 fprintf(stderr,"%s", msg);
95 break;
96 case _EGL_WARNING:
97 fprintf(stderr,"%s", msg);
98 break;
99 case _EGL_FATAL:
100 fprintf(stderr,"%s", msg);
101 break;
102 default:
103 break;
104 }
105 }
106
107
108 /**
109 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
110 */
111 static _EGLSurface *
112 haiku_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
113 _EGLConfig *conf, void *native_surface, const EGLint *attrib_list)
114 {
115 return NULL;
116 }
117
118
119 /**
120 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
121 */
122 static _EGLSurface *
123 haiku_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
124 _EGLConfig *conf, void *native_window, const EGLint *attrib_list)
125 {
126 CALLED();
127
128 struct haiku_egl_surface* surface;
129 surface = (struct haiku_egl_surface*)calloc(1,sizeof (*surface));
130
131 _eglInitSurface(&surface->surf, disp, EGL_WINDOW_BIT, conf, attrib_list);
132 (&surface->surf)->SwapInterval = 1;
133
134 TRACE("Creating window\n");
135 BWindow* win = (BWindow*)native_window;
136
137 TRACE("Creating GL view\n");
138 surface->gl = new BGLView(win->Bounds(), "OpenGL", B_FOLLOW_ALL_SIDES, 0,
139 BGL_RGB | BGL_DOUBLE | BGL_ALPHA);
140
141 TRACE("Adding GL\n");
142 win->AddChild(surface->gl);
143
144 TRACE("Showing window\n");
145 win->Show();
146 return &surface->surf;
147 }
148
149
150 static _EGLSurface *
151 haiku_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
152 _EGLConfig *conf, void *native_pixmap, const EGLint *attrib_list)
153 {
154 return NULL;
155 }
156
157
158 static _EGLSurface *
159 haiku_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
160 _EGLConfig *conf, const EGLint *attrib_list)
161 {
162 return NULL;
163 }
164
165
166 static EGLBoolean
167 haiku_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
168 {
169 return EGL_TRUE;
170 }
171
172
173 static EGLBoolean
174 haiku_add_configs_for_visuals(_EGLDisplay *dpy)
175 {
176 CALLED();
177
178 struct haiku_egl_config* conf;
179 conf = CALLOC_STRUCT(haiku_egl_config);
180
181 _eglInitConfig(&conf->base, dpy, 1);
182 TRACE("Config inited\n");
183
184 _eglSetConfigKey(&conf->base, EGL_RED_SIZE, 8);
185 _eglSetConfigKey(&conf->base, EGL_BLUE_SIZE, 8);
186 _eglSetConfigKey(&conf->base, EGL_GREEN_SIZE, 8);
187 _eglSetConfigKey(&conf->base, EGL_LUMINANCE_SIZE, 0);
188 _eglSetConfigKey(&conf->base, EGL_ALPHA_SIZE, 8);
189 _eglSetConfigKey(&conf->base, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
190 EGLint r = (_eglGetConfigKey(&conf->base, EGL_RED_SIZE)
191 + _eglGetConfigKey(&conf->base, EGL_GREEN_SIZE)
192 + _eglGetConfigKey(&conf->base, EGL_BLUE_SIZE)
193 + _eglGetConfigKey(&conf->base, EGL_ALPHA_SIZE));
194 _eglSetConfigKey(&conf->base, EGL_BUFFER_SIZE, r);
195 _eglSetConfigKey(&conf->base, EGL_CONFIG_CAVEAT, EGL_NONE);
196 _eglSetConfigKey(&conf->base, EGL_CONFIG_ID, 1);
197 _eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE);
198 _eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE);
199 _eglSetConfigKey(&conf->base, EGL_STENCIL_SIZE, 0);
200 _eglSetConfigKey(&conf->base, EGL_TRANSPARENT_TYPE, EGL_NONE);
201 _eglSetConfigKey(&conf->base, EGL_NATIVE_RENDERABLE, EGL_TRUE); // Let's say yes
202 _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_ID, 0); // No visual
203 _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_TYPE, EGL_NONE); // No visual
204 _eglSetConfigKey(&conf->base, EGL_RENDERABLE_TYPE, 0x8);
205 _eglSetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS, 0); // TODO: How to get the right value ?
206 _eglSetConfigKey(&conf->base, EGL_SAMPLES, _eglGetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS) == 0 ? 0 : 0);
207 _eglSetConfigKey(&conf->base, EGL_DEPTH_SIZE, 24); // TODO: How to get the right value ?
208 _eglSetConfigKey(&conf->base, EGL_LEVEL, 0);
209 _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_WIDTH, 0); // TODO: How to get the right value ?
210 _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_HEIGHT, 0); // TODO: How to get the right value ?
211 _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_PIXELS, 0); // TODO: How to get the right value ?
212 _eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT /*| EGL_PIXMAP_BIT | EGL_PBUFFER_BIT*/);
213
214 TRACE("Config configuated\n");
215 if (!_eglValidateConfig(&conf->base, EGL_FALSE)) {
216 _eglLog(_EGL_DEBUG, "Haiku: failed to validate config");
217 return EGL_FALSE;
218 }
219 TRACE("Validated config\n");
220
221 _eglLinkConfig(&conf->base);
222 if (!_eglGetArraySize(dpy->Configs)) {
223 _eglLog(_EGL_WARNING, "Haiku: failed to create any config");
224 return EGL_FALSE;
225 }
226 TRACE("Config successfull\n");
227
228 return EGL_TRUE;
229 }
230
231 extern "C"
232 EGLBoolean
233 init_haiku(_EGLDriver *drv, _EGLDisplay *dpy)
234 {
235 CALLED();
236
237 _eglSetLogProc(haiku_log);
238
239 loader_set_logger(_eglLog);
240
241 TRACE("Add configs\n");
242 haiku_add_configs_for_visuals(dpy);
243
244 dpy->Version = 14;
245
246 TRACE("Initialization finished\n");
247
248 return EGL_TRUE;
249 }
250
251
252 extern "C"
253 EGLBoolean
254 haiku_terminate(_EGLDriver* drv,_EGLDisplay* dpy)
255 {
256 return EGL_TRUE;
257 }
258
259
260 extern "C"
261 _EGLContext*
262 haiku_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
263 _EGLContext *share_list, const EGLint *attrib_list)
264 {
265 CALLED();
266
267 struct haiku_egl_context* context;
268 context=(struct haiku_egl_context*)calloc(1,sizeof (*context));
269
270 if (!_eglInitContext(&context->ctx, disp, conf, attrib_list))
271 ERROR("ERROR creating context");
272
273 TRACE("Context created\n");
274 return &context->ctx;
275 }
276
277
278 extern "C"
279 EGLBoolean
280 haiku_destroy_context(_EGLDriver* drv, _EGLDisplay *disp, _EGLContext* ctx)
281 {
282 ctx=NULL;
283 return EGL_TRUE;
284 }
285
286
287 extern "C"
288 EGLBoolean
289 haiku_make_current(_EGLDriver* drv, _EGLDisplay* dpy, _EGLSurface *dsurf,
290 _EGLSurface *rsurf, _EGLContext *ctx)
291 {
292 CALLED();
293
294 struct haiku_egl_context* cont=haiku_egl_context(ctx);
295 struct haiku_egl_surface* surf=haiku_egl_surface(dsurf);
296 _EGLContext *old_ctx;
297 _EGLSurface *old_dsurf, *old_rsurf;
298 _eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf);
299 //cont->ctx.DrawSurface=&surf->surf;
300 surf->gl->LockGL();
301 return EGL_TRUE;
302 }
303
304
305 extern "C"
306 EGLBoolean
307 haiku_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
308 {
309 struct haiku_egl_surface* surface=haiku_egl_surface(surf);
310 surface->gl->SwapBuffers();
311 //gl->Render();
312 return EGL_TRUE;
313 }
314
315
316 extern "C"
317 void
318 haiku_unload(_EGLDriver* drv)
319 {
320
321 }
322
323
324 /**
325 * This is the main entrypoint into the driver, called by libEGL.
326 * Create a new _EGLDriver object and init its dispatch table.
327 */
328 extern "C"
329 _EGLDriver*
330 _eglBuiltInDriverHaiku(const char *args)
331 {
332 CALLED();
333
334 struct haiku_egl_driver* driver;
335 driver=(struct haiku_egl_driver*)calloc(1,sizeof(*driver));
336 _eglInitDriverFallbacks(&driver->base);
337 driver->base.API.Initialize = init_haiku;
338 driver->base.API.Terminate = haiku_terminate;
339 driver->base.API.CreateContext = haiku_create_context;
340 driver->base.API.DestroyContext = haiku_destroy_context;
341 driver->base.API.MakeCurrent = haiku_make_current;
342 driver->base.API.CreateWindowSurface = haiku_create_window_surface;
343 driver->base.API.CreatePixmapSurface = haiku_create_pixmap_surface;
344 driver->base.API.CreatePbufferSurface = haiku_create_pbuffer_surface;
345 driver->base.API.DestroySurface = haiku_destroy_surface;
346
347 driver->base.API.SwapBuffers = haiku_swap_buffers;
348
349 driver->base.Name = "Haiku";
350 driver->base.Unload = haiku_unload;
351
352 TRACE("API Calls defined\n");
353
354 return &driver->base;
355 }