mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-20 15:38:19 +02:00
vl: Subpicture/compositing fixes.
This commit is contained in:
parent
8580b7a0ee
commit
8046846489
6 changed files with 233 additions and 62 deletions
|
|
@ -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)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue