backend-drm: make GBM optional
authorStefan Agner <stefan@agner.ch>
Tue, 9 Jul 2019 20:02:00 +0000 (22:02 +0200)
committerStefan Agner <stefan@agner.ch>
Fri, 25 Oct 2019 13:32:07 +0000 (15:32 +0200)
Make GBM optional in case GL renderer is disabled. This allows to
build Weston with DRM backend without Mesa dependencies.

Signed-off-by: Stefan Agner <stefan@agner.ch>
libweston/backend-drm/drm-gbm.c [new file with mode: 0644]
libweston/backend-drm/drm-internal.h
libweston/backend-drm/drm.c
libweston/backend-drm/fb.c
libweston/backend-drm/meson.build
libweston/backend-drm/state-propose.c

diff --git a/libweston/backend-drm/drm-gbm.c b/libweston/backend-drm/drm-gbm.c
new file mode 100644 (file)
index 0000000..5cb07e8
--- /dev/null
@@ -0,0 +1,366 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2011 Intel Corporation
+ * Copyright © 2017, 2018 Collabora, Ltd.
+ * Copyright © 2017, 2018 General Electric Company
+ * Copyright (c) 2018 DisplayLink (UK) Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "drm-internal.h"
+#include "pixman-renderer.h"
+#include "pixel-formats.h"
+#include "renderer-gl/gl-renderer.h"
+#include "shared/weston-egl-ext.h"
+#include "linux-dmabuf.h"
+#include "linux-explicit-synchronization.h"
+
+struct gl_renderer_interface *gl_renderer;
+
+static struct gbm_device *
+create_gbm_device(int fd)
+{
+       struct gbm_device *gbm;
+
+       gl_renderer = weston_load_module("gl-renderer.so",
+                                        "gl_renderer_interface");
+       if (!gl_renderer)
+               return NULL;
+
+       /* GBM will load a dri driver, but even though they need symbols from
+        * libglapi, in some version of Mesa they are not linked to it. Since
+        * only the gl-renderer module links to it, the call above won't make
+        * these symbols globally available, and loading the DRI driver fails.
+        * Workaround this by dlopen()'ing libglapi with RTLD_GLOBAL. */
+       dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
+
+       gbm = gbm_create_device(fd);
+
+       return gbm;
+}
+
+/* When initializing EGL, if the preferred buffer format isn't available
+ * we may be able to substitute an ARGB format for an XRGB one.
+ *
+ * This returns 0 if substitution isn't possible, but 0 might be a
+ * legitimate format for other EGL platforms, so the caller is
+ * responsible for checking for 0 before calling gl_renderer->create().
+ *
+ * This works around https://bugs.freedesktop.org/show_bug.cgi?id=89689
+ * but it's entirely possible we'll see this again on other implementations.
+ */
+static uint32_t
+fallback_format_for(uint32_t format)
+{
+       const struct pixel_format_info *pf;
+
+       pf = pixel_format_get_info_by_opaque_substitute(format);
+       if (!pf)
+               return 0;
+
+       return pf->format;
+}
+
+static int
+drm_backend_create_gl_renderer(struct drm_backend *b)
+{
+       uint32_t format[3] = {
+               b->gbm_format,
+               fallback_format_for(b->gbm_format),
+               0,
+       };
+       unsigned n_formats = 2;
+
+       if (format[1])
+               n_formats = 3;
+       if (gl_renderer->display_create(b->compositor,
+                                       EGL_PLATFORM_GBM_KHR,
+                                       (void *)b->gbm,
+                                       EGL_WINDOW_BIT,
+                                       format,
+                                       n_formats) < 0) {
+               return -1;
+       }
+
+       return 0;
+}
+
+int
+init_egl(struct drm_backend *b)
+{
+       b->gbm = create_gbm_device(b->drm.fd);
+
+       if (!b->gbm)
+               return -1;
+
+       if (drm_backend_create_gl_renderer(b) < 0) {
+               gbm_device_destroy(b->gbm);
+               return -1;
+       }
+
+       return 0;
+}
+
+static void drm_output_fini_cursor_egl(struct drm_output *output)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_LENGTH(output->gbm_cursor_fb); i++) {
+               drm_fb_unref(output->gbm_cursor_fb[i]);
+               output->gbm_cursor_fb[i] = NULL;
+       }
+}
+
+static int
+drm_output_init_cursor_egl(struct drm_output *output, struct drm_backend *b)
+{
+       unsigned int i;
+
+       /* No point creating cursors if we don't have a plane for them. */
+       if (!output->cursor_plane)
+               return 0;
+
+       for (i = 0; i < ARRAY_LENGTH(output->gbm_cursor_fb); i++) {
+               struct gbm_bo *bo;
+
+               bo = gbm_bo_create(b->gbm, b->cursor_width, b->cursor_height,
+                                  GBM_FORMAT_ARGB8888,
+                                  GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
+               if (!bo)
+                       goto err;
+
+               output->gbm_cursor_fb[i] =
+                       drm_fb_get_from_bo(bo, b, false, BUFFER_CURSOR);
+               if (!output->gbm_cursor_fb[i]) {
+                       gbm_bo_destroy(bo);
+                       goto err;
+               }
+               output->gbm_cursor_handle[i] = gbm_bo_get_handle(bo).s32;
+       }
+
+       return 0;
+
+err:
+       weston_log("cursor buffers unavailable, using gl cursors\n");
+       b->cursors_are_broken = 1;
+       drm_output_fini_cursor_egl(output);
+       return -1;
+}
+
+/* Init output state that depends on gl or gbm */
+int
+drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
+{
+       uint32_t format[2] = {
+               output->gbm_format,
+               fallback_format_for(output->gbm_format),
+       };
+       unsigned n_formats = 1;
+       struct weston_mode *mode = output->base.current_mode;
+       struct drm_plane *plane = output->scanout_plane;
+       unsigned int i;
+
+       assert(output->gbm_surface == NULL);
+
+       for (i = 0; i < plane->count_formats; i++) {
+               if (plane->formats[i].format == output->gbm_format)
+                       break;
+       }
+
+       if (i == plane->count_formats) {
+               weston_log("format 0x%x not supported by output %s\n",
+                          output->gbm_format, output->base.name);
+               return -1;
+       }
+
+#ifdef HAVE_GBM_MODIFIERS
+       if (plane->formats[i].count_modifiers > 0) {
+               output->gbm_surface =
+                       gbm_surface_create_with_modifiers(b->gbm,
+                                                         mode->width,
+                                                         mode->height,
+                                                         output->gbm_format,
+                                                         plane->formats[i].modifiers,
+                                                         plane->formats[i].count_modifiers);
+       }
+
+       /* If allocating with modifiers fails, try again without. This can
+        * happen when the KMS display device supports modifiers but the
+        * GBM driver does not, e.g. the old i915 Mesa driver. */
+       if (!output->gbm_surface)
+#endif
+       {
+               output->gbm_surface =
+                   gbm_surface_create(b->gbm, mode->width, mode->height,
+                                      output->gbm_format,
+                                      output->gbm_bo_flags);
+       }
+
+       if (!output->gbm_surface) {
+               weston_log("failed to create gbm surface\n");
+               return -1;
+       }
+
+       if (format[1])
+               n_formats = 2;
+       if (gl_renderer->output_window_create(&output->base,
+                                             (EGLNativeWindowType)output->gbm_surface,
+                                             output->gbm_surface,
+                                             format,
+                                             n_formats) < 0) {
+               weston_log("failed to create gl renderer output state\n");
+               gbm_surface_destroy(output->gbm_surface);
+               output->gbm_surface = NULL;
+               return -1;
+       }
+
+       drm_output_init_cursor_egl(output, b);
+
+       return 0;
+}
+
+void
+drm_output_fini_egl(struct drm_output *output)
+{
+       struct drm_backend *b = to_drm_backend(output->base.compositor);
+
+       /* Destroying the GBM surface will destroy all our GBM buffers,
+        * regardless of refcount. Ensure we destroy them here. */
+       if (!b->shutting_down &&
+           output->scanout_plane->state_cur->fb &&
+           output->scanout_plane->state_cur->fb->type == BUFFER_GBM_SURFACE) {
+               drm_plane_state_free(output->scanout_plane->state_cur, true);
+               output->scanout_plane->state_cur =
+                       drm_plane_state_alloc(NULL, output->scanout_plane);
+               output->scanout_plane->state_cur->complete = true;
+       }
+
+       gl_renderer->output_destroy(&output->base);
+       gbm_surface_destroy(output->gbm_surface);
+       output->gbm_surface = NULL;
+       drm_output_fini_cursor_egl(output);
+}
+
+struct drm_fb *
+drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage)
+{
+       struct drm_output *output = state->output;
+       struct drm_backend *b = to_drm_backend(output->base.compositor);
+       struct gbm_bo *bo;
+       struct drm_fb *ret;
+
+       output->base.compositor->renderer->repaint_output(&output->base,
+                                                         damage);
+
+       bo = gbm_surface_lock_front_buffer(output->gbm_surface);
+       if (!bo) {
+               weston_log("failed to lock front buffer: %s\n",
+                          strerror(errno));
+               return NULL;
+       }
+
+       /* The renderer always produces an opaque image. */
+       ret = drm_fb_get_from_bo(bo, b, true, BUFFER_GBM_SURFACE);
+       if (!ret) {
+               weston_log("failed to get drm_fb for bo\n");
+               gbm_surface_release_buffer(output->gbm_surface, bo);
+               return NULL;
+       }
+       ret->gbm_surface = output->gbm_surface;
+
+       return ret;
+}
+
+static void
+switch_to_gl_renderer(struct drm_backend *b)
+{
+       struct drm_output *output;
+       bool dmabuf_support_inited;
+       bool linux_explicit_sync_inited;
+
+       if (!b->use_pixman)
+               return;
+
+       dmabuf_support_inited = !!b->compositor->renderer->import_dmabuf;
+       linux_explicit_sync_inited =
+               b->compositor->capabilities & WESTON_CAP_EXPLICIT_SYNC;
+
+       weston_log("Switching to GL renderer\n");
+
+       b->gbm = create_gbm_device(b->drm.fd);
+       if (!b->gbm) {
+               weston_log("Failed to create gbm device. "
+                          "Aborting renderer switch\n");
+               return;
+       }
+
+       wl_list_for_each(output, &b->compositor->output_list, base.link)
+               pixman_renderer_output_destroy(&output->base);
+
+       b->compositor->renderer->destroy(b->compositor);
+
+       if (drm_backend_create_gl_renderer(b) < 0) {
+               gbm_device_destroy(b->gbm);
+               weston_log("Failed to create GL renderer. Quitting.\n");
+               /* FIXME: we need a function to shutdown cleanly */
+               assert(0);
+       }
+
+       wl_list_for_each(output, &b->compositor->output_list, base.link)
+               drm_output_init_egl(output, b);
+
+       b->use_pixman = 0;
+
+       if (!dmabuf_support_inited && b->compositor->renderer->import_dmabuf) {
+               if (linux_dmabuf_setup(b->compositor) < 0)
+                       weston_log("Error: initializing dmabuf "
+                                  "support failed.\n");
+       }
+
+       if (!linux_explicit_sync_inited &&
+           (b->compositor->capabilities & WESTON_CAP_EXPLICIT_SYNC)) {
+               if (linux_explicit_synchronization_setup(b->compositor) < 0)
+                       weston_log("Error: initializing explicit "
+                                  " synchronization support failed.\n");
+       }
+}
+
+void
+renderer_switch_binding(struct weston_keyboard *keyboard,
+                       const struct timespec *time, uint32_t key, void *data)
+{
+       struct drm_backend *b =
+               to_drm_backend(keyboard->seat->compositor);
+
+       switch_to_gl_renderer(b);
+}
+
index d43f292ccb0f684cc4be788a700ce903014b9d8a..b55061ab65d7f837f777ac25c3bc77c3dd61a8e1 100644 (file)
@@ -47,7 +47,9 @@
 #include <xf86drmMode.h>
 #include <drm_fourcc.h>
 
+#ifdef BUILD_DRM_GBM
 #include <gbm.h>
+#endif
 #include <libudev.h>
 
 #include <libweston/libweston.h>
@@ -634,9 +636,17 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int height,
 struct drm_fb *
 drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
                   bool is_opaque, enum drm_fb_type type);
-struct drm_fb *
-drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev);
 
+#ifdef BUILD_DRM_GBM
+extern struct drm_fb *
+drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev);
+#else
+static inline struct drm_fb *
+drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev)
+{
+       return NULL;
+}
+#endif
 
 struct drm_pending_state *
 drm_pending_state_alloc(struct drm_backend *backend);
@@ -712,8 +722,51 @@ drm_backend_init_virtual_output_api(struct weston_compositor *compositor)
 }
 #endif
 
+#ifdef BUILD_DRM_GBM
+int
+init_egl(struct drm_backend *b);
+
 int
 drm_output_init_egl(struct drm_output *output, struct drm_backend *b);
+
 void
 drm_output_fini_egl(struct drm_output *output);
 
+struct drm_fb *
+drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage);
+
+void
+renderer_switch_binding(struct weston_keyboard *keyboard,
+                       const struct timespec *time, uint32_t key, void *data);
+#else
+inline static int
+init_egl(struct drm_backend *b)
+{
+       weston_log("Compiled without GBM/EGL support\n");
+       return -1;
+}
+
+inline static int
+drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
+{
+       return -1;
+}
+
+inline static void
+drm_output_fini_egl(struct drm_output *output)
+{
+}
+
+inline static struct drm_fb *
+drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage)
+{
+       return NULL;
+}
+
+inline static void
+renderer_switch_binding(struct weston_keyboard *keyboard,
+                       const struct timespec *time, uint32_t key, void *data)
+{
+       weston_log("Compiled without GBM/EGL support\n");
+}
+#endif
index d37837dc7f0d92beaf89f13724acb558dbd8acb2..878d71ec3d6f797f813bafdc0a7d58d3899cb1ca 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/vt.h>
 #include <assert.h>
 #include <sys/mman.h>
