[waffle] [PATCH v2 3/4] gbm: initial functional gbm support

Jordan Justen jordan.l.justen at intel.com
Mon Aug 13 17:11:45 PDT 2012


src/waffle/gbm is based on src/waffle/wayland, and then heavily
modified.

Tested as functional with: examples/gl_basic gbm gl|gles2

Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
---
 CMakeLists.txt                   |   23 ++++-
 include/waffle/waffle_config.h   |    2 +
 include/waffle/waffle_enum.h     |    1 +
 src/waffle/CMakeLists.txt        |   16 ++++
 src/waffle/api/waffle_init.c     |    8 ++
 src/waffle/gbm/gbm_config.c      |  109 +++++++++++++++++++++++
 src/waffle/gbm/gbm_config.h      |   58 ++++++++++++
 src/waffle/gbm/gbm_context.c     |  114 ++++++++++++++++++++++++
 src/waffle/gbm/gbm_context.h     |   51 +++++++++++
 src/waffle/gbm/gbm_display.c     |  181 ++++++++++++++++++++++++++++++++++++++
 src/waffle/gbm/gbm_display.h     |   59 +++++++++++++
 src/waffle/gbm/gbm_platform.c    |  137 +++++++++++++++++++++++++++++
 src/waffle/gbm/gbm_platform.h    |   49 +++++++++++
 src/waffle/gbm/gbm_priv_egl.c    |   29 ++++++
 src/waffle/gbm/gbm_priv_egl.h    |   30 +++++++
 src/waffle/gbm/gbm_window.c      |  144 ++++++++++++++++++++++++++++++
 src/waffle/gbm/gbm_window.h      |   53 +++++++++++
 tests/functional/gl_basic_test.c |   52 +++++++++++
 18 files changed, 1113 insertions(+), 3 deletions(-)
 create mode 100644 src/waffle/gbm/gbm_config.c
 create mode 100644 src/waffle/gbm/gbm_config.h
 create mode 100644 src/waffle/gbm/gbm_context.c
 create mode 100644 src/waffle/gbm/gbm_context.h
 create mode 100644 src/waffle/gbm/gbm_display.c
 create mode 100644 src/waffle/gbm/gbm_display.h
 create mode 100644 src/waffle/gbm/gbm_platform.c
 create mode 100644 src/waffle/gbm/gbm_platform.h
 create mode 100644 src/waffle/gbm/gbm_priv_egl.c
 create mode 100644 src/waffle/gbm/gbm_priv_egl.h
 create mode 100644 src/waffle/gbm/gbm_window.c
 create mode 100644 src/waffle/gbm/gbm_window.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a4a48cb..a5d573e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -62,6 +62,7 @@ set(waffle_build_examples "Build examples" ON)
 option(waffle_has_glx "Build support for GLX" OFF)
 option(waffle_has_wayland "Build support for Wayland" OFF)
 option(waffle_has_x11_egl "Build support for X11/EGL" OFF)
+option(waffle_has_gbm "Build support for GBM" OFF)
 
 set(waffle_install_includedir "${CMAKE_INSTALL_PREFIX}/include"
     CACHE PATH "Directory where header files will be installed")
