From c14c84f383309ee0fdf007c0d3e968c38f3af86e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Sat, 25 Feb 2012 12:26:37 +0100 Subject: [PATCH] vl: move dirty area handling into winsys abstraction MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Fixing uninitialized areas in SwapBuffers mode. Signed-off-by: Christian König --- .../state_trackers/vdpau/presentation.c | 7 ++-- .../state_trackers/vdpau/vdpau_private.h | 1 - src/gallium/state_trackers/xvmc/surface.c | 5 ++- .../state_trackers/xvmc/xvmc_private.h | 3 -- src/gallium/winsys/g3dvl/dri/dri_winsys.c | 33 +++++++++++++++++++ src/gallium/winsys/g3dvl/vl_winsys.h | 3 ++ src/gallium/winsys/g3dvl/xlib/xsp_winsys.c | 14 ++++++-- 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c index e3ad03a2a51..37c5c695e4d 100644 --- a/src/gallium/state_trackers/vdpau/presentation.c +++ b/src/gallium/state_trackers/vdpau/presentation.c @@ -73,8 +73,6 @@ vlVdpPresentationQueueCreate(VdpDevice device, goto no_compositor; } - vl_compositor_reset_dirty_area(&pq->dirty_area); - *presentation_queue = vlAddDataHTAB(pq); if (*presentation_queue == 0) { ret = VDP_STATUS_ERROR; @@ -205,6 +203,7 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue, struct pipe_resource *tex; struct pipe_surface surf_templ, *surf_draw; struct pipe_video_rect src_rect, dst_clip; + struct u_rect *dirty_area; pq = vlGetDataHTAB(presentation_queue); if (!pq) @@ -216,6 +215,8 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue, if (!tex) return VDP_STATUS_INVALID_HANDLE; + dirty_area = vl_screen_get_dirty_area(pq->device->vscreen); + memset(&surf_templ, 0, sizeof(surf_templ)); surf_templ.format = tex->format; surf_templ.usage = PIPE_BIND_RENDER_TARGET; @@ -239,7 +240,7 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue, vl_compositor_clear_layers(&pq->compositor); vl_compositor_set_rgba_layer(&pq->compositor, 0, surf->sampler_view, &src_rect, NULL); - vl_compositor_render(&pq->compositor, surf_draw, NULL, &dst_clip, &pq->dirty_area); + vl_compositor_render(&pq->compositor, surf_draw, NULL, &dst_clip, dirty_area); pipe->screen->flush_frontbuffer ( diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h index e02744ffd41..1645362444e 100644 --- a/src/gallium/state_trackers/vdpau/vdpau_private.h +++ b/src/gallium/state_trackers/vdpau/vdpau_private.h @@ -301,7 +301,6 @@ typedef struct vlVdpDevice *device; Drawable drawable; struct vl_compositor compositor; - struct u_rect dirty_area; } vlVdpPresentationQueue; typedef struct diff --git a/src/gallium/state_trackers/xvmc/surface.c b/src/gallium/state_trackers/xvmc/surface.c index 8fc96072344..c6f6ef593b4 100644 --- a/src/gallium/state_trackers/xvmc/surface.c +++ b/src/gallium/state_trackers/xvmc/surface.c @@ -359,6 +359,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, struct pipe_resource *tex; struct pipe_surface surf_templ, *surf; + struct u_rect *dirty_area; XVMC_MSG(XVMC_TRACE, "[XvMC] Displaying surface %p.\n", surface); @@ -380,6 +381,8 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, compositor = &context_priv->compositor; tex = vl_screen_texture_from_drawable(context_priv->vscreen, drawable); + dirty_area = vl_screen_get_dirty_area(context_priv->vscreen); + memset(&surf_templ, 0, sizeof(surf_templ)); surf_templ.format = tex->format; surf_templ.usage = PIPE_BIND_RENDER_TARGET; @@ -427,7 +430,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, // Workaround for r600g, there seems to be a bug in the fence refcounting code pipe->screen->fence_reference(pipe->screen, &surface_priv->fence, NULL); - vl_compositor_render(compositor, surf, &dst_rect, NULL, &context_priv->dirty_area); + vl_compositor_render(compositor, surf, &dst_rect, NULL, dirty_area); pipe->flush(pipe, &surface_priv->fence); diff --git a/src/gallium/state_trackers/xvmc/xvmc_private.h b/src/gallium/state_trackers/xvmc/xvmc_private.h index 8242be9aea8..4117f5bf689 100644 --- a/src/gallium/state_trackers/xvmc/xvmc_private.h +++ b/src/gallium/state_trackers/xvmc/xvmc_private.h @@ -35,7 +35,6 @@ #include "util/u_debug.h" #include "util/u_math.h" -#include "util/u_rect.h" #include "vl/vl_csc.h" #include "vl/vl_compositor.h" @@ -62,8 +61,6 @@ typedef struct unsigned short subpicture_max_width; unsigned short subpicture_max_height; - struct u_rect dirty_area; - } XvMCContextPrivate; typedef struct diff --git a/src/gallium/winsys/g3dvl/dri/dri_winsys.c b/src/gallium/winsys/g3dvl/dri/dri_winsys.c index 096f068dbb4..c1e4a54bc49 100644 --- a/src/gallium/winsys/g3dvl/dri/dri_winsys.c +++ b/src/gallium/winsys/g3dvl/dri/dri_winsys.c @@ -43,6 +43,7 @@ #include "util/u_hash_table.h" #include "util/u_inlines.h" +#include "vl/vl_compositor.h" #include "vl_winsys.h" struct vl_dri_screen @@ -51,6 +52,12 @@ struct vl_dri_screen xcb_connection_t *conn; xcb_drawable_t drawable; + unsigned width, height; + + bool current_buffer; + uint32_t buffer_names[2]; + struct u_rect dirty_areas[2]; + bool flushed; xcb_dri2_swap_buffers_cookie_t swap_cookie; xcb_dri2_wait_sbc_cookie_t wait_cookie; @@ -79,6 +86,8 @@ vl_dri2_flush_frontbuffer(struct pipe_screen *screen, scrn->swap_cookie = xcb_dri2_swap_buffers_unchecked(scrn->conn, scrn->drawable, 0, 0, 0, 0, 0, 0); scrn->wait_cookie = xcb_dri2_wait_sbc_unchecked(scrn->conn, scrn->drawable, 0, 0); scrn->buffers_cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, scrn->drawable, 1, 1, attachments); + + scrn->current_buffer = !scrn->current_buffer; } static void @@ -113,6 +122,9 @@ vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable) if (scrn->drawable != drawable) { vl_dri2_destroy_drawable(scrn); xcb_dri2_create_drawable(scrn->conn, drawable); + scrn->current_buffer = false; + vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]); + vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]); scrn->drawable = drawable; if (scrn->flushed) { @@ -138,6 +150,17 @@ vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable) assert(reply->count == 1); + if (reply->width != scrn->width || reply->height != scrn->height) { + vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]); + vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]); + scrn->width = reply->width; + scrn->height = reply->height; + + } else if (buffers[0].name != scrn->buffer_names[scrn->current_buffer]) { + vl_compositor_reset_dirty_area(&scrn->dirty_areas[scrn->current_buffer]); + scrn->buffer_names[scrn->current_buffer] = buffers[0].name; + } + memset(&dri2_front_handle, 0, sizeof(dri2_front_handle)); dri2_front_handle.type = DRM_API_HANDLE_TYPE_SHARED; dri2_front_handle.handle = buffers[0].name; @@ -161,6 +184,14 @@ vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable) return tex; } +struct u_rect * +vl_screen_get_dirty_area(struct vl_screen *vscreen) +{ + struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen; + assert(scrn); + return &scrn->dirty_areas[scrn->current_buffer]; +} + void* vl_screen_get_private(struct vl_screen *vscreen) { @@ -234,6 +265,8 @@ vl_screen_create(Display *display, int screen) goto free_screen; scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer; + vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]); + vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]); free(dri2_query); free(connect); diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h index 3e7d771db2f..281a391266d 100644 --- a/src/gallium/winsys/g3dvl/vl_winsys.h +++ b/src/gallium/winsys/g3dvl/vl_winsys.h @@ -48,6 +48,9 @@ void vl_screen_destroy(struct vl_screen *vscreen); struct pipe_resource* vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable); +struct u_rect * +vl_screen_get_dirty_area(struct vl_screen *vscreen); + void* vl_screen_get_private(struct vl_screen *vscreen); diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c index 6cd16bf4647..a4f5326d8c0 100644 --- a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c @@ -34,6 +34,7 @@ #include "state_tracker/xlib_sw_winsys.h" #include "softpipe/sp_public.h" +#include "vl/vl_compositor.h" #include "vl_winsys.h" struct vl_xsp_screen @@ -44,6 +45,7 @@ struct vl_xsp_screen Visual visual; struct xlib_drawable xdraw; struct pipe_resource *tex; + struct u_rect dirty_area; }; struct pipe_resource* @@ -68,8 +70,8 @@ vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable) if (xsp_screen->tex) { if (xsp_screen->tex->width0 == width && xsp_screen->tex->height0 == height) return xsp_screen->tex; - else - pipe_resource_reference(&xsp_screen->tex, NULL); + pipe_resource_reference(&xsp_screen->tex, NULL); + vl_compositor_reset_dirty_area(&xsp_screen->dirty_area); } memset(&templat, 0, sizeof(struct pipe_resource)); @@ -91,6 +93,13 @@ vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable) return xsp_screen->tex; } +struct u_rect * +vl_screen_get_dirty_area(struct vl_screen *vscreen) +{ + struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vscreen; + return &xsp_screen->dirty_area; +} + void* vl_screen_get_private(struct vl_screen *vscreen) { @@ -126,6 +135,7 @@ vl_screen_create(Display *display, int screen) xsp_screen->display = display; xsp_screen->screen = screen; xsp_screen->xdraw.visual = XDefaultVisual(display, screen); + vl_compositor_reset_dirty_area(&xsp_screen->dirty_area); return &xsp_screen->base; } -- 2.30.2