-#include <dlfcn.h>
 #include <time.h>
 
 #include <xf86drm.h>
@@ -56,8 +55,6 @@
 #include "shared/helpers.h"
 #include "shared/timespec-util.h"
 #include "shared/string-helpers.h"
-#include "renderer-gl/gl-renderer.h"
-#include "shared/weston-egl-ext.h"
 #include "pixman-renderer.h"
 #include "pixel-formats.h"
 #include "libbacklight.h"
@@ -69,8 +66,6 @@
 #include "linux-dmabuf-unstable-v1-server-protocol.h"
 #include "linux-explicit-synchronization.h"
 
-struct gl_renderer_interface *gl_renderer;
-
 static const char default_seat[] = "seat0";
 
 static void
@@ -276,37 +271,6 @@ drm_output_update_complete(struct drm_output *output, uint32_t flags,
                weston_output_schedule_repaint(&output->base);
 }
 
-
-static struct drm_fb *
-drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage)
-{
-       struct drm_output *output = state->output;
-       struct drm_backend *b = to_drm_backend(output->base.compositor);
-       struct gbm_bo *bo;
-       struct drm_fb *ret;
-
-       output->base.compositor->renderer->repaint_output(&output->base,
-                                                         damage);
-
-       bo = gbm_surface_lock_front_buffer(output->gbm_surface);
-       if (!bo) {
-               weston_log("failed to lock front buffer: %s\n",
-                          strerror(errno));
-               return NULL;
-       }
-
-       /* The renderer always produces an opaque image. */
-       ret = drm_fb_get_from_bo(bo, b, true, BUFFER_GBM_SURFACE);
-       if (!ret) {
-               weston_log("failed to get drm_fb for bo\n");
-               gbm_surface_release_buffer(output->gbm_surface, bo);
-               return NULL;
-       }
-       ret->gbm_surface = output->gbm_surface;
-
-       return ret;
-}
-
 static struct drm_fb *
 drm_output_render_pixman(struct drm_output_state *state,
                         pixman_region32_t *damage)
