From 80468464897682b8e10aeab310f20fdd7ddc6cb4 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Fri, 5 Mar 2010 23:26:03 -0500 Subject: [PATCH 1/1] vl: Subpicture/compositing fixes. --- src/gallium/auxiliary/vl/vl_compositor.c | 73 ++++++++++----- .../drivers/softpipe/sp_video_context.c | 52 ++++++++--- src/gallium/include/pipe/p_video_context.h | 10 +++ .../state_trackers/xorg/xvmc/subpicture.c | 88 +++++++++++++++++-- .../state_trackers/xorg/xvmc/surface.c | 23 ++++- .../state_trackers/xorg/xvmc/xvmc_private.h | 49 +++++++---- 6 files changed, 233 insertions(+), 62 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 44b3714dcc3..e6d787b4d74 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -349,7 +349,7 @@ static void gen_rect_verts(unsigned pos, assert(pos < VL_COMPOSITOR_MAX_LAYERS + 2); assert(src_rect); assert(src_inv_size); - assert((dst_rect && dst_inv_size) || (!dst_rect && !dst_inv_size)); + assert((dst_rect && dst_inv_size) /*|| (!dst_rect && !dst_inv_size)*/); assert(vb); vb[pos * 6 + 0].x = dst_rect->x * dst_inv_size->x; @@ -383,39 +383,52 @@ static void gen_rect_verts(unsigned pos, vb[pos * 6 + 5].w = (src_rect->y + src_rect->h) * src_inv_size->y; } -static unsigned gen_verts(struct vl_compositor *c, - struct pipe_video_rect *src_rect, - struct vertex2f *src_inv_size, - struct pipe_video_rect *dst_rect) +static unsigned gen_data(struct vl_compositor *c, + struct pipe_texture *src_surface, + struct pipe_video_rect *src_rect, + struct pipe_video_rect *dst_rect, + struct pipe_texture **textures) { void *vb; unsigned num_rects = 0; unsigned i; assert(c); + assert(src_surface); assert(src_rect); - assert(src_inv_size); assert(dst_rect); + assert(textures); vb = pipe_buffer_map(c->pipe->screen, c->vertex_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD); + if (!vb) + return 0; + if (c->dirty_bg) { struct vertex2f bg_inv_size = {1.0f / c->bg->width0, 1.0f / c->bg->height0}; - gen_rect_verts(num_rects++, &c->bg_src_rect, &bg_inv_size, NULL, NULL, vb); + gen_rect_verts(num_rects, &c->bg_src_rect, &bg_inv_size, NULL, NULL, vb); + textures[num_rects] = c->bg; + ++num_rects; c->dirty_bg = false; } - gen_rect_verts(num_rects++, src_rect, src_inv_size, dst_rect, &c->fb_inv_size, vb); - - for (i = 0; c->dirty_layers > 0; i++) { + struct vertex2f src_inv_size = { 1.0f / src_surface->width0, 1.0f / src_surface->height0}; + gen_rect_verts(num_rects, src_rect, &src_inv_size, dst_rect, &c->fb_inv_size, vb); + textures[num_rects] = src_surface; + ++num_rects; + } + + for (i = 0; c->dirty_layers > 0; i++) { assert(i < VL_COMPOSITOR_MAX_LAYERS); if (c->dirty_layers & (1 << i)) { struct vertex2f layer_inv_size = {1.0f / c->layers[i]->width0, 1.0f / c->layers[i]->height0}; - gen_rect_verts(num_rects++, &c->layer_src_rects[i], &layer_inv_size, + gen_rect_verts(num_rects, &c->layer_src_rects[i], &layer_inv_size, &c->layer_dst_rects[i], &c->fb_inv_size, vb); + textures[num_rects] = c->layers[i]; + ++num_rects; c->dirty_layers &= ~(1 << i); } } @@ -425,6 +438,28 @@ static unsigned gen_verts(struct vl_compositor *c, return num_rects; } +static void draw_layers(struct vl_compositor *c, + struct pipe_texture *src_surface, + struct pipe_video_rect *src_rect, + struct pipe_video_rect *dst_rect) +{ + unsigned num_rects; + struct pipe_texture *textures[VL_COMPOSITOR_MAX_LAYERS + 2]; + unsigned i; + + assert(c); + assert(src_surface); + assert(src_rect); + assert(dst_rect); + + num_rects = gen_data(c, src_surface, src_rect, dst_rect, textures); + + for (i = 0; i < num_rects; ++i) { + c->pipe->set_fragment_sampler_textures(c->pipe, 1, &textures[i]); + c->pipe->draw_arrays(c->pipe, PIPE_PRIM_TRIANGLES, i * 6, 6); + } +} + void vl_compositor_render(struct vl_compositor *compositor, struct pipe_texture *src_surface, enum pipe_mpeg12_picture_type picture_type, @@ -437,8 +472,6 @@ void vl_compositor_render(struct vl_compositor *compositor, struct pipe_video_rect *dst_area, struct pipe_fence_handle **fence) { - unsigned num_rects; - assert(compositor); assert(src_surface); assert(src_area); @@ -459,7 +492,7 @@ void vl_compositor_render(struct vl_compositor *compositor, ( compositor->pipe->screen, dst_surface, - 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE + 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ_WRITE ); compositor->viewport.scale[0] = compositor->fb_state.width; @@ -474,22 +507,15 @@ void vl_compositor_render(struct vl_compositor *compositor, compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state); compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport); compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 1, &compositor->sampler); - compositor->pipe->set_fragment_sampler_textures(compositor->pipe, 1, &src_surface); compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader); compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader); compositor->pipe->set_vertex_buffers(compositor->pipe, 1, &compositor->vertex_buf); compositor->pipe->set_vertex_elements(compositor->pipe, 2, compositor->vertex_elems); compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, &compositor->fs_const_buf); - { - struct vertex2f src_inv_size = {1.0f / src_surface->width0, 1.0f / src_surface->height0}; - num_rects = gen_verts(compositor, src_area, &src_inv_size, dst_area); - } + draw_layers(compositor, src_surface, src_area, dst_area); assert(!compositor->dirty_bg && !compositor->dirty_layers); - assert(num_rects > 0); - - compositor->pipe->draw_arrays(compositor->pipe, PIPE_PRIM_TRIANGLES, 0, num_rects * 6); compositor->pipe->flush(compositor->pipe, PIPE_FLUSH_RENDER_CACHE, fence); pipe_surface_reference(&compositor->fb_state.cbufs[0], NULL); @@ -501,7 +527,8 @@ void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float memcpy ( - pipe_buffer_map(compositor->pipe->screen, compositor->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + pipe_buffer_map(compositor->pipe->screen, compositor->fs_const_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD), mat, sizeof(struct fragment_shader_consts) ); diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index f7231dc3f12..f43b3d63ad3 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -39,7 +39,7 @@ sp_mpeg12_destroy(struct pipe_video_context *vpipe) struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; assert(vpipe); - + /* Asserted in softpipe_delete_fs_state() for some reason */ ctx->pipe->bind_vs_state(ctx->pipe, NULL); ctx->pipe->bind_fs_state(ctx->pipe, NULL); @@ -119,8 +119,6 @@ sp_mpeg12_surface_copy(struct pipe_video_context *vpipe, static void sp_mpeg12_render_picture(struct pipe_video_context *vpipe, - /*struct pipe_surface *backround, - struct pipe_video_rect *backround_area,*/ struct pipe_video_surface *src_surface, enum pipe_mpeg12_picture_type picture_type, /*unsigned num_past_surfaces, @@ -130,24 +128,50 @@ sp_mpeg12_render_picture(struct pipe_video_context *vpipe, struct pipe_video_rect *src_area, struct pipe_surface *dst_surface, struct pipe_video_rect *dst_area, - /*unsigned num_layers, - struct pipe_surface *layers, - struct pipe_video_rect *layer_src_areas, - struct pipe_video_rect *layer_dst_areas*/ struct pipe_fence_handle **fence) { struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; - + assert(vpipe); assert(src_surface); assert(src_area); assert(dst_surface); assert(dst_area); - + vl_compositor_render(&ctx->compositor, softpipe_video_surface(src_surface)->tex, picture_type, src_area, dst_surface->texture, dst_area, fence); } +static void +sp_mpeg12_set_picture_background(struct pipe_video_context *vpipe, + struct pipe_texture *bg, + struct pipe_video_rect *bg_src_rect) +{ + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + + assert(vpipe); + assert(bg); + assert(bg_src_rect); + + vl_compositor_set_background(&ctx->compositor, bg, bg_src_rect); +} + +static void +sp_mpeg12_set_picture_layers(struct pipe_video_context *vpipe, + struct pipe_texture *layers[], + struct pipe_video_rect *src_rects[], + struct pipe_video_rect *dst_rects[], + unsigned num_layers) +{ + struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe; + + assert(vpipe); + assert((layers && src_rects && dst_rects) || + (!layers && !src_rects && !dst_rects)); + + vl_compositor_set_layers(&ctx->compositor, layers, src_rects, dst_rects, num_layers); +} + static void sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe, struct pipe_video_surface *dt) @@ -179,7 +203,7 @@ init_pipe_state(struct sp_mpeg12_context *ctx) unsigned i; assert(ctx); - + rast.flatshade = 1; rast.flatshade_first = 0; rast.light_twoside = 0; @@ -244,7 +268,7 @@ init_pipe_state(struct sp_mpeg12_context *ctx) dsa.alpha.ref_value = 0; ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa); ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); - + return true; } @@ -276,6 +300,8 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile, ctx->base.render_picture = sp_mpeg12_render_picture; ctx->base.surface_fill = sp_mpeg12_surface_fill; ctx->base.surface_copy = sp_mpeg12_surface_copy; + ctx->base.set_picture_background = sp_mpeg12_set_picture_background; + ctx->base.set_picture_layers = sp_mpeg12_set_picture_layers; ctx->base.set_decode_target = sp_mpeg12_set_decode_target; ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix; @@ -288,14 +314,14 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile, FREE(ctx); return NULL; } - + if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) { vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); ctx->pipe->destroy(ctx->pipe); FREE(ctx); return NULL; } - + if (!init_pipe_state(ctx)) { vl_compositor_cleanup(&ctx->compositor); vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h index 9ae595b224e..b3346b219f8 100644 --- a/src/gallium/include/pipe/p_video_context.h +++ b/src/gallium/include/pipe/p_video_context.h @@ -109,6 +109,16 @@ struct pipe_video_context * Parameter-like states (or properties) */ /*@{*/ + void (*set_picture_background)(struct pipe_video_context *vpipe, + struct pipe_texture *bg, + struct pipe_video_rect *bg_src_rect); + + void (*set_picture_layers)(struct pipe_video_context *vpipe, + struct pipe_texture *layers[], + struct pipe_video_rect *src_rects[], + struct pipe_video_rect *dst_rects[], + unsigned num_layers); + void (*set_picture_desc)(struct pipe_video_context *vpipe, const struct pipe_picture_desc *desc); diff --git a/src/gallium/state_trackers/xorg/xvmc/subpicture.c b/src/gallium/state_trackers/xorg/xvmc/subpicture.c index d64d075f330..4f75c73413b 100644 --- a/src/gallium/state_trackers/xorg/xvmc/subpicture.c +++ b/src/gallium/state_trackers/xorg/xvmc/subpicture.c @@ -42,7 +42,7 @@ Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture * unsigned short width, unsigned short height, int xvimage_id) { XvMCContextPrivate *context_priv; - XvMCSubPicturePrivate *subpicture_priv; + XvMCSubpicturePrivate *subpicture_priv; struct pipe_video_context *vpipe; struct pipe_texture template; struct pipe_texture *tex; @@ -67,7 +67,7 @@ Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture * if (xvimage_id != FOURCC_RGB) return BadMatch; - subpicture_priv = CALLOC(1, sizeof(XvMCSubPicturePrivate)); + subpicture_priv = CALLOC(1, sizeof(XvMCSubpicturePrivate)); if (!subpicture_priv) return BadAlloc; @@ -84,12 +84,13 @@ Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture * template.height0 = util_next_power_of_two(height); } template.depth0 = 1; - template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; + template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; subpicture_priv->context = context; tex = vpipe->screen->texture_create(vpipe->screen, &template); subpicture_priv->sfc = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_READ_WRITE); + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ); pipe_texture_reference(&tex, NULL); if (!subpicture_priv->sfc) { @@ -120,8 +121,9 @@ Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture * Status XvMCClearSubpicture(Display *dpy, XvMCSubpicture *subpicture, short x, short y, unsigned short width, unsigned short height, unsigned int color) { - XvMCSubPicturePrivate *subpicture_priv; + XvMCSubpicturePrivate *subpicture_priv; XvMCContextPrivate *context_priv; + assert(dpy); if (!subpicture) @@ -141,6 +143,15 @@ Status XvMCCompositeSubpicture(Display *dpy, XvMCSubpicture *subpicture, XvImage short srcx, short srcy, unsigned short width, unsigned short height, short dstx, short dsty) { + XvMCSubpicturePrivate *subpicture_priv; + XvMCContextPrivate *context_priv; + struct pipe_screen *screen; + struct pipe_transfer *xfer; + unsigned char *src, *dst; + unsigned x, y; + + XVMC_MSG(XVMC_TRACE, "[XvMC] Compositing subpicture %p.\n", subpicture); + assert(dpy); if (!subpicture) @@ -151,14 +162,56 @@ Status XvMCCompositeSubpicture(Display *dpy, XvMCSubpicture *subpicture, XvImage if (subpicture->xvimage_id != image->id) return BadMatch; + /* No planar support for now */ + if (image->num_planes != 1) + return BadMatch; + + subpicture_priv = subpicture->privData; + context_priv = subpicture_priv->context->privData; + screen = context_priv->vctx->vpipe->screen; + /* TODO: Assert rects are within bounds? Or clip? */ + xfer = screen->get_tex_transfer(screen, subpicture_priv->sfc->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, dstx, dsty, width, height); + if (!xfer) + return BadAlloc; + + src = image->data; + dst = screen->transfer_map(screen, xfer); + if (!dst) { + screen->tex_transfer_destroy(xfer); + return BadAlloc; + } + + switch (image->id) + { + case FOURCC_RGB: + assert(subpicture_priv->sfc->format == PIPE_FORMAT_X8R8G8B8_UNORM); + for (y = 0; y < height; ++y) { + for (x = 0; x < width; ++x, src += 3, dst += 4) { + /* TODO: Confirm or fix */ + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + } + } + break; + default: + assert(false); + } + + screen->transfer_unmap(screen, xfer); + screen->tex_transfer_destroy(xfer); + + XVMC_MSG(XVMC_TRACE, "[XvMC] Subpicture %p composited.\n", subpicture); + return Success; } Status XvMCDestroySubpicture(Display *dpy, XvMCSubpicture *subpicture) { - XvMCSubPicturePrivate *subpicture_priv; + XvMCSubpicturePrivate *subpicture_priv; XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying subpicture %p.\n", subpicture); @@ -193,6 +246,11 @@ Status XvMCBlendSubpicture(Display *dpy, XvMCSurface *target_surface, XvMCSubpic short subx, short suby, unsigned short subw, unsigned short subh, short surfx, short surfy, unsigned short surfw, unsigned short surfh) { + XvMCSurfacePrivate *surface_priv; + XvMCSubpicturePrivate *subpicture_priv; + + XVMC_MSG(XVMC_TRACE, "[XvMC] Associating subpicture %p with surface %p.\n", subpicture, target_surface); + assert(dpy); if (!target_surface) @@ -204,7 +262,24 @@ Status XvMCBlendSubpicture(Display *dpy, XvMCSurface *target_surface, XvMCSubpic if (target_surface->context_id != subpicture->context_id) return BadMatch; + /* TODO: Verify against subpicture independent scaling */ + + surface_priv = target_surface->privData; + subpicture_priv = subpicture->privData; + /* TODO: Assert rects are within bounds? Or clip? */ + + surface_priv->subpicture = subpicture; + surface_priv->subx = subx; + surface_priv->suby = suby; + surface_priv->subw = subw; + surface_priv->subh = subh; + surface_priv->surfx = surfx; + surface_priv->surfy = surfy; + surface_priv->surfw = surfw; + surface_priv->surfh = surfh; + subpicture_priv->surface = target_surface; + return Success; } @@ -227,6 +302,7 @@ Status XvMCBlendSubpicture2(Display *dpy, XvMCSurface *source_surface, XvMCSurfa return BadMatch; /* TODO: Assert rects are within bounds? Or clip? */ + return Success; } diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index 79dae3fb8b7..4d6c5246b5e 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -342,6 +342,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, struct pipe_video_context *vpipe; XvMCSurfacePrivate *surface_priv; XvMCContextPrivate *context_priv; + XvMCSubpicturePrivate *subpicture_priv; XvMCContext *context; struct pipe_video_rect src_rect = {srcx, srcy, srcw, srch}; struct pipe_video_rect dst_rect = {destx, desty, destw, desth}; @@ -374,14 +375,34 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, surface_priv = surface->privData; context = surface_priv->context; context_priv = context->privData; + subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL; vpipe = context_priv->vctx->vpipe; if (!CreateOrResizeBackBuffer(context_priv->vctx, width, height, &context_priv->backbuffer)) return BadAlloc; + if (subpicture_priv) { + struct pipe_video_rect src_rect = {surface_priv->subx, surface_priv->suby, surface_priv->subw, surface_priv->subh}; + struct pipe_video_rect dst_rect = {surface_priv->surfx, surface_priv->surfy, surface_priv->surfw, surface_priv->surfh}; + struct pipe_video_rect *src_rects[1] = {&src_rect}; + struct pipe_video_rect *dst_rects[1] = {&dst_rect}; + + XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture); + + assert(subpicture_priv->surface == surface); + vpipe->set_picture_layers(vpipe, &subpicture_priv->sfc->texture, &src_rects, &dst_rects, 1); + + surface_priv->subpicture = NULL; + subpicture_priv->surface = NULL; + } + else + vpipe->set_picture_layers(vpipe, NULL, NULL, NULL, 0); + vpipe->render_picture(vpipe, surface_priv->pipe_vsfc, PictureToPipe(flags), &src_rect, context_priv->backbuffer, &dst_rect, surface_priv->disp_fence); + XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface); + vl_video_bind_drawable(context_priv->vctx, drawable); vpipe->screen->flush_frontbuffer @@ -391,7 +412,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, vpipe->priv ); - XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display.\n", surface); + XVMC_MSG(XVMC_TRACE, "[XvMC] Pushed surface %p to front buffer.\n", surface); return Success; } diff --git a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h index 96fe7a9f5e3..df2a0dcc6f3 100644 --- a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h +++ b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2009 Younes Manton. * All Rights Reserved. - * + * * 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 @@ -10,11 +10,11 @@ * distribute, sub license, 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 NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * 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. - * + * **************************************************************************/ #ifndef xvmc_private_h @@ -41,28 +41,39 @@ struct pipe_fence_handle; typedef struct { - struct vl_context *vctx; - struct pipe_surface *backbuffer; + struct vl_context *vctx; + struct pipe_surface *backbuffer; } XvMCContextPrivate; typedef struct { - struct pipe_video_surface *pipe_vsfc; - struct pipe_fence_handle *render_fence; - struct pipe_fence_handle *disp_fence; - - /* Some XvMC functions take a surface but not a context, - so we keep track of which context each surface belongs to. */ - XvMCContext *context; + struct pipe_video_surface *pipe_vsfc; + struct pipe_fence_handle *render_fence; + struct pipe_fence_handle *disp_fence; + + /* The subpicture associated with this surface, if any. */ + XvMCSubpicture *subpicture; + short subx, suby; + unsigned short subw, subh; + short surfx, surfy; + unsigned short surfw, surfh; + + /* Some XvMC functions take a surface but not a context, + so we keep track of which context each surface belongs to. */ + XvMCContext *context; } XvMCSurfacePrivate; typedef struct { - struct pipe_surface *sfc; - /* Some XvMC functions take a subpicture but not a context, - so we keep track of which context each subpicture belongs to. */ - XvMCContext *context; -} XvMCSubPicturePrivate; + struct pipe_surface *sfc; + + /* The surface this subpicture is currently associated with, if any. */ + XvMCSurface *surface; + + /* Some XvMC functions take a subpicture but not a context, + so we keep track of which context each subpicture belongs to. */ + XvMCContext *context; +} XvMCSubpicturePrivate; #define XVMC_OUT 0 #define XVMC_ERR 1 -- 2.30.2