@@ -81,7 +82,7 @@ set(waffle_install_docdir "${CMAKE_INSTALL_PREFIX}/share/doc/waffle"
 #     waffle_tls_model_initial_exec
 check_thread_local_storage()
 
-if(waffle_has_wayland OR waffle_has_x11_egl)
+if(waffle_has_wayland OR waffle_has_x11_egl OR waffle_has_gbm)
     set(waffle_has_egl TRUE)
 else(waffle_has_wayland OR waffle_has_x11_egl)
     set(waffle_has_egl FALSE)
@@ -98,8 +99,12 @@ endif()
 # ----------------------------------------------
 
 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
-    if(NOT waffle_has_glx AND NOT waffle_has_wayland AND NOT waffle_has_x11_egl)
-        message(FATAL_ERROR "Must enable at least one of: waffle_has_glx, waffle_has_wayland, waffle_has_x11_egl.")
+    if(NOT waffle_has_glx AND NOT waffle_has_wayland AND
+       NOT waffle_has_x11_egl AND NOT waffle_has_gbm)
+        message(FATAL_ERROR
+                "Must enable at least one of: "
+                "waffle_has_glx, waffle_has_wayland, "
+                "waffle_has_x11_egl, waffle_has_gbm.")
     endif()
 elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
     if(waffle_has_glx)
@@ -153,6 +158,11 @@ if(waffle_has_x11)
     waffle_find_library(waffle_X11-xcb_library X11-xcb)
 endif()
 
+if(waffle_has_gbm)
+    waffle_find_library(waffle_GL_library GL)
+    waffle_find_library(waffle_udev_library udev)
+endif()
+
 
 # ------------------------------------------------------------------------------
 # Compiler Flags
@@ -197,6 +207,10 @@ if(waffle_has_x11_egl)
     add_definitions(-DWAFFLE_HAS_X11_EGL)
 endif()
 
+if(waffle_has_gbm)
+    add_definitions(-DWAFFLE_HAS_GBM)
+endif()
+
 # ------------------------------------------------------------------------------
 # Add subdirectories
 # ------------------------------------------------------------------------------
@@ -258,6 +272,9 @@ endif()
 if(waffle_has_x11_egl)
     message("    x11_egl")
 endif()
+if(waffle_has_gbm)
+    message("    gbm")
+endif()
 message("")
 message("Libraries:")
 if(DEFINED waffle_EGL_library)
diff --git a/include/waffle/waffle_config.h b/include/waffle/waffle_config.h
index 279522f..72a04fe 100644
--- a/include/waffle/waffle_config.h
+++ b/include/waffle/waffle_config.h
@@ -45,6 +45,7 @@ struct waffle_display;
 
 struct waffle_android_config;
 struct waffle_cgl_config;
+struct waffle_gbm_config;
 struct waffle_glx_config;
 struct waffle_x11_egl_config;
 struct waffle_wayland_config;
@@ -52,6 +53,7 @@ struct waffle_wayland_config;
 union waffle_native_config {
     struct waffle_android_config *android;
     struct waffle_cgl_config *cgl;
+    struct waffle_gbm_config *gbm;
     struct waffle_glx_config *glx;
     struct waffle_x11_egl_config *x11_egl;
     struct waffle_wayland_config *wayland;
diff --git a/include/waffle/waffle_enum.h b/include/waffle/waffle_enum.h
index b8fc17a..ffcc42f 100644
--- a/include/waffle/waffle_enum.h
+++ b/include/waffle/waffle_enum.h
@@ -70,6 +70,7 @@ enum waffle_enum {
         WAFFLE_PLATFORM_GLX                                     = 0x0013,
         WAFFLE_PLATFORM_WAYLAND                                 = 0x0014,
         WAFFLE_PLATFORM_X11_EGL                                 = 0x0015,
+        WAFFLE_PLATFORM_GBM                                     = 0x0016,
 
     // ------------------------------------------------------------------
     // For waffle_config_choose()
diff --git a/src/waffle/CMakeLists.txt b/src/waffle/CMakeLists.txt
index 3117198..2e609f4 100644
--- a/src/waffle/CMakeLists.txt
+++ b/src/waffle/CMakeLists.txt
@@ -111,6 +111,22 @@ if(waffle_has_x11_egl)
     )
 endif()
 
+if(waffle_has_gbm)
+    list(APPEND waffle_sources
+        gbm/gbm_config.c
+        gbm/gbm_context.c
+        gbm/gbm_display.c
+        gbm/gbm_platform.c
+        gbm/gbm_priv_egl.c
+        gbm/gbm_window.c
+    )
+    list(APPEND waffle_libdeps
+        ${waffle_gbm-client_library}
+        ${waffle_gbm-egl_library}
+        ${waffle_udev_library}
+        )
+endif()
+
 # CMake will pass to the C compiler only C sources. CMake does not recognize the
 # .m extension and ignores any such files in the source lists. To coerce CMake
 # to pass .m files to the compiler, we must lie and claim that they are
diff --git a/src/waffle/api/waffle_init.c b/src/waffle/api/waffle_init.c
index c70e8e9..d51be43 100644
--- a/src/waffle/api/waffle_init.c
+++ b/src/waffle/api/waffle_init.c
@@ -41,6 +41,7 @@ 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);
+struct wcore_platform* gbm_platform_create(void);
 
 static bool
 waffle_init_parse_attrib_list(
@@ -72,6 +73,9 @@ waffle_init_parse_attrib_list(
 #ifdef WAFFLE_HAS_X11_EGL
                     case WAFFLE_PLATFORM_X11_EGL:
 #endif
+#ifdef WAFFLE_HAS_GBM
+                    case WAFFLE_PLATFORM_GBM:
+#endif
                         found_platform = true;
                         *platform = value;
                         break;
@@ -124,6 +128,10 @@ waffle_init_create_platform(int32_t waffle_platform)
         case WAFFLE_PLATFORM_X11_EGL:
             return xegl_platform_create();
 #endif
+#ifdef WAFFLE_HAS_GBM
+        case WAFFLE_PLATFORM_GBM:
+            return gbm_platform_create();
+#endif
         default:
             assert(false);
             return NULL;
diff --git a/src/waffle/gbm/gbm_config.c b/src/waffle/gbm/gbm_config.c
new file mode 100644
index 0000000..3fd2801
--- /dev/null
+++ b/src/waffle/gbm/gbm_config.c
@@ -0,0 +1,109 @@
+// 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.
+
+#define __GBM__ 1
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <waffle/core/wcore_config_attrs.h>
+#include <waffle/core/wcore_error.h>
+
+#include "gbm_config.h"
+#include "gbm_display.h"
+#include "gbm_platform.h"
+#include "gbm_priv_egl.h"
+
+static const struct wcore_config_vtbl gbm_config_wcore_vtbl;
+
+static bool
+gbm_config_destroy(struct wcore_config *wc_self)
+{
+    struct gbm_config *self = gbm_config(wc_self);
+    bool ok = true;
+
+    if (!self)
+        return ok;
+
+    ok &= wcore_config_teardown(wc_self);
+    free(self);
+    return ok;
+}
+
+struct wcore_config*
+gbm_config_choose(struct wcore_platform *wc_plat,
+                   struct wcore_display *wc_dpy,
+                   const struct wcore_config_attrs *attrs)
+{
+    struct gbm_config *self;
+    struct gbm_display *dpy = gbm_display(wc_dpy);
+    bool ok = true;
+
+    self = wcore_calloc(sizeof(*self));
+    if (self == NULL)
+        return NULL;
+
+    ok = wcore_config_init(&self->wcore, wc_dpy);
+    if (!ok)
+        goto error;
+
+    ok = egl_get_render_buffer_attrib(attrs, &self->egl_render_buffer);
+    if (!ok)
+        goto error;
+
+    self->egl = egl_choose_config(wc_plat, dpy->egl, attrs);
+    if (!self->egl)
+        goto error;
+
+    self->waffle_context_api = attrs->context_api;
+    self->wcore.vtbl = &gbm_config_wcore_vtbl;
+    return &self->wcore;
+
+error:
+    gbm_config_destroy(&self->wcore);
+    return NULL;
+}
+
+static union waffle_native_config*
+gbm_config_get_native(struct wcore_config *wc_self)
+{
+    struct gbm_config *self = gbm_config(wc_self);
+    struct gbm_display *dpy = gbm_display(wc_self->display);
+    struct waffle_gbm_config *n_config;
+
+    n_config = wcore_malloc(sizeof(*n_config));
+    if (n_config == NULL)
+        return NULL;
+
+    gbm_display_fill_native(dpy, &n_config->display);
+    n_config->egl_config = self->egl;
+
+    return (union waffle_native_config*) n_config;
+}
+
+static const struct wcore_config_vtbl gbm_config_wcore_vtbl = {
+    .destroy = gbm_config_destroy,
+    .get_native = gbm_config_get_native,
+};
diff --git a/src/waffle/gbm/gbm_config.h b/src/waffle/gbm/gbm_config.h
new file mode 100644
index 0000000..6db9df9
--- /dev/null
+++ b/src/waffle/gbm/gbm_config.h
@@ -0,0 +1,58 @@
+// 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 <stdbool.h>
+#include <stdint.h>
+
+#include <EGL/egl.h>
+
+#include <waffle/core/wcore_config.h>
+#include <waffle/core/wcore_util.h>
+
+struct wcore_config_attrs;
+struct wcore_platform;
+
+struct gbm_config {
+    struct wcore_config wcore;
+
+    EGLConfig egl;
+    int32_t waffle_context_api;
+
+    /// The value of @c EGL_RENDER_BUFFER that will be set in the attrib_list
+    /// of eglCreateWindowSurface().
+    EGLint egl_render_buffer;
+};
+
+DEFINE_CONTAINER_CAST_FUNC(gbm_config,
+                           struct gbm_config,
+                           struct wcore_config,
+                           wcore)
+
+struct wcore_config*
+gbm_config_choose(struct wcore_platform *wc_plat,
+                      struct wcore_display *wc_dpy,
+                      const struct wcore_config_attrs *attrs);
diff --git a/src/waffle/gbm/gbm_context.c b/src/waffle/gbm/gbm_context.c
new file mode 100644
index 0000000..f0c06f4
--- /dev/null
+++ b/src/waffle/gbm/gbm_context.c
@@ -0,0 +1,114 @@
+// 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.
+
+#define __GBM__ 1
+
+#include <stdlib.h>
+
+#include <waffle/core/wcore_config.h>
+#include <waffle/core/wcore_error.h>
+
+#include "gbm_config.h"
+#include "gbm_context.h"
+#include "gbm_display.h"
+#include "gbm_priv_egl.h"
+
+static const struct wcore_context_vtbl gbm_context_wcore_vtbl;
+
+static bool
+gbm_context_destroy(struct wcore_context *wc_self)
+{
+    struct gbm_context *self = gbm_context(wc_self);
+    bool ok = true;
+
+    if (!self)
+        return ok;
+
+    if (self->egl)
+        ok &= egl_destroy_context(gbm_display(wc_self->display)->egl,
+                                  self->egl);
+
+    ok &= wcore_context_teardown(wc_self);
+    free(self);
+    return ok;
+}
+
+struct wcore_context*
+gbm_context_create(struct wcore_platform *wc_plat,
+                    struct wcore_config *wc_config,
+                    struct wcore_context *wc_share_ctx)
+{
+    struct gbm_context *self;
+    struct gbm_config *config = gbm_config(wc_config);
+    struct gbm_context *share_ctx = gbm_context(wc_share_ctx);
+    struct gbm_display *dpy = gbm_display(wc_config->display);
+    bool ok = true;
+
+    self = wcore_calloc(sizeof(*self));
+    if (self == NULL)
+        return NULL;
+
+    ok = wcore_context_init(&self->wcore, wc_config);
+    if (!ok)
+        goto error;
+
+    self->egl = egl_create_context(dpy->egl,
+                                   config->egl,
+                                   share_ctx
+                                      ? share_ctx->egl
+                                      : NULL,
+                                   config->waffle_context_api);
+    if (!self->egl)
+        goto error;
+
+    self->wcore.vtbl = &gbm_context_wcore_vtbl;
+    return &self->wcore;
+
+error:
+    gbm_context_destroy(&self->wcore);
+    return NULL;
+}
+
+static union waffle_native_context*
+gbm_context_get_native(struct wcore_context *wc_self)
+{
+    struct gbm_context *self = gbm_context(wc_self);
+    struct gbm_display *dpy = gbm_display(wc_self->display);
+    struct waffle_gbm_context *n_ctx;
+
+    n_ctx = wcore_malloc(sizeof(*n_ctx));
+    if (n_ctx == NULL)
+        return NULL;
+
+    gbm_display_fill_native(dpy, &n_ctx->display);
+    n_ctx->egl_context = self->egl;
+
+    return (union waffle_native_context*) n_ctx;
+}
+
+static const struct wcore_context_vtbl gbm_context_wcore_vtbl = {
+    .destroy = gbm_context_destroy,
+    .get_native = gbm_context_get_native,
+};
diff --git a/src/waffle/gbm/gbm_context.h b/src/waffle/gbm/gbm_context.h
new file mode 100644
index 0000000..80b05ce
--- /dev/null
+++ b/src/waffle/gbm/gbm_context.h
@@ -0,0 +1,51 @@
+// 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 <stdbool.h>
+
+#include <EGL/egl.h>
+
+#include <waffle/core/wcore_context.h>
+#include <waffle/core/wcore_util.h>
+
+struct wcore_config;
+struct wcore_platform;
+
+struct gbm_context {
+    struct wcore_context wcore;
+    EGLContext egl;
+};
+
+DEFINE_CONTAINER_CAST_FUNC(gbm_context,
+                           struct gbm_context,
+                           struct wcore_context,
+                           wcore)
+
+struct wcore_context*
+gbm_context_create(struct wcore_platform *wc_plat,
+                       struct wcore_config *wc_config,
+                       struct wcore_context *wc_share_ctx);
diff --git a/src/waffle/gbm/gbm_display.c b/src/waffle/gbm/gbm_display.c
new file mode 100644
index 0000000..e45aaab
--- /dev/null
+++ b/src/waffle/gbm/gbm_display.c
@@ -0,0 +1,181 @@
+// 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.
+
+#define __GBM__ 1
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <gbm.h>
+#include <libudev.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <linux/input.h>
+
+#include <waffle/core/wcore_error.h>
+#include <waffle/core/wcore_display.h>
+
+#include "gbm_display.h"
+#include "gbm_platform.h"
+#include "gbm_priv_egl.h"
+
+static const struct wcore_display_vtbl gbm_display_wcore_vtbl;
+
+static bool
+gbm_display_destroy(struct wcore_display *wc_self)
+{
+    struct gbm_display *self = gbm_display(wc_self);
+    bool ok = true;
+
+    if (!self)
+        return ok;
+
+    if (self->egl)
+        ok &= egl_terminate(self->egl);
+
+    if (self->gbm_device)
+        gbm_device_destroy(self->gbm_device);
+
+    ok &= wcore_display_teardown(&self->wcore);
+    free(self);
+    return ok;
+}
+
+static int
+gbm_get_fd(void)
+{
+    struct udev *ud;
+    struct udev_enumerate *en;
+    struct udev_list_entry *entry;
+    const char *path, *filename;
+    struct udev_device *device;
+    int fd;
+
+    ud = udev_new();
+    en = udev_enumerate_new(ud);
+    udev_enumerate_add_match_subsystem(en, "drm");
+    udev_enumerate_add_match_sysname(en, "card[0-9]*");
+    udev_enumerate_scan_devices(en);
+
+    udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(en)) {
+        path = udev_list_entry_get_name(entry);
+        device = udev_device_new_from_syspath(ud, path);
+        filename = udev_device_get_devnode(device);
+        fd = open(filename, O_RDWR | O_CLOEXEC);
+        udev_device_unref(device);
+        if (fd >= 0) {
+            return fd;
+        }
+    }
+
+    return -1;
+}
+
+struct wcore_display*
+gbm_display_connect(struct wcore_platform *wc_plat,
+                    const char *name)
+{
+    struct gbm_display *self;
+    bool ok = true;
+    int fd;
+
+    self = wcore_calloc(sizeof(*self));
+    if (self == NULL)
+        return NULL;
+
+    ok = wcore_display_init(&self->wcore, wc_plat);
+    if (!ok)
+        goto error;
+
+    if (name != NULL) {
+        fd = open(name, O_RDWR | O_CLOEXEC);
+    } else {
+        fd = gbm_get_fd();
+    }
+
+    if (fd < 0) {
+        wcore_errorf(WAFFLE_ERROR_UNKNOWN, "open drm file for gbm failed");
+        goto error;
+    }
+
+    self->gbm_device = gbm_create_device(fd);
+    if (!self->gbm_device) {
+        wcore_errorf(WAFFLE_ERROR_UNKNOWN, "gbm_create_device failed");
+        goto error;
+    }
+
+    self->egl = gbm_egl_initialize(self->gbm_device);
+    if (!self->egl) {
+        wcore_errorf(WAFFLE_ERROR_UNKNOWN, "gbm_egl_initialize failed");
+        goto error;
+    }
+
+    self->wcore.vtbl = &gbm_display_wcore_vtbl;
+    return &self->wcore;
+
+error:
+    gbm_display_destroy(&self->wcore);
+    return NULL;
+}
+
+
+static bool
+gbm_display_supports_context_api(struct wcore_display *wc_self,
+                                     int32_t waffle_context_api)
+{
+    return egl_supports_context_api(wc_self->platform, waffle_context_api);
+}
+
+void
+gbm_display_fill_native(struct gbm_display *self,
+                            struct waffle_gbm_display *n_dpy)
+{
+    n_dpy->gbm_device = self->gbm_device;
+    n_dpy->egl_display = self->egl;
+}
+
+static union waffle_native_display*
+gbm_display_get_native(struct wcore_display *wc_self)
+{
+    struct gbm_display *self = gbm_display(wc_self);
+    struct waffle_gbm_display *n_dpy;
+
+    n_dpy = wcore_malloc(sizeof(*n_dpy));
+    if (n_dpy == NULL)
+        return NULL;
+
+    gbm_display_fill_native(self, n_dpy);
+
+    return (union waffle_native_display*) n_dpy;
+}
+
+static const struct wcore_display_vtbl gbm_display_wcore_vtbl = {
+    .destroy = gbm_display_destroy,
+    .get_native = gbm_display_get_native,
+    .supports_context_api = gbm_display_supports_context_api,
+};
diff --git a/src/waffle/gbm/gbm_display.h b/src/waffle/gbm/gbm_display.h
new file mode 100644
index 0000000..05eb054
--- /dev/null
+++ b/src/waffle/gbm/gbm_display.h
@@ -0,0 +1,59 @@
+// 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 <stdbool.h>
+#include <stdint.h>
+
+#include <EGL/egl.h>
+
+#include <waffle/core/wcore_display.h>
+#include <waffle/core/wcore_util.h>
+#include <waffle/native/waffle_gbm.h>
+
+struct wcore_platform;
+struct gbm_device;
+
+struct gbm_display {
+    struct wcore_display wcore;
+
+    struct gbm_device *gbm_device;
+
+    EGLDisplay egl;
+};
+
+DEFINE_CONTAINER_CAST_FUNC(gbm_display,
+                           struct gbm_display,
+                           struct wcore_display,
+                           wcore)
+
+struct wcore_display*
+gbm_display_connect(struct wcore_platform *wc_plat,
+                        const char *name);
+
+void
+gbm_display_fill_native(struct gbm_display *self,
+                            struct waffle_gbm_display *n_dpy);
diff --git a/src/waffle/gbm/gbm_platform.c b/src/waffle/gbm/gbm_platform.c
new file mode 100644
index 0000000..1c3f955
--- /dev/null
+++ b/src/waffle/gbm/gbm_platform.c
@@ -0,0 +1,137 @@
+// 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.
+
+#define __GBM__ 1
+#define _POSIX_C_SOURCE 200112 // glib feature macro for unsetenv()
+
+#include <stdlib.h>
+
+#include <waffle/core/wcore_error.h>
+#include <waffle/linux/linux_platform.h>
+
+#include "gbm_config.h"
+#include "gbm_context.h"
+#include "gbm_display.h"
+#include "gbm_platform.h"
+#include "gbm_priv_egl.h"
+#include "gbm_window.h"
+
+static const struct wcore_platform_vtbl gbm_platform_wcore_vtbl;
+
+static bool
+gbm_platform_destroy(struct wcore_platform *wc_self)
+{
+    struct gbm_platform *self = gbm_platform(wc_self);
+    bool ok = true;
+
+    if (!self)
+        return true;
+
+    unsetenv("EGL_PLATFORM");
+    unsetenv("EGL_DRIVER");
+
+    if (self->linux)
+        ok &= linux_platform_destroy(self->linux);
+
+    ok &= wcore_platform_teardown(wc_self);
+    free(self);
+    return ok;
+}
+
+struct wcore_platform*
+gbm_platform_create(void)
+{
+    struct gbm_platform *self;
+    bool ok = true;
+
+    self = wcore_calloc(sizeof(*self));
+    if (self == NULL)
+        return NULL;
+
+    ok = wcore_platform_init(&self->wcore);
+    if (!ok)
+        goto error;
+
+    self->linux = linux_platform_create();
+    if (!self->linux)
+        goto error;
+
+    setenv("EGL_PLATFORM", "drm", true);
+
+    self->wcore.vtbl = &gbm_platform_wcore_vtbl;
+    return &self->wcore;
+
+error:
+    gbm_platform_destroy(&self->wcore);
+    return NULL;
+}
+
+static bool
+gbm_platform_make_current(struct wcore_platform *wc_self,
+                              struct wcore_display *wc_dpy,
+                              struct wcore_window *wc_window,
+                              struct wcore_context *wc_ctx)
+{
+    return egl_make_current(gbm_display(wc_dpy)->egl,
+                            wc_window ? gbm_window(wc_window)->egl : NULL,
+                            wc_ctx ? gbm_context(wc_ctx)->egl : NULL);
+}
+
+static void*
+gbm_platform_get_proc_address(struct wcore_platform *wc_self,
+                                  const char *name)
+{
+    return eglGetProcAddress(name);
+}
+
+static bool
+gbm_platform_dl_can_open(struct wcore_platform *wc_self,
+                             int32_t waffle_dl)
+{
+    return linux_platform_dl_can_open(gbm_platform(wc_self)->linux,
+                                      waffle_dl);
+}
+
+static void*
+gbm_platform_dl_sym(struct wcore_platform *wc_self,
+                        int32_t waffle_dl,
+                        const char *name)
+{
+    return linux_platform_dl_sym(gbm_platform(wc_self)->linux,
+                                                  waffle_dl,
+                                                  name);
+}
+
+static const struct wcore_platform_vtbl gbm_platform_wcore_vtbl = {
+    .destroy = gbm_platform_destroy,
+    .connect_to_display = gbm_display_connect,
+    .choose_config = gbm_config_choose,
+    .create_context = gbm_context_create,
+    .create_window = gbm_window_create,
+    .make_current = gbm_platform_make_current,
+    .get_proc_address = gbm_platform_get_proc_address,
+    .dl_can_open = gbm_platform_dl_can_open,
+    .dl_sym = gbm_platform_dl_sym,
+};
diff --git a/src/waffle/gbm/gbm_platform.h b/src/waffle/gbm/gbm_platform.h
new file mode 100644
index 0000000..fe4a257
--- /dev/null
+++ b/src/waffle/gbm/gbm_platform.h
@@ -0,0 +1,49 @@
+// 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 <stdbool.h>
+#include <stdlib.h>
+
+#undef linux
+
+#include <waffle/core/wcore_platform.h>
+#include <waffle/core/wcore_util.h>
+
+struct linux_platform;
+
+struct gbm_platform {
+    struct wcore_platform wcore;
+    struct linux_platform *linux;
+};
+
+DEFINE_CONTAINER_CAST_FUNC(gbm_platform,
+                           struct gbm_platform,
+                           struct wcore_platform,
+                           wcore)
+
+struct wcore_platform*
+gbm_platform_create(void);
diff --git a/src/waffle/gbm/gbm_priv_egl.c b/src/waffle/gbm/gbm_priv_egl.c
new file mode 100644
index 0000000..536f00d
--- /dev/null
+++ b/src/waffle/gbm/gbm_priv_egl.c
@@ -0,0 +1,29 @@
+// 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.
+
+#define __GBM__ 1
+
+#include "gbm_priv_egl.h"
+#include <waffle/egl/egl_native_template.c>
diff --git a/src/waffle/gbm/gbm_priv_egl.h b/src/waffle/gbm/gbm_priv_egl.h
new file mode 100644
index 0000000..f129d6c
--- /dev/null
+++ b/src/waffle/gbm/gbm_priv_egl.h
@@ -0,0 +1,30 @@
+// 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
+
+#define NATIVE_EGL(basename) gbm_egl_##basename
+
+#include <waffle/egl/egl.h>
diff --git a/src/waffle/gbm/gbm_window.c b/src/waffle/gbm/gbm_window.c
new file mode 100644
index 0000000..f73bef0
--- /dev/null
+++ b/src/waffle/gbm/gbm_window.c
@@ -0,0 +1,144 @@
+// 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.
+
+#define __GBM__ 1
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <gbm.h>
+
+#include <waffle/core/wcore_error.h>
+#include <waffle/native/waffle_gbm.h>
+
+#include "gbm_config.h"
+#include "gbm_display.h"
+#include "gbm_priv_egl.h"
+#include "gbm_window.h"
+
+static const struct wcore_window_vtbl gbm_window_wcore_vtbl;
+
+static bool
+gbm_window_destroy(struct wcore_window *wc_self)
+{
+    struct gbm_window *self = gbm_window(wc_self);
+    struct gbm_display *dpy;
+    bool ok = true;
+
+    if (!self)
+        return ok;
+
+    dpy = gbm_display(wc_self->display);
+
+    if (self->egl)
+        ok &= egl_destroy_surface(dpy->egl, self->egl);
+
+    ok &= wcore_window_teardown(wc_self);
+    free(self);
+    return ok;
+}
+
+struct wcore_window*
+gbm_window_create(struct wcore_platform *wc_plat,
+                  struct wcore_config *wc_config,
+                  int width,
+                  int height)
+{
+    struct gbm_window *self;
+    struct gbm_config *config = gbm_config(wc_config);
+    struct gbm_display *dpy = gbm_display(wc_config->display);
+    bool ok = true;
+
+    self = wcore_calloc(sizeof(*self));
+    if (self == NULL)
+        return NULL;
+
+    ok = wcore_window_init(&self->wcore, wc_config);
+    if (!ok)
+        goto error;
+
+    self->gbm_surface = gbm_surface_create(dpy->gbm_device, width, height,
+                                           GBM_FORMAT_XRGB8888,
+                                           GBM_BO_USE_RENDERING);
+    if (!self->gbm_surface) {
+        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
+                     "gbm_surface_create failed");
+        goto error;
+    }
+
+    self->egl = gbm_egl_create_window_surface(dpy->egl,
+                                              config->egl,
+                                              self->gbm_surface,
+                                              config->egl_render_buffer);
+    if (!self->egl)
+        goto error;
+
+    self->wcore.vtbl = &gbm_window_wcore_vtbl;
+    return &self->wcore;
+
+error:
+    gbm_window_destroy(&self->wcore);
+    return NULL;
+}
+
+
+static bool
+gbm_window_show(struct wcore_window *wc_self)
+{
+    return true;
+}
+
+static bool
+gbm_window_swap_buffers(struct wcore_window *wc_self)
+{
+    struct gbm_window *self = gbm_window(wc_self);
+    struct gbm_display *dpy = gbm_display(wc_self->display);
+
+    return egl_swap_buffers(dpy->egl, self->egl);
+}
+
+static union waffle_native_window*
+gbm_window_get_native(struct wcore_window *wc_self)
+{
+    struct gbm_window *self = gbm_window(wc_self);
+    struct gbm_display *dpy = gbm_display(wc_self->display);
+    struct waffle_gbm_window *n_window;
+
+    n_window = wcore_malloc(sizeof(*n_window));
+    if (n_window == NULL)
+        return NULL;
+
+    gbm_display_fill_native(dpy, &n_window->display);
+    n_window->egl_surface = self->egl;
+
+    return (union waffle_native_window*) n_window;
+}
+
+static const struct wcore_window_vtbl gbm_window_wcore_vtbl = {
+    .destroy = gbm_window_destroy,
+    .get_native = gbm_window_get_native,
+    .show = gbm_window_show,
+    .swap_buffers = gbm_window_swap_buffers,
+};
diff --git a/src/waffle/gbm/gbm_window.h b/src/waffle/gbm/gbm_window.h
new file mode 100644
index 0000000..1f11db1
--- /dev/null
+++ b/src/waffle/gbm/gbm_window.h
@@ -0,0 +1,53 @@
+// 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 <stdbool.h>
+
+#include <EGL/egl.h>
+
+#include <waffle/core/wcore_window.h>
+#include <waffle/core/wcore_util.h>
+
+struct wcore_platform;
+
+struct gbm_window {
+    struct wcore_window wcore;
+
+    struct gbm_surface *gbm_surface;
+
+    EGLSurface egl;
+};
+
+DEFINE_CONTAINER_CAST_FUNC(gbm_window,
+                           struct gbm_window,
+                           struct wcore_window,
+                           wcore)
+struct wcore_window*
+gbm_window_create(struct wcore_platform *wc_plat,
+                      struct wcore_config *wc_config,
+                      int width,
+                      int height);
diff --git a/tests/functional/gl_basic_test.c b/tests/functional/gl_basic_test.c
index b90ecad..50f1d16 100644
--- a/tests/functional/gl_basic_test.c
+++ b/tests/functional/gl_basic_test.c
@@ -425,6 +425,55 @@ testsuite_x11_egl(void)
 }
 #endif // WAFFLE_HAS_X11_EGL
 
