2 * Mesa 3-D graphics library
4 * Copyright (C) 2014 Adrián Arroyo Calle <adrian.arroyocalle@gmail.com>
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
31 #include "eglconfig.h"
32 #include "eglcontext.h"
33 #include "egldisplay.h"
34 #include "egldriver.h"
35 #include "eglcurrent.h"
37 #include "eglsurface.h"
39 #include "egltypedefs.h"
42 #include <InterfaceKit.h>
43 #include <OpenGLKit.h>
46 #define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
49 _EGL_DRIVER_STANDARD_TYPECASTS(haiku_egl
)
52 struct haiku_egl_driver
57 _EGLProc (*get_proc_address
)(const char *procname
);
58 void (*glFlush
)(void);
61 struct haiku_egl_config
66 struct haiku_egl_context
71 struct haiku_egl_surface
80 swrastCreateDrawable(struct dri2_egl_display * dri2_dpy,
81 struct dri2_egl_surface * dri2_surf, int depth)
88 swrastDestroyDrawable(struct dri2_egl_display * dri2_dpy,
89 struct dri2_egl_surface * dri2_surf)
96 swrastGetDrawableInfo(__DRIdrawable * draw, int *x, int *y,
97 int *w, int *h, void *loaderPrivate)
104 swrastPutImage(__DRIdrawable * draw, int op, int x, int y,
105 int w, int h, char *data, void *loaderPrivate)
112 swrastGetImage(__DRIdrawable * read, int x, int y,
113 int w, int h, char *data, void *loaderPrivate)
121 haiku_log(EGLint level
, const char *msg
)
125 fprintf(stderr
,"%s", msg
);
128 fprintf(stderr
,"%s", msg
);
131 fprintf(stderr
,"%s", msg
);
134 fprintf(stderr
,"%s", msg
);
143 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
146 haiku_create_surface(_EGLDriver
*drv
, _EGLDisplay
*disp
, EGLint type
,
147 _EGLConfig
*conf
, void *native_surface
, const EGLint
*attrib_list
)
154 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
157 haiku_create_window_surface(_EGLDriver
*drv
, _EGLDisplay
*disp
,
158 _EGLConfig
*conf
, void *native_window
, const EGLint
*attrib_list
)
160 struct haiku_egl_surface
* surface
;
161 surface
= (struct haiku_egl_surface
*)calloc(1,sizeof (*surface
));
163 _eglInitSurface(&surface
->surf
, disp
, EGL_WINDOW_BIT
, conf
, attrib_list
);
164 (&surface
->surf
)->SwapInterval
= 1;
166 _eglLog(_EGL_DEBUG
, "Creating window");
167 BWindow
* win
= (BWindow
*)native_window
;
169 _eglLog(_EGL_DEBUG
, "Creating GL view");
170 surface
->gl
= new BGLView(win
->Bounds(), "OpenGL", B_FOLLOW_ALL_SIDES
, 0,
171 BGL_RGB
| BGL_DOUBLE
| BGL_ALPHA
);
173 _eglLog(_EGL_DEBUG
, "Adding GL");
174 win
->AddChild(surface
->gl
);
176 _eglLog(_EGL_DEBUG
, "Showing window");
178 return &surface
->surf
;
183 haiku_create_pixmap_surface(_EGLDriver
*drv
, _EGLDisplay
*disp
,
184 _EGLConfig
*conf
, void *native_pixmap
, const EGLint
*attrib_list
)
191 haiku_create_pbuffer_surface(_EGLDriver
*drv
, _EGLDisplay
*disp
,
192 _EGLConfig
*conf
, const EGLint
*attrib_list
)
199 haiku_destroy_surface(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLSurface
*surf
)
206 haiku_add_configs_for_visuals(_EGLDisplay
*dpy
)
208 printf("Adding configs\n");
209 struct haiku_egl_config conf
, *final
;
210 //conf=CALLOC_STRUCT(haiku_egl_config);
211 memset(&conf
, 0, sizeof(conf
));
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*/);
244 printf("Config configurated\n");
245 if (!_eglValidateConfig(&conf
.base
, EGL_FALSE
)) {
246 _eglLog(_EGL_DEBUG
, "Haiku failed to validate config");
249 printf("Validated config\n");
251 final
= CALLOC_STRUCT(haiku_egl_config
);
252 memcpy(final
, &conf
, sizeof(conf
));
254 _eglLinkConfig(&final
->base
);
255 if (!_eglGetArraySize(dpy
->Configs
)) {
256 _eglLog(_EGL_WARNING
, "Haiku: failed to create any config");
259 printf("Config succesfull\n");
266 init_haiku(_EGLDriver
*drv
, _EGLDisplay
*dpy
)
268 _eglLog(_EGL_DEBUG
,"\nInitializing Haiku EGL\n");
269 //_EGLDisplay* egl_dpy;
271 printf("Initializing Haiku EGL\n");
272 _eglSetLogProc(haiku_log
);
274 loader_set_logger(_eglLog
);
276 /*egl_dpy = (_EGLDisplay*) calloc(1, sizeof(_EGLDisplay));
278 return _eglError(EGL_BAD_ALLOC, "eglInitialize");
280 dpy->DriverData=(void*) egl_dpy;
281 if (!dpy->PlatformDisplay) {
283 //dri2_dpy->bwindow = (void*)haiku_create_window();
284 //dri2_dpy->own_device = true;
286 //dri2_dpy->bwindow = (BWindow*)dpy->PlatformDisplay;
289 //dri2_dpy->driver_name = strdup("swrast");
290 //if (!dri2_load_driver_swrast(dpy))
291 // goto cleanup_conn;
293 /*dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
294 dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION;
295 dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo;
296 dri2_dpy->swrast_loader_extension.putImage = swrastPutImage;
297 dri2_dpy->swrast_loader_extension.getImage = swrastGetImage;
299 dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base;
300 dri2_dpy->extensions[1] = NULL;
301 dri2_dpy->extensions[2] = NULL;*/
303 /*if (dri2_dpy->bwindow) {
304 if (!dri2_haiku_add_configs_for_visuals(dri2_dpy, dpy))
305 goto cleanup_configs;
307 _eglLog(_EGL_DEBUG
,"Add configs");
308 haiku_add_configs_for_visuals(dpy
);
313 //dpy->Extensions.KHR_create_context = true;
315 //dri2_dpy->vtbl = &dri2_haiku_display_vtbl;
316 _eglLog(_EGL_DEBUG
, "Initialization finished");
324 haiku_terminate(_EGLDriver
* drv
,_EGLDisplay
* dpy
)
332 haiku_create_context(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLConfig
*conf
,
333 _EGLContext
*share_list
, const EGLint
*attrib_list
)
335 _eglLog(_EGL_DEBUG
,"Creating context");
336 struct haiku_egl_context
* context
;
337 context
=(struct haiku_egl_context
*)calloc(1,sizeof (*context
));
338 if(!_eglInitContext(&context
->ctx
, disp
, conf
, attrib_list
))
339 printf("ERROR creating context");
340 _eglLog(_EGL_DEBUG
, "Context created");
341 return &context
->ctx
;
347 haiku_destroy_context(_EGLDriver
* drv
, _EGLDisplay
*disp
, _EGLContext
* ctx
)
356 haiku_make_current(_EGLDriver
* drv
, _EGLDisplay
* dpy
, _EGLSurface
*dsurf
,
357 _EGLSurface
*rsurf
, _EGLContext
*ctx
)
359 struct haiku_egl_context
* cont
=haiku_egl_context(ctx
);
360 struct haiku_egl_surface
* surf
=haiku_egl_surface(dsurf
);
361 _EGLContext
*old_ctx
;
362 _EGLSurface
*old_dsurf
, *old_rsurf
;
363 _eglBindContext(ctx
, dsurf
, rsurf
, &old_ctx
, &old_dsurf
, &old_rsurf
);
364 //cont->ctx.DrawSurface=&surf->surf;
372 haiku_swap_buffers(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
)
374 struct haiku_egl_surface
* surface
=haiku_egl_surface(surf
);
375 surface
->gl
->SwapBuffers();
383 haiku_unload(_EGLDriver
* drv
)
390 * This is the main entrypoint into the driver, called by libEGL.
391 * Create a new _EGLDriver object and init its dispatch table.
395 _eglBuiltInDriverHaiku(const char *args
)
397 _eglLog(_EGL_DEBUG
,"Driver loaded");
398 struct haiku_egl_driver
* driver
;
399 driver
=(struct haiku_egl_driver
*)calloc(1,sizeof(*driver
));
400 _eglInitDriverFallbacks(&driver
->base
);
401 driver
->base
.API
.Initialize
= init_haiku
;
402 driver
->base
.API
.Terminate
= haiku_terminate
;
403 driver
->base
.API
.CreateContext
= haiku_create_context
;
404 driver
->base
.API
.DestroyContext
= haiku_destroy_context
;
405 driver
->base
.API
.MakeCurrent
= haiku_make_current
;
406 driver
->base
.API
.CreateWindowSurface
= haiku_create_window_surface
;
407 driver
->base
.API
.CreatePixmapSurface
= haiku_create_pixmap_surface
;
408 driver
->base
.API
.CreatePbufferSurface
= haiku_create_pbuffer_surface
;
409 driver
->base
.API
.DestroySurface
= haiku_destroy_surface
;
411 driver->API.GetProcAddress = dri2_get_proc_address;
412 driver->API.WaitClient = dri2_wait_client;
413 driver->API.WaitNative = dri2_wait_native;
414 driver->API.BindTexImage = dri2_bind_tex_image;
415 driver->API.ReleaseTexImage = dri2_release_tex_image;
416 driver->API.SwapInterval = dri2_swap_interval;
419 driver
->base
.API
.SwapBuffers
= haiku_swap_buffers
;
421 driver->API.SwapBuffersWithDamageEXT = dri2_swap_buffers_with_damage;
422 driver->API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
423 driver->API.PostSubBufferNV = dri2_post_sub_buffer;
424 driver->API.CopyBuffers = dri2_copy_buffers,
425 driver->API.QueryBufferAge = dri2_query_buffer_age;
426 driver->API.CreateImageKHR = dri2_create_image;
427 driver->API.DestroyImageKHR = dri2_destroy_image_khr;
428 driver->API.CreateWaylandBufferFromImageWL = dri2_create_wayland_buffer_from_image;
429 driver->API.GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium;
432 driver
->base
.Name
= "Haiku";
433 driver
->base
.Unload
= haiku_unload
;
435 _eglLog(_EGL_DEBUG
, "API Calls defined");
437 return &driver
->base
;