@@ -681,97 +645,12 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
        return 0;
 }
 
-static struct gbm_device *
-create_gbm_device(int fd)
-{
-       struct gbm_device *gbm;
-
-       gl_renderer = weston_load_module("gl-renderer.so",
-                                        "gl_renderer_interface");
-       if (!gl_renderer)
-               return NULL;
-
-       /* GBM will load a dri driver, but even though they need symbols from
-        * libglapi, in some version of Mesa they are not linked to it. Since
-        * only the gl-renderer module links to it, the call above won't make
-        * these symbols globally available, and loading the DRI driver fails.
-        * Workaround this by dlopen()'ing libglapi with RTLD_GLOBAL. */
-       dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
-
-       gbm = gbm_create_device(fd);
-
-       return gbm;
-}
-
-/* When initializing EGL, if the preferred buffer format isn't available
- * we may be able to substitute an ARGB format for an XRGB one.
- *
- * This returns 0 if substitution isn't possible, but 0 might be a
- * legitimate format for other EGL platforms, so the caller is
- * responsible for checking for 0 before calling gl_renderer->create().
- *
- * This works around https://bugs.freedesktop.org/show_bug.cgi?id=89689
- * but it's entirely possible we'll see this again on other implementations.
- */
-static uint32_t
-fallback_format_for(uint32_t format)
-{
-       const struct pixel_format_info *pf;
-
-       pf = pixel_format_get_info_by_opaque_substitute(format);
-       if (!pf)
-               return 0;
-
-       return pf->format;
-}
-
-static int
-drm_backend_create_gl_renderer(struct drm_backend *b)
-{
-       uint32_t format[3] = {
-               b->gbm_format,
-               fallback_format_for(b->gbm_format),
-               0,
-       };
-       unsigned n_formats = 2;
-
-       if (format[1])
-               n_formats = 3;
-       if (gl_renderer->display_create(b->compositor,
-                                       EGL_PLATFORM_GBM_KHR,
-                                       (void *)b->gbm,
-                                       EGL_WINDOW_BIT,
-                                       format,
-                                       n_formats) < 0) {
-               return -1;
-       }
-
-       return 0;
-}
-
-static int
-init_egl(struct drm_backend *b)
-{
-       b->gbm = create_gbm_device(b->drm.fd);
-
-       if (!b->gbm)
-               return -1;
-
-       if (drm_backend_create_gl_renderer(b) < 0) {
-               gbm_device_destroy(b->gbm);
-               return -1;
-       }
-
-       return 0;
-}
-
 static int
 init_pixman(struct drm_backend *b)
 {
        return pixman_renderer_init(b->compositor);
 }
 
