From 602fc904b0b15d4841c7a40a27d50351e9147296 Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Thu, 31 May 2012 21:57:40 -0700 Subject: all: Replace tagged unions with a more traditional object model This rewrites the bulk of Waffle's code. When I first began writing Waffle, I wanted to experiment with a non-traditional object model that used tagged unions. Very soon I began to abhor the "innovative" decision. This patch replaces the tagged-union model with a more traditional object model (as found in the Linux kernel [1], Google's NaCl, libdrm, and many other places) that uses vtables and embedded structures. [1] Neil Brown. LWN, 2011 June 1. Object-oriented design patterns in the kernel. (Part 1: http://lwn.net/Articles/444910/). (Part 2: http://lwn.net/Articles/446317/). As an example of the new object model, below is an outline of how waffle_window_swap_buffers() is now implemeneted. // file: waffle_window.c bool waffle_window_swap_buffers(struct waffle_window *self) { struct wcore_window *wc_self = wcore_window(self); // safe cast // Check preconditions ... return wc_self->vtbl->swap_buffers(wc_self); } // file: wcore_window.h struct wcore_window_vtbl { bool (*swap_buffers)(struct wcore_window *self); // More member functions ... }; struct wcore_window { const struct wcore_window_vtbl *vtbl; struct waffle_window {} wfl; // More members ... }; // file: glx_window.h struct glx_window { struct wcore_window wcore; // More members ... }; // file: glx_window.c static bool glx_window_swap_buffers(struct wcore_window *wc_self) { struct glx_window *self = glx_window(wc_self); // safe cast // Call glXSwapBuffers ... return true; } static const struct wcore_window_vtbl glx_window_wcore_vtbl = { .swap_buffers = glx_window_swap_buffers, // More members ... }; Signed-off-by: Chad Versace --- src/waffle/CMakeLists.txt | 12 +- src/waffle/api/api_object.h | 38 ++++++ src/waffle/api/api_priv.c | 23 +--- src/waffle/api/api_priv.h | 70 +--------- src/waffle/api/waffle_config.c | 42 +++--- src/waffle/api/waffle_context.c | 51 +++----- src/waffle/api/waffle_display.c | 38 ++---- src/waffle/api/waffle_dl.c | 7 +- src/waffle/api/waffle_gl_misc.c | 37 +++--- src/waffle/api/waffle_init.c | 53 ++++++-- src/waffle/api/waffle_window.c | 55 ++++---- src/waffle/cgl/WaffleGLView.h | 2 - src/waffle/cgl/WaffleGLView.m | 3 - src/waffle/cgl/cgl_config.h | 29 ++--- src/waffle/cgl/cgl_config.m | 72 +++++----- src/waffle/cgl/cgl_context.h | 32 +++-- src/waffle/cgl/cgl_context.m | 89 +++++++------ src/waffle/cgl/cgl_display.h | 33 ++--- src/waffle/cgl/cgl_display.m | 68 ++++++---- src/waffle/cgl/cgl_dl.h | 27 ++-- src/waffle/cgl/cgl_dl.m | 107 ++++++++------- src/waffle/cgl/cgl_gl_misc.h | 53 -------- src/waffle/cgl/cgl_gl_misc.m | 69 ---------- src/waffle/cgl/cgl_platform.h | 28 ++-- src/waffle/cgl/cgl_platform.m | 114 ++++++++++------ src/waffle/cgl/cgl_window.h | 42 +++--- src/waffle/cgl/cgl_window.m | 113 +++++++++------- src/waffle/core/wcore_config.h | 76 +++++++++++ src/waffle/core/wcore_context.h | 77 +++++++++++ src/waffle/core/wcore_display.c | 57 ++++++++ src/waffle/core/wcore_display.h | 69 ++++++++++ src/waffle/core/wcore_platform.c | 147 --------------------- src/waffle/core/wcore_platform.h | 92 +++++++++---- src/waffle/core/wcore_util.h | 50 +++++++ src/waffle/core/wcore_window.h | 80 ++++++++++++ src/waffle/egl/egl_no_native.c | 19 +-- src/waffle/egl/egl_no_native.h | 6 +- src/waffle/glx/glx_config.c | 123 ++++++++++-------- src/waffle/glx/glx_config.h | 46 ++++--- src/waffle/glx/glx_context.c | 123 ++++++++++-------- src/waffle/glx/glx_context.h | 34 ++--- src/waffle/glx/glx_display.c | 96 +++++++------- src/waffle/glx/glx_display.h | 43 +++--- src/waffle/glx/glx_dl.c | 56 -------- src/waffle/glx/glx_dl.h | 49 ------- src/waffle/glx/glx_gl_misc.c | 57 -------- src/waffle/glx/glx_gl_misc.h | 53 -------- src/waffle/glx/glx_platform.c | 128 ++++++++++-------- src/waffle/glx/glx_platform.h | 32 +++-- src/waffle/glx/glx_priv_types.h | 84 ------------ src/waffle/glx/glx_window.c | 111 ++++++++-------- src/waffle/glx/glx_window.h | 40 +++--- src/waffle/native.h | 139 -------------------- src/waffle/wayland/wayland_config.c | 74 ++++++----- src/waffle/wayland/wayland_config.h | 39 +++--- src/waffle/wayland/wayland_context.c | 98 +++++++------- src/waffle/wayland/wayland_context.h | 34 ++--- src/waffle/wayland/wayland_display.c | 121 ++++++++--------- src/waffle/wayland/wayland_display.h | 43 +++--- src/waffle/wayland/wayland_dl.c | 56 -------- src/waffle/wayland/wayland_dl.h | 51 -------- src/waffle/wayland/wayland_gl_misc.c | 58 --------- src/waffle/wayland/wayland_gl_misc.h | 53 -------- src/waffle/wayland/wayland_platform.c | 129 ++++++++++-------- src/waffle/wayland/wayland_platform.h | 30 +++-- src/waffle/wayland/wayland_priv_egl.c | 7 +- src/waffle/wayland/wayland_priv_egl.h | 13 +- src/waffle/wayland/wayland_priv_types.h | 84 ------------ src/waffle/wayland/wayland_window.c | 154 ++++++++++++---------- src/waffle/wayland/wayland_window.h | 42 +++--- src/waffle/x11/x11.c | 224 -------------------------------- src/waffle/x11/x11.h | 67 ---------- src/waffle/x11/x11_display.c | 68 ++++++++++ src/waffle/x11/x11_display.h | 42 ++++++ src/waffle/x11/x11_window.c | 197 ++++++++++++++++++++++++++++ src/waffle/x11/x11_window.h | 50 +++++++ src/waffle/x11_egl/xegl_config.c | 84 ++++++------ src/waffle/x11_egl/xegl_config.h | 44 ++++--- src/waffle/x11_egl/xegl_context.c | 96 +++++++------- src/waffle/x11_egl/xegl_context.h | 33 ++--- src/waffle/x11_egl/xegl_display.c | 88 ++++++------- src/waffle/x11_egl/xegl_display.h | 38 +++--- src/waffle/x11_egl/xegl_dl.c | 56 -------- src/waffle/x11_egl/xegl_dl.h | 49 ------- src/waffle/x11_egl/xegl_gl_misc.c | 58 --------- src/waffle/x11_egl/xegl_gl_misc.h | 53 -------- src/waffle/x11_egl/xegl_platform.c | 128 ++++++++++-------- src/waffle/x11_egl/xegl_platform.h | 29 +++-- src/waffle/x11_egl/xegl_priv_egl.c | 7 - src/waffle/x11_egl/xegl_priv_egl.h | 9 +- src/waffle/x11_egl/xegl_priv_types.h | 77 ----------- src/waffle/x11_egl/xegl_window.c | 133 ++++++++++--------- src/waffle/x11_egl/xegl_window.h | 50 ++++--- 93 files changed, 2656 insertions(+), 3304 deletions(-) create mode 100644 src/waffle/api/api_object.h delete mode 100644 src/waffle/cgl/cgl_gl_misc.h delete mode 100644 src/waffle/cgl/cgl_gl_misc.m create mode 100644 src/waffle/core/wcore_config.h create mode 100644 src/waffle/core/wcore_context.h create mode 100644 src/waffle/core/wcore_display.c create mode 100644 src/waffle/core/wcore_display.h delete mode 100644 src/waffle/core/wcore_platform.c create mode 100644 src/waffle/core/wcore_util.h create mode 100644 src/waffle/core/wcore_window.h delete mode 100644 src/waffle/glx/glx_dl.c delete mode 100644 src/waffle/glx/glx_dl.h delete mode 100644 src/waffle/glx/glx_gl_misc.c delete mode 100644 src/waffle/glx/glx_gl_misc.h delete mode 100644 src/waffle/glx/glx_priv_types.h delete mode 100644 src/waffle/native.h delete mode 100644 src/waffle/wayland/wayland_dl.c delete mode 100644 src/waffle/wayland/wayland_dl.h delete mode 100644 src/waffle/wayland/wayland_gl_misc.c delete mode 100644 src/waffle/wayland/wayland_gl_misc.h delete mode 100644 src/waffle/wayland/wayland_priv_types.h delete mode 100644 src/waffle/x11/x11.c delete mode 100644 src/waffle/x11/x11.h create mode 100644 src/waffle/x11/x11_display.c create mode 100644 src/waffle/x11/x11_display.h create mode 100644 src/waffle/x11/x11_window.c create mode 100644 src/waffle/x11/x11_window.h delete mode 100644 src/waffle/x11_egl/xegl_dl.c delete mode 100644 src/waffle/x11_egl/xegl_dl.h delete mode 100644 src/waffle/x11_egl/xegl_gl_misc.c delete mode 100644 src/waffle/x11_egl/xegl_gl_misc.h delete mode 100644 src/waffle/x11_egl/xegl_priv_types.h (limited to 'src/waffle') diff --git a/src/waffle/CMakeLists.txt b/src/waffle/CMakeLists.txt index a8dc648..5508b28 100644 --- a/src/waffle/CMakeLists.txt +++ b/src/waffle/CMakeLists.txt @@ -15,8 +15,8 @@ set(waffle_sources api/waffle_init.c api/waffle_window.c core/wcore_config_attrs.c + core/wcore_display.c core/wcore_error.c - core/wcore_platform.c core/wcore_tinfo.c ) @@ -27,7 +27,6 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") cgl/cgl_display.m cgl/cgl_dl.m cgl/cgl_error.m - cgl/cgl_gl_misc.m cgl/cgl_platform.m cgl/cgl_window.m @@ -54,8 +53,6 @@ if(waffle_has_glx) glx/glx_config.c glx/glx_context.c glx/glx_display.c - glx/glx_dl.c - glx/glx_gl_misc.c glx/glx_platform.c glx/glx_window.c ) @@ -80,8 +77,6 @@ if(waffle_has_wayland) wayland/wayland_config.c wayland/wayland_context.c wayland/wayland_display.c - wayland/wayland_dl.c - wayland/wayland_gl_misc.c wayland/wayland_platform.c wayland/wayland_priv_egl.c wayland/wayland_window.c @@ -94,7 +89,8 @@ endif() if(waffle_has_x11) list(APPEND waffle_sources - x11/x11.c + x11/x11_display.c + x11/x11_window.c ) list(APPEND waffle_libdeps ${waffle_X11-xcb_library} @@ -108,8 +104,6 @@ if(waffle_has_x11_egl) x11_egl/xegl_config.c x11_egl/xegl_context.c x11_egl/xegl_display.c - x11_egl/xegl_dl.c - x11_egl/xegl_gl_misc.c x11_egl/xegl_platform.c x11_egl/xegl_priv_egl.c x11_egl/xegl_window.c diff --git a/src/waffle/api/api_object.h b/src/waffle/api/api_object.h new file mode 100644 index 0000000..f3a67a5 --- /dev/null +++ b/src/waffle/api/api_object.h @@ -0,0 +1,38 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include + +// This header is so sad and lonely... but there is no other appropriate place +// to define this struct. + +struct api_object { + /// @brief Display to which object belongs. + /// + /// For consistency, a `waffle_display` belongs to itself. + size_t display_id; +}; diff --git a/src/waffle/api/api_priv.c b/src/waffle/api/api_priv.c index 9579857..7f334fa 100644 --- a/src/waffle/api/api_priv.c +++ b/src/waffle/api/api_priv.c @@ -28,15 +28,17 @@ /// @file +#include "api_priv.h" + #include #include -#include "api_priv.h" - #include #include -struct wcore_platform *api_current_platform = 0; +#include "api_object.h" + +struct wcore_platform *api_platform = 0; bool api_check_entry(const struct api_object *obj_list[], int length) @@ -45,7 +47,7 @@ api_check_entry(const struct api_object *obj_list[], int length) wcore_error_reset(); - if (!api_current_platform) { + if (!api_platform) { wcore_error(WAFFLE_NOT_INITIALIZED); return false; } @@ -65,17 +67,4 @@ api_check_entry(const struct api_object *obj_list[], int length) return true; } -size_t -api_new_object_id(void) -{ - static size_t counter = 1; - - if (counter == 0) { - fprintf(stderr, "waffle: error: internal counter wrapped to 0\n"); - abort(); - } - - return counter++; -} - /// @} diff --git a/src/waffle/api/api_priv.h b/src/waffle/api/api_priv.h index b728d94..8a886c7 100644 --- a/src/waffle/api/api_priv.h +++ b/src/waffle/api/api_priv.h @@ -38,13 +38,12 @@ struct api_object; struct wcore_platform; -union native_config; -union native_context; -union native_display; -union native_window; /// @brief Managed by waffle_init(). -extern struct wcore_platform *api_current_platform; +/// +/// This is null if and only if waffle has not been initialized with +/// waffle_init(). +extern struct wcore_platform *api_platform; /// @brief Used to validate most API entry points. /// @@ -54,67 +53,8 @@ extern struct wcore_platform *api_current_platform; /// Emit an error and return false if any of the following: /// - waffle is not initialized /// - an object pointer is null -/// - an object has an old platform id +/// - two objects belong to different displays bool api_check_entry(const struct api_object *obj_list[], int length); -/// @brief Create a unique id. -size_t -api_new_object_id(void); - -struct api_object { - /// @brief Display to which object belongs. - /// - /// This is identical to object_id for waffle_display. - size_t display_id; -}; - -struct waffle_config { - struct api_object api; - union native_config *native; -}; - -struct waffle_context { - struct api_object api; - union native_context *native; -}; - -struct waffle_display { - struct api_object api; - union native_display *native; -}; - -struct waffle_window { - struct api_object api; - union native_window *native; -}; - -/// Return null if @a config is null. -static inline struct api_object* -waffle_config_get_api_obj(struct waffle_config *config) -{ - return config ? &config->api : NULL; -} - -/// Return null if @a ctx is null. -static inline struct api_object* -waffle_context_get_api_obj(struct waffle_context *ctx) -{ - return ctx ? &ctx->api : NULL; -} - -/// Return null if @a display is null. -static inline struct api_object* -waffle_display_get_api_obj(struct waffle_display *display) -{ - return display ? &display->api : NULL; -} - -/// Return null if @a window is null. -static inline struct api_object* -waffle_window_get_api_obj(struct waffle_window *window) -{ - return window ? &window->api : NULL; -} - /// @} diff --git a/src/waffle/api/waffle_config.c b/src/waffle/api/waffle_config.c index 09dbf21..0d87e4d 100644 --- a/src/waffle/api/waffle_config.c +++ b/src/waffle/api/waffle_config.c @@ -32,9 +32,9 @@ #include -#include #include -#include +#include +#include #include #include "api_priv.h" @@ -44,56 +44,44 @@ waffle_config_choose( struct waffle_display *dpy, const int32_t attrib_list[]) { - struct waffle_config *self = NULL; + struct wcore_config *wc_self; + struct wcore_display *wc_dpy = wcore_display(dpy); struct wcore_config_attrs attrs; bool ok = true; const struct api_object *obj_list[] = { - waffle_display_get_api_obj(dpy), + wc_dpy ? &wc_dpy->api : NULL, }; if (!api_check_entry(obj_list, 1)) return NULL; - self = malloc(sizeof(*self)); - if (!self) { - wcore_error(WAFFLE_OUT_OF_MEMORY); - return NULL; - } - ok = wcore_config_attrs_parse(attrib_list, &attrs); if (!ok) - goto error; - - self->api.display_id = dpy->api.display_id; - - self->native = api_current_platform->dispatch-> - config_choose(dpy->native, &attrs); - if (!self->native) - goto error; + return NULL; - return self; + wc_self = api_platform->vtbl->choose_config(api_platform, + wc_dpy, + &attrs); + if (!wc_self) + return NULL; -error: - free(self); - return NULL; + return &wc_self->wfl; } bool waffle_config_destroy(struct waffle_config *self) { - bool ok = true; + struct wcore_config *wc_self = wcore_config(self); const struct api_object *obj_list[] = { - waffle_config_get_api_obj(self), + wc_self ? &wc_self->api : NULL, }; if (!api_check_entry(obj_list, 1)) return false; - ok &= api_current_platform->dispatch->config_destroy(self->native); - free(self); - return ok; + return wc_self->vtbl->destroy(wc_self); } /// @} diff --git a/src/waffle/api/waffle_context.c b/src/waffle/api/waffle_context.c index a9dc5df..7125822 100644 --- a/src/waffle/api/waffle_context.c +++ b/src/waffle/api/waffle_context.c @@ -32,8 +32,7 @@ #include -#include -#include +#include #include #include "api_priv.h" @@ -43,56 +42,42 @@ waffle_context_create( struct waffle_config *config, struct waffle_context *shared_ctx) { - struct waffle_context *self; - int obj_list_length; + struct wcore_context *wc_self; + struct wcore_config *wc_config = wcore_config(config); + struct wcore_context *wc_shared_ctx = wcore_context(shared_ctx); - const struct api_object *obj_list[] = { - waffle_config_get_api_obj(config), - waffle_context_get_api_obj(shared_ctx), - }; + const struct api_object *obj_list[2]; + int len = 0; - if (shared_ctx) - obj_list_length = 2; - else - obj_list_length = 1; + obj_list[len++] = wc_config ? &wc_config->api : NULL; + if (wc_shared_ctx) + obj_list[len++] = wc_shared_ctx ? &wc_shared_ctx->api : NULL; - if (!api_check_entry(obj_list, obj_list_length)) + if (!api_check_entry(obj_list, len)) return false; - self = malloc(sizeof(*self)); - if (!self) { - wcore_error(WAFFLE_OUT_OF_MEMORY); - return NULL; - } - - self->api.display_id = config->api.display_id; - - self->native = api_current_platform->dispatch-> - context_create(config->native, - shared_ctx ? shared_ctx->native : NULL); - if (!self->native) { - free(self); + wc_self = api_platform->vtbl->create_context(api_platform, + wc_config, + wc_shared_ctx); + if (!wc_self) return NULL; - } - return self; + return &wc_self->wfl; } bool waffle_context_destroy(struct waffle_context *self) { - bool ok = true; + struct wcore_context *wc_self = wcore_context(self); const struct api_object *obj_list[] = { - waffle_context_get_api_obj(self), + wc_self ? &wc_self->api : NULL, }; if (!api_check_entry(obj_list, 1)) return false; - ok &= api_current_platform->dispatch->context_destroy(self->native); - free(self); - return ok; + return wc_self->vtbl->destroy(wc_self); } /// @} diff --git a/src/waffle/api/waffle_display.c b/src/waffle/api/waffle_display.c index a530b5a..cf8fdd0 100644 --- a/src/waffle/api/waffle_display.c +++ b/src/waffle/api/waffle_display.c @@ -32,55 +32,42 @@ #include -#include #include #include +#include #include +#include #include "api_priv.h" struct waffle_display* waffle_display_connect(const char *name) { - struct waffle_display *self; + struct wcore_display *wc_self; if (!api_check_entry(NULL, 0)) return NULL; - self = malloc(sizeof(*self)); - if (!self) { - wcore_error(WAFFLE_OUT_OF_MEMORY); + wc_self = api_platform->vtbl->connect_to_display(api_platform, name); + if (!wc_self) return NULL; - } - - self->api.display_id = api_new_object_id(); - self->native = api_current_platform->dispatch-> - display_connect(api_current_platform->native, name); - - if (!self->native) { - free(self); - return NULL; - } - - return self; + return &wc_self->wfl; } bool waffle_display_disconnect(struct waffle_display *self) { - bool ok = true; + struct wcore_display *wc_self = wcore_display(self); const struct api_object *obj_list[] = { - waffle_display_get_api_obj(self), + wc_self ? &wc_self->api : NULL, }; if (!api_check_entry(obj_list, 1)) return false; - ok &= api_current_platform->dispatch->display_disconnect(self->native); - free(self); - return ok; + return wc_self->vtbl->destroy(wc_self); } bool @@ -88,8 +75,10 @@ waffle_display_supports_context_api( struct waffle_display *self, int32_t context_api) { + struct wcore_display *wc_self = wcore_display(self); + const struct api_object *obj_list[] = { - waffle_display_get_api_obj(self), + wc_self ? &wc_self->api : NULL, }; if (!api_check_entry(obj_list, 1)) @@ -106,8 +95,7 @@ waffle_display_supports_context_api( return false; } - return api_current_platform->dispatch-> - display_supports_context_api(self->native, context_api); + return wc_self->vtbl->supports_context_api(wc_self, context_api); } /// @} diff --git a/src/waffle/api/waffle_dl.c b/src/waffle/api/waffle_dl.c index ad0761b..7a346c2 100644 --- a/src/waffle/api/waffle_dl.c +++ b/src/waffle/api/waffle_dl.c @@ -30,7 +30,6 @@ #include -#include #include #include #include @@ -60,8 +59,7 @@ waffle_dl_can_open(int32_t dl) if (!waffle_dl_check_enum(dl)) return false; - return api_current_platform->dispatch-> - dl_can_open(api_current_platform->native, dl); + return api_platform->vtbl->dl_can_open(api_platform, dl); } void* @@ -73,8 +71,7 @@ waffle_dl_sym(int32_t dl, const char *name) if (!waffle_dl_check_enum(dl)) return false; - return api_current_platform->dispatch-> - dl_sym(api_current_platform->native, dl, name); + return api_platform->vtbl->dl_sym(api_platform, dl, name); } /// @} diff --git a/src/waffle/api/waffle_gl_misc.c b/src/waffle/api/waffle_gl_misc.c index e8bca45..32869c9 100644 --- a/src/waffle/api/waffle_gl_misc.c +++ b/src/waffle/api/waffle_gl_misc.c @@ -33,10 +33,12 @@ #include #include -#include #include +#include +#include #include #include +#include #include "api_priv.h" @@ -83,26 +85,26 @@ waffle_make_current( struct waffle_window *window, struct waffle_context *ctx) { - int obj_list_length = 1; + struct wcore_display *wc_dpy = wcore_display(dpy); + struct wcore_window *wc_window = wcore_window(window); + struct wcore_context *wc_ctx = wcore_context(ctx); - const struct api_object *obj_list[] = { - waffle_display_get_api_obj(dpy), - 0, - 0, - }; + const struct api_object *obj_list[3]; + int len = 0; - if (window) - obj_list[obj_list_length++] = waffle_window_get_api_obj(window); - if (ctx) - obj_list[obj_list_length++] = waffle_context_get_api_obj(ctx); + obj_list[len++] = wc_dpy ? &wc_dpy->api : NULL; + if (wc_window) + obj_list[len++] = wc_window ? &wc_window->api : NULL; + if (wc_ctx) + obj_list[len++] = wc_ctx ? &wc_ctx->api : NULL; - if (!api_check_entry(obj_list, obj_list_length)) + if (!api_check_entry(obj_list, len)) return false; - return api_current_platform->dispatch-> - make_current(dpy->native, - window ? window->native :NULL, - ctx ? ctx->native : NULL); + return api_platform->vtbl->make_current(api_platform, + wc_dpy, + wc_window, + wc_ctx); } void* @@ -111,8 +113,7 @@ waffle_get_proc_address(const char *name) if (!api_check_entry(NULL, 0)) return NULL; - return api_current_platform->dispatch-> - get_proc_address(api_current_platform->native, name); + return api_platform->vtbl->get_proc_address(api_platform, name); } /// @} diff --git a/src/waffle/api/waffle_init.c b/src/waffle/api/waffle_init.c index e395e69..4fc4795 100644 --- a/src/waffle/api/waffle_init.c +++ b/src/waffle/api/waffle_init.c @@ -36,6 +36,12 @@ #include "api_priv.h" +struct wcore_platform* droid_platform_create(void); +struct wcore_platform* cgl_platform_create(void); +struct wcore_platform* glx_platform_create(void); +struct wcore_platform* wayland_platform_create(void); +struct wcore_platform* xegl_platform_create(void); + static bool waffle_init_parse_attrib_list( const int32_t attrib_list[], @@ -93,6 +99,36 @@ waffle_init_parse_attrib_list( return true; } +static struct wcore_platform* +waffle_init_create_platform(int32_t waffle_platform) +{ + switch (waffle_platform) { +#ifdef WAFFLE_HAS_ANDROID + case WAFFLE_PLATFORM_ANDROID: + return droid_platform_create(); +#endif +#ifdef WAFFLE_HAS_CGL + case WAFFLE_PLATFORM_CGL: + return cgl_platform_create(); +#endif +#ifdef WAFFLE_HAS_GLX + case WAFFLE_PLATFORM_GLX: + return glx_platform_create(); +#endif +#ifdef WAFFLE_HAS_WAYLAND + case WAFFLE_PLATFORM_WAYLAND: + return wayland_platform_create(); +#endif +#ifdef WAFFLE_HAS_X11_EGL + case WAFFLE_PLATFORM_X11_EGL: + return xegl_platform_create(); +#endif + default: + assert(false); + return NULL; + } +} + bool waffle_init(const int32_t *attrib_list) { @@ -101,7 +137,7 @@ waffle_init(const int32_t *attrib_list) wcore_error_reset(); - if (api_current_platform) { + if (api_platform) { wcore_error(WAFFLE_ALREADY_INITIALIZED); return false; } @@ -110,22 +146,11 @@ waffle_init(const int32_t *attrib_list) if (!ok) return false; - api_current_platform = wcore_platform_create(platform); - if (!api_current_platform) + api_platform = waffle_init_create_platform(platform); + if (!api_platform) return false; return true; } -int32_t -waffle_get_platform(void) -{ - wcore_error_reset(); - - if (api_current_platform) - return api_current_platform->native_tag; - else - return WAFFLE_NONE; -} - /// @} diff --git a/src/waffle/api/waffle_window.c b/src/waffle/api/waffle_window.c index 6c0df64..16d19cc 100644 --- a/src/waffle/api/waffle_window.c +++ b/src/waffle/api/waffle_window.c @@ -32,9 +32,9 @@ #include -#include -#include +#include #include +#include #include "api_priv.h" @@ -43,78 +43,69 @@ waffle_window_create( struct waffle_config *config, int width, int height) { + struct wcore_window *wc_self; + struct wcore_config *wc_config = wcore_config(config); + const struct api_object *obj_list[] = { - waffle_config_get_api_obj(config), + wc_config ? &wc_config->api : NULL, }; - struct waffle_window *self; - if (!api_check_entry(obj_list, 1)) return false; - self = malloc(sizeof(*self)); - if (!self) { - wcore_error(WAFFLE_OUT_OF_MEMORY); - return NULL; - } - - self->api.display_id = config->api.display_id; - - self->native = api_current_platform->dispatch-> - window_create(config->native, width, height); - - if (!self->native) { - free(self); + wc_self = api_platform->vtbl->create_window(api_platform, + wc_config, + width, + height); + if (!wc_self) return NULL; - } - return self; + return &wc_self->wfl; } bool waffle_window_destroy(struct waffle_window *self) { - bool ok = true; + struct wcore_window *wc_self = wcore_window(self); const struct api_object *obj_list[] = { - waffle_window_get_api_obj(self), - 0, + wc_self ? &wc_self->api : NULL, }; if (!api_check_entry(obj_list, 1)) return false; - ok &= api_current_platform->dispatch->window_destroy(self->native); - free(self); - return ok; + return wc_self->vtbl->destroy(wc_self); } WAFFLE_API bool waffle_window_show(struct waffle_window *self) { + struct wcore_window *wc_self = wcore_window(self); + const struct api_object *obj_list[] = { - waffle_window_get_api_obj(self), + wc_self ? &wc_self->api : NULL, }; if (!api_check_entry(obj_list, 1)) return false; - return api_current_platform->dispatch-> - window_show(self->native); + return wc_self->vtbl->show(wc_self); } bool waffle_window_swap_buffers(struct waffle_window *self) { + struct wcore_window *wc_self = wcore_window(self); + const struct api_object *obj_list[] = { - waffle_window_get_api_obj(self), + wc_self ? &wc_self->api : NULL, }; if (!api_check_entry(obj_list, 1)) return false; - return api_current_platform->dispatch-> - window_swap_buffers(self->native); + return wc_self->vtbl->swap_buffers(wc_self); } /// @} diff --git a/src/waffle/cgl/WaffleGLView.h b/src/waffle/cgl/WaffleGLView.h index 646d5e3..f33cbb7 100644 --- a/src/waffle/cgl/WaffleGLView.h +++ b/src/waffle/cgl/WaffleGLView.h @@ -26,8 +26,6 @@ /// @addtogroup cgl /// @{ -/// @file - #import #import diff --git a/src/waffle/cgl/WaffleGLView.m b/src/waffle/cgl/WaffleGLView.m index 4792d04..3314733 100644 --- a/src/waffle/cgl/WaffleGLView.m +++ b/src/waffle/cgl/WaffleGLView.m @@ -25,9 +25,6 @@ #include "WaffleGLView.h" -#include -#include - @implementation WaffleGLView @synthesize glContext = _glContext; diff --git a/src/waffle/cgl/cgl_config.h b/src/waffle/cgl/cgl_config.h index 5e56ecd..784e183 100644 --- a/src/waffle/cgl/cgl_config.h +++ b/src/waffle/cgl/cgl_config.h @@ -23,12 +23,6 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup cgl_config cgl_config -/// @ingroup cgl -/// @{ - -/// @file - #pragma once #include @@ -36,20 +30,23 @@ #include +#include +#include + struct wcore_config_attrs; -union native_config; -union native_display; +struct wcore_platform; struct cgl_config { + struct wcore_config wcore; CGLPixelFormatObj pixel_format; }; -union native_config* -cgl_config_choose( - union native_display *dpy, - const struct wcore_config_attrs *attrs); - -bool -cgl_config_destroy(union native_config *self); +DEFINE_CONTAINER_CAST_FUNC(cgl_config, + struct cgl_config, + struct wcore_config, + wcore) -/// @} +struct wcore_config* +cgl_config_choose(struct wcore_platform *wc_plat, + struct wcore_display *wc_dpy, + const struct wcore_config_attrs *attrs); diff --git a/src/waffle/cgl/cgl_config.m b/src/waffle/cgl/cgl_config.m index 8684291..992e75f 100644 --- a/src/waffle/cgl/cgl_config.m +++ b/src/waffle/cgl/cgl_config.m @@ -23,24 +23,33 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup cgl_config -/// @{ - -/// @file - -#include "cgl_config.h" - #include #include #include -#include #include + #include #include +#include "cgl_config.h" #include "cgl_error.h" +static const struct wcore_config_vtbl cgl_config_wcore_vtbl; + +static bool +cgl_config_destroy(struct wcore_config *wc_self) +{ + bool ok = true; + + if (wc_self == NULL) + return ok; + + ok &= wcore_config_teardown(wc_self); + free(cgl_config(wc_self)); + return ok; +} + /// @brief Check the values of `attrs->context_*`. static bool cgl_config_check_attrs(const struct wcore_config_attrs *attrs) @@ -138,11 +147,12 @@ cgl_config_fill_pixel_format_attrs( return true; } -union native_config* -cgl_config_choose( - union native_display *display, - const struct wcore_config_attrs *attrs) +struct wcore_config* +cgl_config_choose(struct wcore_platform *wc_plat, + struct wcore_display *wc_dpy, + const struct wcore_config_attrs *attrs) { + struct cgl_config *self; bool ok = true; int error = 0; int ignore; @@ -151,49 +161,39 @@ cgl_config_choose( if (!cgl_config_check_attrs(attrs)) return NULL; - union native_config *self; - NATIVE_ALLOC(self, cgl); + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } + ok = wcore_config_init(&self->wcore, wc_dpy); + if (!ok) + goto error; + ok = cgl_config_fill_pixel_format_attrs(attrs, pixel_attrs); if (!ok) goto error; - error = CGLChoosePixelFormat(pixel_attrs, &self->cgl->pixel_format, &ignore); + error = CGLChoosePixelFormat(pixel_attrs, &self->pixel_format, &ignore); if (error) { cgl_error_failed_func("CGLChoosePixelFormat", error); goto error; } - if (!self->cgl->pixel_format) { + if (!self->pixel_format) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "CGLChoosePixelFormat failed to find a pixel format"); goto error; } - goto end; + self->wcore.vtbl = &cgl_config_wcore_vtbl; + return &self->wcore; error: - cgl_config_destroy(self); - self = NULL; - -end: - return self; -} - -bool -cgl_config_destroy(union native_config *self) -{ - if (!self) - return true; - - if (self->cgl->pixel_format) - CGLReleasePixelFormat(self->cgl->pixel_format); - - free(self); - return true; + cgl_config_destroy(&self->wcore); + return NULL; } -/// @} +static const struct wcore_config_vtbl cgl_config_wcore_vtbl = { + .destroy = cgl_config_destroy, +}; diff --git a/src/waffle/cgl/cgl_context.h b/src/waffle/cgl/cgl_context.h index 84774a2..01074be 100644 --- a/src/waffle/cgl/cgl_context.h +++ b/src/waffle/cgl/cgl_context.h @@ -23,12 +23,6 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup cgl_context cgl_context -/// @ingroup cgl -/// @{ - -/// @file - #pragma once #include @@ -36,19 +30,23 @@ #include #include -union native_context; -union native_config; +#include +#include + +struct wcore_config; +struct wcore_platform; struct cgl_context { - NSOpenGLContext *ns_context; + struct wcore_context wcore; + NSOpenGLContext *ns; }; -union native_context* -cgl_context_create( - union native_config *config, - union native_context *share_ctx); - -bool -cgl_context_destroy(union native_context *self); +DEFINE_CONTAINER_CAST_FUNC(cgl_context, + struct cgl_context, + struct wcore_context, + wcore) -/// @} +struct wcore_context* +cgl_context_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + struct wcore_context *wc_share_ctx); diff --git a/src/waffle/cgl/cgl_context.m b/src/waffle/cgl/cgl_context.m index 4d0f30a..8df0c35 100644 --- a/src/waffle/cgl/cgl_context.m +++ b/src/waffle/cgl/cgl_context.m @@ -23,81 +23,84 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup cgl_context -/// @{ - -/// @file - -#include "cgl_context.h" - #include #include -#include #include #include #include "cgl_config.h" +#include "cgl_context.h" #include "cgl_error.h" -union native_context* -cgl_context_create( - union native_config *config, - union native_context *share_ctx) +static const struct wcore_context_vtbl cgl_context_wcore_vtbl; + +static bool +cgl_context_destroy(struct wcore_context *wc_self) +{ + struct cgl_context *self = cgl_context(wc_self); + bool ok = true; + + if (!self) + return ok; + + [self->ns release]; + ok &= wcore_context_teardown(wc_self); + free(self); + return ok; +} + +struct wcore_context* +cgl_context_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + struct wcore_context *wc_share_ctx) { + struct cgl_context *self; + struct cgl_config *config = cgl_config(wc_config); + struct cgl_context *share_ctx = cgl_context(wc_share_ctx); + + CGLContextObj cgl_self = NULL; + CGLContextObj cgl_share_ctx = NULL; + int error = 0; - CGLContextObj real_cgl_ctx = NULL; - CGLContextObj real_cgl_share_ctx = NULL; - union native_context *self; - NATIVE_ALLOC(self, cgl); + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } + error = !wcore_context_init(&self->wcore, wc_config); + if (error) + goto fail; + if (share_ctx) - real_cgl_share_ctx = [share_ctx->cgl->ns_context CGLContextObj]; + cgl_share_ctx = [share_ctx->ns CGLContextObj]; - error = CGLCreateContext(config->cgl->pixel_format, - real_cgl_share_ctx, - &real_cgl_ctx); + error = CGLCreateContext(config->pixel_format, cgl_share_ctx, &cgl_self); if (error) { cgl_error_failed_func("CGLCreateContext", error); goto fail; } - self->cgl->ns_context = [[[NSOpenGLContext alloc] - initWithCGLContextObj:real_cgl_ctx] - autorelease]; - if (!self->cgl->ns_context) { + self->ns = [[NSOpenGLContext alloc] initWithCGLContextObj:cgl_self]; + if (!self->ns) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "NSOpenGLContext.initWithCGLContextObj failed"); goto fail; } // The NSOpenGLContext now owns the CGLContext. - CGLReleaseContext(real_cgl_ctx); + CGLReleaseContext(cgl_self); - goto end; + self->wcore.vtbl = &cgl_context_wcore_vtbl; + return &self->wcore; fail: - cgl_context_destroy(self); - self = NULL; - -end: - return self; -} - -bool -cgl_context_destroy(union native_context *self) -{ - if (!self) - return true; - - [self->cgl->ns_context release]; - free(self); - return true; + cgl_context_destroy(&self->wcore); + return NULL; } -/// @} +static const struct wcore_context_vtbl cgl_context_wcore_vtbl = { + .destroy = cgl_context_destroy, +}; diff --git a/src/waffle/cgl/cgl_display.h b/src/waffle/cgl/cgl_display.h index ea70fe3..8515b26 100644 --- a/src/waffle/cgl/cgl_display.h +++ b/src/waffle/cgl/cgl_display.h @@ -23,34 +23,25 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup cgl_display cgl_display -/// @ingroup cgl -/// @{ - -/// @file - #pragma once #include #include -union native_display; -union native_platform; +#include +#include + +struct wcore_platform; struct cgl_display { + struct wcore_display wcore; }; -union native_display* -cgl_display_connect( - union native_platform *platform, - const char *name); - -bool -cgl_display_disconnect(union native_display *self); - -bool -cgl_display_supports_context_api( - union native_display *self, - int32_t context_api); +DEFINE_CONTAINER_CAST_FUNC(cgl_display, + struct cgl_display, + struct wcore_display, + wcore) -/// @} +struct wcore_display* +cgl_display_connect(struct wcore_platform *wc_plat, + const char *name); diff --git a/src/waffle/cgl/cgl_display.m b/src/waffle/cgl/cgl_display.m index 3ee636a..d565d2f 100644 --- a/src/waffle/cgl/cgl_display.m +++ b/src/waffle/cgl/cgl_display.m @@ -23,46 +23,59 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup cgl_display -/// @{ - -/// @file - -#include "cgl_display.h" #include -#include #include #include -union native_display* -cgl_display_connect( - union native_platform *native_platform, - const char *name) +#include "cgl_display.h" + +static const struct wcore_display_vtbl cgl_display_wcore_vtbl; + +static bool +cgl_display_destroy(struct wcore_display *wc_self) { - union native_display *native_self; + struct cgl_display *self = cgl_display(wc_self); + bool ok = true; - NATIVE_ALLOC(native_self, cgl); - if (!native_self) { + if (!self) + return ok; + + ok &= wcore_display_teardown(&self->wcore); + free(self); + return ok; +} + + +struct wcore_display* +cgl_display_connect(struct wcore_platform *wc_plat, + const char *name) +{ + struct cgl_display *self; + bool ok = true; + + self = calloc(1, sizeof(*self)); + if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - return native_self; -} + ok = wcore_display_init(&self->wcore, wc_plat); + if (!ok) + goto error; -bool -cgl_display_disconnect(union native_display *native_self) -{ - free(native_self); - return true; + self->wcore.vtbl = &cgl_display_wcore_vtbl; + return &self->wcore; + +error: + cgl_display_destroy(&self->wcore); + return NULL; } -bool -cgl_display_supports_context_api( - union native_display *native_self, - int32_t context_api) +static bool +cgl_display_supports_context_api(struct wcore_display *wc_self, + int32_t context_api) { switch (context_api) { case WAFFLE_CONTEXT_OPENGL: @@ -78,4 +91,7 @@ cgl_display_supports_context_api( } } -/// @} +static const struct wcore_display_vtbl cgl_display_wcore_vtbl = { + .destroy = cgl_display_destroy, + .supports_context_api = cgl_display_supports_context_api, +}; diff --git a/src/waffle/cgl/cgl_dl.h b/src/waffle/cgl/cgl_dl.h index 3f18ec1..a0df71a 100644 --- a/src/waffle/cgl/cgl_dl.h +++ b/src/waffle/cgl/cgl_dl.h @@ -23,32 +23,21 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup cgl_dl cgl_dl -/// @ingroup cgl -/// @{ - -/// @file - #pragma once #include #include -struct cgl_platform; -union native_platform; +struct wcore_platform; bool -cgl_dl_can_open( - union native_platform *native, - int32_t waffle_dl); +cgl_dl_can_open(struct wcore_platform *wc_plat, + int32_t waffle_dl); + void* -cgl_dl_sym( - union native_platform *native, - int32_t waffle_dl, - const char *name); +cgl_dl_sym(struct wcore_platform *wc_plat, + int32_t waffle_dl, + const char *name); -/// Used by cgl_platform_destroy(). bool -cgl_dl_close(struct cgl_platform *platform); - -/// @} +cgl_dl_close(struct wcore_platform *wc_plat); diff --git a/src/waffle/cgl/cgl_dl.m b/src/waffle/cgl/cgl_dl.m index ff9f345..9c04f9f 100644 --- a/src/waffle/cgl/cgl_dl.m +++ b/src/waffle/cgl/cgl_dl.m @@ -23,20 +23,14 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup cgl_dl -/// @{ - -/// @file - -#include "cgl_dl.h" - #include #include #include -#include + #include +#include "cgl_dl.h" #include "cgl_platform.h" static const char *cgl_dl_gl_path = @@ -63,10 +57,11 @@ cgl_dl_check_enum(int32_t waffle_dl) } static bool -cgl_dl_open(union native_platform *platform) +cgl_dl_open(struct cgl_platform *plat) { - platform->cgl->dl_gl = dlopen(cgl_dl_gl_path, RTLD_LAZY); - if (!platform->cgl->dl_gl) { + plat->dl_gl = dlopen(cgl_dl_gl_path, RTLD_LAZY); + + if (!plat->dl_gl) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "dlopen(\"%s\") failed", cgl_dl_gl_path); return false; @@ -76,69 +71,44 @@ cgl_dl_open(union native_platform *platform) } bool -cgl_dl_can_open( - union native_platform *platform, - int32_t waffle_dl) +cgl_dl_can_open(struct wcore_platform *wc_plat, + int32_t waffle_dl) { + struct cgl_platform *plat = cgl_platform(wc_plat); + if (!cgl_dl_check_enum(waffle_dl)) return false; - if (platform->cgl->dl_gl != NULL) + if (plat->dl_gl != NULL) return true; WCORE_ERROR_DISABLED({ - cgl_dl_open(platform); + cgl_dl_open(plat); }); - return platform->cgl->dl_gl != NULL; -} - -bool -cgl_dl_close(struct cgl_platform *platform) -{ - int error_code = 0; - const char *error_msg = NULL; - - if (!platform->dl_gl) - return true; - - error_code = dlclose(platform->dl_gl); - - if (error_code) - error_msg = dlerror(); - - if (error_code && error_msg) { - wcore_errorf(WAFFLE_UNKNOWN_ERROR, - "dlclose(libname=\"%s\") failed: %s", - error_msg); - } - else if (error_code && !error_msg) { - wcore_errorf(WAFFLE_UNKNOWN_ERROR, - "dlclose(libname=\"%s\") failed"); - } - - return !error_code; + return plat->dl_gl != NULL; } void* -cgl_dl_sym( - union native_platform *platform, - int32_t waffle_dl, - const char *symbol) +cgl_dl_sym(struct wcore_platform *wc_plat, + int32_t waffle_dl, + const char *name) { + struct cgl_platform *plat = cgl_platform(wc_plat); + if (!cgl_dl_check_enum(waffle_dl)) return NULL; - if (platform->cgl->dl_gl == NULL) - cgl_dl_open(platform); + if (plat->dl_gl == NULL) + cgl_dl_open(plat); - if (platform->cgl->dl_gl == NULL) + if (plat->dl_gl == NULL) return NULL; // Clear any previous error. dlerror(); - void *sym = dlsym(platform->cgl->dl_gl, symbol); + void *sym = dlsym(plat->dl_gl, name); if (sym) return sym; @@ -148,10 +118,39 @@ cgl_dl_sym( if (error) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "dlsym(libname=\"%s\", symbol=\"%s\") failed: %s", - cgl_dl_gl_path, symbol, error); + cgl_dl_gl_path, name, error); } return NULL; } -/// @} +bool +cgl_dl_close(struct wcore_platform *wc_plat) +{ + struct cgl_platform *plat = cgl_platform(wc_plat); + + int error_code = 0; + const char *error_msg = NULL; + + if (!plat->dl_gl) + return true; + + error_code = dlclose(plat->dl_gl); + + if (!error_code) + return true; + + error_msg = dlerror(); + + if (error_msg) { + wcore_errorf(WAFFLE_UNKNOWN_ERROR, + "dlclose(libname=\"%s\") failed: %s", + error_msg); + } + else { + wcore_errorf(WAFFLE_UNKNOWN_ERROR, + "dlclose(libname=\"%s\") failed"); + } + + return false; +} diff --git a/src/waffle/cgl/cgl_gl_misc.h b/src/waffle/cgl/cgl_gl_misc.h deleted file mode 100644 index a0d4a4b..0000000 --- a/src/waffle/cgl/cgl_gl_misc.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup cgl_gl_misc cgl_gl_misc -/// @ingroup cgl -/// @{ - -/// @file - -#pragma once - -#include -#include - -union native_platform; -union native_display; -union native_window; -union native_context; - -bool -cgl_make_current( - union native_display *dpy, - union native_window *window, - union native_context *ctx); - -void* -cgl_get_proc_address( - union native_platform *native, - const char *name); - -/// @} diff --git a/src/waffle/cgl/cgl_gl_misc.m b/src/waffle/cgl/cgl_gl_misc.m deleted file mode 100644 index 02c9d20..0000000 --- a/src/waffle/cgl/cgl_gl_misc.m +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @addtogroup cgl_gl_misc -/// @{ - -/// @file - -#include "cgl_gl_misc.h" - -#include - -#include "cgl_context.h" -#include "cgl_window.h" - -@class NSView; - -bool -cgl_make_current( - union native_display *dpy, - union native_window *window, - union native_context *ctx) -{ - NSOpenGLContext *cocoa_ctx = ctx ? ctx->cgl->ns_context : NULL; - WaffleGLView* cocoa_view = window ? window->cgl->gl_view : NULL; - - if (cocoa_view) - cocoa_view.glContext = cocoa_ctx; - - if (cocoa_ctx) { - [cocoa_ctx makeCurrentContext]; - [cocoa_ctx setView:cocoa_view]; - } - - return true; -} - -void* -cgl_get_proc_address( - union native_platform *native, - const char *name) -{ - // There is no CGLGetProcAddress. - return NULL; -} - -/// @} diff --git a/src/waffle/cgl/cgl_platform.h b/src/waffle/cgl/cgl_platform.h index 20ab590..1f5f655 100644 --- a/src/waffle/cgl/cgl_platform.h +++ b/src/waffle/cgl/cgl_platform.h @@ -23,28 +23,24 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup cgl_platform cgl_platform -/// @ingroup cgl -/// @{ - -/// @file - #pragma once -#include +#include +#include -struct native_dispatch; -union native_platform; +struct linux_platform; struct cgl_platform { - /// @brief OpenGL library, opened with dlopen(). + struct wcore_platform wcore; + + /// @brief The OpenGL library obtained with dlopen(). void *dl_gl; }; -union native_platform* -cgl_platform_create(const struct native_dispatch **dispatch); - -bool -cgl_platform_destroy(union native_platform *self); +DEFINE_CONTAINER_CAST_FUNC(cgl_platform, + struct cgl_platform, + struct wcore_platform, + wcore) -/// @} +struct wcore_platform* +cgl_platform_create(void); diff --git a/src/waffle/cgl/cgl_platform.m b/src/waffle/cgl/cgl_platform.m index d01baca..a2b5dc6 100644 --- a/src/waffle/cgl/cgl_platform.m +++ b/src/waffle/cgl/cgl_platform.m @@ -23,70 +23,100 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup cgl_platform -/// @{ - -/// @file - -#include "cgl_platform.h" - #include -#include #include #include "cgl_config.h" #include "cgl_context.h" #include "cgl_display.h" #include "cgl_dl.h" -#include "cgl_gl_misc.h" +#include "cgl_platform.h" + #include "cgl_window.h" -static const struct native_dispatch cgl_dispatch = { - .display_connect = cgl_display_connect, - .display_disconnect = cgl_display_disconnect, - .display_supports_context_api = cgl_display_supports_context_api, - .config_choose = cgl_config_choose, - .config_destroy = cgl_config_destroy, - .context_create = cgl_context_create, - .context_destroy = cgl_context_destroy, - .dl_can_open = cgl_dl_can_open, - .dl_sym = cgl_dl_sym, - .window_create = cgl_window_create, - .window_destroy = cgl_window_destroy, - .window_show = cgl_window_show, - .window_swap_buffers = cgl_window_swap_buffers, - .make_current = cgl_make_current, - .get_proc_address = cgl_get_proc_address, -}; +static const struct wcore_platform_vtbl cgl_platform_wcore_vtbl; -union native_platform* -cgl_platform_create(const struct native_dispatch **dispatch) +static bool +cgl_platform_destroy(struct wcore_platform *wc_self) { - union native_platform *self; - NATIVE_ALLOC(self, cgl); + struct cgl_platform *self = cgl_platform(wc_self); + bool ok = true; + + if (!self) + return ok; + + if (self->dl_gl) + ok &= cgl_dl_close(&self->wcore); + + ok &= wcore_platform_teardown(wc_self); + free(self); + return ok; +} + +struct wcore_platform* +cgl_platform_create(void) +{ + struct cgl_platform *self; + bool ok = true; + + self= calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - *dispatch = &cgl_dispatch; - return self; + ok = wcore_platform_init(&self->wcore); + if (!ok) + goto error; + + self->wcore.vtbl = &cgl_platform_wcore_vtbl; + return &self->wcore; + +error: + cgl_platform_destroy(&self->wcore); + return NULL; } -bool -cgl_platform_destroy(union native_platform *self) +static bool +cgl_platform_make_current(struct wcore_platform *wc_self, + struct wcore_display *wc_dpy, + struct wcore_window *wc_window, + struct wcore_context *wc_ctx) { - bool ok = true; + struct cgl_window *window = cgl_window(wc_window); + struct cgl_context *ctx = cgl_context(wc_ctx); - if (!self) - return true; + NSOpenGLContext *cocoa_ctx = ctx ? ctx->ns : NULL; + WaffleGLView* cocoa_view = window ? window->gl_view : NULL; - if (self->cgl->dl_gl) - ok &= cgl_dl_close(self->cgl); + if (cocoa_view) + cocoa_view.glContext = cocoa_ctx; - free(self); - return ok; + if (cocoa_ctx) { + [cocoa_ctx makeCurrentContext]; + [cocoa_ctx setView:cocoa_view]; + } + + return true; +} + +static void* +cgl_platform_get_proc_address(struct wcore_platform *wc_self, + const char *name) +{ + // There is no CGLGetProcAddress. + return NULL; } -/// @} +static const struct wcore_platform_vtbl cgl_platform_wcore_vtbl = { + .destroy = cgl_platform_destroy, + .connect_to_display = cgl_display_connect, + .choose_config = cgl_config_choose, + .create_context = cgl_context_create, + .create_window = cgl_window_create, + .make_current = cgl_platform_make_current, + .get_proc_address = cgl_platform_get_proc_address, + .dl_can_open = cgl_dl_can_open, + .dl_sym = cgl_dl_sym, +}; diff --git a/src/waffle/cgl/cgl_window.h b/src/waffle/cgl/cgl_window.h index c699eb4..2ac5188 100644 --- a/src/waffle/cgl/cgl_window.h +++ b/src/waffle/cgl/cgl_window.h @@ -23,42 +23,30 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup cgl_window cgl_window -/// @ingroup cgl -/// @{ - -/// @file - #pragma once #include -#include "WaffleGLView.h" +#include +#include -union native_config; -union native_display; -union native_window; +#include "WaffleGLView.h" -@class NSWindow; +struct wcore_platform; struct cgl_window { + struct wcore_window wcore; + NSWindow *ns_window; WaffleGLView *gl_view; }; -union native_window* -cgl_window_create( - union native_config *config, - int width, - int height); - -bool -cgl_window_destroy(union native_window *self); - -bool -cgl_window_show(union native_window *self); - -bool -cgl_window_swap_buffers(union native_window *self); - -/// @} +DEFINE_CONTAINER_CAST_FUNC(cgl_window, + struct cgl_window, + struct wcore_window, + wcore) +struct wcore_window* +cgl_window_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + int width, + int height); diff --git a/src/waffle/cgl/cgl_window.m b/src/waffle/cgl/cgl_window.m index 0918a66..a16b95d 100644 --- a/src/waffle/cgl/cgl_window.m +++ b/src/waffle/cgl/cgl_window.m @@ -23,25 +23,42 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup cgl_window -/// @{ +#import +#import -/// @file +#include +#include "cgl_config.h" #include "cgl_window.h" -#import -#import +static const struct wcore_window_vtbl cgl_window_wcore_vtbl; + +static bool +cgl_window_destroy(struct wcore_window *wc_self) +{ + struct cgl_window *self = cgl_window(wc_self); + bool ok = true; + + if (!self) + return ok; + + if (self->gl_view) + [self->gl_view release]; + + if (self->ns_window) + [self->ns_window release]; + + ok &= wcore_window_teardown(&self->wcore); + free(self); + return ok; +} -#include -#include static WaffleGLView* cgl_window_create_gl_view(int width, int height) { - WaffleGLView *view = [[[WaffleGLView alloc] - initWithFrame:NSMakeRect(0, 0, width, height)] - autorelease]; + WaffleGLView *view = [[WaffleGLView alloc] + initWithFrame:NSMakeRect(0, 0, width, height)]; if (!view) wcore_errorf(WAFFLE_UNKNOWN_ERROR, "failed to create NSView"); @@ -56,12 +73,11 @@ cgl_window_create_ns_window(NSView *view) // WARNING(chad): likely all wrong. int styleMask = NSTitledWindowMask | NSClosableWindowMask; - NSWindow *window = [[[NSWindow alloc] - initWithContentRect:[view frame] - styleMask:styleMask - backing:NSBackingStoreBuffered - defer:NO] - autorelease]; + NSWindow *window = [[NSWindow alloc] + initWithContentRect:[view frame] + styleMask:styleMask + backing:NSBackingStoreBuffered + defer:NO]; if (!window) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "failed to create NSWindow"); @@ -76,61 +92,58 @@ cgl_window_create_ns_window(NSView *view) return window; } -union native_window* -cgl_window_create( - union native_config *config, - int width, - int height) +struct wcore_window* +cgl_window_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + int width, + int height) { - union native_window *self; - NATIVE_ALLOC(self, cgl); + struct cgl_window *self; + bool ok = true; + + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->cgl->gl_view = cgl_window_create_gl_view(width, height); - if (!self->cgl->gl_view) + ok = wcore_window_init(&self->wcore, wc_config); + if (!ok) goto error; - self->cgl->ns_window = cgl_window_create_ns_window(self->cgl->gl_view); - if (!self->cgl->ns_window) + self->gl_view = cgl_window_create_gl_view(width, height); + if (!self->gl_view) goto error; - return self; + self->ns_window = cgl_window_create_ns_window(self->gl_view); + if (!self->ns_window) + goto error; + + self->wcore.vtbl = &cgl_window_wcore_vtbl; + return &self->wcore; error: - cgl_window_destroy(self); + cgl_window_destroy(&self->wcore); return NULL; } -bool -cgl_window_destroy(union native_window *self) +static bool +cgl_window_show(struct wcore_window *wc_self) { - if (!self) - return true; - - if (self->cgl->gl_view) - [self->cgl->gl_view release]; - - if (self->cgl->ns_window) - [self->cgl->ns_window release]; - - free(self); return true; } -bool -cgl_window_show(union native_window *self) +static bool +cgl_window_swap_buffers(struct wcore_window *wc_self) { + struct cgl_window *self = cgl_window(wc_self); + [self->gl_view swapBuffers]; return true; -} -bool -cgl_window_swap_buffers(union native_window *self) -{ - [self->cgl->gl_view swapBuffers]; - return true; } -/// @} +static const struct wcore_window_vtbl cgl_window_wcore_vtbl = { + .destroy = cgl_window_destroy, + .show = cgl_window_show, + .swap_buffers = cgl_window_swap_buffers, +}; diff --git a/src/waffle/core/wcore_config.h b/src/waffle/core/wcore_config.h new file mode 100644 index 0000000..abccdf8 --- /dev/null +++ b/src/waffle/core/wcore_config.h @@ -0,0 +1,76 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include +#include +#include + +#include + +#include "wcore_display.h" +#include "wcore_util.h" + +struct wcore_config; + +struct wcore_config_vtbl { + bool + (*destroy)(struct wcore_config *self); +}; + +struct wcore_config { + const struct wcore_config_vtbl *vtbl; + + struct waffle_config {} wfl; + struct api_object api; + + struct wcore_display *display; +}; + +DEFINE_CONTAINER_CAST_FUNC(wcore_config, + struct wcore_config, + struct waffle_config, + wfl) + +static inline bool +wcore_config_init(struct wcore_config *self, + struct wcore_display *display) +{ + assert(self); + assert(display); + + self->api.display_id = display->api.display_id; + self->display = display; + + return true; +} + +static inline bool +wcore_config_teardown(struct wcore_config *self) +{ + assert(self); + return true; +} diff --git a/src/waffle/core/wcore_context.h b/src/waffle/core/wcore_context.h new file mode 100644 index 0000000..7d1163d --- /dev/null +++ b/src/waffle/core/wcore_context.h @@ -0,0 +1,77 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include +#include +#include + +#include + +#include "wcore_config.h" +#include "wcore_util.h" + +struct wcore_context; +struct wcore_display; + +struct wcore_context_vtbl { + bool + (*destroy)(struct wcore_context *self); +}; + +struct wcore_context { + const struct wcore_context_vtbl *vtbl; + + struct waffle_context {} wfl; + struct api_object api; + + struct wcore_display *display; +}; + +DEFINE_CONTAINER_CAST_FUNC(wcore_context, + struct wcore_context, + struct waffle_context, + wfl) + +static inline bool +wcore_context_init(struct wcore_context *self, + struct wcore_config *config) +{ + assert(self); + assert(config); + + self->api.display_id = config->display->api.display_id; + self->display = config->display; + + return true; +} + +static inline bool +wcore_context_teardown(struct wcore_context *self) +{ + assert(self); + return true; +} diff --git a/src/waffle/core/wcore_display.c b/src/waffle/core/wcore_display.c new file mode 100644 index 0000000..0e42c96 --- /dev/null +++ b/src/waffle/core/wcore_display.c @@ -0,0 +1,57 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "wcore_display.h" + +#include +#include + +bool +wcore_display_init(struct wcore_display *self, + struct wcore_platform *platform) +{ + static size_t id_counter = 0; + + assert(self); + assert(platform); + + // FIXME: Not thread safe. + self->api.display_id = ++id_counter; + self->platform = platform; + + if (self->api.display_id == 0) { + fprintf(stderr, "waffle: error: internal counter wrapped to 0\n"); + abort(); + } + + return true; +} + +bool +wcore_display_teardown(struct wcore_display *self) +{ + assert(self); + return true; +} diff --git a/src/waffle/core/wcore_display.h b/src/waffle/core/wcore_display.h new file mode 100644 index 0000000..d01a81a --- /dev/null +++ b/src/waffle/core/wcore_display.h @@ -0,0 +1,69 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include +#include +#include + +#include + +#include "wcore_util.h" + +struct wcore_display; +struct wcore_platform; + +struct wcore_display_vtbl { + bool + (*destroy)(struct wcore_display *self); + + bool + (*supports_context_api)( + struct wcore_display *self, + int32_t context_api); +}; + +struct wcore_display { + const struct wcore_display_vtbl *vtbl; + + struct waffle_display {} wfl; + struct api_object api; + + struct wcore_platform *platform; +}; + +DEFINE_CONTAINER_CAST_FUNC(wcore_display, + struct wcore_display, + struct waffle_display, + wfl) + +bool +wcore_display_init(struct wcore_display *self, + struct wcore_platform *platform); + + +bool +wcore_display_teardown(struct wcore_display *self); diff --git a/src/waffle/core/wcore_platform.c b/src/waffle/core/wcore_platform.c deleted file mode 100644 index 22cd914..0000000 --- a/src/waffle/core/wcore_platform.c +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @addtogroup wcore_platform -/// @{ - -/// @file - -#include "wcore_platform.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "wcore_error.h" - -static uint64_t id_counter = 0; - -struct wcore_platform* -wcore_platform_create(int platform) -{ - struct wcore_platform *self; - - self = calloc(1, sizeof(*self)); - if (!self) { - wcore_error(WAFFLE_OUT_OF_MEMORY); - return NULL; - } - - self->id = ++id_counter; - if (self->id == 0) { - fprintf(stderr, "waffle: error: internal counter wrapped around to 0"); - abort(); - } - - switch (platform) { -#ifdef WAFFLE_HAS_CGL - case WAFFLE_PLATFORM_CGL: - self->native = cgl_platform_create(&self->dispatch); - if (!self->native) - goto error; - break; -#endif -#ifdef WAFFLE_HAS_GLX - case WAFFLE_PLATFORM_GLX: - self->native = glx_platform_create(&self->dispatch); - if (!self->native) - goto error; - break; -#endif -#ifdef WAFFLE_HAS_WAYLAND - case WAFFLE_PLATFORM_WAYLAND: - self->native = wayland_platform_create(&self->dispatch); - if (!self->native) - goto error; - break; -#endif -#ifdef WAFFLE_HAS_X11_EGL - case WAFFLE_PLATFORM_X11_EGL: - self->native = xegl_platform_create(&self->dispatch); - if (!self->native) - goto error; - break; -#endif - default: - wcore_error_internal("bad value for platform (0x%x)", platform); - goto error; - } - - self->native_tag = platform; - - return self; - -error: - wcore_platform_destroy(self); - return NULL; -} - -bool -wcore_platform_destroy(struct wcore_platform *self) -{ - bool ok = true; - - if (!self) - return true; - - switch (self->native_tag) { -#ifdef WAFFLE_HAS_CGL - case WAFFLE_PLATFORM_CGL: - ok &= cgl_platform_destroy(self->native); - break; -#endif -#ifdef WAFFLE_HAS_GLX - case WAFFLE_PLATFORM_GLX: - ok &= glx_platform_destroy(self->native); - break; -#endif -#ifdef WAFFLE_HAS_WAYLAND - case WAFFLE_PLATFORM_WAYLAND: - ok &= wayland_platform_destroy(self->native); - break; -#endif -#ifdef WAFFLE_HAS_X11_EGL - case WAFFLE_PLATFORM_X11_EGL: - ok &= xegl_platform_destroy(self->native); - break; -#endif - default: - ok = false; - wcore_error_internal("bad value for wcore_platform._native_tag " - "(0x%x)", self->native_tag); - break; - } - - return ok; -} - -/// @} diff --git a/src/waffle/core/wcore_platform.h b/src/waffle/core/wcore_platform.h index dbb9237..587b280 100644 --- a/src/waffle/core/wcore_platform.h +++ b/src/waffle/core/wcore_platform.h @@ -23,37 +23,85 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup wcore_platform wcore_platform -/// @ingroup wcore -/// -/// @brief Abstract native platform. -/// @{ - -/// @file - #pragma once +#include #include #include -struct native_dispatch; -union native_platform; +struct wcore_config; +struct wcore_config_attrs; +struct wcore_context; +struct wcore_display; +struct wcore_platform; +struct wcore_window; -struct wcore_platform { - /// @brief Each instance has a unique id. - uint64_t id; +struct wcore_platform_vtbl { + bool + (*destroy)(struct wcore_platform *self); + + struct wcore_display* + (*connect_to_display)( + struct wcore_platform *self, + const char *name); + + struct wcore_config* + (*choose_config)( + struct wcore_platform *self, + struct wcore_display *dpy, + const struct wcore_config_attrs *attrs); + + struct wcore_context* + (*create_context)( + struct wcore_platform *self, + struct wcore_config *config, + struct wcore_context *share_ctx); - /// @brief One of WAFFLE_PLATFORM_*. Denotes type of `native`. - int native_tag; + struct wcore_window* + (*create_window)( + struct wcore_platform *self, + struct wcore_config *config, + int width, + int height); - union native_platform *native; - const struct native_dispatch *dispatch; + bool + (*make_current)( + struct wcore_platform *self, + struct wcore_display *dpy, + struct wcore_window *window, + struct wcore_context *ctx); + + void* + (*get_proc_address)( + struct wcore_platform *self, + const char *proc); + + bool + (*dl_can_open)( + struct wcore_platform *self, + int32_t waffle_dl); + + void* + (*dl_sym)( + struct wcore_platform *self, + int32_t waffle_dl, + const char *symbol); }; -struct wcore_platform* -wcore_platform_create(int platform); +struct wcore_platform { + const struct wcore_platform_vtbl *vtbl; +}; -bool -wcore_platform_destroy(struct wcore_platform *self); +static inline bool +wcore_platform_init(struct wcore_platform *self) +{ + assert(self); + return true; +} -/// @} +static inline bool +wcore_platform_teardown(struct wcore_platform *self) +{ + assert(self); + return true; +} diff --git a/src/waffle/core/wcore_util.h b/src/waffle/core/wcore_util.h new file mode 100644 index 0000000..ad5921e --- /dev/null +++ b/src/waffle/core/wcore_util.h @@ -0,0 +1,50 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include + +#define container_of(ptr, type, member) ({ \ + const __typeof__(((type *)0)->member ) *__mptr = (ptr); \ + (type*)((void*)__mptr - offsetof(type, member)); \ + }) + +/// @brief Safe downcast using container_of(). +/// +/// If given a null pointer, return null. +#define DEFINE_CONTAINER_CAST_FUNC(func_name, \ + container_type, \ + member_type, \ + member) \ + \ + static inline container_type* \ + func_name(member_type *member##_self) \ + { \ + if (member##_self) \ + return container_of(member##_self, container_type, member); \ + else \ + return 0; \ + } diff --git a/src/waffle/core/wcore_window.h b/src/waffle/core/wcore_window.h new file mode 100644 index 0000000..c642e80 --- /dev/null +++ b/src/waffle/core/wcore_window.h @@ -0,0 +1,80 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include +#include + +#include "wcore_config.h" +#include "wcore_util.h" + +struct wcore_window; + +struct wcore_window_vtbl { + bool + (*destroy)(struct wcore_window *self); + + bool + (*show)(struct wcore_window *self); + + bool + (*swap_buffers)(struct wcore_window *self); +}; + +struct wcore_window { + const struct wcore_window_vtbl *vtbl; + + struct waffle_window {} wfl; + struct api_object api; + + struct wcore_display *display; +}; + +DEFINE_CONTAINER_CAST_FUNC(wcore_window, + struct wcore_window, + struct waffle_window, + wfl) + + +static inline bool +wcore_window_init(struct wcore_window *self, + struct wcore_config *config) +{ + assert(self); + assert(config); + + self->api.display_id = config->display->api.display_id; + self->display = config->display; + + return true; +} + +static inline bool +wcore_window_teardown(struct wcore_window *self) +{ + assert(self); + return true; +} diff --git a/src/waffle/egl/egl_no_native.c b/src/waffle/egl/egl_no_native.c index 4447081..1aa6cb8 100644 --- a/src/waffle/egl/egl_no_native.c +++ b/src/waffle/egl/egl_no_native.c @@ -33,9 +33,10 @@ #include #include + #include #include -#include +#include void egl_get_error(const char *egl_func_call) @@ -86,7 +87,7 @@ egl_terminate(EGLDisplay dpy) /// @brief Check the `wcore_config_attrs.context_` attributes. static bool egl_config_check_context_attrs( - struct linux_platform *platform, + struct wcore_platform *plat, const struct wcore_config_attrs *attrs) { int version = 10 * attrs->context_major_version @@ -100,21 +101,21 @@ egl_config_check_context_attrs( "the default value 1.0"); return false; } - if (!linux_platform_dl_can_open(platform, WAFFLE_DL_OPENGL)) { + if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL)) { wcore_errorf(WAFFLE_UNSUPPORTED_ON_PLATFORM, "failed to open the OpenGL library"); return false; } return true; case WAFFLE_CONTEXT_OPENGL_ES1: - if (!linux_platform_dl_can_open(platform, WAFFLE_DL_OPENGL_ES1)) { + if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL_ES1)) { wcore_errorf(WAFFLE_UNSUPPORTED_ON_PLATFORM, "failed to open the OpenGL ES1 library"); return false; } return true; case WAFFLE_CONTEXT_OPENGL_ES2: - if (!linux_platform_dl_can_open(platform, WAFFLE_DL_OPENGL_ES2)) { + if (!plat->vtbl->dl_can_open(plat, WAFFLE_DL_OPENGL_ES2)) { wcore_errorf(WAFFLE_UNSUPPORTED_ON_PLATFORM, "failed to open the OpenGL ES2 library"); return false; @@ -129,13 +130,13 @@ egl_config_check_context_attrs( EGLConfig egl_choose_config( - struct linux_platform *platform, + struct wcore_platform *plat, EGLDisplay dpy, const struct wcore_config_attrs *attrs) { bool ok = true; - if (!egl_config_check_context_attrs(platform, attrs)) + if (!egl_config_check_context_attrs(plat, attrs)) return false; if (attrs->accum_buffer) { @@ -328,7 +329,7 @@ egl_get_render_buffer_attrib( bool egl_supports_context_api( - struct linux_platform *platform, + struct wcore_platform *plat, int32_t context_api) { int32_t waffle_dl; @@ -344,7 +345,7 @@ egl_supports_context_api( return false; } - return linux_platform_dl_can_open(platform, waffle_dl); + return plat->vtbl->dl_can_open(plat, waffle_dl); } /// @} diff --git a/src/waffle/egl/egl_no_native.h b/src/waffle/egl/egl_no_native.h index 0c4663c..2317e34 100644 --- a/src/waffle/egl/egl_no_native.h +++ b/src/waffle/egl/egl_no_native.h @@ -38,8 +38,8 @@ #include #include -struct linux_platform; struct wcore_config_attrs; +struct wcore_platform; /// @brief Sets the waffle error with info from eglGetError(). /// @param egl_func_call Examples are "eglMakeCurrent()" and @@ -52,7 +52,7 @@ egl_terminate(EGLDisplay dpy); EGLConfig egl_choose_config( - struct linux_platform *platform, + struct wcore_platform *plat, EGLDisplay dpy, const struct wcore_config_attrs *attrs); @@ -98,7 +98,7 @@ egl_get_render_buffer_attrib( /// @brief Helper for waffle_display_supports_context_api(). bool egl_supports_context_api( - struct linux_platform *platform, + struct wcore_platform *plat, int32_t context_api); /// @} diff --git a/src/waffle/glx/glx_config.c b/src/waffle/glx/glx_config.c index 2e345ab..744ca09 100644 --- a/src/waffle/glx/glx_config.c +++ b/src/waffle/glx/glx_config.c @@ -23,31 +23,40 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup glx_config -/// @{ - -/// @file - -#include "glx_config.h" - #include #include -#include #include + #include #include #include -#include "glx_priv_types.h" +#include "glx_config.h" +#include "glx_display.h" +#include "glx_platform.h" + +static const struct wcore_config_vtbl glx_config_wcore_vtbl; + +static bool +glx_config_destroy(struct wcore_config *wc_self) +{ + bool ok = true; + + if (wc_self == NULL) + return ok; + + ok &= wcore_config_teardown(wc_self); + free(glx_config(wc_self)); + return ok; +} /// @brief Check the values of `attrs->context_*`. static bool -glx_config_check_context_attrs( - struct glx_display *dpy, - const struct wcore_config_attrs *attrs) +glx_config_check_context_attrs(struct glx_display *dpy, + const struct wcore_config_attrs *attrs) { - struct glx_platform *platform = dpy->platform->glx; + struct glx_platform *plat = glx_platform(dpy->wcore.platform); int version = 10 * attrs->context_major_version + attrs->context_minor_version; @@ -84,7 +93,7 @@ glx_config_check_context_attrs( "to create an OpenGL ES2 context"); return false; } - if (!linux_platform_dl_can_open(platform->linux_, + if (!linux_platform_dl_can_open(plat->linux, WAFFLE_DL_OPENGL_ES2)) { wcore_errorf(WAFFLE_UNSUPPORTED_ON_PLATFORM, "failed to open the OpenGL ES2 library"); @@ -98,20 +107,33 @@ glx_config_check_context_attrs( } } -union native_config* -glx_config_choose( - union native_display *dpy, - const struct wcore_config_attrs *attrs) +struct wcore_config* +glx_config_choose(struct wcore_platform *wc_plat, + struct wcore_display *wc_dpy, + const struct wcore_config_attrs *attrs) { - bool ok = true; + struct glx_config *self; + struct glx_display *dpy = glx_display(wc_dpy); GLXFBConfig *configs = NULL; - int num_configs; + int num_configs = 0; XVisualInfo *vi = NULL; - if (!glx_config_check_context_attrs(dpy->glx, attrs)) + bool ok = true; + + if (!glx_config_check_context_attrs(dpy, attrs)) return NULL; + self = calloc(1, sizeof(*self)); + if (!self) { + wcore_error(WAFFLE_OUT_OF_MEMORY); + return NULL; + } + + ok = wcore_config_init(&self->wcore, wc_dpy); + if (!ok) + goto error; + int attrib_list[] = { GLX_BUFFER_SIZE, attrs->rgba_size, GLX_RED_SIZE, attrs->red_size, @@ -140,18 +162,9 @@ glx_config_choose( 0, }; - union native_config *self; - NATIVE_ALLOC(self, glx); - if (!self) { - wcore_error(WAFFLE_OUT_OF_MEMORY); - return NULL; - } - - self->glx->display = dpy; - // Set glx_fbconfig. - configs = glXChooseFBConfig(dpy->glx->xlib_display, - DefaultScreen(dpy->glx->xlib_display), + configs = glXChooseFBConfig(dpy->x11.xlib, + dpy->x11.screen, attrib_list, &num_configs); if (!configs || num_configs == 0) { @@ -160,56 +173,52 @@ glx_config_choose( goto error; } // Simply take the first. - self->glx->glx_fbconfig = configs[0]; + self->glx_fbconfig = configs[0]; // Set glx_fbconfig_id. - ok = !glXGetFBConfigAttrib(dpy->glx->xlib_display, - self->glx->glx_fbconfig, + ok = !glXGetFBConfigAttrib(dpy->x11.xlib, + self->glx_fbconfig, GLX_FBCONFIG_ID, - &self->glx->glx_fbconfig_id); + &self->glx_fbconfig_id); if (!ok) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "glxGetFBConfigAttrib failed"); goto error; } // Set xcb_visual_id. - vi = glXGetVisualFromFBConfig(dpy->glx->xlib_display, - self->glx->glx_fbconfig); + vi = glXGetVisualFromFBConfig(dpy->x11.xlib, + self->glx_fbconfig); if (!vi) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "glXGetVisualInfoFromFBConfig failed with " - "GLXFBConfigID=0x%x\n", self->glx->glx_fbconfig_id); + "GLXFBConfigID=0x%x\n", self->glx_fbconfig_id); goto error; } - self->glx->xcb_visual_id = vi->visualid; + self->xcb_visual_id = vi->visualid; // Set context attributes. - self->glx->context_api = attrs->context_api; - self->glx->context_major_version = attrs->context_major_version; - self->glx->context_minor_version = attrs->context_minor_version; - self->glx->context_profile = attrs->context_profile; + self->waffle_context_api = attrs->context_api; + self->waffle_context_major_version = attrs->context_major_version; + self->waffle_context_minor_version = attrs->context_minor_version; + self->waffle_context_profile = attrs->context_profile; + + self->wcore.vtbl = &glx_config_wcore_vtbl; - goto end; + goto cleanup; error: - glx_config_destroy(self); + glx_config_destroy(&self->wcore); self = NULL; -end: +cleanup: if (configs) XFree(configs); if (vi) XFree(vi); - return self; - -} - -bool -glx_config_destroy(union native_config *self) -{ - free(self); - return true; + return &self->wcore; } -/// @} +static const struct wcore_config_vtbl glx_config_wcore_vtbl = { + .destroy = glx_config_destroy, +}; diff --git a/src/waffle/glx/glx_config.h b/src/waffle/glx/glx_config.h index 97fa6d3..f6b01a8 100644 --- a/src/waffle/glx/glx_config.h +++ b/src/waffle/glx/glx_config.h @@ -23,27 +23,39 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup glx_config glx_config -/// @ingroup glx -/// @{ - -/// @file - #pragma once #include #include -struct wcore_config_attrs; -union native_config; -union native_display; +#include +#include -union native_config* -glx_config_choose( - union native_display *dpy, - const struct wcore_config_attrs *attrs); +#include +#include -bool -glx_config_destroy(union native_config *self); - -/// @} +struct wcore_config_attrs; +struct wcore_platform; + +struct glx_config { + struct wcore_config wcore; + + GLXFBConfig glx_fbconfig; + int32_t glx_fbconfig_id; + xcb_visualid_t xcb_visual_id; + + int waffle_context_api; + int waffle_context_major_version; + int waffle_context_minor_version; + int waffle_context_profile; +}; + +DEFINE_CONTAINER_CAST_FUNC(glx_config, + struct glx_config, + struct wcore_config, + wcore) + +struct wcore_config* +glx_config_choose(struct wcore_platform *wc_plat, + struct wcore_display *wc_dpy, + const struct wcore_config_attrs *attrs); diff --git a/src/waffle/glx/glx_context.c b/src/waffle/glx/glx_context.c index ab83054..b79b90e 100644 --- a/src/waffle/glx/glx_context.c +++ b/src/waffle/glx/glx_context.c @@ -23,52 +23,71 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup glx_context -/// @{ - -/// @file - #define GLX_GLXEXT_PROTOTYPES -#include "glx_context.h" - #include #include -#include #include + #include -#include "glx_priv_types.h" +#include "glx_config.h" +#include "glx_context.h" +#include "glx_display.h" +#include "glx_platform.h" + +static const struct wcore_context_vtbl glx_context_wcore_vtbl; enum { WAFFLE_GLX_CONTEXT_ATTRS_LENGTH = 7, }; + +static bool +glx_context_destroy(struct wcore_context *wc_self) +{ + struct glx_context *self; + struct glx_display *dpy; + bool ok = true; + + if (!wc_self) + return ok; + + self = glx_context(wc_self); + dpy = glx_display(wc_self->display); + + if (self->glx) + glXDestroyContext(dpy->x11.xlib, self->glx); + + ok &= wcore_context_teardown(wc_self); + free(self); + return ok; +} + /// @brief Fill @a attrib_list, which will be given to glXCreateContextAttribsARB(). /// /// This does not validate the `config->context_*` attributes. That validation /// occurred during waffle_config_choose(). static bool -glx_context_fill_attrib_list( - struct glx_config *config, - int attrib_list[]) +glx_context_fill_attrib_list(struct glx_config *config, + int attrib_list[]) { - struct glx_display *dpy = config->display->glx; + struct glx_display *dpy = glx_display(config->wcore.display); int i = 0; attrib_list[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; - attrib_list[i++] = config->context_major_version; + attrib_list[i++] = config->waffle_context_major_version; attrib_list[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; - attrib_list[i++] = config->context_minor_version; + attrib_list[i++] = config->waffle_context_minor_version; if (dpy->extensions.ARB_create_context_profile) { attrib_list[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; - switch (config->context_api) { + switch (config->waffle_context_api) { case WAFFLE_CONTEXT_OPENGL: - switch (config->context_profile) { + switch (config->waffle_context_profile) { case WAFFLE_CONTEXT_CORE_PROFILE: attrib_list[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; break; @@ -91,13 +110,13 @@ glx_context_fill_attrib_list( } static GLXContext -glx_context_create_native( - struct glx_config *config, - GLXContext share_ctx) +glx_context_create_native(struct glx_config *config, + struct glx_context *share_ctx) { GLXContext ctx; - struct glx_display *dpy = config->display->glx; - struct glx_platform *platform = dpy->platform->glx; + GLXContext real_share_ctx = share_ctx ? share_ctx->glx : NULL; + struct glx_display *dpy = glx_display(config->wcore.display); + struct glx_platform *platform = glx_platform(dpy->wcore.platform); if (dpy->extensions.ARB_create_context) { bool ok; @@ -107,9 +126,9 @@ glx_context_create_native( if (!ok) return false; - ctx = platform->glXCreateContextAttribsARB(dpy->xlib_display, + ctx = platform->glXCreateContextAttribsARB(dpy->x11.xlib, config->glx_fbconfig, - share_ctx, + real_share_ctx, true /*direct?*/, attrib_list); if (!ctx) { @@ -119,10 +138,10 @@ glx_context_create_native( } } else { - ctx = glXCreateNewContext(dpy->xlib_display, + ctx = glXCreateNewContext(dpy->x11.xlib, config->glx_fbconfig, GLX_RGBA_TYPE, - share_ctx, + real_share_ctx, true /*direct?*/); if (!ctx) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "glXCreateContext failed"); @@ -133,48 +152,38 @@ glx_context_create_native( return ctx; } -union native_context* -glx_context_create( - union native_config *config, - union native_context *share_ctx) +struct wcore_context* +glx_context_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + struct wcore_context *wc_share_ctx) { - union native_display *dpy = config->glx->display; + struct glx_context *self; + struct glx_config *config = glx_config(wc_config); + struct glx_context *share_ctx = glx_context(wc_share_ctx); + bool ok = true; - union native_context *self; - NATIVE_ALLOC(self, glx); + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->glx->display = dpy; - self->glx->glx_context = glx_context_create_native( - config->glx, - share_ctx ? share_ctx->glx->glx_context : NULL); - if (!self->glx->glx_context) + ok = wcore_context_init(&self->wcore, wc_config); + if (!ok) + goto error; + + self->glx = glx_context_create_native(config, share_ctx); + if (!self->glx) goto error; - return self; + self->wcore.vtbl = &glx_context_wcore_vtbl; + return &self->wcore; error: - free(self); + glx_context_destroy(&self->wcore); return NULL; } -bool -glx_context_destroy(union native_context *self) -{ - if (!self) - return true; - - union native_display *dpy = self->glx->display; - - if (self->glx->glx_context) - glXDestroyContext(dpy->glx->xlib_display, - self->glx->glx_context); - - free(self); - return true; -} - -/// @} +static const struct wcore_context_vtbl glx_context_wcore_vtbl = { + .destroy = glx_context_destroy, +}; diff --git a/src/waffle/glx/glx_context.h b/src/waffle/glx/glx_context.h index 9e7bf8b..4c5041a 100644 --- a/src/waffle/glx/glx_context.h +++ b/src/waffle/glx/glx_context.h @@ -23,25 +23,29 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup glx_context glx_context -/// @ingroup glx -/// @{ - -/// @file - #pragma once #include -union native_context; -union native_config; +#include + +#include +#include + +struct wcore_config; +struct wcore_platform; -union native_context* -glx_context_create( - union native_config *config, - union native_context *share_ctx); +struct glx_context { + struct wcore_context wcore; + GLXContext glx; +}; -bool -glx_context_destroy(union native_context *self); +DEFINE_CONTAINER_CAST_FUNC(glx_context, + struct glx_context, + struct wcore_context, + wcore) -/// @} +struct wcore_context* +glx_context_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + struct wcore_context *wc_share_ctx); diff --git a/src/waffle/glx/glx_display.c b/src/waffle/glx/glx_display.c index 201320e..564159c 100644 --- a/src/waffle/glx/glx_display.c +++ b/src/waffle/glx/glx_display.c @@ -23,32 +23,40 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup glx_display -/// @{ - -/// @file - -#include "glx_display.h" - #include -#include - -#include #include #include + #include #include -#include -#include "glx_priv_types.h" +#include "glx_display.h" +#include "glx_platform.h" + +static const struct wcore_display_vtbl glx_display_wcore_vtbl; + +static bool +glx_display_destroy(struct wcore_display *wc_self) +{ + struct glx_display *self = glx_display(wc_self); + bool ok = true; + + if (!self) + return ok; + + ok &= x11_display_teardown(&self->x11); + ok &= wcore_display_teardown(&self->wcore); + free(self); + return ok; +} static bool glx_display_set_extensions(struct glx_display *self) { - const char *s = glXQueryExtensionsString(self->xlib_display, - self->screen); + const char *s = glXQueryExtensionsString(self->x11.xlib, + self->x11.screen); if (!s) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "glXQueryExtensionsString failed"); @@ -62,60 +70,45 @@ glx_display_set_extensions(struct glx_display *self) return true; } -union native_display* -glx_display_connect( - union native_platform *platform, - const char *name) +struct wcore_display* +glx_display_connect(struct wcore_platform *wc_plat, + const char *name) { + struct glx_display *self; bool ok = true; - union native_display *self; - NATIVE_ALLOC(self, glx); + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->glx->platform = platform; + ok = wcore_display_init(&self->wcore, wc_plat); + if (!ok) + goto error; - ok &= x11_display_connect(name, - &self->glx->xlib_display, - &self->glx->xcb_connection); + ok = x11_display_init(&self->x11, name); if (!ok) goto error; - ok = glx_display_set_extensions(self->glx); + ok = glx_display_set_extensions(self); if (!ok) goto error; - return self; + self->wcore.vtbl = &glx_display_wcore_vtbl; + return &self->wcore; error: - glx_display_disconnect(self); + glx_display_destroy(&self->wcore); return NULL; } -bool -glx_display_disconnect(union native_display *self) -{ - bool ok = true; - - if (!self) - return true; - - if (self->glx->xlib_display) - ok &= x11_display_disconnect(self->glx->xlib_display); - - free(self); - return ok; -} - -bool -glx_display_supports_context_api( - union native_display *self, - int32_t context_api) +static bool +glx_display_supports_context_api(struct wcore_display *wc_self, + int32_t context_api) { - struct linux_platform *linux_plat = self->glx->platform->glx->linux_; + struct glx_display *self = glx_display(wc_self); + struct glx_platform *plat = glx_platform(wc_self->platform); switch (context_api) { case WAFFLE_CONTEXT_OPENGL: @@ -123,8 +116,8 @@ glx_display_supports_context_api( case WAFFLE_CONTEXT_OPENGL_ES1: return false; case WAFFLE_CONTEXT_OPENGL_ES2: - return self->glx->extensions.EXT_create_context_es2_profile - && linux_platform_dl_can_open(linux_plat, + return self->extensions.EXT_create_context_es2_profile + && linux_platform_dl_can_open(plat->linux, WAFFLE_DL_OPENGL_ES2); default: wcore_error_internal("waffle_context_api has bad value %#x", @@ -133,4 +126,7 @@ glx_display_supports_context_api( } } -/// @} +static const struct wcore_display_vtbl glx_display_wcore_vtbl = { + .destroy = glx_display_destroy, + .supports_context_api = glx_display_supports_context_api, +}; diff --git a/src/waffle/glx/glx_display.h b/src/waffle/glx/glx_display.h index d03d349..090e01f 100644 --- a/src/waffle/glx/glx_display.h +++ b/src/waffle/glx/glx_display.h @@ -23,31 +23,36 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup glx_display glx_display -/// @ingroup glx -/// @{ - -/// @file - #pragma once #include #include -union native_display; -union native_platform; +#include +#include + +#include +#include +#include + +struct wcore_platform; -union native_display* -glx_display_connect( - union native_platform *platform, - const char *name); +struct glx_display { + struct wcore_display wcore; + struct x11_display x11; -bool -glx_display_disconnect(union native_display *self); + struct glx_extentions { + bool ARB_create_context; + bool ARB_create_context_profile; + bool EXT_create_context_es2_profile; + } extensions; +}; -bool -glx_display_supports_context_api( - union native_display *self, - int32_t context_api); +DEFINE_CONTAINER_CAST_FUNC(glx_display, + struct glx_display, + struct wcore_display, + wcore) -/// @} +struct wcore_display* +glx_display_connect(struct wcore_platform *wc_plat, + const char *name); diff --git a/src/waffle/glx/glx_dl.c b/src/waffle/glx/glx_dl.c deleted file mode 100644 index f1c4a50..0000000 --- a/src/waffle/glx/glx_dl.c +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @addtogroup glx_dl -/// @{ - -/// @file - -#include "glx_dl.h" - -#include -#include -#include - -#include "glx_priv_types.h" - -bool -glx_dl_can_open( - union native_platform *native, - int32_t waffle_dl) -{ - return linux_platform_dl_can_open(native->glx->linux_, waffle_dl); -} - -void* -glx_dl_sym( - union native_platform *native, - int32_t waffle_dl, - const char *name) -{ - return linux_platform_dl_sym(native->glx->linux_, waffle_dl, name); -} - -/// @} diff --git a/src/waffle/glx/glx_dl.h b/src/waffle/glx/glx_dl.h deleted file mode 100644 index 0e8f42f..0000000 --- a/src/waffle/glx/glx_dl.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup glx_dl glx_dl -/// @ingroup glx -/// @{ - -/// @file - -#pragma once - -#include -#include - -union native_platform; - -bool -glx_dl_can_open( - union native_platform *native, - int32_t waffle_dl); -void* -glx_dl_sym( - union native_platform *native, - int32_t waffle_dl, - const char *name); - -/// @} diff --git a/src/waffle/glx/glx_gl_misc.c b/src/waffle/glx/glx_gl_misc.c deleted file mode 100644 index e6f7c85..0000000 --- a/src/waffle/glx/glx_gl_misc.c +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @addtogroup glx_gl_misc -/// @{ - -/// @file - -#include "glx_gl_misc.h" - -#include -#include - -#include "glx_priv_types.h" - -bool -glx_make_current( - union native_display *dpy, - union native_window *window, - union native_context *ctx) -{ - return glXMakeCurrent(dpy->glx->xlib_display, - window ? window->glx->xcb_window : 0, - ctx ? ctx->glx->glx_context : 0); -} - -void* -glx_get_proc_address( - union native_platform *native, - const char *name) -{ - return glXGetProcAddress((const uint8_t*) name); -} - -/// @} diff --git a/src/waffle/glx/glx_gl_misc.h b/src/waffle/glx/glx_gl_misc.h deleted file mode 100644 index 3d1831f..0000000 --- a/src/waffle/glx/glx_gl_misc.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup glx_gl_misc glx_gl_misc -/// @ingroup glx -/// @{ - -/// @file - -#pragma once - -#include -#include - -union native_platform; -union native_display; -union native_window; -union native_context; - -bool -glx_make_current( - union native_display *dpy, - union native_window *window, - union native_context *ctx); - -void* -glx_get_proc_address( - union native_platform *native, - const char *name); - -/// @} diff --git a/src/waffle/glx/glx_platform.c b/src/waffle/glx/glx_platform.c index 241d2d4..b5922f6 100644 --- a/src/waffle/glx/glx_platform.c +++ b/src/waffle/glx/glx_platform.c @@ -15,7 +15,7 @@ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// DISCLAIMED. IN NO EVENT SHALL TH E COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER @@ -23,84 +23,110 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup glx_platform -/// @{ - -/// @file - -#include "glx_platform.h" - -#include #include -#include -#include #include #include #include "glx_config.h" #include "glx_context.h" #include "glx_display.h" -#include "glx_dl.h" -#include "glx_gl_misc.h" -#include "glx_priv_types.h" +#include "glx_platform.h" #include "glx_window.h" -static const struct native_dispatch glx_dispatch = { - .display_connect = glx_display_connect, - .display_disconnect = glx_display_disconnect, - .display_supports_context_api = glx_display_supports_context_api, - .config_choose = glx_config_choose, - .config_destroy = glx_config_destroy, - .context_create = glx_context_create, - .context_destroy = glx_context_destroy, - .dl_can_open = glx_dl_can_open, - .dl_sym = glx_dl_sym, - .window_create = glx_window_create, - .window_destroy = glx_window_destroy, - .window_show = glx_window_show, - .window_swap_buffers = glx_window_swap_buffers, - .make_current = glx_make_current, - .get_proc_address = glx_get_proc_address, -}; +static const struct wcore_platform_vtbl glx_platform_wcore_vtbl; + +static bool +glx_platform_destroy(struct wcore_platform *wc_self) +{ + struct glx_platform *self = glx_platform(wc_self); + bool ok = true; + + if (!self) + return true; + + if (self->linux) + ok &= linux_platform_destroy(self->linux); + + ok &= wcore_platform_teardown(wc_self); + free(self); + return ok; +} -union native_platform* -glx_platform_create(const struct native_dispatch **dispatch) +struct wcore_platform* +glx_platform_create(void) { - union native_platform *self; - NATIVE_ALLOC(self, glx); + struct glx_platform *self; + bool ok = true; + + self= calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->glx->glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const uint8_t*) "glXCreateContextAttribsARB"); + ok = wcore_platform_init(&self->wcore); + if (!ok) + goto error; - self->glx->linux_ = linux_platform_create(); - if (!self->glx->linux_) + self->linux = linux_platform_create(); + if (!self->linux) goto error; - *dispatch = &glx_dispatch; - return self; + self->glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const uint8_t*) "glXCreateContextAttribsARB"); + + self->wcore.vtbl = &glx_platform_wcore_vtbl; + return &self->wcore; error: - glx_platform_destroy(self); + glx_platform_destroy(&self->wcore); return NULL; } -bool -glx_platform_destroy(union native_platform *self) +static bool +glx_platform_make_current(struct wcore_platform *wc_self, + struct wcore_display *wc_dpy, + struct wcore_window *wc_window, + struct wcore_context *wc_ctx) { - bool ok = true; + return glXMakeCurrent(glx_display(wc_dpy)->x11.xlib, + wc_window ? glx_window(wc_window)->x11.xcb : 0, + wc_ctx ? glx_context(wc_ctx)->glx : NULL); +} - if (!self) - return true; +static void* +glx_platform_get_proc_address(struct wcore_platform *wc_self, + const char *name) +{ + return glXGetProcAddress((const GLubyte*) name); +} - if (self->glx->linux_) - ok &= linux_platform_destroy(self->glx->linux_); +static bool +glx_platform_dl_can_open(struct wcore_platform *wc_self, + int32_t waffle_dl) +{ + return linux_platform_dl_can_open(glx_platform(wc_self)->linux, + waffle_dl); +} - free(self); - return ok; +static void* +glx_platform_dl_sym(struct wcore_platform *wc_self, + int32_t waffle_dl, + const char *name) +{ + return linux_platform_dl_sym(glx_platform(wc_self)->linux, + waffle_dl, + name); } -/// @} +static const struct wcore_platform_vtbl glx_platform_wcore_vtbl = { + .destroy = glx_platform_destroy, + .connect_to_display = glx_display_connect, + .choose_config = glx_config_choose, + .create_context = glx_context_create, + .create_window = glx_window_create, + .make_current = glx_platform_make_current, + .get_proc_address = glx_platform_get_proc_address, + .dl_can_open = glx_platform_dl_can_open, + .dl_sym = glx_platform_dl_sym, +}; diff --git a/src/waffle/glx/glx_platform.h b/src/waffle/glx/glx_platform.h index e779975..f61c169 100644 --- a/src/waffle/glx/glx_platform.h +++ b/src/waffle/glx/glx_platform.h @@ -23,23 +23,29 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup glx_platform glx_platform -/// @ingroup glx -/// @{ +#pragma once -/// @file +#include +#include +#include +#undef linux -#pragma once +#include +#include -#include +struct linux_platform; -struct native_dispatch; -union native_platform; +struct glx_platform { + struct wcore_platform wcore; + struct linux_platform *linux; -union native_platform* -glx_platform_create(const struct native_dispatch **dispatch); + PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB; +}; -bool -glx_platform_destroy(union native_platform *self); +DEFINE_CONTAINER_CAST_FUNC(glx_platform, + struct glx_platform, + struct wcore_platform, + wcore) -/// @} +struct wcore_platform* +glx_platform_create(void); diff --git a/src/waffle/glx/glx_priv_types.h b/src/waffle/glx/glx_priv_types.h deleted file mode 100644 index e3de2ff..0000000 --- a/src/waffle/glx/glx_priv_types.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup glx_priv_types glx_priv_types -/// @ingroup glx -/// @{ - -/// @file - -#pragma once - -#include -#include -#include - -struct linux_platform; - -union native_display; -union native_platform; - -struct glx_platform { - struct linux_platform *linux_; - - PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB; -}; - -struct glx_display { - union native_platform *platform; - Display *xlib_display; - xcb_connection_t *xcb_connection; - int screen; - - struct glx_extentions { - bool ARB_create_context; - bool ARB_create_context_profile; - bool EXT_create_context_es2_profile; - } extensions; -}; - -struct glx_config { - union native_display *display; - GLXFBConfig glx_fbconfig; - int32_t glx_fbconfig_id; - xcb_visualid_t xcb_visual_id; - - int context_api; - int context_major_version; - int context_minor_version; - int context_profile; -}; - -struct glx_context { - union native_display *display; - GLXContext glx_context; -}; - -struct glx_window { - union native_display *display; - xcb_window_t xcb_window; -}; - -/// @} diff --git a/src/waffle/glx/glx_window.c b/src/waffle/glx/glx_window.c index ebb2586..8ca5ec5 100644 --- a/src/waffle/glx/glx_window.c +++ b/src/waffle/glx/glx_window.c @@ -23,85 +23,92 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup glx_window -/// @{ +#include +#include -/// @file +#include +#include "glx_config.h" +#include "glx_display.h" #include "glx_window.h" -#include -#include +static const struct wcore_window_vtbl glx_window_wcore_vtbl; -#include -#include -#include +static bool +glx_window_destroy(struct wcore_window *wc_self) +{ + struct glx_window *self; + struct glx_display *dpy; + bool ok = true; + + if (!wc_self) + return ok; -#include "glx_priv_types.h" + self = glx_window(wc_self); + dpy = glx_display(wc_self->display); + + ok &= x11_window_teardown(&self->x11); + ok &= wcore_window_teardown(wc_self); + free(self); + return ok; +} -union native_window* -glx_window_create( - union native_config *config, - int width, - int height) +struct wcore_window* +glx_window_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + int width, + int height) { - union native_display *display = config->glx->display; + struct glx_window *self; + struct glx_display *dpy = glx_display(wc_config->display); + struct glx_config *config = glx_config(wc_config); + bool ok = true; - union native_window *self; - NATIVE_ALLOC(self, glx); + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->glx->display = display; - self->glx->xcb_window = x11_window_create( - display->glx->xcb_connection, - config->glx->xcb_visual_id, - width, - height); - if (!self->glx->xcb_window) + ok = wcore_window_init(&self->wcore, wc_config); + if (!ok) + goto error; + + ok = x11_window_init(&self->x11, + &dpy->x11, + config->xcb_visual_id, + width, + height); + if (!ok) goto error; - return self; + self->wcore.vtbl = &glx_window_wcore_vtbl; + return &self->wcore; error: - glx_window_destroy(self); + glx_window_destroy(&self->wcore); return NULL; } -bool -glx_window_destroy(union native_window *self) +static bool +glx_window_show(struct wcore_window *wc_self) { - if (!self) - return true; - - bool ok = true; - union native_display *dpy = self->glx->display; - - if (self->glx->xcb_window) - ok &= x11_window_destroy(dpy->glx->xcb_connection, - self->glx->xcb_window); - - free(self); - return ok; + return x11_window_show(&glx_window(wc_self)->x11); } -bool -glx_window_show(union native_window *native_self) +static bool +glx_window_swap_buffers(struct wcore_window *wc_self) { - struct glx_window *self = native_self->glx; - struct glx_display *display = self->display->glx; + struct glx_window *self = glx_window(wc_self); + struct glx_display *dpy = glx_display(wc_self->display); - return x11_window_show(display->xcb_connection, self->xcb_window); -} + glXSwapBuffers(dpy->x11.xlib, self->x11.xcb); -bool -glx_window_swap_buffers(union native_window *self) -{ - union native_display *dpy = self->glx->display; - glXSwapBuffers(dpy->glx->xlib_display, self->glx->xcb_window); return true; } -/// @} +static const struct wcore_window_vtbl glx_window_wcore_vtbl = { + .destroy = glx_window_destroy, + .show = glx_window_show, + .swap_buffers = glx_window_swap_buffers, +}; diff --git a/src/waffle/glx/glx_window.h b/src/waffle/glx/glx_window.h index 8b3bde0..76dcd31 100644 --- a/src/waffle/glx/glx_window.h +++ b/src/waffle/glx/glx_window.h @@ -23,33 +23,29 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup glx_window glx_window -/// @ingroup glx -/// @{ - -/// @file - #pragma once #include -union native_config; -union native_display; -union native_window; - -union native_window* -glx_window_create( - union native_config *config, - int width, - int height); +#include -bool -glx_window_destroy(union native_window *self); +#include +#include +#include -bool -glx_window_show(union native_window *native_self); +struct wcore_platform; -bool -glx_window_swap_buffers(union native_window *self); +struct glx_window { + struct wcore_window wcore; + struct x11_window x11; +}; -/// @} +DEFINE_CONTAINER_CAST_FUNC(glx_window, + struct glx_window, + struct wcore_window, + wcore) +struct wcore_window* +glx_window_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + int width, + int height); diff --git a/src/waffle/native.h b/src/waffle/native.h deleted file mode 100644 index e503886..0000000 --- a/src/waffle/native.h +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup native native -/// @{ - -/// @file - -#pragma once - -#include -#include -#include - -struct wcore_config_attrs; - -#define NATIVE_UNION(name) \ - struct cgl_##name; \ - struct droid_##name; \ - struct glx_##name; \ - struct wayland_##name; \ - struct xegl_##name; \ - \ - union native_##name { \ - struct cgl_##name *cgl; \ - struct droid_##name *droid; \ - struct glx_##name *glx; \ - struct wayland_##name *wl; \ - struct xegl_##name *xegl; \ - } - -NATIVE_UNION(platform); -NATIVE_UNION(config); -NATIVE_UNION(context); -NATIVE_UNION(display); -NATIVE_UNION(window); - -/// @brief Allocate a `union native_?`. -/// -/// @param x must have type `union native_?`. -/// @param platform is one of droid, glx, mac, wl, xegl. -#define NATIVE_ALLOC(x, platform) \ - do { \ - x = calloc(1, sizeof(*x) + sizeof(*x->platform)); \ - x->platform = (void*) (x + 1); \ - } while (0) - - -struct native_dispatch { - union native_display* - (*display_connect)( - union native_platform *platform, - const char *name); - - bool - (*display_disconnect)(union native_display *self); - - bool - (*display_supports_context_api)( - union native_display *self, - int32_t context_api); - - union native_config* - (*config_choose)( - union native_display *dpy, - const struct wcore_config_attrs *attrs); - - bool - (*config_destroy)(union native_config *self); - - union native_context* - (*context_create)( - union native_config *config, - union native_context *shared_context); - - bool - (*context_destroy)(union native_context *self); - - bool - (*dl_can_open)( - union native_platform *platform, - int32_t waffle_dl); - - void* - (*dl_sym)( - union native_platform *platform, - int32_t waffle_dl, - const char *name); - - union native_window* - (*window_create)( - union native_config *config, - int width, - int height); - - bool - (*window_destroy)(union native_window *self); - - bool - (*window_show)(union native_window *self); - - bool - (*window_swap_buffers)(union native_window *self); - - bool - (*make_current)( - union native_display *dpy, - union native_window *window, - union native_context *ctx); - - void* - (*get_proc_address)( - union native_platform *platform, - const char *name); -}; - -/// @} diff --git a/src/waffle/wayland/wayland_config.c b/src/waffle/wayland/wayland_config.c index b8d5b63..910ce47 100644 --- a/src/waffle/wayland/wayland_config.c +++ b/src/waffle/wayland/wayland_config.c @@ -23,65 +23,71 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup wayland_config -/// @{ - -/// @file - -#include "wayland_config.h" +#define WL_EGL_PLATFORM 1 #include #include -#include -#include #include #include +#include "wayland_config.h" +#include "wayland_display.h" +#include "wayland_platform.h" #include "wayland_priv_egl.h" -#include "wayland_priv_types.h" -union native_config* -wayland_config_choose( - union native_display *dpy, - const struct wcore_config_attrs *attrs) +static const struct wcore_config_vtbl wayland_config_wcore_vtbl; + +static bool +wayland_config_destroy(struct wcore_config *wc_self) +{ + struct wayland_config *self = wayland_config(wc_self); + bool ok = true; + + if (!self) + return ok; + + ok &= wcore_config_teardown(wc_self); + free(self); + return ok; +} + +struct wcore_config* +wayland_config_choose(struct wcore_platform *wc_plat, + struct wcore_display *wc_dpy, + const struct wcore_config_attrs *attrs) { - union native_platform *platform = dpy->wl->platform; + struct wayland_config *self; + struct wayland_display *dpy = wayland_display(wc_dpy); bool ok = true; - union native_config *self; - NATIVE_ALLOC(self, wl); + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->wl->display = dpy; - - ok &= egl_get_render_buffer_attrib(attrs, &self->wl->egl_render_buffer); + ok = wcore_config_init(&self->wcore, wc_dpy); if (!ok) goto error; - self->wl->egl_config = egl_choose_config(platform->wl->linux_, - dpy->wl->egl_display, - attrs); - if (!self->wl->egl_config) + ok = egl_get_render_buffer_attrib(attrs, &self->egl_render_buffer); + if (!ok) goto error; - self->wl->waffle_context_api = attrs->context_api; + self->egl = egl_choose_config(wc_plat, dpy->egl, attrs); + if (!self->egl) + goto error; - return self; + self->waffle_context_api = attrs->context_api; + self->wcore.vtbl = &wayland_config_wcore_vtbl; + return &self->wcore; error: - free(self); + wayland_config_destroy(&self->wcore); return NULL; } -bool -wayland_config_destroy(union native_config *self) -{ - free(self); - return true; -} - -/// @} +static const struct wcore_config_vtbl wayland_config_wcore_vtbl = { + .destroy = wayland_config_destroy, +}; diff --git a/src/waffle/wayland/wayland_config.h b/src/waffle/wayland/wayland_config.h index 5c0884f..efe5c12 100644 --- a/src/waffle/wayland/wayland_config.h +++ b/src/waffle/wayland/wayland_config.h @@ -23,27 +23,36 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup wayland_config wayland_config -/// @ingroup wayland -/// @{ - -/// @file - #pragma once #include #include +#include + +#include +#include + struct wcore_config_attrs; -union native_config; -union native_display; +struct wcore_platform; + +struct wayland_config { + struct wcore_config wcore; + + EGLConfig egl; + int32_t waffle_context_api; -union native_config* -wayland_config_choose( - union native_display *dpy, - const struct wcore_config_attrs *attrs); + /// The value of @c EGL_RENDER_BUFFER that will be set in the attrib_list + /// of eglCreateWindowSurface(). + EGLint egl_render_buffer; +}; -bool -wayland_config_destroy(union native_config *self); +DEFINE_CONTAINER_CAST_FUNC(wayland_config, + struct wayland_config, + struct wcore_config, + wcore) -/// @} +struct wcore_config* +wayland_config_choose(struct wcore_platform *wc_plat, + struct wcore_display *wc_dpy, + const struct wcore_config_attrs *attrs); diff --git a/src/waffle/wayland/wayland_context.c b/src/waffle/wayland/wayland_context.c index f4db769..d8faf1e 100644 --- a/src/waffle/wayland/wayland_context.c +++ b/src/waffle/wayland/wayland_context.c @@ -23,66 +23,76 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup wayland_context -/// @{ - -/// @file - -#include "wayland_context.h" +#define WL_EGL_PLATFORM 1 #include -#include +#include #include +#include "wayland_config.h" +#include "wayland_context.h" +#include "wayland_display.h" #include "wayland_priv_egl.h" -#include "wayland_priv_types.h" -union native_context* -wayland_context_create( - union native_config *config, - union native_context *share_ctx) +static const struct wcore_context_vtbl wayland_context_wcore_vtbl; + +static bool +wayland_context_destroy(struct wcore_context *wc_self) { - union native_display *dpy = config->wl->display; + struct wayland_context *self = wayland_context(wc_self); + bool ok = true; - union native_context *self; - NATIVE_ALLOC(self, wl); - if (!self) { - wcore_error(WAFFLE_OUT_OF_MEMORY); - return NULL; - } + if (!self) + return ok; - self->wl->display = config->wl->display; - self->wl->egl_context = egl_create_context( - dpy->wl->egl_display, - config->wl->egl_config, - share_ctx - ? share_ctx->wl->egl_context - : NULL, - config->wl->waffle_context_api); + if (self->egl) + ok &= egl_destroy_context(wayland_display(wc_self->display)->egl, + self->egl); + + ok &= wcore_context_teardown(wc_self); + free(self); + return ok; +} - if (!self->wl->egl_context) { - free(self); +struct wcore_context* +wayland_context_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + struct wcore_context *wc_share_ctx) +{ + struct wayland_context *self; + struct wayland_config *config = wayland_config(wc_config); + struct wayland_context *share_ctx = wayland_context(wc_share_ctx); + struct wayland_display *dpy = wayland_display(wc_config->display); + bool ok = true; + + self = calloc(1, sizeof(*self)); + if (!self) { + wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - return self; -} + ok = wcore_context_init(&self->wcore, wc_config); + if (!ok) + goto error; -bool -wayland_context_destroy(union native_context *self) -{ - if (!self) - return true; + self->egl = egl_create_context(dpy->egl, + config->egl, + share_ctx + ? share_ctx->egl + : NULL, + config->waffle_context_api); + if (!self->egl) + goto error; - bool ok = true; - union native_display *dpy = self->wl->display; + self->wcore.vtbl = &wayland_context_wcore_vtbl; + return &self->wcore; - if (self->wl->egl_context) - ok &= egl_destroy_context(dpy->wl->egl_display, - self->wl->egl_context); - free(self); - return ok; +error: + wayland_context_destroy(&self->wcore); + return NULL; } -/// @} +static const struct wcore_context_vtbl wayland_context_wcore_vtbl = { + .destroy = wayland_context_destroy, +}; diff --git a/src/waffle/wayland/wayland_context.h b/src/waffle/wayland/wayland_context.h index e0f59e2..1be76bc 100644 --- a/src/waffle/wayland/wayland_context.h +++ b/src/waffle/wayland/wayland_context.h @@ -23,25 +23,29 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup wayland_context wayland_context -/// @ingroup wayland -/// @{ - -/// @file - #pragma once #include -union native_context; -union native_config; +#include + +#include +#include + +struct wcore_config; +struct wcore_platform; -union native_context* -wayland_context_create( - union native_config *config, - union native_context *share_ctx); +struct wayland_context { + struct wcore_context wcore; + EGLContext egl; +}; -bool -wayland_context_destroy(union native_context *self); +DEFINE_CONTAINER_CAST_FUNC(wayland_context, + struct wayland_context, + struct wcore_context, + wcore) -/// @} +struct wcore_context* +wayland_context_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + struct wcore_context *wc_share_ctx); diff --git a/src/waffle/wayland/wayland_display.c b/src/waffle/wayland/wayland_display.c index c9c5f4b..809e782 100644 --- a/src/waffle/wayland/wayland_display.c +++ b/src/waffle/wayland/wayland_display.c @@ -23,103 +23,108 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup wayland_display -/// @{ - -/// @file - -#include "wayland_display.h" +#define WL_EGL_PLATFORM 1 #include #include -#include +#include +#undef container_of + #include +#include +#include "wayland_display.h" +#include "wayland_platform.h" #include "wayland_priv_egl.h" -#include "wayland_priv_types.h" + +static const struct wcore_display_vtbl wayland_display_wcore_vtbl; + +static bool +wayland_display_destroy(struct wcore_display *wc_self) +{ + struct wayland_display *self = wayland_display(wc_self); + bool ok = true; + + if (!self) + return ok; + + if (self->egl) + ok &= egl_terminate(self->egl); + + if (self->wl_display) + wl_display_disconnect(self->wl_display); + + ok &= wcore_display_teardown(&self->wcore); + free(self); + return ok; +} static void -wayland_display_listener( - struct wl_display *display, - uint32_t id, - const char *interface, - uint32_t version, - void *data) +wayland_display_listener(struct wl_display *display, + uint32_t name, + const char *interface, + uint32_t version, + void *data) { - union native_display *self = data; + struct wayland_display *self = data; if (!strncmp(interface, "wl_compositor", 14)) { - self->wl->wl_compositor = wl_display_bind(display, id, - &wl_compositor_interface); + self->wl_compositor = wl_display_bind(display, name, &wl_compositor_interface); } else if (!strncmp(interface, "wl_shell", 9)) { - self->wl->wl_shell = wl_display_bind(display, id, - &wl_shell_interface); + self->wl_shell = wl_display_bind(display, name, &wl_shell_interface); } } -union native_display* -wayland_display_connect( - union native_platform *platform, - const char *name) +struct wcore_display* +wayland_display_connect(struct wcore_platform *wc_plat, + const char *name) { - union native_display *self; - NATIVE_ALLOC(self, wl); + struct wayland_display *self; + bool ok = true; + + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->wl->platform = platform; + ok = wcore_display_init(&self->wcore, wc_plat); + if (!ok) + goto error; - self->wl->wl_display = wl_display_connect(name); - if (!self->wl->wl_display) { + self->wl_display = wl_display_connect(name); + if (!self->wl_display) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "wl_display_connect failed"); goto error; } - wl_display_add_global_listener(self->wl->wl_display, + wl_display_add_global_listener(self->wl_display, wayland_display_listener, self); - self->wl->egl_display = wayland_egl_initialize(self->wl->wl_display); - if (!self->wl->egl_display) + self->egl = wayland_egl_initialize(self->wl_display); + if (!self->egl) goto error; - return self; + self->wcore.vtbl = &wayland_display_wcore_vtbl; + return &self->wcore; error: - wayland_display_disconnect(self); + wayland_display_destroy(&self->wcore); return NULL; } -bool -wayland_display_disconnect(union native_display *self) -{ - bool ok = true; - - if (!self) - return true; - if (self->wl->egl_display) - ok &= egl_terminate(self->wl->egl_display); - - if (self->wl->wl_display) - wl_display_disconnect(self->wl->wl_display); - - free(self); - return ok; -} - -bool -wayland_display_supports_context_api( - union native_display *self, - int32_t context_api) +static bool +wayland_display_supports_context_api(struct wcore_display *wc_self, + int32_t waffle_context_api) { - union native_platform *platform = self->wl->platform; - return egl_supports_context_api(platform->wl->linux_, context_api); + return egl_supports_context_api(wc_self->platform, waffle_context_api); } - -/// @} +static const struct wcore_display_vtbl wayland_display_wcore_vtbl = { + .destroy = wayland_display_destroy, + .supports_context_api = wayland_display_supports_context_api, +}; diff --git a/src/waffle/wayland/wayland_display.h b/src/waffle/wayland/wayland_display.h index 5aad291..557181f 100644 --- a/src/waffle/wayland/wayland_display.h +++ b/src/waffle/wayland/wayland_display.h @@ -23,31 +23,36 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup wayland_display wayland_display -/// @ingroup wayland -/// @{ - -/// @file - #pragma once #include #include -union native_display; -union native_platform; +#include + +#include +#include + +struct wcore_platform; +struct wl_display; +struct wl_compositor; +struct wl_shell; + +struct wayland_display { + struct wcore_display wcore; -union native_display* -wayland_display_connect( - union native_platform *platform, - const char *name); + struct wl_display *wl_display; + struct wl_compositor *wl_compositor; + struct wl_shell *wl_shell; -bool -wayland_display_disconnect(union native_display *self); + EGLDisplay egl; +}; -bool -wayland_display_supports_context_api( - union native_display *self, - int32_t context_api); +DEFINE_CONTAINER_CAST_FUNC(wayland_display, + struct wayland_display, + struct wcore_display, + wcore) -/// @} +struct wcore_display* +wayland_display_connect(struct wcore_platform *wc_plat, + const char *name); diff --git a/src/waffle/wayland/wayland_dl.c b/src/waffle/wayland/wayland_dl.c deleted file mode 100644 index 2d03f29..0000000 --- a/src/waffle/wayland/wayland_dl.c +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @addtogroup wayland_dl -/// @{ - -/// @file - -#include "wayland_dl.h" - -#include -#include -#include - -#include "wayland_priv_types.h" - -bool -wayland_dl_can_open( - union native_platform *native, - int32_t waffle_dl) -{ - return linux_platform_dl_can_open(native->wl->linux_, waffle_dl); -} - -void* -wayland_dl_sym( - union native_platform *native, - int32_t waffle_dl, - const char *name) -{ - return linux_platform_dl_sym(native->wl->linux_, waffle_dl, name); -} - -/// @} diff --git a/src/waffle/wayland/wayland_dl.h b/src/waffle/wayland/wayland_dl.h deleted file mode 100644 index 68efb5a..0000000 --- a/src/waffle/wayland/wayland_dl.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup wayland_dl wayland_dl -/// @ingroup wayland -/// @{ - -/// @file - -#pragma once - - -#include -#include - -union native_platform; - -bool -wayland_dl_can_open( - union native_platform *native, - int32_t waffle_dl); - -void* -wayland_dl_sym( - union native_platform *native, - int32_t waffle_dl, - const char *name); - -/// @} diff --git a/src/waffle/wayland/wayland_gl_misc.c b/src/waffle/wayland/wayland_gl_misc.c deleted file mode 100644 index 3f0e8e7..0000000 --- a/src/waffle/wayland/wayland_gl_misc.c +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @addtogroup wayland_gl_misc -/// @{ - -/// @file - -#include "wayland_gl_misc.h" - -#include -#include - -#include "wayland_priv_egl.h" -#include "wayland_priv_types.h" - -bool -wayland_make_current( - union native_display *dpy, - union native_window *window, - union native_context *ctx) -{ - return egl_make_current(dpy->wl->egl_display, - window ? window->wl->egl_surface : 0, - ctx ? ctx->wl->egl_context : 0); -} - -void* -wayland_get_proc_address( - union native_platform *native, - const char *name) -{ - return eglGetProcAddress(name); -} - -/// @} diff --git a/src/waffle/wayland/wayland_gl_misc.h b/src/waffle/wayland/wayland_gl_misc.h deleted file mode 100644 index a5e20fa..0000000 --- a/src/waffle/wayland/wayland_gl_misc.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup wayland_gl_misc wayland_gl_misc -/// @ingroup wayland -/// @{ - -/// @file - -#pragma once - -#include -#include - -union native_platform; -union native_display; -union native_window; -union native_context; - -bool -wayland_make_current( - union native_display *dpy, - union native_window *window, - union native_context *ctx); - -void* -wayland_get_proc_address( - union native_platform *native, - const char *name); - -/// @} diff --git a/src/waffle/wayland/wayland_platform.c b/src/waffle/wayland/wayland_platform.c index 04558ef..9ecd48a 100644 --- a/src/waffle/wayland/wayland_platform.c +++ b/src/waffle/wayland/wayland_platform.c @@ -23,89 +23,116 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup wayland_platform -/// @{ - -/// @file - -#include "wayland_platform.h" - +#define WL_EGL_PLATFORM 1 #define _POSIX_C_SOURCE 200112 // glib feature macro for unsetenv() -#include #include -#include -#include #include #include #include "wayland_config.h" #include "wayland_context.h" #include "wayland_display.h" -#include "wayland_dl.h" -#include "wayland_gl_misc.h" +#include "wayland_platform.h" #include "wayland_priv_egl.h" -#include "wayland_priv_types.h" #include "wayland_window.h" -static const struct native_dispatch wayland_dispatch = { - .display_connect = wayland_display_connect, - .display_disconnect = wayland_display_disconnect, - .display_supports_context_api = wayland_display_supports_context_api, - .config_choose = wayland_config_choose, - .config_destroy = wayland_config_destroy, - .context_create = wayland_context_create, - .context_destroy = wayland_context_destroy, - .dl_can_open = wayland_dl_can_open, - .dl_sym = wayland_dl_sym, - .window_create = wayland_window_create, - .window_destroy = wayland_window_destroy, - .window_show = wayland_window_show, - .window_swap_buffers = wayland_window_swap_buffers, - .make_current = wayland_make_current, - .get_proc_address = wayland_get_proc_address, -}; +static const struct wcore_platform_vtbl wayland_platform_wcore_vtbl; + +static bool +wayland_platform_destroy(struct wcore_platform *wc_self) +{ + struct wayland_platform *self = wayland_platform(wc_self); + bool ok = true; + + if (!self) + return true; + + unsetenv("EGL_PLATFORM"); + + if (self->linux) + ok &= linux_platform_destroy(self->linux); + + ok &= wcore_platform_teardown(wc_self); + free(self); + return ok; +} -union native_platform* -wayland_platform_create(const struct native_dispatch **dispatch) +struct wcore_platform* +wayland_platform_create(void) { - union native_platform *self; - NATIVE_ALLOC(self, wl); + struct wayland_platform *self; + bool ok = true; + + self= calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->wl->linux_ = linux_platform_create(); - if (!self->wl->linux_) + ok = wcore_platform_init(&self->wcore); + if (!ok) + goto error; + + self->linux = linux_platform_create(); + if (!self->linux) goto error; setenv("EGL_PLATFORM", "wayland", true); - *dispatch = &wayland_dispatch; - return self; + self->wcore.vtbl = &wayland_platform_wcore_vtbl; + return &self->wcore; error: - wayland_platform_destroy(self); + wayland_platform_destroy(&self->wcore); return NULL; } -bool -wayland_platform_destroy(union native_platform *self) +static bool +wayland_platform_make_current(struct wcore_platform *wc_self, + struct wcore_display *wc_dpy, + struct wcore_window *wc_window, + struct wcore_context *wc_ctx) { - bool ok = true; - - if (!self) - return true; + return egl_make_current(wayland_display(wc_dpy)->egl, + wc_window ? wayland_window(wc_window)->egl : NULL, + wc_ctx ? wayland_context(wc_ctx)->egl : NULL); +} - unsetenv("EGL_PLATFORM"); +static void* +wayland_platform_get_proc_address(struct wcore_platform *wc_self, + const char *name) +{ + return eglGetProcAddress(name); +} - if (self->wl->linux_) - ok &= linux_platform_destroy(self->wl->linux_); +static bool +wayland_platform_dl_can_open(struct wcore_platform *wc_self, + int32_t waffle_dl) +{ + return linux_platform_dl_can_open(wayland_platform(wc_self)->linux, + waffle_dl); +} - free(self); - return ok; +static void* +wayland_platform_dl_sym(struct wcore_platform *wc_self, + int32_t waffle_dl, + const char *name) +{ + return linux_platform_dl_sym(wayland_platform(wc_self)->linux, + waffle_dl, + name); } -/// @} +static const struct wcore_platform_vtbl wayland_platform_wcore_vtbl = { + .destroy = wayland_platform_destroy, + .connect_to_display = wayland_display_connect, + .choose_config = wayland_config_choose, + .create_context = wayland_context_create, + .create_window = wayland_window_create, + .make_current = wayland_platform_make_current, + .get_proc_address = wayland_platform_get_proc_address, + .dl_can_open = wayland_platform_dl_can_open, + .dl_sym = wayland_platform_dl_sym, +}; diff --git a/src/waffle/wayland/wayland_platform.h b/src/waffle/wayland/wayland_platform.h index 9b9fc92..8f5a11a 100644 --- a/src/waffle/wayland/wayland_platform.h +++ b/src/waffle/wayland/wayland_platform.h @@ -23,23 +23,27 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup wayland_platform wayland_platform -/// @ingroup wayland -/// @{ - -/// @file - #pragma once #include +#include + +#undef linux + +#include +#include -struct native_dispatch; -union native_platform; +struct linux_platform; -union native_platform* -wayland_platform_create(const struct native_dispatch **dispatch); +struct wayland_platform { + struct wcore_platform wcore; + struct linux_platform *linux; +}; -bool -wayland_platform_destroy(union native_platform *self); +DEFINE_CONTAINER_CAST_FUNC(wayland_platform, + struct wayland_platform, + struct wcore_platform, + wcore) -/// @} +struct wcore_platform* +wayland_platform_create(void); diff --git a/src/waffle/wayland/wayland_priv_egl.c b/src/waffle/wayland/wayland_priv_egl.c index 2982584..d5851e1 100644 --- a/src/waffle/wayland/wayland_priv_egl.c +++ b/src/waffle/wayland/wayland_priv_egl.c @@ -23,12 +23,7 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup wayland_priv_egl -/// @{ - -/// @file +#define WL_EGL_PLATFORM 1 #include "wayland_priv_egl.h" #include - -/// @} diff --git a/src/waffle/wayland/wayland_priv_egl.h b/src/waffle/wayland/wayland_priv_egl.h index d595921..d9b415b 100644 --- a/src/waffle/wayland/wayland_priv_egl.h +++ b/src/waffle/wayland/wayland_priv_egl.h @@ -23,19 +23,8 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup wayland_priv_egl wayland_priv_egl -/// @ingroup wayland -/// @{ - -/// @file - #pragma once -// WL_EGL_PLATFORM configures Mesa's to define native types (such -// as EGLNativeDisplay) as Wayland types rather than Xlib types. -#define WL_EGL_PLATFORM 1 - #define NATIVE_EGL(basename) wayland_egl_##basename -#include -/// @} +#include diff --git a/src/waffle/wayland/wayland_priv_types.h b/src/waffle/wayland/wayland_priv_types.h deleted file mode 100644 index 95c200b..0000000 --- a/src/waffle/wayland/wayland_priv_types.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup wayland_priv_types wayland_priv_types -/// @ingroup wayland -/// @{ - -/// @file - -#pragma once - -// WL_EGL_PLATFORM configures Mesa's to define native types (such -// as EGLNativeDisplay) as Wayland types rather than Xlib types. -#define WL_EGL_PLATFORM 1 - -#include -#include - -#include - -struct linux_platform; - -union native_display; -union native_platform; - -struct wayland_platform { - struct linux_platform *linux_; -}; - -struct wayland_display { - union native_platform *platform; - struct wl_display *wl_display; - struct wl_compositor *wl_compositor; - struct wl_shell *wl_shell; - EGLDisplay egl_display; -}; - -struct wayland_config { - union native_display *display; - EGLConfig egl_config; - - /// The value of @c EGL_RENDER_BUFFER that will be set in the attrib_list - /// of eglCreateWindowSurface(). - EGLint egl_render_buffer; - - int32_t waffle_context_api; -}; - -struct wayland_context { - union native_display *display; - EGLContext egl_context; -}; - -struct wayland_window { - union native_display *display; - struct wl_surface *wl_surface; - struct wl_shell_surface *wl_shell_surface; - struct wl_egl_window *wl_window; - EGLSurface egl_surface; -}; - -/// @} diff --git a/src/waffle/wayland/wayland_window.c b/src/waffle/wayland/wayland_window.c index ae36550..cd2c6c7 100644 --- a/src/waffle/wayland/wayland_window.c +++ b/src/waffle/wayland/wayland_window.c @@ -23,116 +23,123 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup wayland_window -/// @{ - -/// @file - -#include "wayland_window.h" +#define WL_EGL_PLATFORM 1 #include #include -#include +#include +#undef container_of + #include -#include +#include "wayland_config.h" +#include "wayland_display.h" #include "wayland_priv_egl.h" -#include "wayland_priv_types.h" +#include "wayland_window.h" + +static const struct wcore_window_vtbl wayland_window_wcore_vtbl; + +static bool +wayland_window_destroy(struct wcore_window *wc_self) +{ + struct wayland_window *self = wayland_window(wc_self); + struct wayland_display *dpy; + bool ok = true; + + if (!self) + return ok; + + dpy = wayland_display(wc_self->display); + + if (self->egl) + ok &= egl_destroy_surface(dpy->egl, self->egl); + + if (self->wl_window) + wl_egl_window_destroy(self->wl_window); + + if (self->wl_shell_surface) + wl_shell_surface_destroy(self->wl_shell_surface); + + if (self->wl_surface) + wl_surface_destroy(self->wl_surface); + + ok &= wcore_window_teardown(wc_self); + free(self); + return ok; +} -union native_window* -wayland_window_create( - union native_config *config, - int width, - int height) +struct wcore_window* +wayland_window_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + int width, + int height) { - union native_display *display = config->wl->display; + struct wayland_window *self; + struct wayland_config *config = wayland_config(wc_config); + struct wayland_display *dpy = wayland_display(wc_config->display); + bool ok = true; - union native_window *self; - NATIVE_ALLOC(self, wl); + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->wl->display = display; + ok = wcore_window_init(&self->wcore, wc_config); + if (!ok) + goto error; - if (!display->wl->wl_compositor) { + if (!dpy->wl_compositor) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "wayland compositor not found"); goto error; } - if (!display->wl->wl_shell) { + if (!dpy->wl_shell) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "wayland shell not found"); goto error; } - self->wl->wl_surface = wl_compositor_create_surface(display->wl->wl_compositor); - if (!self->wl->wl_surface) { + self->wl_surface = wl_compositor_create_surface(dpy->wl_compositor); + if (!self->wl_surface) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "wl_compositor_create_surface failed"); goto error; } - self->wl->wl_shell_surface = wl_shell_get_shell_surface( - display->wl->wl_shell, - self->wl->wl_surface); - if (!self->wl->wl_shell_surface) { + self->wl_shell_surface = wl_shell_get_shell_surface(dpy->wl_shell, + self->wl_surface); + if (!self->wl_shell_surface) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "wl_shell_get_shell_surface failed"); goto error; } - self->wl->wl_window = wl_egl_window_create(self->wl->wl_surface, - width, - height); - if (!self->wl->wl_window) { + self->wl_window = wl_egl_window_create(self->wl_surface, width, height); + if (!self->wl_window) { wcore_errorf(WAFFLE_UNKNOWN_ERROR, "wl_egl_window_create failed"); goto error; } - self->wl->egl_surface = wayland_egl_create_window_surface( - display->wl->egl_display, - config->wl->egl_config, - self->wl->wl_window, - config->wl->egl_render_buffer); - if (!self->wl->egl_surface) - goto error; + self->egl = wayland_egl_create_window_surface(dpy->egl, + config->egl, + self->wl_window, + config->egl_render_buffer); + if (!self->egl) + goto error; - return self; + self->wcore.vtbl = &wayland_window_wcore_vtbl; + return &self->wcore; error: - wayland_window_destroy(self); + wayland_window_destroy(&self->wcore); return NULL; } -bool -wayland_window_destroy(union native_window *self) -{ - if (!self) - return true; - bool ok = true; - union native_display *dpy = self->wl->display; - - if (self->wl->egl_surface) - ok &= egl_destroy_surface(dpy->wl->egl_display, - self->wl->egl_surface); - - if (self->wl->wl_window) - wl_egl_window_destroy(self->wl->wl_window); - if (self->wl->wl_shell_surface) - wl_shell_surface_destroy(self->wl->wl_shell_surface); - if (self->wl->wl_surface) - wl_surface_destroy(self->wl->wl_surface); - - free(self); - return ok; -} - -bool -wayland_window_show(union native_window *native_self) +static bool +wayland_window_show(struct wcore_window *wc_self) { - struct wayland_window *self = native_self->wl; + struct wayland_window *self = wayland_window(wc_self); wl_shell_surface_set_toplevel(self->wl_shell_surface); @@ -140,12 +147,17 @@ wayland_window_show(union native_window *native_self) return true; } -bool -wayland_window_swap_buffers(union native_window *self) +static bool +wayland_window_swap_buffers(struct wcore_window *wc_self) { - union native_display *dpy = self->wl->display; - return egl_swap_buffers(dpy->wl->egl_display, - self->wl->egl_surface); + struct wayland_window *self = wayland_window(wc_self); + struct wayland_display *dpy = wayland_display(wc_self->display); + + return egl_swap_buffers(dpy->egl, self->egl); } -/// @} +static const struct wcore_window_vtbl wayland_window_wcore_vtbl = { + .destroy = wayland_window_destroy, + .show = wayland_window_show, + .swap_buffers = wayland_window_swap_buffers, +}; diff --git a/src/waffle/wayland/wayland_window.h b/src/waffle/wayland/wayland_window.h index b6ca086..01fdcdf 100644 --- a/src/waffle/wayland/wayland_window.h +++ b/src/waffle/wayland/wayland_window.h @@ -23,33 +23,33 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup wayland_window wayland_window -/// @ingroup wayland -/// @{ - -/// @file - #pragma once #include -union native_config; -union native_display; -union native_window; +#include + +#include +#include -union native_window* -wayland_window_create( - union native_config *config, - int width, - int height); +struct wcore_platform; -bool -wayland_window_destroy(union native_window *self); +struct wayland_window { + struct wcore_window wcore; -bool -wayland_window_show(union native_window *native_self); + struct wl_surface *wl_surface; + struct wl_shell_surface *wl_shell_surface; + struct wl_egl_window *wl_window; -bool -wayland_window_swap_buffers(union native_window *self); + EGLSurface egl; +}; -/// @} +DEFINE_CONTAINER_CAST_FUNC(wayland_window, + struct wayland_window, + struct wcore_window, + wcore) +struct wcore_window* +wayland_window_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + int width, + int height); diff --git a/src/waffle/x11/x11.c b/src/waffle/x11/x11.c deleted file mode 100644 index e7680d8..0000000 --- a/src/waffle/x11/x11.c +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @addtogroup x11 -/// @{ - -/// @file - -#include "x11.h" - -#include - -static void -x11_error(const char *func_call) -{ - wcore_errorf(WAFFLE_UNKNOWN_ERROR, "%s", func_call); -} - -bool -x11_display_connect( - const char *name, - Display **xlib_dpy, - xcb_connection_t **xcb_conn) -{ - *xlib_dpy = XOpenDisplay(name); - if (!*xlib_dpy) { - x11_error("XOpenDisplay"); - return false; - } - - *xcb_conn = XGetXCBConnection(*xlib_dpy); - if (!xcb_conn) { - XCloseDisplay(*xlib_dpy); - return false; - } - - return true; -} - -bool -x11_display_disconnect(Display *dpy) -{ - int error = XCloseDisplay(dpy); - if (error) - x11_error("XCloseDisplay"); - return !error; -} - -static uint8_t -x11_get_depth_for_visual( - xcb_connection_t *conn, - const xcb_screen_t *screen, - xcb_visualid_t id) -{ - xcb_depth_iterator_t depth = xcb_screen_allowed_depths_iterator(screen); - for (; depth.rem; xcb_depth_next(&depth)) { - xcb_visualtype_iterator_t visual = - xcb_depth_visuals_iterator (depth.data); - for (; visual.rem; xcb_visualtype_next(&visual)) { - if (visual.data->visual_id == id) - return depth.data->depth; - } - } - return 0; -} - -xcb_window_t -x11_window_create( - xcb_connection_t *conn, - xcb_visualid_t visual_id, - int width, - int height) -{ - const xcb_setup_t *setup = xcb_get_setup(conn); - xcb_colormap_t colormap = 0; - xcb_window_t window = 0; - if (!setup){ - wcore_errorf(WAFFLE_UNKNOWN_ERROR, "xcb_get_setup() failed"); - goto error; - } - - const xcb_screen_t *screen = xcb_setup_roots_iterator(setup).data; - if (!screen) { - wcore_errorf(WAFFLE_UNKNOWN_ERROR, "failed to get xcb screen"); - goto error; - } - - colormap = xcb_generate_id(conn); - window = xcb_generate_id(conn); - if (colormap <= 0 || window <= 0) { - wcore_errorf(WAFFLE_UNKNOWN_ERROR, "xcb_generate_id() failed"); - goto error; - } - - xcb_void_cookie_t colormap_cookie = xcb_create_colormap_checked( - conn, - XCB_COLORMAP_ALLOC_NONE, - colormap, - screen->root, - visual_id); - - const uint32_t event_mask = XCB_EVENT_MASK_BUTTON_PRESS - | XCB_EVENT_MASK_EXPOSURE - | XCB_EVENT_MASK_KEY_PRESS; - - // Please keep attrib_mask sorted the same as attrib_list. - const uint32_t attrib_mask = XCB_CW_BORDER_PIXEL - | XCB_CW_EVENT_MASK - | XCB_CW_COLORMAP; - - // XCB requires that attrib_list be sorted in the same order as - // `enum xcb_cw_t`. - const uint32_t attrib_list[] = { - /* border_pixel */ 0, - event_mask, - colormap, - }; - - xcb_void_cookie_t create_cookie = xcb_create_window_checked( - conn, - x11_get_depth_for_visual(conn, screen, visual_id), // depth - window, - screen->root, // parent - 0, 0, // x, y - width, height, - 0, // border width - XCB_WINDOW_CLASS_INPUT_OUTPUT, - visual_id, - attrib_mask, - attrib_list); - - // Check errors. - xcb_generic_error_t *error; - error = xcb_request_check(conn, colormap_cookie); - if (error) { - wcore_errorf(WAFFLE_UNKNOWN_ERROR, - "xcb_create_colormap() failed on visual_id=0x%x with " - "error=0x%x\n", visual_id, error->error_code); - goto error; - } - error = xcb_request_check(conn, create_cookie); - if (error) { - wcore_errorf(WAFFLE_UNKNOWN_ERROR, - "xcb_create_window_checked() failed: error=0x%x", - error->error_code); - goto error; - } - - goto end; - -error: - xcb_free_colormap(conn, colormap); - - if (window) - xcb_destroy_window(conn, window); - window = 0; - -end: - - return window; -} - -bool -x11_window_destroy( - xcb_connection_t *conn, - xcb_window_t window) -{ - bool ok = true; - - xcb_void_cookie_t cookie = xcb_destroy_window_checked(conn, window); - xcb_generic_error_t *error = xcb_request_check(conn, cookie); - - if (error) { - ok = false; - wcore_errorf(WAFFLE_UNKNOWN_ERROR, - "xcb_destroy_window_checked() failed: error=0x%x", - error->error_code); - } - - return ok; -} - -bool -x11_window_show( - xcb_connection_t *conn, - xcb_window_t window) -{ - xcb_void_cookie_t cookie; - xcb_generic_error_t *error; - - cookie = xcb_map_window_checked(conn, window); - error = xcb_request_check(conn, cookie); - if (error) { - wcore_errorf(WAFFLE_UNKNOWN_ERROR, - "xcb_map_window_checked() failed: error=0x%x", - error->error_code); - } - - return error == NULL; -} - -/// @} diff --git a/src/waffle/x11/x11.h b/src/waffle/x11/x11.h deleted file mode 100644 index 2a13521..0000000 --- a/src/waffle/x11/x11.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup x11 x11 -/// -/// @brief Wrappers for X11 functions. -/// -/// Waffle supports two X11 platforms (GLX and X11/EGL). This header declares -/// all common code. -/// @{ - -/// @file - -#pragma once - -#include -#include - -bool -x11_display_connect( - const char *name, - Display **xlib_dpy, - xcb_connection_t **xcb_conn); - -bool -x11_display_disconnect(Display *dpy); - -xcb_window_t -x11_window_create( - xcb_connection_t *conn, - xcb_visualid_t visual_id, - int width, - int height); - -bool -x11_window_destroy( - xcb_connection_t *conn, - xcb_window_t window); - -bool -x11_window_show( - xcb_connection_t *conn, - xcb_window_t window); - -/// @} diff --git a/src/waffle/x11/x11_display.c b/src/waffle/x11/x11_display.c new file mode 100644 index 0000000..0e5780f --- /dev/null +++ b/src/waffle/x11/x11_display.c @@ -0,0 +1,68 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include + +#include "x11_display.h" + +bool +x11_display_init(struct x11_display *self, const char *name) +{ + assert(self); + + self->xlib = XOpenDisplay(name); + if (!self->xlib) { + wcore_errorf(WAFFLE_UNKNOWN_ERROR, "XOpenDisplay failed"); + return false; + } + + self->xcb = XGetXCBConnection(self->xlib); + if (!self->xcb) { + wcore_errorf(WAFFLE_UNKNOWN_ERROR, "XGetXCBConnection failed"); + XCloseDisplay(self->xlib); + return false; + } + + // FIXME: Don't assume screen is 0. + self->screen = 0; + + return true; +} + +bool +x11_display_teardown(struct x11_display *self) +{ + int error = 0; + + assert(self); + + error = XCloseDisplay(self->xlib); + if (error) + wcore_errorf(WAFFLE_UNKNOWN_ERROR, "XCloseDisplay failed"); + + return !error; +} diff --git a/src/waffle/x11/x11_display.h b/src/waffle/x11/x11_display.h new file mode 100644 index 0000000..d394bc4 --- /dev/null +++ b/src/waffle/x11/x11_display.h @@ -0,0 +1,42 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include + +#include + +struct x11_display { + Display *xlib; + xcb_connection_t *xcb; + int screen; +}; + +bool +x11_display_init(struct x11_display *self, const char *name); + +bool +x11_display_teardown(struct x11_display *self); diff --git a/src/waffle/x11/x11_window.c b/src/waffle/x11/x11_window.c new file mode 100644 index 0000000..b8c79ea --- /dev/null +++ b/src/waffle/x11/x11_window.c @@ -0,0 +1,197 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include + +#include "x11_display.h" +#include "x11_window.h" + +static uint8_t +x11_winddow_get_depth(xcb_connection_t *conn, + const xcb_screen_t *screen, + xcb_visualid_t id) +{ + for (xcb_depth_iterator_t depth = + xcb_screen_allowed_depths_iterator(screen); + depth.rem; + xcb_depth_next(&depth)) + { + for (xcb_visualtype_iterator_t visual = + xcb_depth_visuals_iterator (depth.data); + visual.rem; + xcb_visualtype_next(&visual)) + { + if (visual.data->visual_id == id) + return depth.data->depth; + } + } + + return 0; +} + +bool +x11_window_init(struct x11_window *self, + struct x11_display *dpy, + xcb_visualid_t visual_id, + int width, + int height) +{ + assert(self); + assert(dpy); + + bool ok = true; + xcb_connection_t *conn = dpy->xcb; + + const xcb_setup_t *setup = xcb_get_setup(conn); + if (!setup){ + wcore_errorf(WAFFLE_UNKNOWN_ERROR, "xcb_get_setup() failed"); + goto error; + } + + const xcb_screen_t *screen = xcb_setup_roots_iterator(setup).data; + if (!screen) { + wcore_errorf(WAFFLE_UNKNOWN_ERROR, "failed to get xcb screen"); + goto error; + } + + xcb_colormap_t colormap = xcb_generate_id(conn); + xcb_window_t window = xcb_generate_id(conn); + if (colormap <= 0 || window <= 0) { + wcore_errorf(WAFFLE_UNKNOWN_ERROR, "xcb_generate_id() failed"); + goto error; + } + + xcb_void_cookie_t colormap_cookie = xcb_create_colormap_checked( + conn, + XCB_COLORMAP_ALLOC_NONE, + colormap, + screen->root, + visual_id); + + const uint32_t event_mask = XCB_EVENT_MASK_BUTTON_PRESS + | XCB_EVENT_MASK_EXPOSURE + | XCB_EVENT_MASK_KEY_PRESS; + + // Please keep attrib_mask sorted the same as attrib_list. + const uint32_t attrib_mask = XCB_CW_BORDER_PIXEL + | XCB_CW_EVENT_MASK + | XCB_CW_COLORMAP; + + // XCB requires that attrib_list be sorted in the same order as + // `enum xcb_cw_t`. + const uint32_t attrib_list[] = { + /* border_pixel */ 0, + event_mask, + colormap, + }; + + xcb_void_cookie_t create_cookie = xcb_create_window_checked( + conn, + x11_winddow_get_depth(conn, screen, visual_id), + window, + screen->root, // parent + 0, 0, // x, y + width, height, + 0, // border width + XCB_WINDOW_CLASS_INPUT_OUTPUT, + visual_id, + attrib_mask, + attrib_list); + + // Check errors. + xcb_generic_error_t *error; + error = xcb_request_check(conn, colormap_cookie); + if (error) { + wcore_errorf(WAFFLE_UNKNOWN_ERROR, + "xcb_create_colormap() failed on visual_id=0x%x with " + "error=0x%x\n", visual_id, error->error_code); + goto error; + } + error = xcb_request_check(conn, create_cookie); + if (error) { + wcore_errorf(WAFFLE_UNKNOWN_ERROR, + "xcb_create_window_checked() failed: error=0x%x", + error->error_code); + goto error; + } + + self->display = dpy; + self->xcb = window; + goto end; + +error: + ok = false; + + if (colormap) + xcb_free_colormap(conn, colormap); + + if (window) + xcb_destroy_window(conn, window); + +end: + return ok; +} + +bool +x11_window_teardown(struct x11_window *self) +{ + xcb_void_cookie_t cookie; + xcb_generic_error_t *error; + + assert(self); + + cookie = xcb_destroy_window_checked(self->display->xcb, self->xcb); + error = xcb_request_check(self->display->xcb, cookie); + + if (error) { + wcore_errorf(WAFFLE_UNKNOWN_ERROR, + "xcb_destroy_window_checked() failed: error=0x%x", + error->error_code); + } + + return !error; +} + +bool +x11_window_show(struct x11_window *self) +{ + xcb_void_cookie_t cookie; + xcb_generic_error_t *error; + + assert(self); + + cookie = xcb_map_window_checked(self->display->xcb, self->xcb); + error = xcb_request_check(self->display->xcb, cookie); + + if (error) { + wcore_errorf(WAFFLE_UNKNOWN_ERROR, + "xcb_map_window_checked() failed: error=0x%x", + error->error_code); + } + + return !error; +} diff --git a/src/waffle/x11/x11_window.h b/src/waffle/x11/x11_window.h new file mode 100644 index 0000000..e1308ad --- /dev/null +++ b/src/waffle/x11/x11_window.h @@ -0,0 +1,50 @@ +// Copyright 2012 Intel Corporation +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include + +#include + +struct x11_display; + +struct x11_window { + struct x11_display *display; + xcb_window_t xcb; +}; + +bool +x11_window_init(struct x11_window *self, + struct x11_display *dpy, + xcb_visualid_t visual_id, + int width, + int height); + +bool +x11_window_teardown(struct x11_window *self); + +bool +x11_window_show(struct x11_window *self); diff --git a/src/waffle/x11_egl/xegl_config.c b/src/waffle/x11_egl/xegl_config.c index 67fb7ed..2ca24b2 100644 --- a/src/waffle/x11_egl/xegl_config.c +++ b/src/waffle/x11_egl/xegl_config.c @@ -23,72 +23,78 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup xegl_config -/// @{ - -/// @file - -#include "xegl_config.h" - #include #include -#include -#include #include #include +#include "xegl_config.h" +#include "xegl_display.h" +#include "xegl_platform.h" #include "xegl_priv_egl.h" -#include "xegl_priv_types.h" -union native_config* -xegl_config_choose( - union native_display *dpy, - const struct wcore_config_attrs *attrs) +static const struct wcore_config_vtbl xegl_config_wcore_vtbl; + +static bool +xegl_config_destroy(struct wcore_config *wc_self) { - union native_platform *platform = dpy->xegl->platform; + struct xegl_config *self = xegl_config(wc_self); bool ok = true; - union native_config *self; - NATIVE_ALLOC(self, xegl); + if (!self) + return ok; + + ok &= wcore_config_teardown(wc_self); + free(self); + return ok; +} + +struct wcore_config* +xegl_config_choose(struct wcore_platform *wc_plat, + struct wcore_display *wc_dpy, + const struct wcore_config_attrs *attrs) +{ + struct xegl_config *self; + struct xegl_display *dpy = xegl_display(wc_dpy); + bool ok = true; + + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->xegl->display = dpy; + ok = wcore_config_init(&self->wcore, wc_dpy); + if (!ok) + goto error; - ok &= egl_get_render_buffer_attrib(attrs, &self->xegl->egl_render_buffer); + ok = egl_get_render_buffer_attrib(attrs, &self->egl_render_buffer); if (!ok) goto error; - self->xegl->egl_config = egl_choose_config(platform->xegl->linux_, - dpy->xegl->egl_display, - attrs); - if (!self->xegl->egl_config) + + self->egl = egl_choose_config(wc_plat, dpy->egl, attrs); + if (!self->egl) goto error; - ok &= eglGetConfigAttrib(dpy->xegl->egl_display, - self->xegl->egl_config, - EGL_NATIVE_VISUAL_ID, - (EGLint*) &self->xegl->xcb_visual_id); + + ok = eglGetConfigAttrib(dpy->egl, + self->egl, + EGL_NATIVE_VISUAL_ID, + (EGLint*) &self->xcb_visual_id); if (!ok) { egl_get_error("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID)"); goto error; } - self->xegl->waffle_context_api = attrs->context_api; - - return self; + self->waffle_context_api = attrs->context_api; + self->wcore.vtbl = &xegl_config_wcore_vtbl; + return &self->wcore; error: - free(self); + xegl_config_destroy(&self->wcore); return NULL; } -bool -xegl_config_destroy(union native_config *self) -{ - free(self); - return true; -} - -/// @} +static const struct wcore_config_vtbl xegl_config_wcore_vtbl = { + .destroy = xegl_config_destroy, +}; diff --git a/src/waffle/x11_egl/xegl_config.h b/src/waffle/x11_egl/xegl_config.h index f6b865a..0cccf4a 100644 --- a/src/waffle/x11_egl/xegl_config.h +++ b/src/waffle/x11_egl/xegl_config.h @@ -23,27 +23,41 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup xegl_config xegl_config -/// @ingroup xegl -/// @{ - -/// @file - #pragma once #include #include +#include +#include + +#include +#include + struct wcore_config_attrs; -union native_config; -union native_display; +struct wcore_platform; + +struct xegl_config { + struct wcore_config wcore; + + EGLConfig egl; + xcb_visualid_t xcb_visual_id; + + /// The value of @c EGL_RENDER_BUFFER that will be set in the attrib_list + /// of eglCreateWindowSurface(). + EGLint egl_render_buffer; -union native_config* -xegl_config_choose( - union native_display *dpy, - const struct wcore_config_attrs *attrs); + /// The API given to xegl_config_choose(). This is later used to + /// select the value of the EGL_RENDERABLE attribute. + int32_t waffle_context_api; +}; -bool -xegl_config_destroy(union native_config *self); +DEFINE_CONTAINER_CAST_FUNC(xegl_config, + struct xegl_config, + struct wcore_config, + wcore) -/// @} +struct wcore_config* +xegl_config_choose(struct wcore_platform *wc_plat, + struct wcore_display *wc_dpy, + const struct wcore_config_attrs *attrs); diff --git a/src/waffle/x11_egl/xegl_context.c b/src/waffle/x11_egl/xegl_context.c index d387185..a21e30b 100644 --- a/src/waffle/x11_egl/xegl_context.c +++ b/src/waffle/x11_egl/xegl_context.c @@ -23,66 +23,74 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup xegl_context -/// @{ +#include -/// @file +#include +#include +#include "xegl_config.h" #include "xegl_context.h" +#include "xegl_display.h" +#include "xegl_priv_egl.h" -#include +static const struct wcore_context_vtbl xegl_context_wcore_vtbl; -#include -#include +static bool +xegl_context_destroy(struct wcore_context *wc_self) +{ + struct xegl_context *self = xegl_context(wc_self); + bool ok = true; -#include "xegl_priv_egl.h" -#include "xegl_priv_types.h" + if (!self) + return ok; + + if (self->egl) + ok &= egl_destroy_context(xegl_display(wc_self->display)->egl, + self->egl); + + ok &= wcore_context_teardown(wc_self); + free(self); + return ok; +} -union native_context* -xegl_context_create( - union native_config *config, - union native_context *share_ctx) +struct wcore_context* +xegl_context_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + struct wcore_context *wc_share_ctx) { - union native_display *dpy = config->xegl->display; + struct xegl_context *self; + struct xegl_config *config = xegl_config(wc_config); + struct xegl_context *share_ctx = xegl_context(wc_share_ctx); + struct xegl_display *dpy = xegl_display(wc_config->display); + bool ok = true; - union native_context *self; - NATIVE_ALLOC(self, xegl); + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->xegl->display = config->xegl->display; - self->xegl->egl_context = egl_create_context( - dpy->xegl->egl_display, - config->xegl->egl_config, - share_ctx - ? share_ctx->xegl->egl_context - : NULL, - config->xegl->waffle_context_api); - - if (!self->xegl->egl_context) { - free(self); - return NULL; - } - - return self; -} + ok = wcore_context_init(&self->wcore, wc_config); + if (!ok) + goto error; -bool -xegl_context_destroy(union native_context *self) -{ - if (!self) - return true; + self->egl = egl_create_context(dpy->egl, + config->egl, + share_ctx + ? share_ctx->egl + : NULL, + config->waffle_context_api); + if (!self->egl) + goto error; - bool ok = true; - union native_display *dpy = self->xegl->display; + self->wcore.vtbl = &xegl_context_wcore_vtbl; + return &self->wcore; - if (self->xegl->egl_context) - ok &= egl_destroy_context(dpy->xegl->egl_display, - self->xegl->egl_context); - free(self); - return ok; +error: + xegl_context_destroy(&self->wcore); + return NULL; } -/// @} +static const struct wcore_context_vtbl xegl_context_wcore_vtbl = { + .destroy = xegl_context_destroy, +}; diff --git a/src/waffle/x11_egl/xegl_context.h b/src/waffle/x11_egl/xegl_context.h index f2a1714..5b76f72 100644 --- a/src/waffle/x11_egl/xegl_context.h +++ b/src/waffle/x11_egl/xegl_context.h @@ -23,25 +23,28 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup xegl_context xegl_context -/// @ingroup xegl -/// @{ - -/// @file - #pragma once #include +#include + +#include +#include -union native_context; -union native_config; +struct wcore_config; +struct wcore_platform; -union native_context* -xegl_context_create( - union native_config *config, - union native_context *share_ctx); +struct xegl_context { + struct wcore_context wcore; + EGLContext egl; +}; -bool -xegl_context_destroy(union native_context *self); +DEFINE_CONTAINER_CAST_FUNC(xegl_context, + struct xegl_context, + struct wcore_context, + wcore) -/// @} +struct wcore_context* +xegl_context_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + struct wcore_context *wc_share_ctx); diff --git a/src/waffle/x11_egl/xegl_display.c b/src/waffle/x11_egl/xegl_display.c index 8512016..357c2aa 100644 --- a/src/waffle/x11_egl/xegl_display.c +++ b/src/waffle/x11_egl/xegl_display.c @@ -23,81 +23,77 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup xegl_display -/// @{ +#include -/// @file +#include +#include #include "xegl_display.h" +#include "xegl_platform.h" +#include "xegl_priv_egl.h" -#include +static const struct wcore_display_vtbl xegl_display_wcore_vtbl; -#include -#include +static bool +xegl_display_destroy(struct wcore_display *wc_self) +{ + struct xegl_display *self = xegl_display(wc_self); + bool ok = true; -#include -#include -#include + if (!self) + return ok; -#include "xegl_priv_egl.h" -#include "xegl_priv_types.h" + if (self->egl) + ok &= egl_terminate(self->egl); + + ok &= x11_display_teardown(&self->x11); + ok &= wcore_display_teardown(&self->wcore); + free(self); + return ok; +} -union native_display* +struct wcore_display* xegl_display_connect( - union native_platform *platform, + struct wcore_platform *wc_plat, const char *name) { + struct xegl_display *self; bool ok = true; - union native_display *self; - NATIVE_ALLOC(self, xegl); + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->xegl->platform = platform; + ok = wcore_display_init(&self->wcore, wc_plat); + if (!ok) + goto error; - ok &= x11_display_connect(name, &self->xegl->xlib_display, &self->xegl->xcb_connection); + ok = x11_display_init(&self->x11, name); if (!ok) goto error; - self->xegl->egl_display = xegl_egl_initialize(self->xegl->xlib_display); - if (!self->xegl->egl_display) + self->egl = xegl_egl_initialize(self->x11.xlib); + if (!self->egl) goto error; - return self; + self->wcore.vtbl = &xegl_display_wcore_vtbl; + return &self->wcore; error: - xegl_display_disconnect(self); + xegl_display_destroy(&self->wcore); return NULL; } -bool -xegl_display_disconnect(union native_display *self) -{ - bool ok = true; - - if (!self) - return true; - - if (self->xegl->egl_display) - ok &= egl_terminate(self->xegl->egl_display); - - if (self->xegl->xlib_display) - ok &= x11_display_disconnect(self->xegl->xlib_display); - - free(self); - return ok; -} - -bool -xegl_display_supports_context_api( - union native_display *self, - int32_t context_api) +static bool +xegl_display_supports_context_api(struct wcore_display *wc_self, + int32_t waffle_context_api) { - union native_platform *platform = self->xegl->platform; - return egl_supports_context_api(platform->xegl->linux_, context_api); + return egl_supports_context_api(wc_self->platform, waffle_context_api); } -/// @} +static const struct wcore_display_vtbl xegl_display_wcore_vtbl = { + .destroy = xegl_display_destroy, + .supports_context_api = xegl_display_supports_context_api, +}; diff --git a/src/waffle/x11_egl/xegl_display.h b/src/waffle/x11_egl/xegl_display.h index 68595d8..062f088 100644 --- a/src/waffle/x11_egl/xegl_display.h +++ b/src/waffle/x11_egl/xegl_display.h @@ -23,31 +23,31 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup xegl_display xegl_display -/// @ingroup xegl -/// @{ - -/// @file - #pragma once #include #include -union native_display; -union native_platform; +#include +#include + +#include +#include +#include -union native_display* -xegl_display_connect( - union native_platform *platform, - const char *name); +struct wcore_platform; -bool -xegl_display_disconnect(union native_display *self); +struct xegl_display { + struct wcore_display wcore; + struct x11_display x11; + EGLDisplay egl; +}; -bool -xegl_display_supports_context_api( - union native_display *self, - int32_t context_api); +DEFINE_CONTAINER_CAST_FUNC(xegl_display, + struct xegl_display, + struct wcore_display, + wcore) -/// @} +struct wcore_display* +xegl_display_connect(struct wcore_platform *wc_plat, + const char *name); diff --git a/src/waffle/x11_egl/xegl_dl.c b/src/waffle/x11_egl/xegl_dl.c deleted file mode 100644 index 04a3181..0000000 --- a/src/waffle/x11_egl/xegl_dl.c +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @addtogroup xegl_dl -/// @{ - -/// @file - -#include "xegl_dl.h" - -#include -#include -#include - -#include "xegl_priv_types.h" - -bool -xegl_dl_can_open( - union native_platform *native, - int32_t waffle_dl) -{ - return linux_platform_dl_can_open(native->xegl->linux_, waffle_dl); -} - -void* -xegl_dl_sym( - union native_platform *native, - int32_t waffle_dl, - const char *name) -{ - return linux_platform_dl_sym(native->xegl->linux_, waffle_dl, name); -} - -/// @} diff --git a/src/waffle/x11_egl/xegl_dl.h b/src/waffle/x11_egl/xegl_dl.h deleted file mode 100644 index 389f245..0000000 --- a/src/waffle/x11_egl/xegl_dl.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup xegl_dl xegl_dl -/// @ingroup xegl -/// @{ - -/// @file - -#pragma once - -#include -#include - -union native_platform; - -bool -xegl_dl_can_open( - union native_platform *native, - int32_t waffle_dl); -void* -xegl_dl_sym( - union native_platform *native, - int32_t waffle_dl, - const char *name); - -/// @} diff --git a/src/waffle/x11_egl/xegl_gl_misc.c b/src/waffle/x11_egl/xegl_gl_misc.c deleted file mode 100644 index 13b897e..0000000 --- a/src/waffle/x11_egl/xegl_gl_misc.c +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @addtogroup xegl_gl_misc -/// @{ - -/// @file - -#include "xegl_gl_misc.h" - -#include -#include - -#include "xegl_priv_egl.h" -#include "xegl_priv_types.h" - -bool -xegl_make_current( - union native_display *dpy, - union native_window *window, - union native_context *ctx) -{ - return egl_make_current(dpy->xegl->egl_display, - window ? window->xegl->egl_surface : 0, - ctx ? ctx->xegl->egl_context : 0); -} - -void* -xegl_get_proc_address( - union native_platform *native, - const char *name) -{ - return eglGetProcAddress(name); -} - -/// @} diff --git a/src/waffle/x11_egl/xegl_gl_misc.h b/src/waffle/x11_egl/xegl_gl_misc.h deleted file mode 100644 index e001806..0000000 --- a/src/waffle/x11_egl/xegl_gl_misc.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup xegl_gl_misc xegl_gl_misc -/// @ingroup xegl -/// @{ - -/// @file - -#pragma once - -#include -#include - -union native_platform; -union native_display; -union native_window; -union native_context; - -bool -xegl_make_current( - union native_display *dpy, - union native_window *window, - union native_context *ctx); - -void* -xegl_get_proc_address( - union native_platform *native, - const char *name); - -/// @} diff --git a/src/waffle/x11_egl/xegl_platform.c b/src/waffle/x11_egl/xegl_platform.c index ad79176..cb67057 100644 --- a/src/waffle/x11_egl/xegl_platform.c +++ b/src/waffle/x11_egl/xegl_platform.c @@ -23,89 +23,115 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup xegl_platform -/// @{ - -/// @file - -#include "xegl_platform.h" - #define _POSIX_C_SOURCE 200112 // glib feature macro for unsetenv() -#include #include -#include -#include #include #include #include "xegl_config.h" #include "xegl_context.h" #include "xegl_display.h" -#include "xegl_dl.h" -#include "xegl_gl_misc.h" +#include "xegl_platform.h" #include "xegl_priv_egl.h" -#include "xegl_priv_types.h" #include "xegl_window.h" -static const struct native_dispatch xegl_dispatch = { - .display_connect = xegl_display_connect, - .display_disconnect = xegl_display_disconnect, - .display_supports_context_api = xegl_display_supports_context_api, - .config_choose = xegl_config_choose, - .config_destroy = xegl_config_destroy, - .context_create = xegl_context_create, - .context_destroy = xegl_context_destroy, - .dl_can_open = xegl_dl_can_open, - .dl_sym = xegl_dl_sym, - .window_create = xegl_window_create, - .window_destroy = xegl_window_destroy, - .window_show = xegl_window_show, - .window_swap_buffers = xegl_window_swap_buffers, - .make_current = xegl_make_current, - .get_proc_address = xegl_get_proc_address, -}; +static const struct wcore_platform_vtbl xegl_platform_wcore_vtbl; + +static bool +xegl_platform_destroy(struct wcore_platform *wc_self) +{ + struct xegl_platform *self = xegl_platform(wc_self); + bool ok = true; + + if (!self) + return true; + + unsetenv("EGL_PLATFORM"); + + if (self->linux) + ok &= linux_platform_destroy(self->linux); + + ok &= wcore_platform_teardown(wc_self); + free(self); + return ok; +} -union native_platform* -xegl_platform_create(const struct native_dispatch **dispatch) +struct wcore_platform* +xegl_platform_create(void) { - union native_platform *self; - NATIVE_ALLOC(self, xegl); + struct xegl_platform *self; + bool ok = true; + + self= calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->xegl->linux_ = linux_platform_create(); - if (!self->xegl->linux_) + ok = wcore_platform_init(&self->wcore); + if (!ok) + goto error; + + self->linux = linux_platform_create(); + if (!self->linux) goto error; setenv("EGL_PLATFORM", "x11", true); - *dispatch = &xegl_dispatch; - return self; + self->wcore.vtbl = &xegl_platform_wcore_vtbl; + return &self->wcore; error: - xegl_platform_destroy(self); + xegl_platform_destroy(&self->wcore); return NULL; } -bool -xegl_platform_destroy(union native_platform *self) +static bool +xegl_platform_make_current(struct wcore_platform *wc_self, + struct wcore_display *wc_dpy, + struct wcore_window *wc_window, + struct wcore_context *wc_ctx) { - bool ok = true; - - if (!self) - return true; + return egl_make_current(xegl_display(wc_dpy)->egl, + wc_window ? xegl_window(wc_window)->egl : NULL, + wc_ctx ? xegl_context(wc_ctx)->egl : NULL); +} - unsetenv("EGL_PLATFORM"); +static void* +xegl_platform_get_proc_address(struct wcore_platform *wc_self, + const char *name) +{ + return eglGetProcAddress(name); +} - if (self->xegl->linux_) - ok &= linux_platform_destroy(self->xegl->linux_); +static bool +xegl_platform_dl_can_open(struct wcore_platform *wc_self, + int32_t waffle_dl) +{ + return linux_platform_dl_can_open(xegl_platform(wc_self)->linux, + waffle_dl); +} - free(self); - return ok; +static void* +xegl_platform_dl_sym(struct wcore_platform *wc_self, + int32_t waffle_dl, + const char *name) +{ + return linux_platform_dl_sym(xegl_platform(wc_self)->linux, + waffle_dl, + name); } -/// @} +static const struct wcore_platform_vtbl xegl_platform_wcore_vtbl = { + .destroy = xegl_platform_destroy, + .connect_to_display = xegl_display_connect, + .choose_config = xegl_config_choose, + .create_context = xegl_context_create, + .create_window = xegl_window_create, + .make_current = xegl_platform_make_current, + .get_proc_address = xegl_platform_get_proc_address, + .dl_can_open = xegl_platform_dl_can_open, + .dl_sym = xegl_platform_dl_sym, +}; diff --git a/src/waffle/x11_egl/xegl_platform.h b/src/waffle/x11_egl/xegl_platform.h index 298f321..63833f5 100644 --- a/src/waffle/x11_egl/xegl_platform.h +++ b/src/waffle/x11_egl/xegl_platform.h @@ -23,23 +23,26 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup xegl_platform xegl_platform -/// @ingroup xegl -/// @{ - -/// @file - #pragma once #include +#include +#undef linux + +#include +#include -struct native_dispatch; -union native_platform; +struct linux_platform; -union native_platform* -xegl_platform_create(const struct native_dispatch **dispatch); +struct xegl_platform { + struct wcore_platform wcore; + struct linux_platform *linux; +}; -bool -xegl_platform_destroy(union native_platform *self); +DEFINE_CONTAINER_CAST_FUNC(xegl_platform, + struct xegl_platform, + struct wcore_platform, + wcore) -/// @} +struct wcore_platform* +xegl_platform_create(void); diff --git a/src/waffle/x11_egl/xegl_priv_egl.c b/src/waffle/x11_egl/xegl_priv_egl.c index cd6203d..99d6aea 100644 --- a/src/waffle/x11_egl/xegl_priv_egl.c +++ b/src/waffle/x11_egl/xegl_priv_egl.c @@ -23,12 +23,5 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup xegl_priv_egl -/// @{ - -/// @file - #include "xegl_priv_egl.h" #include - -/// @} diff --git a/src/waffle/x11_egl/xegl_priv_egl.h b/src/waffle/x11_egl/xegl_priv_egl.h index 0e08f3d..5ea4d99 100644 --- a/src/waffle/x11_egl/xegl_priv_egl.h +++ b/src/waffle/x11_egl/xegl_priv_egl.h @@ -23,15 +23,8 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup xegl_priv_egl xegl_priv_egl -/// @ingroup xegl -/// @{ - -/// @file - #pragma once #define NATIVE_EGL(basename) xegl_egl_##basename -#include -/// @} +#include diff --git a/src/waffle/x11_egl/xegl_priv_types.h b/src/waffle/x11_egl/xegl_priv_types.h deleted file mode 100644 index 387eadf..0000000 --- a/src/waffle/x11_egl/xegl_priv_types.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2012 Intel Corporation -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/// @defgroup xegl_priv_types xegl_priv_types -/// @ingroup xegl -/// @{ - -/// @file - -#pragma once - -#include -#include -#include - -struct linux_platform; - -union native_display; -union native_platform; - -struct xegl_platform { - struct linux_platform *linux_; -}; - -struct xegl_display { - union native_platform *platform; - Display *xlib_display; - xcb_connection_t *xcb_connection; - EGLDisplay egl_display; -}; - -struct xegl_config { - union native_display *display; - EGLConfig egl_config; - xcb_visualid_t xcb_visual_id; - - /// The value of @c EGL_RENDER_BUFFER that will be set in the attrib_list - /// of eglCreateWindowSurface(). - EGLint egl_render_buffer; - - int32_t waffle_context_api; -}; - -struct xegl_context { - union native_display *display; - EGLContext egl_context; -}; - -struct xegl_window { - union native_display *display; - xcb_window_t xcb_window; - EGLSurface egl_surface; -}; - -/// @} diff --git a/src/waffle/x11_egl/xegl_window.c b/src/waffle/x11_egl/xegl_window.c index 4c2c977..ec253ca 100644 --- a/src/waffle/x11_egl/xegl_window.c +++ b/src/waffle/x11_egl/xegl_window.c @@ -23,97 +23,100 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @addtogroup xegl_window -/// @{ - -/// @file - -#include "xegl_window.h" - #include #include -#include #include -#include +#include "xegl_config.h" +#include "xegl_display.h" #include "xegl_priv_egl.h" -#include "xegl_priv_types.h" +#include "xegl_window.h" + +static const struct wcore_window_vtbl xegl_window_wcore_vtbl; + +static bool +xegl_window_destroy(struct wcore_window *wc_self) +{ + struct xegl_window *self = xegl_window(wc_self); + struct xegl_display *dpy; + bool ok = true; + + if (!self) + return ok; + + dpy = xegl_display(wc_self->display); + + if (self->egl) + ok &= egl_destroy_surface(dpy->egl, self->egl); + + ok &= x11_window_teardown(&self->x11); + ok &= wcore_window_teardown(&self->wcore); + free(self); + return ok; +} -union native_window* -xegl_window_create( - union native_config *config, - int width, - int height) +struct wcore_window* +xegl_window_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + int width, + int height) { - union native_display *display = config->xegl->display; + struct xegl_window *self; + struct xegl_config *config = xegl_config(wc_config); + struct xegl_display *dpy = xegl_display(wc_config->display); + bool ok = true; - union native_window *self; - NATIVE_ALLOC(self, xegl); + self = calloc(1, sizeof(*self)); if (!self) { wcore_error(WAFFLE_OUT_OF_MEMORY); return NULL; } - self->xegl->display = display; - self->xegl->xcb_window = x11_window_create( - display->xegl->xcb_connection, - config->xegl->xcb_visual_id, - width, - height); - if (!self->xegl->xcb_window) + ok = wcore_window_init(&self->wcore, wc_config); + if (!ok) + goto error; + + ok = x11_window_init(&self->x11, + &dpy->x11, + config->xcb_visual_id, + width, + height); + if (!ok) goto error; - self->xegl->egl_surface = xegl_egl_create_window_surface( - display->xegl->egl_display, - config->xegl->egl_config, - self->xegl->xcb_window, - config->xegl->egl_render_buffer); - if (!self->xegl->egl_surface) - goto error; + self->egl = xegl_egl_create_window_surface(dpy->egl, + config->egl, + self->x11.xcb, + config->egl_render_buffer); + if (!self->egl) + goto error; - return self; + self->wcore.vtbl = &xegl_window_wcore_vtbl; + return &self->wcore; error: - xegl_window_destroy(self); + xegl_window_destroy(&self->wcore); return NULL; } -bool -xegl_window_destroy(union native_window *self) +static bool +xegl_window_show(struct wcore_window *wc_self) { - if (!self) - return true; - - bool ok = true; - union native_display *dpy = self->xegl->display; - - if (self->xegl->egl_surface) - ok &= egl_destroy_surface(dpy->xegl->egl_display, - self->xegl->egl_surface); - if (self->xegl->xcb_window) - ok &= x11_window_destroy(dpy->xegl->xcb_connection, - self->xegl->xcb_window); - - free(self); - return ok; + return x11_window_show(&xegl_window(wc_self)->x11); } -bool -xegl_window_show(union native_window *native_self) +static bool +xegl_window_swap_buffers(struct wcore_window *wc_self) { - struct xegl_window *self = native_self->xegl; - struct xegl_display *display = self->display->xegl; + struct xegl_window *self = xegl_window(wc_self); + struct xegl_display *dpy = xegl_display(wc_self->display); - return x11_window_show(display->xcb_connection, self->xcb_window); -} - - -bool -xegl_window_swap_buffers(union native_window *self) -{ - return egl_swap_buffers(self->xegl->display->xegl->egl_display, - self->xegl->egl_surface); + return egl_swap_buffers(dpy->egl, self->egl); } -/// @} +static const struct wcore_window_vtbl xegl_window_wcore_vtbl = { + .destroy = xegl_window_destroy, + .show = xegl_window_show, + .swap_buffers = xegl_window_swap_buffers, +}; diff --git a/src/waffle/x11_egl/xegl_window.h b/src/waffle/x11_egl/xegl_window.h index 69f7750..26186fd 100644 --- a/src/waffle/x11_egl/xegl_window.h +++ b/src/waffle/x11_egl/xegl_window.h @@ -23,33 +23,31 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -/// @defgroup xegl_window xegl_window -/// @ingroup xegl -/// @{ - -/// @file - #pragma once #include -union native_config; -union native_display; -union native_window; - -union native_window* -xegl_window_create( - union native_config *config, - int width, - int height); - -bool -xegl_window_destroy(union native_window *self); - -bool -xegl_window_show(union native_window *native_self); - -bool -xegl_window_swap_buffers(union native_window *self); - -/// @} +#include +#include + +#include +#include +#include + +struct wcore_platform; + +struct xegl_window { + struct wcore_window wcore; + struct x11_window x11; + EGLSurface egl; +}; + +DEFINE_CONTAINER_CAST_FUNC(xegl_window, + struct xegl_window, + struct wcore_window, + wcore) +struct wcore_window* +xegl_window_create(struct wcore_platform *wc_plat, + struct wcore_config *wc_config, + int width, + int height); -- cgit v1.2.3