PUBLIC Status XvMCSetSubpicturePalette(Display *dpy, XvMCSubpicture *subpicture, unsigned char *palette) { XvMCSubpicturePrivate *subpicture_priv; XvMCContextPrivate *context_priv; struct pipe_context *pipe; struct pipe_box dst_box = {0, 0, 0, 0, 1, 1}; assert(dpy); assert(palette); if (!subpicture) return XvMCBadSubpicture; subpicture_priv = subpicture->privData; context_priv = subpicture_priv->context->privData; pipe = context_priv->pipe; dst_box.width = subpicture->num_palette_entries; upload_sampler(pipe, subpicture_priv->palette, &dst_box, palette, 0, 0, 0); XVMC_MSG(XVMC_TRACE, "[XvMC] Palette of Subpicture %p set.\n", subpicture); return Success; }
PUBLIC Status XvMCCompositeSubpicture(Display *dpy, XvMCSubpicture *subpicture, XvImage *image, short srcx, short srcy, unsigned short width, unsigned short height, short dstx, short dsty) { XvMCSubpicturePrivate *subpicture_priv; XvMCContextPrivate *context_priv; struct pipe_context *pipe; struct pipe_box dst_box = {dstx, dsty, 0, width, height, 1}; unsigned src_stride; XVMC_MSG(XVMC_TRACE, "[XvMC] Compositing subpicture %p.\n", subpicture); assert(dpy); if (!subpicture) return XvMCBadSubpicture; assert(image); 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; pipe = context_priv->pipe; /* clipping should be done by upload_sampler and regardles what the documentation says image->pitches[0] doesn't seems to be in bytes, so don't use it */ src_stride = image->width * util_format_get_blocksize(subpicture_priv->sampler->texture->format); upload_sampler(pipe, subpicture_priv->sampler, &dst_box, image->data, src_stride, srcx, srcy); XVMC_MSG(XVMC_TRACE, "[XvMC] Subpicture %p composited.\n", subpicture); return Success; }
static VAStatus vlVaPutSubpictures(vlVaSurface *surf, vlVaDriver *drv, struct pipe_surface *surf_draw, struct u_rect *dirty_area, struct u_rect *src_rect, struct u_rect *dst_rect) { vlVaSubpicture *sub; int i; if (!(surf->subpics.data || surf->subpics.size)) return VA_STATUS_SUCCESS; for (i = 0; i < surf->subpics.size/sizeof(vlVaSubpicture *); i++) { struct pipe_blend_state blend; void *blend_state; vlVaBuffer *buf; struct pipe_box box; struct u_rect *s, *d, sr, dr, c; int sw, sh, dw, dh; sub = ((vlVaSubpicture **)surf->subpics.data)[i]; if (!sub) continue; buf = handle_table_get(drv->htab, sub->image->buf); if (!buf) return VA_STATUS_ERROR_INVALID_IMAGE; box.x = 0; box.y = 0; box.z = 0; box.width = sub->dst_rect.x1 - sub->dst_rect.x0; box.height = sub->dst_rect.y1 - sub->dst_rect.y0; box.depth = 1; s = &sub->src_rect; d = &sub->dst_rect; sw = s->x1 - s->x0; sh = s->y1 - s->y0; dw = d->x1 - d->x0; dh = d->y1 - d->y0; c.x0 = MAX2(d->x0, s->x0); c.y0 = MAX2(d->y0, s->y0); c.x1 = MIN2(d->x0 + dw, src_rect->x1); c.y1 = MIN2(d->y0 + dh, src_rect->y1); sr.x0 = s->x0 + (c.x0 - d->x0)*(sw/(float)dw); sr.y0 = s->y0 + (c.y0 - d->y0)*(sh/(float)dh); sr.x1 = s->x0 + (c.x1 - d->x0)*(sw/(float)dw); sr.y1 = s->y0 + (c.y1 - d->y0)*(sh/(float)dh); s = src_rect; d = dst_rect; sw = s->x1 - s->x0; sh = s->y1 - s->y0; dw = d->x1 - d->x0; dh = d->y1 - d->y0; dr.x0 = d->x0 + c.x0*(dw/(float)sw); dr.y0 = d->y0 + c.y0*(dh/(float)sh); dr.x1 = d->x0 + c.x1*(dw/(float)sw); dr.y1 = d->y0 + c.y1*(dh/(float)sh); memset(&blend, 0, sizeof(blend)); blend.independent_blend_enable = 0; blend.rt[0].blend_enable = 1; blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO; blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; blend.rt[0].rgb_func = PIPE_BLEND_ADD; blend.rt[0].alpha_func = PIPE_BLEND_ADD; blend.rt[0].colormask = PIPE_MASK_RGBA; blend.logicop_enable = 0; blend.logicop_func = PIPE_LOGICOP_CLEAR; blend.dither = 0; blend_state = drv->pipe->create_blend_state(drv->pipe, &blend); vl_compositor_clear_layers(&drv->cstate); vl_compositor_set_layer_blend(&drv->cstate, 0, blend_state, false); upload_sampler(drv->pipe, sub->sampler, &box, buf->data, sub->image->pitches[0], 0, 0); vl_compositor_set_rgba_layer(&drv->cstate, &drv->compositor, 0, sub->sampler, &sr, NULL, NULL); vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dr); vl_compositor_render(&drv->cstate, &drv->compositor, surf_draw, dirty_area, false); drv->pipe->delete_blend_state(drv->pipe, blend_state); } return VA_STATUS_SUCCESS; }