-
 /**
  * Create a drm_plane for a hardware plane
  *
@@ -1224,146 +1103,6 @@ make_connector_name(const drmModeConnector *con)
        return name;
 }
 
-static void drm_output_fini_cursor_egl(struct drm_output *output)
-{
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_LENGTH(output->gbm_cursor_fb); i++) {
-               drm_fb_unref(output->gbm_cursor_fb[i]);
-               output->gbm_cursor_fb[i] = NULL;
-       }
-}
-
-static int
-drm_output_init_cursor_egl(struct drm_output *output, struct drm_backend *b)
-{
-       unsigned int i;
-
-       /* No point creating cursors if we don't have a plane for them. */
-       if (!output->cursor_plane)
-               return 0;
-
-       for (i = 0; i < ARRAY_LENGTH(output->gbm_cursor_fb); i++) {
-               struct gbm_bo *bo;
-
-               bo = gbm_bo_create(b->gbm, b->cursor_width, b->cursor_height,
-                                  GBM_FORMAT_ARGB8888,
-                                  GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
-               if (!bo)
-                       goto err;
-
-               output->gbm_cursor_fb[i] =
-                       drm_fb_get_from_bo(bo, b, false, BUFFER_CURSOR);
-               if (!output->gbm_cursor_fb[i]) {
-                       gbm_bo_destroy(bo);
-                       goto err;
-               }
-               output->gbm_cursor_handle[i] = gbm_bo_get_handle(bo).s32;
-       }
-
-       return 0;
-
-err:
-       weston_log("cursor buffers unavailable, using gl cursors\n");
-       b->cursors_are_broken = 1;
-       drm_output_fini_cursor_egl(output);
-       return -1;
-}
-
-/* Init output state that depends on gl or gbm */
-int
-drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
-{
-       uint32_t format[2] = {
-               output->gbm_format,
-               fallback_format_for(output->gbm_format),
-       };
-       unsigned n_formats = 1;
-       struct weston_mode *mode = output->base.current_mode;
-       struct drm_plane *plane = output->scanout_plane;
-       unsigned int i;
-
-       assert(output->gbm_surface == NULL);
-
-       for (i = 0; i < plane->count_formats; i++) {
-               if (plane->formats[i].format == output->gbm_format)
-                       break;
-       }
-
-       if (i == plane->count_formats) {
-               weston_log("format 0x%x not supported by output %s\n",
-                          output->gbm_format, output->base.name);
-               return -1;
-       }
-
-#ifdef HAVE_GBM_MODIFIERS
-       if (plane->formats[i].count_modifiers > 0) {
-               output->gbm_surface =
-                       gbm_surface_create_with_modifiers(b->gbm,
-                                                         mode->width,
-                                                         mode->height,
-                                                         output->gbm_format,
-                                                         plane->formats[i].modifiers,
-                                                         plane->formats[i].count_modifiers);
-       }
-
-       /* If allocating with modifiers fails, try again without. This can
-        * happen when the KMS display device supports modifiers but the
-        * GBM driver does not, e.g. the old i915 Mesa driver. */
-       if (!output->gbm_surface)
-#endif
-       {
-               output->gbm_surface =
-                   gbm_surface_create(b->gbm, mode->width, mode->height,
-                                      output->gbm_format,
-                                      output->gbm_bo_flags);
-       }
-
-       if (!output->gbm_surface) {
-               weston_log("failed to create gbm surface\n");
-               return -1;
-       }
-
-       if (format[1])
-               n_formats = 2;
-       if (gl_renderer->output_window_create(&output->base,
-                                             (EGLNativeWindowType)output->gbm_surface,
-                                             output->gbm_surface,
-                                             format,
-                                             n_formats) < 0) {
-               weston_log("failed to create gl renderer output state\n");
-               gbm_surface_destroy(output->gbm_surface);
-               output->gbm_surface = NULL;
-               return -1;
-       }
-
-       drm_output_init_cursor_egl(output, b);
-
-       return 0;
-}
-
-void
-drm_output_fini_egl(struct drm_output *output)
-{
-       struct drm_backend *b = to_drm_backend(output->base.compositor);
-
-       /* Destroying the GBM surface will destroy all our GBM buffers,
-        * regardless of refcount. Ensure we destroy them here. */
-       if (!b->shutting_down &&
-           output->scanout_plane->state_cur->fb &&
-           output->scanout_plane->state_cur->fb->type == BUFFER_GBM_SURFACE) {
-               drm_plane_state_free(output->scanout_plane->state_cur, true);
-               output->scanout_plane->state_cur =
-                       drm_plane_state_alloc(NULL, output->scanout_plane);
-               output->scanout_plane->state_cur->complete = true;
-       }
-
-       gl_renderer->output_destroy(&output->base);
-       gbm_surface_destroy(output->gbm_surface);
-       output->gbm_surface = NULL;
-       drm_output_fini_cursor_egl(output);
-}
-
 static int
 drm_output_init_pixman(struct drm_output *output, struct drm_backend *b)
 {
@@ -2339,7 +2078,9 @@ drm_output_create(struct weston_compositor *compositor, const char *name)
                return NULL;
 
        output->backend = b;
+#ifdef BUILD_DRM_GBM
        output->gbm_bo_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
+#endif
 
        weston_output_init(&output->base, compositor, name);
 
@@ -2587,8 +2328,10 @@ drm_destroy(struct weston_compositor *ec)
        wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
                drm_head_destroy(to_drm_head(base));
 
+#ifdef BUILD_DRM_GBM
        if (b->gbm)
                gbm_device_destroy(b->gbm);
+#endif
 
        udev_monitor_unref(b->udev_monitor);
        udev_unref(b->udev);
@@ -2979,69 +2722,6 @@ recorder_binding(struct weston_keyboard *keyboard, const struct timespec *time,
 }
 #endif
 
-static void
-switch_to_gl_renderer(struct drm_backend *b)
-{
-       struct drm_output *output;
-       bool dmabuf_support_inited;
-       bool linux_explicit_sync_inited;
-
-       if (!b->use_pixman)
-               return;
-
-       dmabuf_support_inited = !!b->compositor->renderer->import_dmabuf;
-       linux_explicit_sync_inited =
-               b->compositor->capabilities & WESTON_CAP_EXPLICIT_SYNC;
-
-       weston_log("Switching to GL renderer\n");
-
-       b->gbm = create_gbm_device(b->drm.fd);
-       if (!b->gbm) {
-               weston_log("Failed to create gbm device. "
-                          "Aborting renderer switch\n");
-               return;
-       }
-
-       wl_list_for_each(output, &b->compositor->output_list, base.link)
-               pixman_renderer_output_destroy(&output->base);
-
-       b->compositor->renderer->destroy(b->compositor);
-
-       if (drm_backend_create_gl_renderer(b) < 0) {
-               gbm_device_destroy(b->gbm);
-               weston_log("Failed to create GL renderer. Quitting.\n");
-               /* FIXME: we need a function to shutdown cleanly */
-               assert(0);
-       }
-
-       wl_list_for_each(output, &b->compositor->output_list, base.link)
-               drm_output_init_egl(output, b);
-
-       b->use_pixman = 0;
-
-       if (!dmabuf_support_inited && b->compositor->renderer->import_dmabuf) {
-               if (linux_dmabuf_setup(b->compositor) < 0)
-                       weston_log("Error: initializing dmabuf "
-                                  "support failed.\n");
-       }
-
-       if (!linux_explicit_sync_inited &&
-           (b->compositor->capabilities & WESTON_CAP_EXPLICIT_SYNC)) {
-               if (linux_explicit_synchronization_setup(b->compositor) < 0)
-                       weston_log("Error: initializing explicit "
-                                  " synchronization support failed.\n");
-       }
-}
-
-static void
-renderer_switch_binding(struct weston_keyboard *keyboard,
-                       const struct timespec *time, uint32_t key, void *data)
-{
-       struct drm_backend *b =
-               to_drm_backend(keyboard->seat->compositor);
-
-       switch_to_gl_renderer(b);
-}
 
 static const struct weston_drm_output_api api = {
        drm_output_set_mode,
@@ -3242,8 +2922,10 @@ err_drm_source:
 err_udev_input:
        udev_input_destroy(&b->input);
 err_sprite:
+#ifdef BUILD_DRM_GBM
        if (b->gbm)
                gbm_device_destroy(b->gbm);
+#endif
        destroy_sprites(b);
 err_udev_dev:
        udev_device_unref(drm_device);
index 58d26ea1311c92a074406b2a6769efecc7e8821f..1eb4a9eb7c8ca44fcffb105dce7158443c70f53a 100644 (file)
@@ -70,16 +70,6 @@ drm_fb_destroy_dumb(struct drm_fb *fb)
        drm_fb_destroy(fb);
 }
 
-static void
-drm_fb_destroy_gbm(struct gbm_bo *bo, void *data)
-{
-       struct drm_fb *fb = data;
-
-       assert(fb->type == BUFFER_GBM_SURFACE || fb->type == BUFFER_CLIENT ||
-              fb->type == BUFFER_CURSOR);
-       drm_fb_destroy(fb);
-}
-
 static int
 drm_fb_addfb(struct drm_backend *b, struct drm_fb *fb)
 {
@@ -211,6 +201,17 @@ drm_fb_ref(struct drm_fb *fb)
        return fb;
 }
 
+#ifdef BUILD_DRM_GBM
+static void
+drm_fb_destroy_gbm(struct gbm_bo *bo, void *data)
+{
+       struct drm_fb *fb = data;
+
+       assert(fb->type == BUFFER_GBM_SURFACE || fb->type == BUFFER_CLIENT ||
+              fb->type == BUFFER_CURSOR);
+       drm_fb_destroy(fb);
+}
+
 static void
 drm_fb_destroy_dmabuf(struct drm_fb *fb)
 {
@@ -450,6 +451,7 @@ drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer *buffer,
        weston_buffer_release_reference(&fb->buffer_release_ref,
                                        buffer_release);
 }
+#endif
 
 void
 drm_fb_unref(struct drm_fb *fb)
@@ -465,6 +467,7 @@ drm_fb_unref(struct drm_fb *fb)
        case BUFFER_PIXMAN_DUMB:
                drm_fb_destroy_dumb(fb);
                break;
+#ifdef BUILD_DRM_GBM
        case BUFFER_CURSOR:
        case BUFFER_CLIENT:
                gbm_bo_destroy(fb->bo);
@@ -475,12 +478,14 @@ drm_fb_unref(struct drm_fb *fb)
        case BUFFER_DMABUF:
                drm_fb_destroy_dmabuf(fb);
                break;
+#endif
        default:
                assert(NULL);
                break;
        }
 }
 