+#ifdef WAFFLE_HAS_GBM
+TEST(gl_basic, gbm_init)
+{
+    gl_basic_init(WAFFLE_PLATFORM_GBM);
+}
+
+TEST(gl_basic, gbm_gl_rgb)
+{
+    gl_basic_draw(WAFFLE_CONTEXT_OPENGL, 0);
+}
+
+TEST(gl_basic, gbm_gles1_rgb)
+{
+    gl_basic_draw(WAFFLE_CONTEXT_OPENGL_ES1, 0);
+}
+
+TEST(gl_basic, gbm_gles2_rgb)
+{
+    gl_basic_draw(WAFFLE_CONTEXT_OPENGL_ES2, 0);
+}
+
+TEST(gl_basic, gbm_gl_rgba)
+{
+    gl_basic_draw(WAFFLE_CONTEXT_OPENGL, 1);
+}
+
+TEST(gl_basic, gbm_gles1_rgba)
+{
+    gl_basic_draw(WAFFLE_CONTEXT_OPENGL_ES1, 1);
+}
+
+TEST(gl_basic, gbm_gles2_rgba)
+{
+    gl_basic_draw(WAFFLE_CONTEXT_OPENGL_ES2, 1);
+}
+
+static void
+testsuite_gbm(void)
+{
+    TEST_RUN(gl_basic, gbm_init);
+    TEST_RUN(gl_basic, gbm_gl_rgb);
+    TEST_RUN(gl_basic, gbm_gles1_rgb);
+    TEST_RUN(gl_basic, gbm_gles2_rgb);
+    TEST_RUN(gl_basic, gbm_gl_rgba);
+    TEST_RUN(gl_basic, gbm_gles1_rgba);
+    TEST_RUN(gl_basic, gbm_gles2_rgba);
+}
+#endif // WAFFLE_HAS_GBM
+
 
 static void
 usage_error(void)
@@ -497,6 +546,9 @@ main(int argc, char *argv[])
 #ifdef WAFFLE_HAS_X11_EGL
     run_testsuite(testsuite_x11_egl);
 #endif
+#ifdef WAFFLE_HAS_GBM
+    run_testsuite(testsuite_gbm);
+#endif
 
    return 0;
 }
-- 
1.7.9.5



More information about the waffle mailing list