From 32c4381d4a0479b3d9bfe305ce701be6b5ac8e18 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Sat, 25 Feb 2012 13:09:17 +0100 Subject: [PATCH] vl/compositor: split shaders and state MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- src/gallium/auxiliary/vl/vl_compositor.c | 328 +++++++++++++---------- src/gallium/auxiliary/vl/vl_compositor.h | 75 ++++-- src/gallium/state_trackers/vdpau/mixer.c | 35 +-- src/gallium/state_trackers/vdpau/output.c | 24 +- src/gallium/state_trackers/vdpau/presentation.c | 18 +- src/gallium/state_trackers/vdpau/vdpau_private.h | 5 +- src/gallium/state_trackers/xvmc/attributes.c | 2 +- src/gallium/state_trackers/xvmc/context.c | 14 +- src/gallium/state_trackers/xvmc/surface.c | 13 +- src/gallium/state_trackers/xvmc/xvmc_private.h | 1 + 10 files changed, 311 insertions(+), 204 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 80cb5ce03a1..9666ad1e047 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -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); + assert(s); + assert(color); - c->clear_color = *color; + s->clear_color = *color; } void -vl_compositor_get_clear_color(struct vl_compositor *c, union pipe_color_union *color) +vl_compositor_get_clear_color(struct vl_compositor_state *s, union pipe_color_union *color) { - assert(c); + assert(s); assert(color); - *color = c->clear_color; + *color = s->clear_color; } void -vl_compositor_clear_layers(struct vl_compositor *c) +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_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_layer_blend(struct vl_compositor *c, +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; +} - vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, csc_matrix); - vl_compositor_set_csc_matrix(c, csc_matrix); +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)); - c->clear_color.f[0] = c->clear_color.f[1] = 0.0f; - c->clear_color.f[2] = c->clear_color.f[3] = 0.0f; + 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(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); +} diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h index 2411d9a1ec1..8c574798591 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.h +++ b/src/gallium/auxiliary/vl/vl_compositor.h @@ -67,16 +67,28 @@ struct vl_compositor_layer struct vertex2f zw; }; -struct vl_compositor +struct vl_compositor_state { struct pipe_context *pipe; - struct pipe_framebuffer_state fb_state; + bool viewport_valid, scissor_valid; struct pipe_viewport_state viewport; struct pipe_scissor_state scissor; - struct pipe_vertex_buffer vertex_buf; 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_vertex_buffer vertex_buf; + void *sampler_linear; void *sampler_nearest; void *blend_clear, *blend_add; @@ -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]; }; /** @@ -107,10 +114,16 @@ 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 */ diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c index 082860888af..ac0ce86beeb 100644 --- a/src/gallium/state_trackers/vdpau/mixer.c +++ b/src/gallium/state_trackers/vdpau/mixer.c @@ -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]; diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c index 5ccb153fabd..0583c52fe82 100644 --- a/src/gallium/state_trackers/vdpau/output.c +++ b/src/gallium/state_trackers/vdpau/output.c @@ -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); diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c index 37c5c695e4d..71447793f58 100644 --- a/src/gallium/state_trackers/vdpau/presentation.c +++ b/src/gallium/state_trackers/vdpau/presentation.c @@ -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 ( diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h index 1645362444e..e74c68187d2 100644 --- a/src/gallium/state_trackers/vdpau/vdpau_private.h +++ b/src/gallium/state_trackers/vdpau/vdpau_private.h @@ -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; diff --git a/src/gallium/state_trackers/xvmc/attributes.c b/src/gallium/state_trackers/xvmc/attributes.c index d40a7b1e6f4..da7b6493ba8 100644 --- a/src/gallium/state_trackers/xvmc/attributes.c +++ b/src/gallium/state_trackers/xvmc/attributes.c @@ -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); diff --git a/src/gallium/state_trackers/xvmc/context.c b/src/gallium/state_trackers/xvmc/context.c index f5751515672..c598cad7455 100644 --- a/src/gallium/state_trackers/xvmc/context.c +++ b/src/gallium/state_trackers/xvmc/context.c @@ -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); diff --git a/src/gallium/state_trackers/xvmc/surface.c b/src/gallium/state_trackers/xvmc/surface.c index c6f6ef593b4..47853cf6924 100644 --- a/src/gallium/state_trackers/xvmc/surface.c +++ b/src/gallium/state_trackers/xvmc/surface.c @@ -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); diff --git a/src/gallium/state_trackers/xvmc/xvmc_private.h b/src/gallium/state_trackers/xvmc/xvmc_private.h index 4117f5bf689..26f874ad87a 100644 --- a/src/gallium/state_trackers/xvmc/xvmc_private.h +++ b/src/gallium/state_trackers/xvmc/xvmc_private.h @@ -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; -- 2.11.0