+#ifdef BUILD_DRM_GBM
 struct drm_fb *
 drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev)
 {
@@ -537,3 +542,4 @@ drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev)
                          ev->surface->buffer_release_ref.buffer_release);
        return fb;
 }
+#endif
index ee92f12536c059e0fbfc29439f5247bf64b224cf..ba22196c5f7b56800ae0b2273d7a4fb0bdf2045d 100644 (file)
@@ -41,11 +41,10 @@ deps_drm = [
        dep_backlight
 ]
 
-# XXX: Actually let DRM-backend build without GBM, it really should
-if true # get_option('renderer-gl')
+if get_option('renderer-gl')
        dep_gbm = dependency('gbm', required: false)
        if not dep_gbm.found()
-               error('drm-backend requires gbm which was not found. Or, you can use \'-Dbackend-drm=false\'.')
+               error('drm-backend with GL renderer requires gbm which was not found. Or, you can use \'-Drenderer-gl=false\'.')
        endif
        if dep_gbm.version().version_compare('>= 17.1')
                config_h.set('HAVE_GBM_MODIFIERS', '1')
@@ -54,6 +53,8 @@ if true # get_option('renderer-gl')
                config_h.set('HAVE_GBM_FD_IMPORT', '1')
        endif
        deps_drm += dep_gbm
