b347eb652832af90565f27bf38bb04c53f86b901
[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
48 _EGL_DRIVER_STANDARD_TYPECASTS(haiku_egl)
49
50
51 struct haiku_egl_driver
52 {
53 _EGLDriver base;
54
55 void *handle;
56 _EGLProc (*get_proc_address)(const char *procname);
57 void (*glFlush)(void);
58 };
59
60 struct haiku_egl_config
61 {
62 _EGLConfig base;
63 };
64
65 struct haiku_egl_context
66 {
67 _EGLContext ctx;
68 };
69
70 struct haiku_egl_surface
71 {
72 _EGLSurface surf;
73 BGLView* gl;
74 };
75
76
77 /*
78 static void
79 swrastCreateDrawable(struct dri2_egl_display * dri2_dpy,
80 struct dri2_egl_surface * dri2_surf, int depth)
81 {
82
83 }
84
85
86 static void
87 swrastDestroyDrawable(struct dri2_egl_display * dri2_dpy,
88 struct dri2_egl_surface * dri2_surf)
89 {
90
91 }
92
93
94 static void
95 swrastGetDrawableInfo(__DRIdrawable * draw, int *x, int *y,
96 int *w, int *h, void *loaderPrivate)
97 {
98
99 }
100
101
102 static void
103 swrastPutImage(__DRIdrawable * draw, int op, int x, int y,
104 int w, int h, char *data, void *loaderPrivate)
105 {
106
107 }
108
109
110 static void
111 swrastGetImage(__DRIdrawable * read, int x, int y,
112 int w, int h, char *data, void *loaderPrivate)
113 {
114
115 }
116 */
117
118
119 static void
120 haiku_log(EGLint level, const char *msg)
121 {
122 switch (level) {
123 case _EGL_DEBUG:
124 fprintf(stderr,"%s", msg);
125 break;
126 case _EGL_INFO:
127 fprintf(stderr,"%s", msg);
128 break;
129 case _EGL_WARNING:
130 fprintf(stderr,"%s", msg);
131 break;
132 case _EGL_FATAL:
133 fprintf(stderr,"%s", msg);
134 break;
135 default:
136 break;
137 }
138 }
139
140
141 /**
142 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
143 */
144 static _EGLSurface *
145 haiku_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
146 _EGLConfig *conf, void *native_surface, const EGLint *attrib_list)
147 {
148 return NULL;
149 }
150
151
152 /**
153 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
154 */
155 static _EGLSurface *
156 haiku_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
157 _EGLConfig *conf, void *native_window, const EGLint *attrib_list)
158 {
159 struct haiku_egl_surface* surface;
160 surface = (struct haiku_egl_surface*)calloc(1,sizeof (*surface));
161
162 _eglInitSurface(&surface->surf, disp, EGL_WINDOW_BIT, conf, attrib_list);
163 (&surface->surf)->SwapInterval = 1;
164
165 _eglLog(_EGL_DEBUG, "Creating window");
166 BWindow* win = (BWindow*)native_window;
167
168 _eglLog(_EGL_DEBUG, "Creating GL view");
169 surface->gl = new BGLView(win->Bounds(), "OpenGL", B_FOLLOW_ALL_SIDES, 0,
170 BGL_RGB | BGL_DOUBLE | BGL_ALPHA);
171
172 _eglLog(_EGL_DEBUG, "Adding GL");
173 win->AddChild(surface->gl);
174
175 _eglLog(_EGL_DEBUG, "Showing window");
176 win->Show();
177 return &surface->surf;
178 }
179
180
181 static _EGLSurface *
182 haiku_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
183 _EGLConfig *conf, void *native_pixmap, const EGLint *attrib_list)
184 {
185 return NULL;
186 }
187
188
189 static _EGLSurface *
190 haiku_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
191 _EGLConfig *conf, const EGLint *attrib_list)
192 {
193 return NULL;
194 }
195
196
197 static EGLBoolean
198 haiku_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
199 {
200 return EGL_TRUE;
201 }
202
203
204 static EGLBoolean
205 haiku_add_configs_for_visuals(_EGLDisplay *dpy)
206 {
207 printf("Adding configs\n");
208
209 struct haiku_egl_config* conf;
210 conf = CALLOC_STRUCT(haiku_egl_config);
211
212 _eglInitConfig(&conf->base, dpy, 1);
213 _eglLog(_EGL_DEBUG,"Config inited\n");
214 _eglSetConfigKey(&conf->base, EGL_RED_SIZE, 8);
215 _eglSetConfigKey(&conf->base, EGL_BLUE_SIZE, 8);
216 _eglSetConfigKey(&conf->base, EGL_GREEN_SIZE, 8);
217 _eglSetConfigKey(&conf->base, EGL_LUMINANCE_SIZE, 0);
218 _eglSetConfigKey(&conf->base, EGL_ALPHA_SIZE, 8);
219 _eglSetConfigKey(&conf->base, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
220 EGLint r = (_eglGetConfigKey(&conf->base, EGL_RED_SIZE)
221 + _eglGetConfigKey(&conf->base, EGL_GREEN_SIZE)
222 + _eglGetConfigKey(&conf->base, EGL_BLUE_SIZE)
223 + _eglGetConfigKey(&conf->base, EGL_ALPHA_SIZE));
224 _eglSetConfigKey(&conf->base, EGL_BUFFER_SIZE, r);
225 _eglSetConfigKey(&conf->base, EGL_CONFIG_CAVEAT, EGL_NONE);
226 _eglSetConfigKey(&conf->base, EGL_CONFIG_ID, 1);
227 _eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE);
228 _eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE);
229 _eglSetConfigKey(&conf->base, EGL_STENCIL_SIZE, 0);
230 _eglSetConfigKey(&conf->base, EGL_TRANSPARENT_TYPE, EGL_NONE);
231 _eglSetConfigKey(&conf->base, EGL_NATIVE_RENDERABLE, EGL_TRUE); // Let's say yes
232 _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_ID, 0); // No visual
233 _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_TYPE, EGL_NONE); // No visual
234 _eglSetConfigKey(&conf->base, EGL_RENDERABLE_TYPE, 0x8);
235 _eglSetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS, 0); // TODO: How to get the right value ?
236 _eglSetConfigKey(&conf->base, EGL_SAMPLES, _eglGetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS) == 0 ? 0 : 0);
237 _eglSetConfigKey(&conf->base, EGL_DEPTH_SIZE, 24); // TODO: How to get the right value ?
238 _eglSetConfigKey(&conf->base, EGL_LEVEL, 0);
239 _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_WIDTH, 0); // TODO: How to get the right value ?
240 _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_HEIGHT, 0); // TODO: How to get the right value ?
241 _eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_PIXELS, 0); // TODO: How to get the right value ?
242 _eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT /*| EGL_PIXMAP_BIT | EGL_PBUFFER_BIT*/);
243
244 printf("Config configuated\n");
245 if (!_eglValidateConfig(&conf->base, EGL_FALSE)) {
246 _eglLog(_EGL_DEBUG, "Haiku failed to validate config");
247 return EGL_FALSE;
248 }
249 printf("Validated config\n");
250
251 _eglLinkConfig(&conf->base);
252 if (!_eglGetArraySize(dpy->Configs)) {
253 _eglLog(_EGL_WARNING, "Haiku: failed to create any config");
254 return EGL_FALSE;
255 }
256 printf("Config successful!\n");
257
258 return EGL_TRUE;
259 }
260
261 extern "C"
262 EGLBoolean
263 init_haiku(_EGLDriver *drv, _EGLDisplay *dpy)
264 {
265 _eglLog(_EGL_DEBUG,"\nInitializing Haiku EGL\n");
266 //_EGLDisplay* egl_dpy;
267
268 printf("Initializing Haiku EGL\n");
269 _eglSetLogProc(haiku_log);
270
271 loader_set_logger(_eglLog);
272
273 /*egl_dpy = (_EGLDisplay*) calloc(1, sizeof(_EGLDisplay));
274 if (!egl_dpy)
275 return _eglError(EGL_BAD_ALLOC, "eglInitialize");
276
277 dpy->DriverData=(void*) egl_dpy;
278 if (!dpy->PlatformDisplay) {
279 // OPEN DEVICE
280 //dri2_dpy->bwindow = (void*)haiku_create_window();
281 //dri2_dpy->own_device = true;
282 } else {
283 //dri2_dpy->bwindow = (BWindow*)dpy->PlatformDisplay;
284 }*/
285
286 //dri2_dpy->driver_name = strdup("swrast");
287 //if (!dri2_load_driver_swrast(dpy))
288 // goto cleanup_conn;
289
290 /*dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
291 dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION;
292 dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo;
293 dri2_dpy->swrast_loader_extension.putImage = swrastPutImage;
294 dri2_dpy->swrast_loader_extension.getImage = swrastGetImage;
295
296 dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base;
297 dri2_dpy->extensions[1] = NULL;
298 dri2_dpy->extensions[2] = NULL;*/
299
300 /*if (dri2_dpy->bwindow) {
301 if (!dri2_haiku_add_configs_for_visuals(dri2_dpy, dpy))
302 goto cleanup_configs;
303 }*/
304 _eglLog(_EGL_DEBUG,"Add configs");
305 haiku_add_configs_for_visuals(dpy);
306
307 dpy->Version = 14;
308
309 //dpy->Extensions.KHR_create_context = true;
310
311 //dri2_dpy->vtbl = &dri2_haiku_display_vtbl;
312 _eglLog(_EGL_DEBUG, "Initialization finished");
313
314 return EGL_TRUE;
315 }
316
317
318 extern "C"
319 EGLBoolean
320 haiku_terminate(_EGLDriver* drv,_EGLDisplay* dpy)
321 {
322 return EGL_TRUE;
323 }
324
325
326 extern "C"
327 _EGLContext*
328 haiku_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
329 _EGLContext *share_list, const EGLint *attrib_list)
330 {
331 _eglLog(_EGL_DEBUG,"Creating context");
332 struct haiku_egl_context* context;
333 context=(struct haiku_egl_context*)calloc(1,sizeof (*context));
334 if(!_eglInitContext(&context->ctx, disp, conf, attrib_list))
335 printf("ERROR creating context");
336 _eglLog(_EGL_DEBUG, "Context created");
337 return &context->ctx;
338 }
339
340
341 extern "C"
342 EGLBoolean
343 haiku_destroy_context(_EGLDriver* drv, _EGLDisplay *disp, _EGLContext* ctx)
344 {
345 ctx=NULL;
346 return EGL_TRUE;
347 }
348
349
350 extern "C"
351 EGLBoolean
352 haiku_make_current(_EGLDriver* drv, _EGLDisplay* dpy, _EGLSurface *dsurf,
353 _EGLSurface *rsurf, _EGLContext *ctx)
354 {
355 struct haiku_egl_context* cont=haiku_egl_context(ctx);
356 struct haiku_egl_surface* surf=haiku_egl_surface(dsurf);
357 _EGLContext *old_ctx;
358 _EGLSurface *old_dsurf, *old_rsurf;
359 _eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf);
360 //cont->ctx.DrawSurface=&surf->surf;
361 surf->gl->LockGL();
362 return EGL_TRUE;
363 }
364
365
366 extern "C"
367 EGLBoolean
368 haiku_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
369 {
370 struct haiku_egl_surface* surface=haiku_egl_surface(surf);
371 surface->gl->SwapBuffers();
372 //gl->Render();
373 return EGL_TRUE;
374 }
375
376
377 extern "C"
378 void
379 haiku_unload(_EGLDriver* drv)
380 {
381
382 }
383
384
385 /**
386 * This is the main entrypoint into the driver, called by libEGL.
387 * Create a new _EGLDriver object and init its dispatch table.
388 */
389 extern "C"
390 _EGLDriver*
391 _eglBuiltInDriverHaiku(const char *args)
392 {
393 _eglLog(_EGL_DEBUG,"Driver loaded");
394 struct haiku_egl_driver* driver;
395 driver=(struct haiku_egl_driver*)calloc(1,sizeof(*driver));
396 _eglInitDriverFallbacks(&driver->base);
397 driver->base.API.Initialize = init_haiku;
398 driver->base.API.Terminate = haiku_terminate;
399 driver->base.API.CreateContext = haiku_create_context;
400 driver->base.API.DestroyContext = haiku_destroy_context;
401 driver->base.API.MakeCurrent = haiku_make_current;
402 driver->base.API.CreateWindowSurface = haiku_create_window_surface;
403 driver->base.API.CreatePixmapSurface = haiku_create_pixmap_surface;
404 driver->base.API.CreatePbufferSurface = haiku_create_pbuffer_surface;
405 driver->base.API.DestroySurface = haiku_destroy_surface;
406 /*
407 driver->API.GetProcAddress = dri2_get_proc_address;
408 driver->API.WaitClient = dri2_wait_client;
409 driver->API.WaitNative = dri2_wait_native;
410 driver->API.BindTexImage = dri2_bind_tex_image;
411 driver->API.ReleaseTexImage = dri2_release_tex_image;
412 driver->API.SwapInterval = dri2_swap_interval;
413 */
414
415 driver->base.API.SwapBuffers = haiku_swap_buffers;
416 /*
417 driver->API.SwapBuffersWithDamageEXT = dri2_swap_buffers_with_damage;
418 driver->API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
419 driver->API.PostSubBufferNV = dri2_post_sub_buffer;
420 driver->API.CopyBuffers = dri2_copy_buffers,
421 driver->API.QueryBufferAge = dri2_query_buffer_age;
422 driver->API.CreateImageKHR = dri2_create_image;
423 driver->API.DestroyImageKHR = dri2_destroy_image_khr;
424 driver->API.CreateWaylandBufferFromImageWL = dri2_create_wayland_buffer_from_image;
425 driver->API.GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium;
426 */
427
428 driver->base.Name = "Haiku";
429 driver->base.Unload = haiku_unload;
430
431 _eglLog(_EGL_DEBUG, "API Calls defined");
432
433 return &driver->base;
434 }