summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorChristian König <[email protected]>2011-05-07 14:11:40 +0200
committerChristian König <[email protected]>2011-05-07 14:11:40 +0200
commit213b9004a6ee033a16af3dcd187aa68b56c39858 (patch)
treef577f4dc276f70dad63f102f69f87f4d566186ef /src/gallium/state_trackers
parent6ad846ee78d9d8ba93dcecdefbf89f2b981333ef (diff)
parent03615c02d81437cf546609fc6a39c6c73be39360 (diff)
Merge remote-tracking branch 'origin/master' into pipe-video
Conflicts: src/gallium/drivers/r600/r600_state.c
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_drm.c303
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_shm.c174
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_wayland.c303
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_wayland.h22
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_pbuffer.c26
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.c50
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c23
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c6
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c6
9 files changed, 634 insertions, 279 deletions
diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c
new file mode 100644
index 00000000000..604720f6e5f
--- /dev/null
+++ b/src/gallium/state_trackers/egl/wayland/native_drm.c
@@ -0,0 +1,303 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.11
+ *
+ * Copyright (C) 2011 Benjamin Franzke <[email protected]>
+ *
+ * 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 "state_tracker/drm_driver.h"
+
+#include "egllog.h"
+#include <errno.h>
+
+#include "native_wayland.h"
+
+/* see get_drm_screen_name */
+#include <radeon_drm.h>
+#include "radeon/drm/radeon_drm_public.h"
+
+#include <wayland-client.h>
+#include "wayland-drm-client-protocol.h"
+#include "wayland-egl-priv.h"
+
+#include <xf86drm.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+struct wayland_drm_display {
+ struct wayland_display base;
+
+ struct native_event_handler *event_handler;
+
+ struct wl_drm *wl_drm;
+ int fd;
+ char *device_name;
+ boolean authenticated;
+};
+
+static INLINE struct wayland_drm_display *
+wayland_drm_display(const struct native_display *ndpy)
+{
+ return (struct wayland_drm_display *) ndpy;
+}
+
+static void
+sync_callback(void *data)
+{
+ int *done = data;
+
+ *done = 1;
+}
+
+static void
+force_roundtrip(struct wl_display *display)
+{
+ int done = 0;
+
+ wl_display_sync_callback(display, sync_callback, &done);
+ wl_display_iterate(display, WL_DISPLAY_WRITABLE);
+ while (!done)
+ wl_display_iterate(display, WL_DISPLAY_READABLE);
+}
+
+static void
+wayland_drm_display_destroy(struct native_display *ndpy)
+{
+ struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy);
+
+ if (drmdpy->fd)
+ close(drmdpy->fd);
+ if (drmdpy->wl_drm)
+ wl_drm_destroy(drmdpy->wl_drm);
+ if (drmdpy->device_name)
+ FREE(drmdpy->device_name);
+ if (drmdpy->base.config)
+ FREE(drmdpy->base.config);
+
+ ndpy_uninit(ndpy);
+
+ FREE(drmdpy);
+}
+
+static struct wl_buffer *
+wayland_create_drm_buffer(struct wayland_display *display,
+ struct wayland_surface *surface,
+ enum native_attachment attachment)
+{
+ struct wayland_drm_display *drmdpy = (struct wayland_drm_display *) display;
+ struct pipe_screen *screen = drmdpy->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);
+
+ wsh.type = DRM_API_HANDLE_TYPE_SHARED;
+ 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_drm_create_buffer(drmdpy->wl_drm, wsh.handle,
+ width, height, wsh.stride, visual);
+}
+
+static const char *
+get_drm_screen_name(int fd, drmVersionPtr version)
+{
+ const char *name = version->name;
+
+ if (name && !strcmp(name, "radeon")) {
+ int chip_id;
+ struct drm_radeon_info info;
+
+ memset(&info, 0, sizeof(info));
+ info.request = RADEON_INFO_DEVICE_ID;
+ info.value = pointer_to_intptr(&chip_id);
+ if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0)
+ return NULL;
+
+ name = is_r3xx(chip_id) ? "r300" : "r600";
+ }
+
+ return name;
+}
+
+static void
+drm_handle_device(void *data, struct wl_drm *drm, const char *device)
+{
+ struct wayland_drm_display *drmdpy = data;
+ drm_magic_t magic;
+
+ drmdpy->device_name = strdup(device);
+ if (!drmdpy->device_name)
+ return;
+
+ drmdpy->fd = open(drmdpy->device_name, O_RDWR);
+ if (drmdpy->fd == -1) {
+ _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
+ drmdpy->device_name, strerror(errno));
+ return;
+ }
+
+ drmGetMagic(drmdpy->fd, &magic);
+ wl_drm_authenticate(drmdpy->wl_drm, magic);
+}
+
+static void
+drm_handle_authenticated(void *data, struct wl_drm *drm)
+{
+ struct wayland_drm_display *drmdpy = data;
+
+ drmdpy->authenticated = true;
+}
+
+static const struct wl_drm_listener drm_listener = {
+ drm_handle_device,
+ drm_handle_authenticated
+};
+
+static boolean
+wayland_drm_display_init_screen(struct native_display *ndpy)
+{
+ struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy);
+ drmVersionPtr version;
+ const char *driver_name;
+ uint32_t id;
+
+ id = wl_display_get_global(drmdpy->base.dpy, "wl_drm", 1);
+ if (id == 0)
+ force_roundtrip(drmdpy->base.dpy);
+ id = wl_display_get_global(drmdpy->base.dpy, "wl_drm", 1);
+ if (id == 0)
+ return FALSE;
+
+ drmdpy->wl_drm = wl_drm_create(drmdpy->base.dpy, id, 1);
+ if (!drmdpy->wl_drm)
+ return FALSE;
+
+ wl_drm_add_listener(drmdpy->wl_drm, &drm_listener, drmdpy);
+ force_roundtrip(drmdpy->base.dpy);
+ if (drmdpy->fd == -1)
+ return FALSE;
+
+ force_roundtrip(drmdpy->base.dpy);
+ if (!drmdpy->authenticated)
+ return FALSE;
+
+ version = drmGetVersion(drmdpy->fd);
+ if (!version) {
+ _eglLog(_EGL_WARNING, "invalid fd %d", drmdpy->fd);
+ return FALSE;
+ }
+
+ /* FIXME: share this with native_drm or egl_dri2 */
+ driver_name = get_drm_screen_name(drmdpy->fd, version);
+
+ drmdpy->base.base.screen =
+ drmdpy->event_handler->new_drm_screen(&drmdpy->base.base,
+ driver_name, drmdpy->fd);
+ drmFreeVersion(version);
+
+ if (!drmdpy->base.base.screen) {
+ _eglLog(_EGL_WARNING, "failed to create DRM screen");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static struct pipe_resource *
+wayland_drm_display_import_buffer(struct native_display *ndpy,
+ const struct pipe_resource *templ,
+ void *buf)
+{
+ return ndpy->screen->resource_from_handle(ndpy->screen,
+ templ, (struct winsys_handle *) buf);
+}
+
+static boolean
+wayland_drm_display_export_buffer(struct native_display *ndpy,
+ struct pipe_resource *res,
+ void *buf)
+{
+ return ndpy->screen->resource_get_handle(ndpy->screen,
+ res, (struct winsys_handle *) buf);
+}
+
+static struct native_display_buffer wayland_drm_display_buffer = {
+ wayland_drm_display_import_buffer,
+ wayland_drm_display_export_buffer
+};
+
+struct wayland_display *
+wayland_create_drm_display(struct wl_display *dpy,
+ struct native_event_handler *event_handler,
+ void *user_data)
+{
+ struct wayland_drm_display *drmdpy;
+
+ drmdpy = CALLOC_STRUCT(wayland_drm_display);
+ if (!drmdpy)
+ return NULL;
+
+ drmdpy->event_handler = event_handler;
+ drmdpy->base.base.user_data = user_data;
+
+ drmdpy->base.dpy = dpy;
+ if (!drmdpy->base.dpy) {
+ wayland_drm_display_destroy(&drmdpy->base.base);
+ return NULL;
+ }
+
+ if (!wayland_drm_display_init_screen(&drmdpy->base.base)) {
+ wayland_drm_display_destroy(&drmdpy->base.base);
+ return NULL;
+ }
+ drmdpy->base.base.destroy = wayland_drm_display_destroy;
+ drmdpy->base.base.buffer = &wayland_drm_display_buffer;
+
+ drmdpy->base.create_buffer = wayland_create_drm_buffer;
+
+ return &drmdpy->base;
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
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 <[email protected]>
+ *
+ * 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 <wayland-client.h>
+#include "wayland-egl-priv.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+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 b9cf8c48f1e..e7ed9d64b7e 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.c
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c
@@ -31,25 +31,10 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "state_tracker/drm_driver.h"
-
#include "egllog.h"
-#include <errno.h>
#include "native_wayland.h"
-/* see get_drm_screen_name */
-#include <radeon_drm.h>
-#include "radeon/drm/radeon_drm_public.h"
-
-#include <wayland-client.h>
-#include "wayland-drm-client-protocol.h"
-#include "wayland-egl-priv.h"
-
-#include <xf86drm.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
static struct native_event_handler *wayland_event_handler;
static void
@@ -113,12 +98,12 @@ wayland_display_get_param(struct native_display *ndpy,
int val;
switch (param) {
- case NATIVE_PARAM_USE_NATIVE_BUFFER:
- case NATIVE_PARAM_PRESERVE_BUFFER:
- case NATIVE_PARAM_MAX_SWAP_INTERVAL:
- default:
- val = 0;
- break;
+ case NATIVE_PARAM_USE_NATIVE_BUFFER:
+ case NATIVE_PARAM_PRESERVE_BUFFER:
+ case NATIVE_PARAM_MAX_SWAP_INTERVAL:
+ default:
+ val = 0;
+ break;
}
return val;
@@ -134,48 +119,6 @@ wayland_display_is_pixmap_supported(struct native_display *ndpy,
return TRUE;
}
-static void
-wayland_display_destroy(struct native_display *ndpy)
-{
- struct wayland_display *display = wayland_display(ndpy);
-
- if (display->fd)
- close(display->fd);
- if (display->wl_drm)
- wl_drm_destroy(display->wl_drm);
- if (display->device_name)
- FREE(display->device_name);
- if (display->config)
- FREE(display->config);
-
- ndpy_uninit(ndpy);
-
- FREE(display);
-}
-
-
-static struct wl_buffer *
-wayland_create_buffer(struct wayland_surface *surface,
- enum native_attachment attachment)
-{
- struct wayland_display *display = surface->display;
- struct pipe_resource *resource;
- struct winsys_handle wsh;
- uint width, height;
-
- resource = resource_surface_get_single_resource(surface->rsurf, attachment);
- resource_surface_get_size(surface->rsurf, &width, &height);
-
- wsh.type = DRM_API_HANDLE_TYPE_SHARED;
- display->base.screen->resource_get_handle(display->base.screen, resource, &wsh);
-
- pipe_resource_reference(&resource, NULL);
-
- return wl_drm_create_buffer(display->wl_drm, wsh.handle,
- width, height,
- wsh.stride, surface->win->visual);
-}
-
static void
wayland_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap)
{
@@ -188,7 +131,7 @@ wayland_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap)
wl_buffer_destroy(egl_pixmap->buffer);
egl_pixmap->buffer = NULL;
}
-
+
egl_pixmap->driver_private = NULL;
egl_pixmap->destroy = NULL;
}
@@ -196,26 +139,16 @@ wayland_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap)
static void
wayland_pixmap_surface_initialize(struct wayland_surface *surface)
{
- struct native_display *ndpy = &surface->display->base;
- struct pipe_resource *resource;
- struct winsys_handle wsh;
+ struct wayland_display *display = wayland_display(&surface->display->base);
const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT;
if (surface->pix->buffer != NULL)
return;
- resource = resource_surface_get_single_resource(surface->rsurf, front_natt);
-
- wsh.type = DRM_API_HANDLE_TYPE_SHARED;
- ndpy->screen->resource_get_handle(ndpy->screen, resource, &wsh);
-
- surface->pix->buffer =
- wl_drm_create_buffer(surface->display->wl_drm, wsh.handle,
- surface->pix->width, surface->pix->height,
- wsh.stride, surface->pix->visual);
-
- surface->pix->destroy = wayland_pixmap_destroy;
- surface->pix->driver_private = resource;
+ surface->pix->buffer = display->create_buffer(display, surface, front_natt);
+ surface->pix->destroy = wayland_pixmap_destroy;
+ surface->pix->driver_private =
+ resource_surface_get_single_resource(surface->rsurf, front_natt);
}
static void
@@ -237,11 +170,11 @@ wayland_window_surface_handle_resize(struct wayland_surface *surface)
struct pipe_resource *front_resource;
const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT;
int i;
-
+
front_resource = resource_surface_get_single_resource(surface->rsurf,
front_natt);
if (resource_surface_set_size(surface->rsurf,
- surface->win->width, surface->win->height)) {
+ surface->win->width, surface->win->height)) {
if (surface->pending_resource)
force_roundtrip(display->dpy);
@@ -328,17 +261,19 @@ wayland_surface_swap_buffers(struct native_surface *nsurf)
if (surface->type == WL_WINDOW_SURFACE) {
resource_surface_swap_buffers(surface->rsurf,
- NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, FALSE);
+ NATIVE_ATTACHMENT_FRONT_LEFT,
+ NATIVE_ATTACHMENT_BACK_LEFT, FALSE);
wayland_buffers_swap(surface->buffer, WL_BUFFER_FRONT, WL_BUFFER_BACK);
if (surface->buffer[WL_BUFFER_FRONT] == NULL)
surface->buffer[WL_BUFFER_FRONT] =
- wayland_create_buffer(surface, NATIVE_ATTACHMENT_FRONT_LEFT);
+ display->create_buffer(display, surface,
+ NATIVE_ATTACHMENT_FRONT_LEFT);
wl_surface_attach(surface->win->surface, surface->buffer[WL_BUFFER_FRONT],
surface->dx, surface->dy);
-
+
resource_surface_get_size(surface->rsurf,
(uint *) &surface->win->attached_width,
(uint *) &surface->win->attached_height);
@@ -348,7 +283,8 @@ wayland_surface_swap_buffers(struct native_surface *nsurf)
surface->sequence_number++;
wayland_event_handler->invalid_surface(&display->base,
- &surface->base, surface->sequence_number);
+ &surface->base,
+ surface->sequence_number);
return TRUE;
}
@@ -408,6 +344,8 @@ wayland_surface_destroy(struct native_surface *nsurf)
FREE(surface);
}
+
+
static struct native_surface *
wayland_create_pixmap_surface(struct native_display *ndpy,
EGLNativePixmapType pix,
@@ -417,6 +355,8 @@ wayland_create_pixmap_surface(struct native_display *ndpy,
struct wayland_surface *surface;
struct wl_egl_pixmap *egl_pixmap = (struct wl_egl_pixmap *) pix;
enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ uint bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT;
surface = CALLOC_STRUCT(wayland_surface);
if (!surface)
@@ -434,15 +374,13 @@ wayland_create_pixmap_surface(struct native_display *ndpy,
surface->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
surface->attachment_mask = (1 << NATIVE_ATTACHMENT_FRONT_LEFT);
-
+
surface->rsurf = resource_surface_create(display->base.screen,
- surface->color_format,
- PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW |
- PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT);
+ surface->color_format, bind);
if (!surface->rsurf) {
- FREE(surface);
- return NULL;
+ FREE(surface);
+ return NULL;
}
resource_surface_set_size(surface->rsurf,
@@ -461,6 +399,7 @@ wayland_create_pixmap_surface(struct native_display *ndpy,
return &surface->base;
}
+
static struct native_surface *
wayland_create_window_surface(struct native_display *ndpy,
EGLNativeWindowType win,
@@ -469,6 +408,8 @@ wayland_create_window_surface(struct native_display *ndpy,
struct wayland_display *display = wayland_display(ndpy);
struct wayland_config *config = wayland_config(nconf);
struct wayland_surface *surface;
+ uint bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT;
surface = CALLOC_STRUCT(wayland_surface);
if (!surface)
@@ -486,16 +427,14 @@ wayland_create_window_surface(struct native_display *ndpy,
surface->buffer[WL_BUFFER_FRONT] = NULL;
surface->buffer[WL_BUFFER_BACK] = NULL;
surface->attachment_mask = (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
- (1 << NATIVE_ATTACHMENT_BACK_LEFT);
+ (1 << NATIVE_ATTACHMENT_BACK_LEFT);
surface->rsurf = resource_surface_create(display->base.screen,
- surface->color_format,
- PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW |
- PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT);
+ surface->color_format, bind);
if (!surface->rsurf) {
- FREE(surface);
- return NULL;
+ FREE(surface);
+ return NULL;
}
surface->base.destroy = wayland_surface_destroy;
@@ -506,178 +445,46 @@ wayland_create_window_surface(struct native_display *ndpy,
return &surface->base;
}
-static const char *
-get_drm_screen_name(int fd, drmVersionPtr version)
-{
- const char *name = version->name;
-
- if (name && !strcmp(name, "radeon")) {
- int chip_id;
- struct drm_radeon_info info;
-
- memset(&info, 0, sizeof(info));
- info.request = RADEON_INFO_DEVICE_ID;
- info.value = pointer_to_intptr(&chip_id);
- if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0)
- return NULL;
-
- name = is_r3xx(chip_id) ? "r300" : "r600";
- }
-
- return name;
-}
-
-static void
-drm_handle_device(void *data, struct wl_drm *drm, const char *device)
-{
- struct wayland_display *display = data;
- drm_magic_t magic;
-
- display->device_name = strdup(device);
- if (!display->device_name)
- return;
-
- display->fd = open(display->device_name, O_RDWR);
- if (display->fd == -1) {
- _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
- display->device_name, strerror(errno));
- return;
- }
-
- drmGetMagic(display->fd, &magic);
- wl_drm_authenticate(display->wl_drm, magic);
-}
-
-static void
-drm_handle_authenticated(void *data, struct wl_drm *drm)
-{
- struct wayland_display *display = data;
-
- display->authenticated = true;
-}
-
-static const struct wl_drm_listener drm_listener = {
- drm_handle_device,
- drm_handle_authenticated
-};
-
-static boolean
-wayland_display_init_screen(struct native_display *ndpy)
-{
- struct wayland_display *display = wayland_display(ndpy);
- drmVersionPtr version;
- const char *driver_name;
- uint32_t id;
-
- id = wl_display_get_global(display->dpy, "wl_drm", 1);
- if (id == 0)
- wl_display_iterate(display->dpy, WL_DISPLAY_READABLE);
- id = wl_display_get_global(display->dpy, "wl_drm", 1);
- if (id == 0)
- return FALSE;
-
- display->wl_drm = wl_drm_create(display->dpy, id, 1);
- if (!display->wl_drm)
- return FALSE;
-
- wl_drm_add_listener(display->wl_drm, &drm_listener, display);
- force_roundtrip(display->dpy);
- if (display->fd == -1)
- return FALSE;
-
- force_roundtrip(display->dpy);
- if (!display->authenticated)
- return FALSE;
-
- version = drmGetVersion(display->fd);
- if (!version) {
- _eglLog(_EGL_WARNING, "invalid fd %d", display->fd);
- return FALSE;
- }
-
- /* FIXME: share this with native_drm or egl_dri2 */
- driver_name = get_drm_screen_name(display->fd, version);
-
- display->base.screen =
- wayland_event_handler->new_drm_screen(&display->base,
- driver_name, display->fd);
- drmFreeVersion(version);
-
- if (!display->base.screen) {
- _eglLog(_EGL_WARNING, "failed to create DRM screen");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
static void
-wayland_set_event_handler(struct native_event_handler *event_handler)
+native_set_event_handler(struct native_event_handler *event_handler)
{
wayland_event_handler = event_handler;
}
-static struct pipe_resource *
-wayland_display_import_buffer(struct native_display *ndpy,
- const struct pipe_resource *templ,
- void *buf)
-{
- return ndpy->screen->resource_from_handle(ndpy->screen,
- templ, (struct winsys_handle *) buf);
-}
-
-static boolean
-wayland_display_export_buffer(struct native_display *ndpy,
- struct pipe_resource *res,
- void *buf)
-{
- return ndpy->screen->resource_get_handle(ndpy->screen,
- res, (struct winsys_handle *) buf);
-}
-
-static struct native_display_buffer wayland_display_buffer = {
- wayland_display_import_buffer,
- wayland_display_export_buffer
-};
-
static struct native_display *
-wayland_display_create(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw, void *user_data)
{
- struct wayland_display *display;
-
- display = CALLOC_STRUCT(wayland_display);
- if (!display)
- return NULL;
-
- display->base.user_data = user_data;
-
- display->dpy = dpy;
- if (!display->dpy) {
- wayland_display_destroy(&display->base);
- return NULL;
+ struct wayland_display *display = NULL;
+
+ 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 (!wayland_display_init_screen(&display->base)) {
- wayland_display_destroy(&display->base);
+ if (!display)
return NULL;
- }
- display->base.destroy = wayland_display_destroy;
display->base.get_param = wayland_display_get_param;
display->base.get_configs = wayland_display_get_configs;
display->base.is_pixmap_supported = wayland_display_is_pixmap_supported;
display->base.create_window_surface = wayland_create_window_surface;
display->base.create_pixmap_surface = wayland_create_pixmap_surface;
- display->base.buffer = &wayland_display_buffer;
return &display->base;
}
static const struct native_platform wayland_platform = {
"wayland", /* name */
- wayland_set_event_handler,
- wayland_display_create
+ native_set_event_handler,
+ native_create_display
};
const struct native_platform *
@@ -685,3 +492,5 @@ native_get_wayland_platform(void)
{
return &wayland_platform;
}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h b/src/gallium/state_trackers/egl/wayland/native_wayland.h
index 14fc9b0fbb2..e69a8f00f82 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.h
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h
@@ -33,17 +33,18 @@
#include "common/native_helper.h"
#include "wayland-egl-priv.h"
-#include "wayland-drm-client-protocol.h"
+
+struct wayland_surface;
struct wayland_display {
struct native_display base;
struct wayland_config *config;
struct wl_display *dpy;
- struct wl_drm *wl_drm;
- int fd;
- char *device_name;
- boolean authenticated;
+
+ struct wl_buffer *(*create_buffer)(struct wayland_display *display,
+ struct wayland_surface *surface,
+ enum native_attachment attachment);
};
enum wayland_buffer_type {
@@ -78,7 +79,7 @@ struct wayland_surface {
};
struct wayland_config {
- struct native_config base;
+ struct native_config base;
};
static INLINE struct wayland_display *
@@ -99,4 +100,13 @@ 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,
+ void *user_data);
+
#endif /* _NATIVE_WAYLAND_H_ */
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
index fb5d5e8b929..424d8daccb3 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
@@ -40,6 +40,30 @@
#include "stw_framebuffer.h"
+#define LARGE_WINDOW_SIZE 60000
+
+
+static LRESULT CALLBACK
+WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ MINMAXINFO *pMMI;
+ switch (uMsg) {
+ case WM_GETMINMAXINFO:
+ // Allow to create a window bigger than the desktop
+ pMMI = (MINMAXINFO *)lParam;
+ pMMI->ptMaxSize.x = LARGE_WINDOW_SIZE;
+ pMMI->ptMaxSize.y = LARGE_WINDOW_SIZE;
+ pMMI->ptMaxTrackSize.x = LARGE_WINDOW_SIZE;
+ pMMI->ptMaxTrackSize.y = LARGE_WINDOW_SIZE;
+ break;
+ default:
+ break;
+ }
+
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+
HPBUFFERARB WINAPI
wglCreatePbufferARB(HDC _hDC,
int iPixelFormat,
@@ -109,7 +133,7 @@ wglCreatePbufferARB(HDC _hDC,
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wc.lpfnWndProc = DefWindowProc;
+ wc.lpfnWndProc = WndProc;
wc.lpszClassName = "wglpbuffer";
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index d8b1440a688..4033365bfbe 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -117,13 +117,26 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb )
RECT window_rect;
POINT client_pos;
+ /*
+ * Sanity checking.
+ */
+
assert(fb->hWnd);
-
- /* Get the client area size. */
- GetClientRect( fb->hWnd, &client_rect );
+ assert(fb->width && fb->height);
+ assert(fb->client_rect.right == fb->client_rect.left + fb->width);
+ assert(fb->client_rect.bottom == fb->client_rect.top + fb->height);
+
+ /*
+ * Get the client area size.
+ */
+
+ if (!GetClientRect(fb->hWnd, &client_rect)) {
+ return;
+ }
+
assert(client_rect.left == 0);
assert(client_rect.top == 0);
- width = client_rect.right - client_rect.left;
+ width = client_rect.right - client_rect.left;
height = client_rect.bottom - client_rect.top;
if (width <= 0 || height <= 0) {
@@ -138,7 +151,7 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb )
return;
}
- if(width != fb->width || height != fb->height) {
+ if (width != fb->width || height != fb->height) {
fb->must_resize = TRUE;
fb->width = width;
fb->height = height;
@@ -146,14 +159,14 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb )
client_pos.x = 0;
client_pos.y = 0;
- ClientToScreen(fb->hWnd, &client_pos);
-
- GetWindowRect(fb->hWnd, &window_rect);
+ if (ClientToScreen(fb->hWnd, &client_pos) &&
+ GetWindowRect(fb->hWnd, &window_rect)) {
+ fb->client_rect.left = client_pos.x - window_rect.left;
+ fb->client_rect.top = client_pos.y - window_rect.top;
+ }
- fb->client_rect.left = client_pos.x - window_rect.left;
- fb->client_rect.top = client_pos.y - window_rect.top;
- fb->client_rect.right = fb->client_rect.left + fb->width;
- fb->client_rect.bottom = fb->client_rect.top + fb->height;
+ fb->client_rect.right = fb->client_rect.left + fb->width;
+ fb->client_rect.bottom = fb->client_rect.top + fb->height;
#if 0
debug_printf("\n");
@@ -253,6 +266,19 @@ stw_framebuffer_create(
fb->refcnt = 1;
+ /*
+ * Windows can be sometimes have zero width and or height, but we ensure
+ * a non-zero framebuffer size at all times.
+ */
+
+ fb->must_resize = TRUE;
+ fb->width = 1;
+ fb->height = 1;
+ fb->client_rect.left = 0;
+ fb->client_rect.top = 0;
+ fb->client_rect.right = fb->client_rect.left + fb->width;
+ fb->client_rect.bottom = fb->client_rect.top + fb->height;
+
stw_framebuffer_get_size(fb);
pipe_mutex_init( fb->mutex );
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index d751ac18704..0499ed1ea0b 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -210,6 +210,9 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
struct pipe_transfer *transfer;
+ struct pipe_fence_handle *fence = NULL;
+ struct pipe_context *ctx = ms->ctx;
+ struct pipe_screen *screen = ms->screen;
if (!crtcp->cursor_tex) {
struct pipe_resource templat;
@@ -218,6 +221,7 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
memset(&templat, 0, sizeof(templat));
templat.bind |= PIPE_BIND_RENDER_TARGET;
templat.bind |= PIPE_BIND_SCANOUT;
+ templat.bind |= PIPE_BIND_CURSOR;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth0 = 1;
@@ -229,23 +233,28 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
memset(&whandle, 0, sizeof(whandle));
whandle.type = DRM_API_HANDLE_TYPE_KMS;
- crtcp->cursor_tex = ms->screen->resource_create(ms->screen,
- &templat);
- ms->screen->resource_get_handle(ms->screen, crtcp->cursor_tex, &whandle);
+ crtcp->cursor_tex = screen->resource_create(screen, &templat);
+ screen->resource_get_handle(screen, crtcp->cursor_tex, &whandle);
crtcp->cursor_handle = whandle.handle;
}
- transfer = pipe_get_transfer(ms->ctx, crtcp->cursor_tex,
+ transfer = pipe_get_transfer(ctx, crtcp->cursor_tex,
0, 0,
PIPE_TRANSFER_WRITE,
0, 0, 64, 64);
- ptr = ms->ctx->transfer_map(ms->ctx, transfer);
+ ptr = ctx->transfer_map(ctx, transfer);
util_copy_rect(ptr, crtcp->cursor_tex->format,
transfer->stride, 0, 0,
64, 64, (void*)image, 64 * 4, 0, 0);
- ms->ctx->transfer_unmap(ms->ctx, transfer);
- ms->ctx->transfer_destroy(ms->ctx, transfer);
+ ctx->transfer_unmap(ctx, transfer);
+ ctx->transfer_destroy(ctx, transfer);
+ ctx->flush(ctx, &fence);
+
+ if (fence) {
+ screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
+ screen->fence_reference(screen, &fence, NULL);
+ }
if (crtc->cursor_shown)
drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id,
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 19e9bf84656..063ae92f6be 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -831,9 +831,9 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#endif
}
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Usefull debugging info follows #\n");
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "#################################\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Useful debugging info follows #\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "#################################\n");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %s backend\n",
ms->screen ? "Gallium3D" : "libkms");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n",
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index e7d6a93e5ca..91c206f1872 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -336,7 +336,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
return FALSE;
if (!exa->pipe)
- XORG_FALLBACK("accle not enabled");
+ XORG_FALLBACK("accel not enabled");
if (!priv || !priv->tex)
XORG_FALLBACK("%s", !priv ? "!priv" : "!priv->tex");
@@ -414,7 +414,7 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
return FALSE;
if (!exa->pipe)
- XORG_FALLBACK("accle not enabled");
+ XORG_FALLBACK("accel not enabled");
if (!priv || !priv->tex)
XORG_FALLBACK("pDst %s", !priv ? "!priv" : "!priv->tex");
@@ -622,7 +622,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
pDstPicture ? render_format_name(pDstPicture->format) : "none");
#endif
if (!exa->pipe)
- XORG_FALLBACK("accle not enabled");
+ XORG_FALLBACK("accel not enabled");
priv = exaGetPixmapDriverPrivate(pDst);
if (!priv || !priv->tex)