+       srcs_drm += 'drm-gbm.c'
+       config_h.set('BUILD_DRM_GBM', '1')
 endif
 
 if get_option('backend-drm-screencast-vaapi')
@@ -71,6 +72,9 @@ if get_option('backend-drm-screencast-vaapi')
 endif
 
 if get_option('remoting')
+       if not get_option('renderer-gl')
+               warning('DRM virtual requires renderer-gl.')
+       endif
        srcs_drm += 'drm-virtual.c'
        config_h.set('BUILD_DRM_VIRTUAL', '1')
 endif
index 76522a1709eb8c65cda21a00ba9f343277df228b..6a01f44bd48157a042f4c71dc5420395d79947e8 100644 (file)
@@ -214,6 +214,7 @@ out:
        return state;
 }
 
+#ifdef BUILD_DRM_GBM
 /**
  * Update the image for the current cursor surface
  *
@@ -361,6 +362,14 @@ err:
        drm_plane_state_put_back(plane_state);
        return NULL;
 }
+#else
+static struct drm_plane_state *
+drm_output_prepare_cursor_view(struct drm_output_state *output_state,
+                              struct weston_view *ev)
+{
+       return NULL;
+}
+#endif
 
 static struct drm_plane_state *
 drm_output_prepare_scanout_view(struct drm_output_state *output_state,