diff options
author | Christian König <[email protected]> | 2011-05-07 14:11:40 +0200 |
---|---|---|
committer | Christian König <[email protected]> | 2011-05-07 14:11:40 +0200 |
commit | 213b9004a6ee033a16af3dcd187aa68b56c39858 (patch) | |
tree | f577f4dc276f70dad63f102f69f87f4d566186ef /src/gallium/state_trackers | |
parent | 6ad846ee78d9d8ba93dcecdefbf89f2b981333ef (diff) | |
parent | 03615c02d81437cf546609fc6a39c6c73be39360 (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.c | 303 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/wayland/native_shm.c | 174 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/wayland/native_wayland.c | 303 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/wayland/native_wayland.h | 22 | ||||
-rw-r--r-- | src/gallium/state_trackers/wgl/stw_ext_pbuffer.c | 26 | ||||
-rw-r--r-- | src/gallium/state_trackers/wgl/stw_framebuffer.c | 50 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_crtc.c | 23 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_driver.c | 6 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.c | 6 |
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) |