760ee453f6d96bcd66735b4cfe85a183bd28af59
[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 #ifdef DEBUG
46 # define TRACE(x...) printf("egl_haiku: " x)
47 # define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
48 #else
49 # define TRACE(x...)
50 # define CALLED()
51 #endif
52 #define ERROR(x...) printf("egl_haiku: " x)
53
54
55 _EGL_DRIVER_STANDARD_TYPECASTS(haiku_egl)
56
57
58 struct haiku_egl_driver
59 {
60 _EGLDriver base;
61
62 void *handle;
63 _EGLProc (*get_proc_address)(const char *procname);
64 void (*glFlush)(void);
65 };
66
67 struct haiku_egl_config
68 {
69 _EGLConfig base;
70 };
71
72 struct haiku_egl_context
73 {
74 _EGLContext ctx;
75 };
76
77 struct haiku_egl_surface
78 {
79 _EGLSurface surf;
80 BGLView* gl;
81 };
82
83
84 static void
85 haiku_log(EGLint level, const char *msg)
86 {
87 switch (level) {
88 case _EGL_DEBUG:
89 fprintf(stderr,"%s", msg);
90 break;
91 case _EGL_INFO:
92 fprintf(stderr,"%s", msg);
93 break;
94 case _EGL_WARNING:
95 fprintf(stderr,"%s", msg);
96 break;
97 case _EGL_FATAL:
98 fprintf(stderr,"%s", msg);
99 break;
100 default:
101 break;
102 }
103 }
104
105
106 /**
107 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
108 */
109 static _EGLSurface *
110 haiku_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
111 _EGLConfig *conf, void *native_surface, const EGLint *attrib_list)
112 {
113 return NULL;
114 }
115
116
117 /**
118 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
119 */
120 static _EGLSurface *
121 haiku_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
122 _EGLConfig *conf, void *native_window, const EGLint *attrib_list)
123 {
124 CALLED();
125
126 struct haiku_egl_surface* surface;
127 surface = (struct haiku_egl_surface*) calloc(1, sizeof (*surface));
128 if (!surface) {
129 _eglError(EGL_BAD_ALLOC, "haiku_create_window_surface");
130 return NULL;
131 }
132
133 if (!_eglInitSurface(&surface->surf, disp, EGL_WINDOW_BIT, conf, attrib_list))
134 goto cleanup_surface;
135
136 (&surface->surf)->SwapInterval = 1;
137
138 TRACE("Creating window\n");
139 BWindow* win = (BWindow*)native_window;
140
141 TRACE("Creating GL view\n");
142 surface->gl = new BGLView(win->Bounds(), "OpenGL", B_FOLLOW_ALL_SIDES, 0,
143 BGL_RGB | BGL_DOUBLE | BGL_ALPHA);
144
145 TRACE("Adding GL\n");
146 win->AddChild(surface->gl);
147
148 TRACE("Showing window\n");
149 win->Show();
150 return &surface->surf;
151
152 cleanup_surface:
153 free(surface);
154 return NULL;
155 }
156
157
158 static _EGLSurface *
159 haiku_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
160 _EGLConfig *conf, void *native_pixmap, const EGLint *attrib_list)
161 {
162 return NULL;
163 }
164
165
166 static _EGLSurface *
167 haiku_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
168 _EGLConfig *conf, const EGLint *attrib_list)
169 {
170 return NULL;
171 }
172
173
174 static EGLBoolean
175 haiku_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
176 {
177 return EGL_TRUE;
178 }
179
180
181 static EGLBoolean
182 haiku_add_configs_for_visuals(_EGLDisplay *dpy)
183 {
184 CALLED();
185
186 struct haiku_egl_config* conf;
187 conf = (struct haiku_egl_config*) calloc(1, sizeof (*conf));
188 if (!conf) {
189 _eglError(EGL_BAD_ALLOC, "haiku_add_configs_for_visuals");
190 return NULL;
191 }
192
193 _eglInitConfig(&conf->base, dpy, 1);
194 TRACE("Config inited\n");
195
196 _eglSetConfigKey(&conf->base, EGL_RED_SIZE, 8);
197 _eglSetConfigKey(&conf->base, EGL_BLUE_SIZE, 8);
198 _eglSetConfigKey(&conf->base, EGL_GREEN_SIZE, 8);
199 _eglSetConfigKey(&conf->base, EGL_LUMINANCE_SIZE, 0);
200 _eglSetConfigKey(&conf->base, EGL_ALPHA_SIZE, 8);
201 _eglSetConfigKey(&conf->base, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
202 EGLint r = (_eglGetConfigKey(&conf->base, EGL_RED_SIZE)
203 + _eglGetConfigKey(&conf->base, EGL_GREEN_SIZE)
204 + _eglGetConfigKey(&conf->base, EGL_BLUE_SIZE)
205 + _eglGetConfigKey(&conf->base, EGL_ALPHA_SIZE));
206 _eglSetConfigKey(&conf->base, EGL_BUFFER_SIZE, r);
207 _eglSetConfigKey(&conf->base, EGL_CONFIG_CAVEAT, EGL_NONE);
208 _eglSetConfigKey(&conf->base, EGL_CONFIG_ID, 1);
209 _eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE);
210 _eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE);
211 _eglSetConfigKey(&conf->base, EGL_STENCIL_SIZE, 0);
212 _eglSetConfigKey(&conf->base, EGL_TRANSPARENT_TYPE, EGL_NONE);
213 _eglSetConfigKey(&conf->base, EGL_NATIVE_RENDERABLE, EGL_TRUE); // Let's say yes
214 _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_ID, 0); // No visual
215 _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_TYPE, EGL_NONE); // No visual
216 _eglSetConfigKey(&conf->base, EGL_RENDERABLE_TYPE, 0x8);
217 _eglSetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS, 0); // TODO: How to get the right value ?
218 _eglSetConfigKey(&conf->base, EGL_SAMPLES, _eglGetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS) == 0 ? 0 : 0);
219 _eglSetConfigKey(&conf->base, EGL_DEPTH_SIZE, 24); // TODO: How to get the right value ?
220 _eglSetConfigKey(&conf->base, EGL_LEVEL, 0);
221 _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_WIDTH, 0); // TODO: How to get the right value ?
222 _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_HEIGHT, 0); // TODO: How to get the right value ?
223 _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_PIXELS, 0); // TODO: How to get the right value ?
224 _eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT /*| EGL_PIXMAP_BIT | EGL_PBUFFER_BIT*/);
225
226 TRACE("Config configuated\n");
227 if (!_eglValidateConfig(&conf->base, EGL_FALSE)) {
228 _eglLog(_EGL_DEBUG, "Haiku: failed to validate config");
229 return EGL_FALSE;
230 }
231 TRACE("Validated config\n");
232
233 _eglLinkConfig(&conf->base);
234 if (!_eglGetArraySize(dpy->Configs)) {
235 _eglLog(_EGL_WARNING, "Haiku: failed to create any config");
236 return EGL_FALSE;
237 }
238 TRACE("Config successfull\n");
239
240 return EGL_TRUE;
241 }
242
243 extern "C"
244 EGLBoolean
245 init_haiku(_EGLDriver *drv, _EGLDisplay *dpy)
246 {
247 CALLED();
248
249 _eglSetLogProc(haiku_log);
250
251 loader_set_logger(_eglLog);
252
253 TRACE("Add configs\n");
254 haiku_add_configs_for_visuals(dpy);
255
256 dpy->Version = 14;
257
258 TRACE("Initialization finished\n");
259
260 return EGL_TRUE;
261 }
262
263
264 extern "C"
265 EGLBoolean
266 haiku_terminate(_EGLDriver* drv,_EGLDisplay* dpy)
267 {
268 return EGL_TRUE;
269 }
270
271
272 extern "C"
273 _EGLContext*
274 haiku_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
275 _EGLContext *share_list, const EGLint *attrib_list)
276 {
277 CALLED();
278
279 struct haiku_egl_context* context;
280 context = (struct haiku_egl_context*) calloc(1, sizeof (*context));
281 if (!context) {
282 _eglError(EGL_BAD_ALLOC, "haiku_create_context");
283 return NULL;
284 }
285
286 if (!_eglInitContext(&context->ctx, disp, conf, attrib_list))
287 ERROR("ERROR creating context");
288
289 TRACE("Context created\n");
290 return &context->ctx;
291 }
292
293
294 extern "C"
295 EGLBoolean
296 haiku_destroy_context(_EGLDriver* drv, _EGLDisplay *disp, _EGLContext* ctx)
297 {
298 ctx=NULL;
299 return EGL_TRUE;
300 }
301
302
303 extern "C"
304 EGLBoolean
305 haiku_make_current(_EGLDriver* drv, _EGLDisplay* dpy, _EGLSurface *dsurf,
306 _EGLSurface *rsurf, _EGLContext *ctx)
307 {
308 CALLED();
309
310 struct haiku_egl_context* cont=haiku_egl_context(ctx);
311 struct haiku_egl_surface* surf=haiku_egl_surface(dsurf);
312 _EGLContext *old_ctx;
313 _EGLSurface *old_dsurf, *old_rsurf;
314 _eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf);
315 //cont->ctx.DrawSurface=&surf->surf;
316 surf->gl->LockGL();
317 return EGL_TRUE;
318 }
319
320
321 extern "C"
322 EGLBoolean
323 haiku_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
324 {
325 struct haiku_egl_surface* surface=haiku_egl_surface(surf);
326 surface->gl->SwapBuffers();
327 //gl->Render();
328 return EGL_TRUE;
329 }
330
331
332 extern "C"
333 void
334 haiku_unload(_EGLDriver* drv)
335 {
336
337 }
338
339
340 /**
341 * This is the main entrypoint into the driver, called by libEGL.
342 * Create a new _EGLDriver object and init its dispatch table.
343 */
344 extern "C"
345 _EGLDriver*
346 _eglBuiltInDriverHaiku(const char *args)
347 {
348 CALLED();
349
350 struct haiku_egl_driver* driver;
351 driver = (struct haiku_egl_driver*) calloc(1, sizeof(*driver));
352 if (!driver) {
353 _eglError(EGL_BAD_ALLOC, "_eglBuiltInDriverHaiku");
354 return NULL;
355 }
356
357 _eglInitDriverFallbacks(&driver->base);
358 driver->base.API.Initialize = init_haiku;
359 driver->base.API.Terminate = haiku_terminate;
360 driver->base.API.CreateContext = haiku_create_context;
361 driver->base.API.DestroyContext = haiku_destroy_context;
362 driver->base.API.MakeCurrent = haiku_make_current;
363 driver->base.API.CreateWindowSurface = haiku_create_window_surface;
364 driver->base.API.CreatePixmapSurface = haiku_create_pixmap_surface;
365 driver->base.API.CreatePbufferSurface = haiku_create_pbuffer_surface;
366 driver->base.API.DestroySurface = haiku_destroy_surface;
367
368 driver->base.API.SwapBuffers = haiku_swap_buffers;
369
370 driver->base.Name = "Haiku";
371 driver->base.Unload = haiku_unload;
372
373 TRACE("API Calls defined\n");
374
375 return &driver->base;
376 }