From d72e7f0dd95fdf28cf64c0b5b6d42c16f087008a Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Sat, 23 Apr 2011 14:21:05 +0200 Subject: [PATCH] st/egl: Add wayland shm softpipe support --- .../state_trackers/egl/wayland/native_shm.c | 174 ++++++++++++++++++ .../egl/wayland/native_wayland.c | 16 +- .../egl/wayland/native_wayland.h | 4 + src/gallium/targets/egl/Makefile | 1 + 4 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 src/gallium/state_trackers/egl/wayland/native_shm.c diff --git a/src/gallium/state_trackers/egl/wayland/native_shm.c b/src/gallium/state_trackers/egl/wayland/native_shm.c new file mode 100644 index 00000000000..609fc0cd04a --- /dev/null +++ b/src/gallium/state_trackers/egl/wayland/native_shm.c @@ -0,0 +1,174 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke + * + * 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 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 "util/u_memory.h" +#include "util/u_inlines.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" + +#include "sw/wayland/wayland_sw_winsys.h" + +#include "egllog.h" + +#include "native_wayland.h" + +#include +#include "wayland-egl-priv.h" + +#include +#include +#include + +struct wayland_shm_display { + struct wayland_display base; + + struct native_event_handler *event_handler; + struct wl_shm *wl_shm; +}; + +static INLINE struct wayland_shm_display * +wayland_shm_display(const struct native_display *ndpy) +{ + return (struct wayland_shm_display *) ndpy; +} + + +static void +wayland_shm_display_destroy(struct native_display *ndpy) +{ + struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy); + + if (shmdpy->base.config) + FREE(shmdpy->base.config); + + ndpy_uninit(ndpy); + + FREE(shmdpy); +} + + +static struct wl_buffer * +wayland_create_shm_buffer(struct wayland_display *display, + struct wayland_surface *surface, + enum native_attachment attachment) +{ + struct wayland_shm_display *shmdpy = (struct wayland_shm_display *) display; + struct pipe_screen *screen = shmdpy->base.base.screen; + struct pipe_resource *resource; + struct winsys_handle wsh; + uint width, height; + struct wl_visual *visual; + + resource = resource_surface_get_single_resource(surface->rsurf, attachment); + resource_surface_get_size(surface->rsurf, &width, &height); + + screen->resource_get_handle(screen, resource, &wsh); + + pipe_resource_reference(&resource, NULL); + + switch (surface->type) { + case WL_WINDOW_SURFACE: + visual = surface->win->visual; + break; + case WL_PIXMAP_SURFACE: + visual = surface->pix->visual; + break; + default: + return NULL; + } + + return wl_shm_create_buffer(shmdpy->wl_shm, wsh.fd, + width, height, + wsh.stride, visual); +} + +static boolean +wayland_shm_display_init_screen(struct native_display *ndpy) +{ + struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy); + struct sw_winsys *winsys = NULL; + uint32_t id; + + id = wl_display_get_global(shmdpy->base.dpy, "wl_shm", 1); + if (id == 0) + wl_display_iterate(shmdpy->base.dpy, WL_DISPLAY_READABLE); + id = wl_display_get_global(shmdpy->base.dpy, "wl_shm", 1); + if (id == 0) + return FALSE; + + shmdpy->wl_shm = wl_shm_create(shmdpy->base.dpy, id, 1); + if (!shmdpy->wl_shm) + return FALSE; + + winsys = wayland_create_sw_winsys(shmdpy->base.dpy); + if (!winsys) + return FALSE; + + shmdpy->base.base.screen = + shmdpy->event_handler->new_sw_screen(&shmdpy->base.base, winsys); + + if (!shmdpy->base.base.screen) { + _eglLog(_EGL_WARNING, "failed to create shm screen"); + return FALSE; + } + + return TRUE; +} + +struct wayland_display * +wayland_create_shm_display(struct wl_display *dpy, + struct native_event_handler *event_handler, + void *user_data) +{ + struct wayland_shm_display *shmdpy; + + shmdpy = CALLOC_STRUCT(wayland_shm_display); + if (!shmdpy) + return NULL; + + shmdpy->event_handler = event_handler; + shmdpy->base.base.user_data = user_data; + + shmdpy->base.dpy = dpy; + if (!shmdpy->base.dpy) { + wayland_shm_display_destroy(&shmdpy->base.base); + return NULL; + } + + if (!wayland_shm_display_init_screen(&shmdpy->base.base)) { + wayland_shm_display_destroy(&shmdpy->base.base); + return NULL; + } + + shmdpy->base.base.destroy = wayland_shm_display_destroy; + shmdpy->base.create_buffer = wayland_create_shm_buffer; + + return &shmdpy->base; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c index a684025d6b3..e7ed9d64b7e 100644 --- a/src/gallium/state_trackers/egl/wayland/native_wayland.c +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c @@ -456,9 +456,19 @@ native_create_display(void *dpy, boolean use_sw, void *user_data) { struct wayland_display *display = NULL; - display = wayland_create_drm_display((struct wl_display *) dpy, - wayland_event_handler, - user_data); + use_sw = use_sw || debug_get_bool_option("EGL_SOFTWARE", FALSE); + + if (use_sw) { + _eglLog(_EGL_INFO, "use software fallback"); + display = wayland_create_shm_display((struct wl_display *) dpy, + wayland_event_handler, + user_data); + } else { + display = wayland_create_drm_display((struct wl_display *) dpy, + wayland_event_handler, + user_data); + } + if (!display) return NULL; diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h b/src/gallium/state_trackers/egl/wayland/native_wayland.h index 5c034421f3d..e69a8f00f82 100644 --- a/src/gallium/state_trackers/egl/wayland/native_wayland.h +++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h @@ -100,6 +100,10 @@ wayland_config(const struct native_config *nconf) return (struct wayland_config *) nconf; } +struct wayland_display * +wayland_create_shm_display(struct wl_display *display, + struct native_event_handler *event_handler, + void *user_data); struct wayland_display * wayland_create_drm_display(struct wl_display *display, struct native_event_handler *event_handler, diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile index de01939e5f1..9d76a706122 100644 --- a/src/gallium/targets/egl/Makefile +++ b/src/gallium/targets/egl/Makefile @@ -48,6 +48,7 @@ egl_LIBS += $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a endif ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) egl_SYS += $(WAYLAND_LIBS) $(LIBDRM_LIB) +egl_LIBS += $(TOP)/src/gallium/winsys/sw/wayland/libws_wayland.a endif ifneq ($(findstring drm, $(EGL_PLATFORMS)),) egl_SYS += $(LIBDRM_LIB) -- 2.30.2