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");
210 struct haiku_egl_config
* conf
;
211 conf
= CALLOC_STRUCT(haiku_egl_config
);
213 _eglInitConfig(&conf
->base
, dpy
, 1);
214 _eglLog(_EGL_DEBUG
,"Config inited\n");
215 _eglSetConfigKey(&conf
->base
, EGL_RED_SIZE
, 8);
216 _eglSetConfigKey(&conf
->base
, EGL_BLUE_SIZE
, 8);
217 _eglSetConfigKey(&conf
->base
, EGL_GREEN_SIZE
, 8);
218 _eglSetConfigKey(&conf
->base
, EGL_LUMINANCE_SIZE
, 0);
219 _eglSetConfigKey(&conf
->base
, EGL_ALPHA_SIZE
, 8);
220 _eglSetConfigKey(&conf
->base
, EGL_COLOR_BUFFER_TYPE
, EGL_RGB_BUFFER
);
221 EGLint r
= (_eglGetConfigKey(&conf
->base
, EGL_RED_SIZE
)
222 + _eglGetConfigKey(&conf
->base
, EGL_GREEN_SIZE
)
223 + _eglGetConfigKey(&conf
->base
, EGL_BLUE_SIZE
)
224 + _eglGetConfigKey(&conf
->base
, EGL_ALPHA_SIZE
));
225 _eglSetConfigKey(&conf
->base
, EGL_BUFFER_SIZE
, r
);
226 _eglSetConfigKey(&conf
->base
, EGL_CONFIG_CAVEAT
, EGL_NONE
);
227 _eglSetConfigKey(&conf
->base
, EGL_CONFIG_ID
, 1);
228 _eglSetConfigKey(&conf
->base
, EGL_BIND_TO_TEXTURE_RGB
, EGL_FALSE
);
229 _eglSetConfigKey(&conf
->base
, EGL_BIND_TO_TEXTURE_RGBA
, EGL_FALSE
);
230 _eglSetConfigKey(&conf
->base
, EGL_STENCIL_SIZE
, 0);
231 _eglSetConfigKey(&conf
->base
, EGL_TRANSPARENT_TYPE
, EGL_NONE
);
232 _eglSetConfigKey(&conf
->base
, EGL_NATIVE_RENDERABLE
, EGL_TRUE
); // Let's say yes
233 _eglSetConfigKey(&conf
->base
, EGL_NATIVE_VISUAL_ID
, 0); // No visual
234 _eglSetConfigKey(&conf
->base
, EGL_NATIVE_VISUAL_TYPE
, EGL_NONE
); // No visual
235 _eglSetConfigKey(&conf
->base
, EGL_RENDERABLE_TYPE
, 0x8);
236 _eglSetConfigKey(&conf
->base
, EGL_SAMPLE_BUFFERS
, 0); // TODO: How to get the right value ?
237 _eglSetConfigKey(&conf
->base
, EGL_SAMPLES
, _eglGetConfigKey(&conf
->base
, EGL_SAMPLE_BUFFERS
) == 0 ? 0 : 0);
238 _eglSetConfigKey(&conf
->base
, EGL_DEPTH_SIZE
, 24); // TODO: How to get the right value ?
239 _eglSetConfigKey(&conf
->base
, EGL_LEVEL
, 0);
240 _eglSetConfigKey(&conf
->base
, EGL_MAX_PBUFFER_WIDTH
, 0); // TODO: How to get the right value ?
241 _eglSetConfigKey(&conf
->base
, EGL_MAX_PBUFFER_HEIGHT
, 0); // TODO: How to get the right value ?
242 _eglSetConfigKey(&conf
->base
, EGL_MAX_PBUFFER_PIXELS
, 0); // TODO: How to get the right value ?
243 _eglSetConfigKey(&conf
->base
, EGL_SURFACE_TYPE
, EGL_WINDOW_BIT
/*| EGL_PIXMAP_BIT | EGL_PBUFFER_BIT*/);
245 printf("Config configuated\n");
246 if (!_eglValidateConfig(&conf
->base
, EGL_FALSE
)) {
247 _eglLog(_EGL_DEBUG
, "Haiku failed to validate config");
250 printf("Validated config\n");
252 _eglLinkConfig(&conf
->base
);
253 if (!_eglGetArraySize(dpy
->Configs
)) {
254 _eglLog(_EGL_WARNING
, "Haiku: failed to create any config");
257 printf("Config successful!\n");
264 init_haiku(_EGLDriver
*drv
, _EGLDisplay
*dpy
)
266 _eglLog(_EGL_DEBUG
,"\nInitializing Haiku EGL\n");
267 //_EGLDisplay* egl_dpy;
269 printf("Initializing Haiku EGL\n");
270 _eglSetLogProc(haiku_log
);
272 loader_set_logger(_eglLog
);
274 /*egl_dpy = (_EGLDisplay*) calloc(1, sizeof(_EGLDisplay));
276 return _eglError(EGL_BAD_ALLOC, "eglInitialize");
278 dpy->DriverData=(void*) egl_dpy;
279 if (!dpy->PlatformDisplay) {
281 //dri2_dpy->bwindow = (void*)haiku_create_window();
282 //dri2_dpy->own_device = true;
284 //dri2_dpy->bwindow = (BWindow*)dpy->PlatformDisplay;
287 //dri2_dpy->driver_name = strdup("swrast");
288 //if (!dri2_load_driver_swrast(dpy))
289 // goto cleanup_conn;
291 /*dri2_dpy->swrast_loader_extension.base.name = __DRI_SWRAST_LOADER;
292 dri2_dpy->swrast_loader_extension.base.version = __DRI_SWRAST_LOADER_VERSION;
293 dri2_dpy->swrast_loader_extension.getDrawableInfo = swrastGetDrawableInfo;
294 dri2_dpy->swrast_loader_extension.putImage = swrastPutImage;
295 dri2_dpy->swrast_loader_extension.getImage = swrastGetImage;
297 dri2_dpy->extensions[0] = &dri2_dpy->swrast_loader_extension.base;
298 dri2_dpy->extensions[1] = NULL;
299 dri2_dpy->extensions[2] = NULL;*/
301 /*if (dri2_dpy->bwindow) {
302 if (!dri2_haiku_add_configs_for_visuals(dri2_dpy, dpy))
303 goto cleanup_configs;
305 _eglLog(_EGL_DEBUG
,"Add configs");
306 haiku_add_configs_for_visuals(dpy
);
311 //dpy->Extensions.KHR_create_context = true;
313 //dri2_dpy->vtbl = &dri2_haiku_display_vtbl;
314 _eglLog(_EGL_DEBUG
, "Initialization finished");
322 haiku_terminate(_EGLDriver
* drv
,_EGLDisplay
* dpy
)
330 haiku_create_context(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLConfig
*conf
,
331 _EGLContext
*share_list
, const EGLint
*attrib_list
)
333 _eglLog(_EGL_DEBUG
,"Creating context");
334 struct haiku_egl_context
* context
;
335 context
=(struct haiku_egl_context
*)calloc(1,sizeof (*context
));
336 if(!_eglInitContext(&context
->ctx
, disp
, conf
, attrib_list
))
337 printf("ERROR creating context");
338 _eglLog(_EGL_DEBUG
, "Context created");
339 return &context
->ctx
;
345 haiku_destroy_context(_EGLDriver
* drv
, _EGLDisplay
*disp
, _EGLContext
* ctx
)
354 haiku_make_current(_EGLDriver
* drv
, _EGLDisplay
* dpy
, _EGLSurface
*dsurf
,
355 _EGLSurface
*rsurf
, _EGLContext
*ctx
)
357 struct haiku_egl_context
* cont
=haiku_egl_context(ctx
);
358 struct haiku_egl_surface
* surf
=haiku_egl_surface(dsurf
);
359 _EGLContext
*old_ctx
;
360 _EGLSurface
*old_dsurf
, *old_rsurf
;
361 _eglBindContext(ctx
, dsurf
, rsurf
, &old_ctx
, &old_dsurf
, &old_rsurf
);
362 //cont->ctx.DrawSurface=&surf->surf;
370 haiku_swap_buffers(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*surf
)
372 struct haiku_egl_surface
* surface
=haiku_egl_surface(surf
);
373 surface
->gl
->SwapBuffers();
381 haiku_unload(_EGLDriver
* drv
)
388 * This is the main entrypoint into the driver, called by libEGL.
389 * Create a new _EGLDriver object and init its dispatch table.
393 _eglBuiltInDriverHaiku(const char *args
)
395 _eglLog(_EGL_DEBUG
,"Driver loaded");
396 struct haiku_egl_driver
* driver
;
397 driver
=(struct haiku_egl_driver
*)calloc(1,sizeof(*driver
));
398 _eglInitDriverFallbacks(&driver
->base
);
399 driver
->base
.API
.Initialize
= init_haiku
;
400 driver
->base
.API
.Terminate
= haiku_terminate
;
401 driver
->base
.API
.CreateContext
= haiku_create_context
;
402 driver
->base
.API
.DestroyContext
= haiku_destroy_context
;
403 driver
->base
.API
.MakeCurrent
= haiku_make_current
;
404 driver
->base
.API
.CreateWindowSurface
= haiku_create_window_surface
;
405 driver
->base
.API
.CreatePixmapSurface
= haiku_create_pixmap_surface
;
406 driver
->base
.API
.CreatePbufferSurface
= haiku_create_pbuffer_surface
;
407 driver
->base
.API
.DestroySurface
= haiku_destroy_surface
;
409 driver->API.GetProcAddress = dri2_get_proc_address;
410 driver->API.WaitClient = dri2_wait_client;
411 driver->API.WaitNative = dri2_wait_native;
412 driver->API.BindTexImage = dri2_bind_tex_image;
413 driver->API.ReleaseTexImage = dri2_release_tex_image;
414 driver->API.SwapInterval = dri2_swap_interval;
417 driver
->base
.API
.SwapBuffers
= haiku_swap_buffers
;
419 driver->API.SwapBuffersWithDamageEXT = dri2_swap_buffers_with_damage;
420 driver->API.SwapBuffersRegionNOK = dri2_swap_buffers_region;
421 driver->API.PostSubBufferNV = dri2_post_sub_buffer;
422 driver->API.CopyBuffers = dri2_copy_buffers,
423 driver->API.QueryBufferAge = dri2_query_buffer_age;
424 driver->API.CreateImageKHR = dri2_create_image;
425 driver->API.DestroyImageKHR = dri2_destroy_image_khr;
426 driver->API.CreateWaylandBufferFromImageWL = dri2_create_wayland_buffer_from_image;
427 driver->API.GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium;
430 driver
->base
.Name
= "Haiku";
431 driver
->base
.Unload
= haiku_unload
;
433 _eglLog(_EGL_DEBUG
, "API Calls defined");
435 return &driver
->base
;