vl/compositor: split shaders and state
Signed-off-by: Christian König <deathsimple@vodafone.de>
This commit is contained in:
parent
834f515988
commit
32c4381d4a
|
@ -386,11 +386,6 @@ init_pipe_state(struct vl_compositor *c)
|
|||
c->fb_state.nr_cbufs = 1;
|
||||
c->fb_state.zsbuf = NULL;
|
||||
|
||||
c->viewport.scale[2] = 1;
|
||||
c->viewport.scale[3] = 1;
|
||||
c->viewport.translate[2] = 0;
|
||||
c->viewport.translate[3] = 0;
|
||||
|
||||
memset(&sampler, 0, sizeof(sampler));
|
||||
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
|
@ -521,19 +516,6 @@ init_buffers(struct vl_compositor *c)
|
|||
vertex_elems[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
c->vertex_elems_state = c->pipe->create_vertex_elements_state(c->pipe, 2, vertex_elems);
|
||||
|
||||
/*
|
||||
* Create our fragment shader's constant buffer
|
||||
* Const buffer contains the color conversion matrix and bias vectors
|
||||
*/
|
||||
/* XXX: Create with IMMUTABLE/STATIC... although it does change every once in a long while... */
|
||||
c->csc_matrix = pipe_buffer_create
|
||||
(
|
||||
c->pipe->screen,
|
||||
PIPE_BIND_CONSTANT_BUFFER,
|
||||
PIPE_USAGE_STATIC,
|
||||
sizeof(csc_matrix)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -544,7 +526,6 @@ cleanup_buffers(struct vl_compositor *c)
|
|||
|
||||
c->pipe->delete_vertex_elements_state(c->pipe, c->vertex_elems_state);
|
||||
pipe_resource_reference(&c->vertex_buf.buffer, NULL);
|
||||
pipe_resource_reference(&c->csc_matrix, NULL);
|
||||
}
|
||||
|
||||
static INLINE struct pipe_video_rect
|
||||
|
@ -614,26 +595,26 @@ gen_rect_verts(struct vertex2f *vb, struct vl_compositor_layer *layer)
|
|||
}
|
||||
|
||||
static INLINE struct u_rect
|
||||
calc_drawn_area(struct vl_compositor *c, struct vl_compositor_layer *layer)
|
||||
calc_drawn_area(struct vl_compositor_state *s, struct vl_compositor_layer *layer)
|
||||
{
|
||||
struct u_rect result;
|
||||
|
||||
// scale
|
||||
result.x0 = layer->dst.tl.x * c->viewport.scale[0] + c->viewport.translate[0];
|
||||
result.y0 = layer->dst.tl.y * c->viewport.scale[1] + c->viewport.translate[1];
|
||||
result.x1 = layer->dst.br.x * c->viewport.scale[0] + c->viewport.translate[0];
|
||||
result.y1 = layer->dst.br.y * c->viewport.scale[1] + c->viewport.translate[1];
|
||||
result.x0 = layer->dst.tl.x * s->viewport.scale[0] + s->viewport.translate[0];
|
||||
result.y0 = layer->dst.tl.y * s->viewport.scale[1] + s->viewport.translate[1];
|
||||
result.x1 = layer->dst.br.x * s->viewport.scale[0] + s->viewport.translate[0];
|
||||
result.y1 = layer->dst.br.y * s->viewport.scale[1] + s->viewport.translate[1];
|
||||
|
||||
// and clip
|
||||
result.x0 = MAX2(result.x0, c->scissor.minx);
|
||||
result.y0 = MAX2(result.y0, c->scissor.miny);
|
||||
result.x1 = MIN2(result.x1, c->scissor.maxx);
|
||||
result.y1 = MIN2(result.y1, c->scissor.maxy);
|
||||
result.x0 = MAX2(result.x0, s->scissor.minx);
|
||||
result.y0 = MAX2(result.y0, s->scissor.miny);
|
||||
result.x1 = MIN2(result.x1, s->scissor.maxx);
|
||||
result.y1 = MIN2(result.y1, s->scissor.maxy);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gen_vertex_data(struct vl_compositor *c, struct u_rect *dirty)
|
||||
gen_vertex_data(struct vl_compositor *c, struct vl_compositor_state *s, struct u_rect *dirty)
|
||||
{
|
||||
struct vertex2f *vb;
|
||||
struct pipe_transfer *buf_transfer;
|
||||
|
@ -654,13 +635,13 @@ gen_vertex_data(struct vl_compositor *c, struct u_rect *dirty)
|
|||
}
|
||||
|
||||
for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; i++) {
|
||||
if (c->used_layers & (1 << i)) {
|
||||
struct vl_compositor_layer *layer = &c->layers[i];
|
||||
if (s->used_layers & (1 << i)) {
|
||||
struct vl_compositor_layer *layer = &s->layers[i];
|
||||
gen_rect_verts(vb, layer);
|
||||
vb += 12;
|
||||
|
||||
if (dirty && layer->clearing) {
|
||||
struct u_rect drawn = calc_drawn_area(c, layer);
|
||||
struct u_rect drawn = calc_drawn_area(s, layer);
|
||||
if (
|
||||
dirty->x0 >= drawn.x0 &&
|
||||
dirty->y0 >= drawn.y0 &&
|
||||
|
@ -679,19 +660,20 @@ gen_vertex_data(struct vl_compositor *c, struct u_rect *dirty)
|
|||
}
|
||||
|
||||
static void
|
||||
draw_layers(struct vl_compositor *c, struct u_rect *dirty)
|
||||
draw_layers(struct vl_compositor *c, struct vl_compositor_state *s, struct u_rect *dirty)
|
||||
{
|
||||
unsigned vb_index, i;
|
||||
|
||||
assert(c);
|
||||
|
||||
for (i = 0, vb_index = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {
|
||||
if (c->used_layers & (1 << i)) {
|
||||
struct vl_compositor_layer *layer = &c->layers[i];
|
||||
if (s->used_layers & (1 << i)) {
|
||||
struct vl_compositor_layer *layer = &s->layers[i];
|
||||
struct pipe_sampler_view **samplers = &layer->sampler_views[0];
|
||||
unsigned num_sampler_views = !samplers[1] ? 1 : !samplers[2] ? 2 : 3;
|
||||
void *blend = layer->blend ? layer->blend : i ? c->blend_add : c->blend_clear;
|
||||
|
||||
c->pipe->bind_blend_state(c->pipe, layer->blend);
|
||||
c->pipe->bind_blend_state(c->pipe, blend);
|
||||
c->pipe->bind_fs_state(c->pipe, layer->fs);
|
||||
c->pipe->bind_fragment_sampler_states(c->pipe, num_sampler_views, layer->samplers);
|
||||
c->pipe->set_fragment_sampler_views(c->pipe, num_sampler_views, samplers);
|
||||
|
@ -700,7 +682,7 @@ draw_layers(struct vl_compositor *c, struct u_rect *dirty)
|
|||
|
||||
if (dirty) {
|
||||
// Remember the currently drawn area as dirty for the next draw command
|
||||
struct u_rect drawn = calc_drawn_area(c, layer);
|
||||
struct u_rect drawn = calc_drawn_area(s, layer);
|
||||
dirty->x0 = MIN2(drawn.x0, dirty->x0);
|
||||
dirty->y0 = MIN2(drawn.y0, dirty->y0);
|
||||
dirty->x1 = MAX2(drawn.x1, dirty->x1);
|
||||
|
@ -720,36 +702,37 @@ vl_compositor_reset_dirty_area(struct u_rect *dirty)
|
|||
}
|
||||
|
||||
void
|
||||
vl_compositor_set_clear_color(struct vl_compositor *c, union pipe_color_union *color)
|
||||
vl_compositor_set_clear_color(struct vl_compositor_state *s, union pipe_color_union *color)
|
||||
{
|
||||
assert(c);
|
||||
|
||||
c->clear_color = *color;
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_get_clear_color(struct vl_compositor *c, union pipe_color_union *color)
|
||||
{
|
||||
assert(c);
|
||||
assert(s);
|
||||
assert(color);
|
||||
|
||||
*color = c->clear_color;
|
||||
s->clear_color = *color;
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_clear_layers(struct vl_compositor *c)
|
||||
vl_compositor_get_clear_color(struct vl_compositor_state *s, union pipe_color_union *color)
|
||||
{
|
||||
assert(s);
|
||||
assert(color);
|
||||
|
||||
*color = s->clear_color;
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_clear_layers(struct vl_compositor_state *s)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
assert(c);
|
||||
assert(s);
|
||||
|
||||
c->used_layers = 0;
|
||||
s->used_layers = 0;
|
||||
for ( i = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {
|
||||
c->layers[i].clearing = i ? false : true;
|
||||
c->layers[i].blend = i ? c->blend_add : c->blend_clear;
|
||||
c->layers[i].fs = NULL;
|
||||
s->layers[i].clearing = i ? false : true;
|
||||
s->layers[i].blend = NULL;
|
||||
s->layers[i].fs = NULL;
|
||||
for ( j = 0; j < 3; j++)
|
||||
pipe_sampler_view_reference(&c->layers[i].sampler_views[j], NULL);
|
||||
pipe_sampler_view_reference(&s->layers[i].sampler_views[j], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -758,47 +741,74 @@ vl_compositor_cleanup(struct vl_compositor *c)
|
|||
{
|
||||
assert(c);
|
||||
|
||||
vl_compositor_clear_layers(c);
|
||||
|
||||
cleanup_buffers(c);
|
||||
cleanup_shaders(c);
|
||||
cleanup_pipe_state(c);
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_set_csc_matrix(struct vl_compositor *c, const float matrix[16])
|
||||
vl_compositor_set_csc_matrix(struct vl_compositor_state *s, const float matrix[16])
|
||||
{
|
||||
struct pipe_transfer *buf_transfer;
|
||||
|
||||
assert(c);
|
||||
assert(s);
|
||||
|
||||
memcpy
|
||||
(
|
||||
pipe_buffer_map(c->pipe, c->csc_matrix,
|
||||
pipe_buffer_map(s->pipe, s->csc_matrix,
|
||||
PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
|
||||
&buf_transfer),
|
||||
matrix,
|
||||
sizeof(csc_matrix)
|
||||
);
|
||||
|
||||
pipe_buffer_unmap(c->pipe, buf_transfer);
|
||||
pipe_buffer_unmap(s->pipe, buf_transfer);
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_set_layer_blend(struct vl_compositor *c,
|
||||
vl_compositor_set_dst_area(struct vl_compositor_state *s, struct pipe_video_rect *dst_area)
|
||||
{
|
||||
assert(s);
|
||||
|
||||
s->viewport_valid = dst_area != NULL;
|
||||
if (dst_area) {
|
||||
s->viewport.scale[0] = dst_area->w;
|
||||
s->viewport.scale[1] = dst_area->h;
|
||||
s->viewport.translate[0] = dst_area->x;
|
||||
s->viewport.translate[1] = dst_area->y;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_set_dst_clip(struct vl_compositor_state *s, struct pipe_video_rect *dst_clip)
|
||||
{
|
||||
assert(s);
|
||||
|
||||
s->scissor_valid = dst_clip != NULL;
|
||||
if (dst_clip) {
|
||||
s->scissor.minx = dst_clip->x;
|
||||
s->scissor.miny = dst_clip->y;
|
||||
s->scissor.maxx = dst_clip->x + dst_clip->w;
|
||||
s->scissor.maxy = dst_clip->y + dst_clip->h;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_set_layer_blend(struct vl_compositor_state *s,
|
||||
unsigned layer, void *blend,
|
||||
bool is_clearing)
|
||||
{
|
||||
assert(c && blend);
|
||||
assert(s && blend);
|
||||
|
||||
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
|
||||
|
||||
c->layers[layer].clearing = is_clearing;
|
||||
c->layers[layer].blend = blend;
|
||||
s->layers[layer].clearing = is_clearing;
|
||||
s->layers[layer].blend = blend;
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_set_buffer_layer(struct vl_compositor *c,
|
||||
vl_compositor_set_buffer_layer(struct vl_compositor_state *s,
|
||||
struct vl_compositor *c,
|
||||
unsigned layer,
|
||||
struct pipe_video_buffer *buffer,
|
||||
struct pipe_video_rect *src_rect,
|
||||
|
@ -808,49 +818,50 @@ vl_compositor_set_buffer_layer(struct vl_compositor *c,
|
|||
struct pipe_sampler_view **sampler_views;
|
||||
unsigned i;
|
||||
|
||||
assert(c && buffer);
|
||||
assert(s && c && buffer);
|
||||
|
||||
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
|
||||
|
||||
c->used_layers |= 1 << layer;
|
||||
s->used_layers |= 1 << layer;
|
||||
sampler_views = buffer->get_sampler_view_components(buffer);
|
||||
for (i = 0; i < 3; ++i) {
|
||||
c->layers[layer].samplers[i] = c->sampler_linear;
|
||||
pipe_sampler_view_reference(&c->layers[layer].sampler_views[i], sampler_views[i]);
|
||||
s->layers[layer].samplers[i] = c->sampler_linear;
|
||||
pipe_sampler_view_reference(&s->layers[layer].sampler_views[i], sampler_views[i]);
|
||||
}
|
||||
|
||||
calc_src_and_dst(&c->layers[layer], buffer->width, buffer->height,
|
||||
src_rect ? *src_rect : default_rect(&c->layers[layer]),
|
||||
dst_rect ? *dst_rect : default_rect(&c->layers[layer]));
|
||||
calc_src_and_dst(&s->layers[layer], buffer->width, buffer->height,
|
||||
src_rect ? *src_rect : default_rect(&s->layers[layer]),
|
||||
dst_rect ? *dst_rect : default_rect(&s->layers[layer]));
|
||||
|
||||
if (buffer->interlaced) {
|
||||
float half_a_line = 0.5f / c->layers[layer].zw.y;
|
||||
float half_a_line = 0.5f / s->layers[layer].zw.y;
|
||||
switch(deinterlace) {
|
||||
case VL_COMPOSITOR_WEAVE:
|
||||
c->layers[layer].fs = c->fs_weave;
|
||||
s->layers[layer].fs = c->fs_weave;
|
||||
break;
|
||||
|
||||
case VL_COMPOSITOR_BOB_TOP:
|
||||
c->layers[layer].zw.x = 0.25f;
|
||||
c->layers[layer].src.tl.y += half_a_line;
|
||||
c->layers[layer].src.br.y += half_a_line;
|
||||
c->layers[layer].fs = c->fs_video_buffer;
|
||||
s->layers[layer].zw.x = 0.25f;
|
||||
s->layers[layer].src.tl.y += half_a_line;
|
||||
s->layers[layer].src.br.y += half_a_line;
|
||||
s->layers[layer].fs = c->fs_video_buffer;
|
||||
break;
|
||||
|
||||
case VL_COMPOSITOR_BOB_BOTTOM:
|
||||
c->layers[layer].zw.x = 0.75f;
|
||||
c->layers[layer].src.tl.y -= half_a_line;
|
||||
c->layers[layer].src.br.y -= half_a_line;
|
||||
c->layers[layer].fs = c->fs_video_buffer;
|
||||
s->layers[layer].zw.x = 0.75f;
|
||||
s->layers[layer].src.tl.y -= half_a_line;
|
||||
s->layers[layer].src.br.y -= half_a_line;
|
||||
s->layers[layer].fs = c->fs_video_buffer;
|
||||
break;
|
||||
}
|
||||
|
||||
} else
|
||||
c->layers[layer].fs = c->fs_video_buffer;
|
||||
s->layers[layer].fs = c->fs_video_buffer;
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_set_palette_layer(struct vl_compositor *c,
|
||||
vl_compositor_set_palette_layer(struct vl_compositor_state *s,
|
||||
struct vl_compositor *c,
|
||||
unsigned layer,
|
||||
struct pipe_sampler_view *indexes,
|
||||
struct pipe_sampler_view *palette,
|
||||
|
@ -858,56 +869,56 @@ vl_compositor_set_palette_layer(struct vl_compositor *c,
|
|||
struct pipe_video_rect *dst_rect,
|
||||
bool include_color_conversion)
|
||||
{
|
||||
assert(c && indexes && palette);
|
||||
assert(s && c && indexes && palette);
|
||||
|
||||
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
|
||||
|
||||
c->used_layers |= 1 << layer;
|
||||
s->used_layers |= 1 << layer;
|
||||
|
||||
c->layers[layer].fs = include_color_conversion ?
|
||||
s->layers[layer].fs = include_color_conversion ?
|
||||
c->fs_palette.yuv : c->fs_palette.rgb;
|
||||
|
||||
c->layers[layer].samplers[0] = c->sampler_linear;
|
||||
c->layers[layer].samplers[1] = c->sampler_nearest;
|
||||
c->layers[layer].samplers[2] = NULL;
|
||||
pipe_sampler_view_reference(&c->layers[layer].sampler_views[0], indexes);
|
||||
pipe_sampler_view_reference(&c->layers[layer].sampler_views[1], palette);
|
||||
pipe_sampler_view_reference(&c->layers[layer].sampler_views[2], NULL);
|
||||
calc_src_and_dst(&c->layers[layer], indexes->texture->width0, indexes->texture->height0,
|
||||
src_rect ? *src_rect : default_rect(&c->layers[layer]),
|
||||
dst_rect ? *dst_rect : default_rect(&c->layers[layer]));
|
||||
s->layers[layer].samplers[0] = c->sampler_linear;
|
||||
s->layers[layer].samplers[1] = c->sampler_nearest;
|
||||
s->layers[layer].samplers[2] = NULL;
|
||||
pipe_sampler_view_reference(&s->layers[layer].sampler_views[0], indexes);
|
||||
pipe_sampler_view_reference(&s->layers[layer].sampler_views[1], palette);
|
||||
pipe_sampler_view_reference(&s->layers[layer].sampler_views[2], NULL);
|
||||
calc_src_and_dst(&s->layers[layer], indexes->texture->width0, indexes->texture->height0,
|
||||
src_rect ? *src_rect : default_rect(&s->layers[layer]),
|
||||
dst_rect ? *dst_rect : default_rect(&s->layers[layer]));
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_set_rgba_layer(struct vl_compositor *c,
|
||||
vl_compositor_set_rgba_layer(struct vl_compositor_state *s,
|
||||
struct vl_compositor *c,
|
||||
unsigned layer,
|
||||
struct pipe_sampler_view *rgba,
|
||||
struct pipe_video_rect *src_rect,
|
||||
struct pipe_video_rect *dst_rect)
|
||||
{
|
||||
assert(c && rgba);
|
||||
assert(s && c && rgba);
|
||||
|
||||
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
|
||||
|
||||
c->used_layers |= 1 << layer;
|
||||
c->layers[layer].fs = c->fs_rgba;
|
||||
c->layers[layer].samplers[0] = c->sampler_linear;
|
||||
c->layers[layer].samplers[1] = NULL;
|
||||
c->layers[layer].samplers[2] = NULL;
|
||||
pipe_sampler_view_reference(&c->layers[layer].sampler_views[0], rgba);
|
||||
pipe_sampler_view_reference(&c->layers[layer].sampler_views[1], NULL);
|
||||
pipe_sampler_view_reference(&c->layers[layer].sampler_views[2], NULL);
|
||||
calc_src_and_dst(&c->layers[layer], rgba->texture->width0, rgba->texture->height0,
|
||||
src_rect ? *src_rect : default_rect(&c->layers[layer]),
|
||||
dst_rect ? *dst_rect : default_rect(&c->layers[layer]));
|
||||
s->used_layers |= 1 << layer;
|
||||
s->layers[layer].fs = c->fs_rgba;
|
||||
s->layers[layer].samplers[0] = c->sampler_linear;
|
||||
s->layers[layer].samplers[1] = NULL;
|
||||
s->layers[layer].samplers[2] = NULL;
|
||||
pipe_sampler_view_reference(&s->layers[layer].sampler_views[0], rgba);
|
||||
pipe_sampler_view_reference(&s->layers[layer].sampler_views[1], NULL);
|
||||
pipe_sampler_view_reference(&s->layers[layer].sampler_views[2], NULL);
|
||||
calc_src_and_dst(&s->layers[layer], rgba->texture->width0, rgba->texture->height0,
|
||||
src_rect ? *src_rect : default_rect(&s->layers[layer]),
|
||||
dst_rect ? *dst_rect : default_rect(&s->layers[layer]));
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_render(struct vl_compositor *c,
|
||||
struct pipe_surface *dst_surface,
|
||||
struct pipe_video_rect *dst_area,
|
||||
struct pipe_video_rect *dst_clip,
|
||||
struct u_rect *dirty_area)
|
||||
vl_compositor_render(struct vl_compositor_state *s,
|
||||
struct vl_compositor *c,
|
||||
struct pipe_surface *dst_surface,
|
||||
struct u_rect *dirty_area)
|
||||
{
|
||||
assert(c);
|
||||
assert(dst_surface);
|
||||
|
@ -916,57 +927,49 @@ vl_compositor_render(struct vl_compositor *c,
|
|||
c->fb_state.height = dst_surface->height;
|
||||
c->fb_state.cbufs[0] = dst_surface;
|
||||
|
||||
if (dst_area) {
|
||||
c->viewport.scale[0] = dst_area->w;
|
||||
c->viewport.scale[1] = dst_area->h;
|
||||
c->viewport.translate[0] = dst_area->x;
|
||||
c->viewport.translate[1] = dst_area->y;
|
||||
} else {
|
||||
c->viewport.scale[0] = dst_surface->width;
|
||||
c->viewport.scale[1] = dst_surface->height;
|
||||
c->viewport.translate[0] = 0;
|
||||
c->viewport.translate[1] = 0;
|
||||
if (!s->viewport_valid) {
|
||||
s->viewport.scale[0] = dst_surface->width;
|
||||
s->viewport.scale[1] = dst_surface->height;
|
||||
s->viewport.translate[0] = 0;
|
||||
s->viewport.translate[1] = 0;
|
||||
}
|
||||
|
||||
if (dst_clip) {
|
||||
c->scissor.minx = dst_clip->x;
|
||||
c->scissor.miny = dst_clip->y;
|
||||
c->scissor.maxx = dst_clip->x + dst_clip->w;
|
||||
c->scissor.maxy = dst_clip->y + dst_clip->h;
|
||||
} else {
|
||||
c->scissor.minx = 0;
|
||||
c->scissor.miny = 0;
|
||||
c->scissor.maxx = dst_surface->width;
|
||||
c->scissor.maxy = dst_surface->height;
|
||||
if (!s->scissor_valid) {
|
||||
s->scissor.minx = 0;
|
||||
s->scissor.miny = 0;
|
||||
s->scissor.maxx = dst_surface->width;
|
||||
s->scissor.maxy = dst_surface->height;
|
||||
}
|
||||
|
||||
gen_vertex_data(c, dirty_area);
|
||||
gen_vertex_data(c, s, dirty_area);
|
||||
|
||||
if (dirty_area && (dirty_area->x0 < dirty_area->x1 ||
|
||||
dirty_area->y0 < dirty_area->y1)) {
|
||||
|
||||
c->pipe->clear_render_target(c->pipe, dst_surface, &c->clear_color,
|
||||
c->pipe->clear_render_target(c->pipe, dst_surface, &s->clear_color,
|
||||
0, 0, dst_surface->width, dst_surface->height);
|
||||
dirty_area->x0 = dirty_area->y0 = MAX_DIRTY;
|
||||
dirty_area->x1 = dirty_area->y1 = MIN_DIRTY;
|
||||
}
|
||||
|
||||
c->pipe->set_scissor_state(c->pipe, &c->scissor);
|
||||
c->pipe->set_scissor_state(c->pipe, &s->scissor);
|
||||
c->pipe->set_framebuffer_state(c->pipe, &c->fb_state);
|
||||
c->pipe->set_viewport_state(c->pipe, &c->viewport);
|
||||
c->pipe->set_viewport_state(c->pipe, &s->viewport);
|
||||
c->pipe->bind_vs_state(c->pipe, c->vs);
|
||||
c->pipe->set_vertex_buffers(c->pipe, 1, &c->vertex_buf);
|
||||
c->pipe->bind_vertex_elements_state(c->pipe, c->vertex_elems_state);
|
||||
c->pipe->set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, c->csc_matrix);
|
||||
c->pipe->set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, s->csc_matrix);
|
||||
c->pipe->bind_rasterizer_state(c->pipe, c->rast);
|
||||
|
||||
draw_layers(c, dirty_area);
|
||||
draw_layers(c, s, dirty_area);
|
||||
}
|
||||
|
||||
bool
|
||||
vl_compositor_init(struct vl_compositor *c, struct pipe_context *pipe)
|
||||
{
|
||||
csc_matrix csc_matrix;
|
||||
assert(c);
|
||||
|
||||
memset(c, 0, sizeof(*c));
|
||||
|
||||
c->pipe = pipe;
|
||||
|
||||
|
@ -984,13 +987,54 @@ vl_compositor_init(struct vl_compositor *c, struct pipe_context *pipe)
|
|||
return false;
|
||||
}
|
||||
|
||||
vl_compositor_clear_layers(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
vl_compositor_init_state(struct vl_compositor_state *s, struct pipe_context *pipe)
|
||||
{
|
||||
csc_matrix csc_matrix;
|
||||
|
||||
assert(s);
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
s->pipe = pipe;
|
||||
|
||||
s->viewport.scale[2] = 1;
|
||||
s->viewport.scale[3] = 1;
|
||||
s->viewport.translate[2] = 0;
|
||||
s->viewport.translate[3] = 0;
|
||||
|
||||
s->clear_color.f[0] = s->clear_color.f[1] = 0.0f;
|
||||
s->clear_color.f[2] = s->clear_color.f[3] = 0.0f;
|
||||
|
||||
/*
|
||||
* Create our fragment shader's constant buffer
|
||||
* Const buffer contains the color conversion matrix and bias vectors
|
||||
*/
|
||||
/* XXX: Create with IMMUTABLE/STATIC... although it does change every once in a long while... */
|
||||
s->csc_matrix = pipe_buffer_create
|
||||
(
|
||||
pipe->screen,
|
||||
PIPE_BIND_CONSTANT_BUFFER,
|
||||
PIPE_USAGE_STATIC,
|
||||
sizeof(csc_matrix)
|
||||
);
|
||||
|
||||
vl_compositor_clear_layers(s);
|
||||
|
||||
vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, csc_matrix);
|
||||
vl_compositor_set_csc_matrix(c, csc_matrix);
|
||||
|
||||
c->clear_color.f[0] = c->clear_color.f[1] = 0.0f;
|
||||
c->clear_color.f[2] = c->clear_color.f[3] = 0.0f;
|
||||
vl_compositor_set_csc_matrix(s, csc_matrix);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
vl_compositor_cleanup_state(struct vl_compositor_state *s)
|
||||
{
|
||||
assert(s);
|
||||
|
||||
vl_compositor_clear_layers(s);
|
||||
pipe_resource_reference(&s->csc_matrix, NULL);
|
||||
}
|
||||
|
|
|
@ -67,15 +67,27 @@ struct vl_compositor_layer
|
|||
struct vertex2f zw;
|
||||
};
|
||||
|
||||
struct vl_compositor_state
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
|
||||
bool viewport_valid, scissor_valid;
|
||||
struct pipe_viewport_state viewport;
|
||||
struct pipe_scissor_state scissor;
|
||||
struct pipe_resource *csc_matrix;
|
||||
|
||||
union pipe_color_union clear_color;
|
||||
|
||||
unsigned used_layers:VL_COMPOSITOR_MAX_LAYERS;
|
||||
struct vl_compositor_layer layers[VL_COMPOSITOR_MAX_LAYERS];
|
||||
};
|
||||
|
||||
struct vl_compositor
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
|
||||
struct pipe_framebuffer_state fb_state;
|
||||
struct pipe_viewport_state viewport;
|
||||
struct pipe_scissor_state scissor;
|
||||
struct pipe_vertex_buffer vertex_buf;
|
||||
struct pipe_resource *csc_matrix;
|
||||
|
||||
void *sampler_linear;
|
||||
void *sampler_nearest;
|
||||
|
@ -93,11 +105,6 @@ struct vl_compositor
|
|||
void *rgb;
|
||||
void *yuv;
|
||||
} fs_palette;
|
||||
|
||||
union pipe_color_union clear_color;
|
||||
|
||||
unsigned used_layers:VL_COMPOSITOR_MAX_LAYERS;
|
||||
struct vl_compositor_layer layers[VL_COMPOSITOR_MAX_LAYERS];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -106,11 +113,17 @@ struct vl_compositor
|
|||
bool
|
||||
vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe);
|
||||
|
||||
/**
|
||||
* init state bag
|
||||
*/
|
||||
bool
|
||||
vl_compositor_init_state(struct vl_compositor_state *state, struct pipe_context *pipe);
|
||||
|
||||
/**
|
||||
* set yuv -> rgba conversion matrix
|
||||
*/
|
||||
void
|
||||
vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float mat[16]);
|
||||
vl_compositor_set_csc_matrix(struct vl_compositor_state *settings, const float mat[16]);
|
||||
|
||||
/**
|
||||
* reset dirty area, so it's cleared with the clear colour
|
||||
|
@ -122,13 +135,25 @@ vl_compositor_reset_dirty_area(struct u_rect *dirty);
|
|||
* set the clear color
|
||||
*/
|
||||
void
|
||||
vl_compositor_set_clear_color(struct vl_compositor *compositor, union pipe_color_union *color);
|
||||
vl_compositor_set_clear_color(struct vl_compositor_state *settings, union pipe_color_union *color);
|
||||
|
||||
/**
|
||||
* get the clear color
|
||||
*/
|
||||
void
|
||||
vl_compositor_get_clear_color(struct vl_compositor *compositor, union pipe_color_union *color);
|
||||
vl_compositor_get_clear_color(struct vl_compositor_state *settings, union pipe_color_union *color);
|
||||
|
||||
/**
|
||||
* set the destination area
|
||||
*/
|
||||
void
|
||||
vl_compositor_set_dst_area(struct vl_compositor_state *settings, struct pipe_video_rect *dst_area);
|
||||
|
||||
/**
|
||||
* set the destination clipping
|
||||
*/
|
||||
void
|
||||
vl_compositor_set_dst_clip(struct vl_compositor_state *settings, struct pipe_video_rect *dst_clip);
|
||||
|
||||
/**
|
||||
* set overlay samplers
|
||||
|
@ -139,20 +164,21 @@ vl_compositor_get_clear_color(struct vl_compositor *compositor, union pipe_color
|
|||
* reset all currently set layers
|
||||
*/
|
||||
void
|
||||
vl_compositor_clear_layers(struct vl_compositor *compositor);
|
||||
vl_compositor_clear_layers(struct vl_compositor_state *state);
|
||||
|
||||
/**
|
||||
* set the blender used to render a layer
|
||||
*/
|
||||
void
|
||||
vl_compositor_set_layer_blend(struct vl_compositor *compositor,
|
||||
vl_compositor_set_layer_blend(struct vl_compositor_state *state,
|
||||
unsigned layer, void *blend, bool is_clearing);
|
||||
|
||||
/**
|
||||
* set a video buffer as a layer to render
|
||||
*/
|
||||
void
|
||||
vl_compositor_set_buffer_layer(struct vl_compositor *compositor,
|
||||
vl_compositor_set_buffer_layer(struct vl_compositor_state *state,
|
||||
struct vl_compositor *compositor,
|
||||
unsigned layer,
|
||||
struct pipe_video_buffer *buffer,
|
||||
struct pipe_video_rect *src_rect,
|
||||
|
@ -163,7 +189,8 @@ vl_compositor_set_buffer_layer(struct vl_compositor *compositor,
|
|||
* set a paletted sampler as a layer to render
|
||||
*/
|
||||
void
|
||||
vl_compositor_set_palette_layer(struct vl_compositor *compositor,
|
||||
vl_compositor_set_palette_layer(struct vl_compositor_state *state,
|
||||
struct vl_compositor *compositor,
|
||||
unsigned layer,
|
||||
struct pipe_sampler_view *indexes,
|
||||
struct pipe_sampler_view *palette,
|
||||
|
@ -175,7 +202,8 @@ vl_compositor_set_palette_layer(struct vl_compositor *compositor,
|
|||
* set a rgba sampler as a layer to render
|
||||
*/
|
||||
void
|
||||
vl_compositor_set_rgba_layer(struct vl_compositor *compositor,
|
||||
vl_compositor_set_rgba_layer(struct vl_compositor_state *state,
|
||||
struct vl_compositor *compositor,
|
||||
unsigned layer,
|
||||
struct pipe_sampler_view *rgba,
|
||||
struct pipe_video_rect *src_rect,
|
||||
|
@ -187,11 +215,10 @@ vl_compositor_set_rgba_layer(struct vl_compositor *compositor,
|
|||
* render the layers to the frontbuffer
|
||||
*/
|
||||
void
|
||||
vl_compositor_render(struct vl_compositor *compositor,
|
||||
struct pipe_surface *dst_surface,
|
||||
struct pipe_video_rect *dst_area,
|
||||
struct pipe_video_rect *dst_clip,
|
||||
struct u_rect *dirty_area);
|
||||
vl_compositor_render(struct vl_compositor_state *state,
|
||||
struct vl_compositor *compositor,
|
||||
struct pipe_surface *dst_surface,
|
||||
struct u_rect *dirty_area);
|
||||
|
||||
/**
|
||||
* destroy this compositor
|
||||
|
@ -199,4 +226,10 @@ vl_compositor_render(struct vl_compositor *compositor,
|
|||
void
|
||||
vl_compositor_cleanup(struct vl_compositor *compositor);
|
||||
|
||||
/**
|
||||
* destroy this state bag
|
||||
*/
|
||||
void
|
||||
vl_compositor_cleanup_state(struct vl_compositor_state *state);
|
||||
|
||||
#endif /* vl_compositor_h */
|
||||
|
|
|
@ -62,11 +62,11 @@ vlVdpVideoMixerCreate(VdpDevice device,
|
|||
return VDP_STATUS_RESOURCES;
|
||||
|
||||
vmixer->device = dev;
|
||||
vl_compositor_init(&vmixer->compositor, dev->context);
|
||||
vl_compositor_init_state(&vmixer->cstate, dev->context);
|
||||
|
||||
vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, vmixer->csc);
|
||||
if (!debug_get_bool_option("G3DVL_NO_CSC", FALSE))
|
||||
vl_compositor_set_csc_matrix(&vmixer->compositor, vmixer->csc);
|
||||
vl_compositor_set_csc_matrix(&vmixer->cstate, vmixer->csc);
|
||||
|
||||
*mixer = vlAddDataHTAB(vmixer);
|
||||
if (*mixer == 0) {
|
||||
|
@ -148,8 +148,9 @@ vlVdpVideoMixerCreate(VdpDevice device,
|
|||
|
||||
no_params:
|
||||
vlRemoveDataHTAB(*mixer);
|
||||
|
||||
no_handle:
|
||||
vl_compositor_cleanup(&vmixer->compositor);
|
||||
vl_compositor_cleanup_state(&vmixer->cstate);
|
||||
FREE(vmixer);
|
||||
return ret;
|
||||
}
|
||||
|
@ -167,7 +168,7 @@ vlVdpVideoMixerDestroy(VdpVideoMixer mixer)
|
|||
return VDP_STATUS_INVALID_HANDLE;
|
||||
vlRemoveDataHTAB(mixer);
|
||||
|
||||
vl_compositor_cleanup(&vmixer->compositor);
|
||||
vl_compositor_cleanup_state(&vmixer->cstate);
|
||||
|
||||
if (vmixer->noise_reduction.filter) {
|
||||
vl_median_filter_cleanup(vmixer->noise_reduction.filter);
|
||||
|
@ -211,10 +212,14 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
|
|||
vlVdpSurface *surf;
|
||||
vlVdpOutputSurface *dst;
|
||||
|
||||
struct vl_compositor *compositor;
|
||||
|
||||
vmixer = vlGetDataHTAB(mixer);
|
||||
if (!vmixer)
|
||||
return VDP_STATUS_INVALID_HANDLE;
|
||||
|
||||
compositor = &vmixer->device->compositor;
|
||||
|
||||
surf = vlGetDataHTAB(video_surface_current);
|
||||
if (!surf)
|
||||
return VDP_STATUS_INVALID_HANDLE;
|
||||
|
@ -238,11 +243,11 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
|
|||
vlVdpOutputSurface *bg = vlGetDataHTAB(background_surface);
|
||||
if (!bg)
|
||||
return VDP_STATUS_INVALID_HANDLE;
|
||||
vl_compositor_set_rgba_layer(&vmixer->compositor, layer++, bg->sampler_view,
|
||||
vl_compositor_set_rgba_layer(&vmixer->cstate, compositor, layer++, bg->sampler_view,
|
||||
RectToPipe(background_source_rect, &src_rect), NULL);
|
||||
}
|
||||
|
||||
vl_compositor_clear_layers(&vmixer->compositor);
|
||||
vl_compositor_clear_layers(&vmixer->cstate);
|
||||
|
||||
switch (current_picture_structure) {
|
||||
case VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD:
|
||||
|
@ -260,13 +265,11 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
|
|||
default:
|
||||
return VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE;
|
||||
};
|
||||
vl_compositor_set_buffer_layer(&vmixer->compositor, layer++, surf->video_buffer,
|
||||
RectToPipe(video_source_rect, &src_rect), NULL,
|
||||
deinterlace);
|
||||
vl_compositor_render(&vmixer->compositor, dst->surface,
|
||||
RectToPipe(destination_video_rect, &dst_rect),
|
||||
RectToPipe(destination_rect, &dst_clip),
|
||||
&dst->dirty_area);
|
||||
vl_compositor_set_buffer_layer(&vmixer->cstate, compositor, layer++, surf->video_buffer,
|
||||
RectToPipe(video_source_rect, &src_rect), NULL, deinterlace);
|
||||
vl_compositor_set_dst_area(&vmixer->cstate, RectToPipe(destination_video_rect, &dst_rect));
|
||||
vl_compositor_set_dst_clip(&vmixer->cstate, RectToPipe(destination_rect, &dst_clip));
|
||||
vl_compositor_render(&vmixer->cstate, compositor, dst->surface, &dst->dirty_area);
|
||||
|
||||
/* applying the noise reduction after scaling is actually not very
|
||||
clever, but currently we should avoid to copy around the image
|
||||
|
@ -544,7 +547,7 @@ vlVdpVideoMixerSetAttributeValues(VdpVideoMixer mixer,
|
|||
color.f[1] = background_color->green;
|
||||
color.f[2] = background_color->blue;
|
||||
color.f[3] = background_color->alpha;
|
||||
vl_compositor_set_clear_color(&vmixer->compositor, &color);
|
||||
vl_compositor_set_clear_color(&vmixer->cstate, &color);
|
||||
break;
|
||||
case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
|
||||
vdp_csc = attribute_values[i];
|
||||
|
@ -554,7 +557,7 @@ vlVdpVideoMixerSetAttributeValues(VdpVideoMixer mixer,
|
|||
else
|
||||
memcpy(vmixer->csc, vdp_csc, sizeof(float)*12);
|
||||
if (!debug_get_bool_option("G3DVL_NO_CSC", FALSE))
|
||||
vl_compositor_set_csc_matrix(&vmixer->compositor, vmixer->csc);
|
||||
vl_compositor_set_csc_matrix(&vmixer->cstate, vmixer->csc);
|
||||
break;
|
||||
|
||||
case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
|
||||
|
@ -664,7 +667,7 @@ vlVdpVideoMixerGetAttributeValues(VdpVideoMixer mixer,
|
|||
for (i = 0; i < attribute_count; ++i) {
|
||||
switch (attributes[i]) {
|
||||
case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
|
||||
vl_compositor_get_clear_color(&vmixer->compositor, attribute_values[i]);
|
||||
vl_compositor_get_clear_color(&vmixer->cstate, attribute_values[i]);
|
||||
break;
|
||||
case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
|
||||
vdp_csc = attribute_values[i];
|
||||
|
|
|
@ -113,6 +113,7 @@ vlVdpOutputSurfaceCreate(VdpDevice device,
|
|||
|
||||
pipe_resource_reference(&res, NULL);
|
||||
|
||||
vl_compositor_init_state(&vlsurface->cstate, pipe);
|
||||
vl_compositor_reset_dirty_area(&vlsurface->dirty_area);
|
||||
|
||||
return VDP_STATUS_OK;
|
||||
|
@ -132,6 +133,7 @@ vlVdpOutputSurfaceDestroy(VdpOutputSurface surface)
|
|||
|
||||
pipe_surface_reference(&vlsurface->surface, NULL);
|
||||
pipe_sampler_view_reference(&vlsurface->sampler_view, NULL);
|
||||
vl_compositor_cleanup_state(&vlsurface->cstate);
|
||||
|
||||
vlRemoveDataHTAB(surface);
|
||||
FREE(vlsurface);
|
||||
|
@ -202,6 +204,7 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
|
|||
vlVdpOutputSurface *vlsurface;
|
||||
struct pipe_context *context;
|
||||
struct vl_compositor *compositor;
|
||||
struct vl_compositor_state *cstate;
|
||||
|
||||
enum pipe_format index_format;
|
||||
enum pipe_format colortbl_format;
|
||||
|
@ -219,6 +222,7 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
|
|||
|
||||
context = vlsurface->device->context;
|
||||
compositor = &vlsurface->device->compositor;
|
||||
cstate = &vlsurface->cstate;
|
||||
|
||||
index_format = FormatIndexedToPipe(source_indexed_format);
|
||||
if (index_format == PIPE_FORMAT_NONE)
|
||||
|
@ -304,10 +308,10 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
|
|||
if (!sv_tbl)
|
||||
goto error_resource;
|
||||
|
||||
vl_compositor_clear_layers(compositor);
|
||||
vl_compositor_set_palette_layer(compositor, 0, sv_idx, sv_tbl, NULL, NULL, false);
|
||||
vl_compositor_render(compositor, vlsurface->surface,
|
||||
RectToPipe(destination_rect, &dst_rect), NULL, NULL);
|
||||
vl_compositor_clear_layers(cstate);
|
||||
vl_compositor_set_palette_layer(cstate, compositor, 0, sv_idx, sv_tbl, NULL, NULL, false);
|
||||
vl_compositor_set_dst_area(cstate, RectToPipe(destination_rect, &dst_rect));
|
||||
vl_compositor_render(cstate, compositor, vlsurface->surface, NULL);
|
||||
|
||||
pipe_sampler_view_reference(&sv_idx, NULL);
|
||||
pipe_sampler_view_reference(&sv_tbl, NULL);
|
||||
|
@ -442,6 +446,7 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface,
|
|||
|
||||
struct pipe_context *context;
|
||||
struct vl_compositor *compositor;
|
||||
struct vl_compositor_state *cstate;
|
||||
|
||||
struct pipe_video_rect src_rect;
|
||||
struct pipe_video_rect dst_rect;
|
||||
|
@ -461,15 +466,16 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface,
|
|||
|
||||
context = dst_vlsurface->device->context;
|
||||
compositor = &dst_vlsurface->device->compositor;
|
||||
cstate = &dst_vlsurface->cstate;
|
||||
|
||||
blend = BlenderToPipe(context, blend_state);
|
||||
|
||||
vl_compositor_clear_layers(compositor);
|
||||
vl_compositor_set_layer_blend(compositor, 0, blend, false);
|
||||
vl_compositor_set_rgba_layer(compositor, 0, src_vlsurface->sampler_view,
|
||||
vl_compositor_clear_layers(cstate);
|
||||
vl_compositor_set_layer_blend(cstate, 0, blend, false);
|
||||
vl_compositor_set_rgba_layer(cstate, compositor, 0, src_vlsurface->sampler_view,
|
||||
RectToPipe(source_rect, &src_rect), NULL);
|
||||
vl_compositor_render(compositor, dst_vlsurface->surface,
|
||||
RectToPipe(destination_rect, &dst_rect), NULL, false);
|
||||
vl_compositor_set_dst_area(cstate, RectToPipe(destination_rect, &dst_rect));
|
||||
vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL);
|
||||
|
||||
context->delete_blend_state(context, blend);
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ vlVdpPresentationQueueCreate(VdpDevice device,
|
|||
pq->device = dev;
|
||||
pq->drawable = pqt->drawable;
|
||||
|
||||
if (!vl_compositor_init(&pq->compositor, dev->context)) {
|
||||
if (!vl_compositor_init_state(&pq->cstate, dev->context)) {
|
||||
ret = VDP_STATUS_ERROR;
|
||||
goto no_compositor;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ vlVdpPresentationQueueDestroy(VdpPresentationQueue presentation_queue)
|
|||
if (!pq)
|
||||
return VDP_STATUS_INVALID_HANDLE;
|
||||
|
||||
vl_compositor_cleanup(&pq->compositor);
|
||||
vl_compositor_cleanup_state(&pq->cstate);
|
||||
|
||||
vlRemoveDataHTAB(presentation_queue);
|
||||
FREE(pq);
|
||||
|
@ -129,7 +129,7 @@ vlVdpPresentationQueueSetBackgroundColor(VdpPresentationQueue presentation_queue
|
|||
color.f[2] = background_color->blue;
|
||||
color.f[3] = background_color->alpha;
|
||||
|
||||
vl_compositor_set_clear_color(&pq->compositor, &color);
|
||||
vl_compositor_set_clear_color(&pq->cstate, &color);
|
||||
|
||||
return VDP_STATUS_OK;
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ vlVdpPresentationQueueGetBackgroundColor(VdpPresentationQueue presentation_queue
|
|||
if (!pq)
|
||||
return VDP_STATUS_INVALID_HANDLE;
|
||||
|
||||
vl_compositor_get_clear_color(&pq->compositor, &color);
|
||||
vl_compositor_get_clear_color(&pq->cstate, &color);
|
||||
|
||||
background_color->red = color.f[0];
|
||||
background_color->green = color.f[1];
|
||||
|
@ -205,11 +205,14 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue,
|
|||
struct pipe_video_rect src_rect, dst_clip;
|
||||
struct u_rect *dirty_area;
|
||||
|
||||
struct vl_compositor *compositor;
|
||||
|
||||
pq = vlGetDataHTAB(presentation_queue);
|
||||
if (!pq)
|
||||
return VDP_STATUS_INVALID_HANDLE;
|
||||
|
||||
pipe = pq->device->context;
|
||||
compositor = &pq->device->compositor;
|
||||
|
||||
tex = vl_screen_texture_from_drawable(pq->device->vscreen, pq->drawable);
|
||||
if (!tex)
|
||||
|
@ -238,9 +241,10 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue,
|
|||
dst_clip.w = clip_width ? clip_width : surf_draw->width;
|
||||
dst_clip.h = clip_height ? clip_height : surf_draw->height;
|
||||
|
||||
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, dirty_area);
|
||||
vl_compositor_clear_layers(&pq->cstate);
|
||||
vl_compositor_set_rgba_layer(&pq->cstate, compositor, 0, surf->sampler_view, &src_rect, NULL);
|
||||
vl_compositor_set_dst_clip(&pq->cstate, &dst_clip);
|
||||
vl_compositor_render(&pq->cstate, compositor, surf_draw, dirty_area);
|
||||
|
||||
pipe->screen->flush_frontbuffer
|
||||
(
|
||||
|
|
|
@ -300,13 +300,13 @@ typedef struct
|
|||
{
|
||||
vlVdpDevice *device;
|
||||
Drawable drawable;
|
||||
struct vl_compositor compositor;
|
||||
struct vl_compositor_state cstate;
|
||||
} vlVdpPresentationQueue;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vlVdpDevice *device;
|
||||
struct vl_compositor compositor;
|
||||
struct vl_compositor_state cstate;
|
||||
|
||||
struct {
|
||||
bool supported, enabled;
|
||||
|
@ -342,6 +342,7 @@ typedef struct
|
|||
struct pipe_surface *surface;
|
||||
struct pipe_sampler_view *sampler_view;
|
||||
struct pipe_fence_handle *fence;
|
||||
struct vl_compositor_state cstate;
|
||||
struct u_rect dirty_area;
|
||||
} vlVdpOutputSurface;
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ Status XvMCSetAttribute(Display *dpy, XvMCContext *context, Atom attribute, int
|
|||
context_priv->color_standard,
|
||||
&context_priv->procamp, true, csc
|
||||
);
|
||||
vl_compositor_set_csc_matrix(&context_priv->compositor, csc);
|
||||
vl_compositor_set_csc_matrix(&context_priv->cstate, csc);
|
||||
|
||||
XVMC_MSG(XVMC_TRACE, "[XvMC] Set attribute %s to value %d.\n", attr, value);
|
||||
|
||||
|
|
|
@ -270,6 +270,17 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
|
|||
return BadAlloc;
|
||||
}
|
||||
|
||||
if (!vl_compositor_init_state(&context_priv->cstate, pipe)) {
|
||||
XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL compositor state.\n");
|
||||
vl_compositor_cleanup(&context_priv->compositor);
|
||||
context_priv->decoder->destroy(context_priv->decoder);
|
||||
pipe->destroy(pipe);
|
||||
vl_screen_destroy(vscreen);
|
||||
FREE(context_priv);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
|
||||
context_priv->color_standard =
|
||||
debug_get_bool_option("G3DVL_NO_CSC", FALSE) ?
|
||||
VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601;
|
||||
|
@ -280,7 +291,7 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
|
|||
context_priv->color_standard,
|
||||
&context_priv->procamp, true, csc
|
||||
);
|
||||
vl_compositor_set_csc_matrix(&context_priv->compositor, csc);
|
||||
vl_compositor_set_csc_matrix(&context_priv->cstate, csc);
|
||||
|
||||
context_priv->vscreen = vscreen;
|
||||
context_priv->pipe = pipe;
|
||||
|
@ -316,6 +327,7 @@ Status XvMCDestroyContext(Display *dpy, XvMCContext *context)
|
|||
|
||||
context_priv = context->privData;
|
||||
context_priv->decoder->destroy(context_priv->decoder);
|
||||
vl_compositor_cleanup_state(&context_priv->cstate);
|
||||
vl_compositor_cleanup(&context_priv->compositor);
|
||||
context_priv->pipe->destroy(context_priv->pipe);
|
||||
vl_screen_destroy(context_priv->vscreen);
|
||||
|
|
|
@ -349,6 +349,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
|
|||
|
||||
struct pipe_context *pipe;
|
||||
struct vl_compositor *compositor;
|
||||
struct vl_compositor_state *cstate;
|
||||
|
||||
XvMCSurfacePrivate *surface_priv;
|
||||
XvMCContextPrivate *context_priv;
|
||||
|
@ -379,6 +380,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
|
|||
subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL;
|
||||
pipe = context_priv->pipe;
|
||||
compositor = &context_priv->compositor;
|
||||
cstate = &context_priv->cstate;
|
||||
|
||||
tex = vl_screen_texture_from_drawable(context_priv->vscreen, drawable);
|
||||
dirty_area = vl_screen_get_dirty_area(context_priv->vscreen);
|
||||
|
@ -407,8 +409,8 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
|
|||
|
||||
context_priv->decoder->flush(context_priv->decoder);
|
||||
|
||||
vl_compositor_clear_layers(compositor);
|
||||
vl_compositor_set_buffer_layer(compositor, 0, surface_priv->video_buffer,
|
||||
vl_compositor_clear_layers(cstate);
|
||||
vl_compositor_set_buffer_layer(cstate, compositor, 0, surface_priv->video_buffer,
|
||||
&src_rect, NULL, VL_COMPOSITOR_WEAVE);
|
||||
|
||||
if (subpicture_priv) {
|
||||
|
@ -417,10 +419,10 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
|
|||
assert(subpicture_priv->surface == surface);
|
||||
|
||||
if (subpicture_priv->palette)
|
||||
vl_compositor_set_palette_layer(compositor, 1, subpicture_priv->sampler, subpicture_priv->palette,
|
||||
vl_compositor_set_palette_layer(cstate, compositor, 1, subpicture_priv->sampler, subpicture_priv->palette,
|
||||
&subpicture_priv->src_rect, &subpicture_priv->dst_rect, true);
|
||||
else
|
||||
vl_compositor_set_rgba_layer(compositor, 1, subpicture_priv->sampler,
|
||||
vl_compositor_set_rgba_layer(cstate, compositor, 1, subpicture_priv->sampler,
|
||||
&subpicture_priv->src_rect, &subpicture_priv->dst_rect);
|
||||
|
||||
surface_priv->subpicture = NULL;
|
||||
|
@ -430,7 +432,8 @@ 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, dirty_area);
|
||||
vl_compositor_set_dst_area(cstate, &dst_rect);
|
||||
vl_compositor_render(cstate, compositor, surf, dirty_area);
|
||||
|
||||
pipe->flush(pipe, &surface_priv->fence);
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ typedef struct
|
|||
enum VL_CSC_COLOR_STANDARD color_standard;
|
||||
struct vl_procamp procamp;
|
||||
struct vl_compositor compositor;
|
||||
struct vl_compositor_state cstate;
|
||||
|
||||
unsigned short subpicture_max_width;
|
||||
unsigned short subpicture_max_height;
|
||||
|
|
Loading…
Reference in New Issue