diff options
author | Chad Versace <chad.versace@linux.intel.com> | 2012-05-31 21:57:40 -0700 |
---|---|---|
committer | Chad Versace <chad.versace@linux.intel.com> | 2012-06-03 16:29:43 -0700 |
commit | 602fc904b0b15d4841c7a40a27d50351e9147296 (patch) | |
tree | 1a6379a2302dc156462b2d4ffb778dee1c350b9b /src/waffle/x11_egl/xegl_platform.c | |
parent | 50b0bca22427bf2890ac07cee2b61cfa4fcd8240 (diff) | |
download | waffle-602fc904b0b15d4841c7a40a27d50351e9147296.tar.gz |
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 <chad.versace@linux.intel.com>
Diffstat (limited to 'src/waffle/x11_egl/xegl_platform.c')
-rw-r--r-- | src/waffle/x11_egl/xegl_platform.c | 128 |
1 files changed, 77 insertions, 51 deletions
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 <dlfcn.h> #include <stdlib.h> -#include <waffle/native.h> -#include <waffle/waffle_enum.h> #include <waffle/core/wcore_error.h> #include <waffle/linux/linux_platform.h> #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, +}; |