diff options
author | Christian König <[email protected]> | 2011-04-03 16:09:23 +0200 |
---|---|---|
committer | Christian König <[email protected]> | 2011-04-03 16:09:23 +0200 |
commit | e5f78a74f8294ee02015552db664dae1e7da9f47 (patch) | |
tree | 1676003e147ab0d60253791ad8a29733d1a14c77 /src/gallium/auxiliary/vl/vl_compositor.c | |
parent | e6d41e4d0326cac60b49e149d86d0f95c2518045 (diff) |
[g3dvl] split compositor out of video context
Also redesign the compositor a bit and make the result a public available interface
Diffstat (limited to 'src/gallium/auxiliary/vl/vl_compositor.c')
-rw-r--r-- | src/gallium/auxiliary/vl/vl_compositor.c | 556 |
1 files changed, 271 insertions, 285 deletions
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index f62706e5066..45e9cea9f66 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -36,38 +36,11 @@ #include <util/u_sampler.h> #include <tgsi/tgsi_ureg.h> #include "vl_csc.h" +#include "vl_types.h" -struct vertex_shader_consts -{ - struct vertex4f dst_scale; - struct vertex4f dst_trans; - struct vertex4f src_scale; - struct vertex4f src_trans; -}; - -struct fragment_shader_consts -{ - float matrix[16]; -}; - -static bool -u_video_rects_equal(struct pipe_video_rect *a, struct pipe_video_rect *b) -{ - assert(a && b); - - if (a->x != b->x) - return false; - if (a->y != b->y) - return false; - if (a->w != b->w) - return false; - if (a->h != b->h) - return false; - - return true; -} +typedef float csc_matrix[16]; -static bool +static void * create_vert_shader(struct vl_compositor *c) { struct ureg_program *shader; @@ -92,15 +65,11 @@ create_vert_shader(struct vl_compositor *c) ureg_END(shader); - c->vertex_shader = ureg_create_shader_and_destroy(shader, c->pipe); - if (!c->vertex_shader) - return false; - - return true; + return ureg_create_shader_and_destroy(shader, c->pipe); } -static bool -create_frag_shader_ycbcr_2_rgb(struct vl_compositor *c) +static void * +create_frag_shader_video_buffer(struct vl_compositor *c) { struct ureg_program *shader; struct ureg_src tc; @@ -139,15 +108,11 @@ create_frag_shader_ycbcr_2_rgb(struct vl_compositor *c) ureg_release_temporary(shader, texel); ureg_END(shader); - c->fragment_shader.ycbcr_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe); - if (!c->fragment_shader.ycbcr_2_rgb) - return false; - - return true; + return ureg_create_shader_and_destroy(shader, c->pipe); } -static bool -create_frag_shader_palette_2_rgb(struct vl_compositor *c) +static void * +create_frag_shader_palette(struct vl_compositor *c) { struct ureg_program *shader; struct ureg_src tc; @@ -167,7 +132,9 @@ create_frag_shader_palette_2_rgb(struct vl_compositor *c) texel = ureg_DECL_temporary(shader); /* - * fragment = tex(tc, sampler) + * texel = tex(tc, sampler) + * fragment.xyz = tex(texel, palette) + * fragment.a = texel.a */ ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler); ureg_TEX(shader, fragment, TGSI_TEXTURE_1D, ureg_src(texel), palette); @@ -176,15 +143,11 @@ create_frag_shader_palette_2_rgb(struct vl_compositor *c) ureg_release_temporary(shader, texel); ureg_END(shader); - c->fragment_shader.palette_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe); - if (!c->fragment_shader.palette_2_rgb) - return false; - - return true; + return ureg_create_shader_and_destroy(shader, c->pipe); } -static bool -create_frag_shader_rgb_2_rgb(struct vl_compositor *c) +static void * +create_frag_shader_rgba(struct vl_compositor *c) { struct ureg_program *shader; struct ureg_src tc; @@ -205,13 +168,51 @@ create_frag_shader_rgb_2_rgb(struct vl_compositor *c) ureg_TEX(shader, fragment, TGSI_TEXTURE_2D, tc, sampler); ureg_END(shader); - c->fragment_shader.rgb_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe); - if (!c->fragment_shader.rgb_2_rgb) + return ureg_create_shader_and_destroy(shader, c->pipe); +} + +static bool +init_shaders(struct vl_compositor *c) +{ + assert(c); + + c->vs = create_vert_shader(c); + if (!c->vs) { + debug_printf("Unable to create vertex shader.\n"); return false; + } + + c->fs_video_buffer = create_frag_shader_video_buffer(c); + if (!c->fs_video_buffer) { + debug_printf("Unable to create YCbCr-to-RGB fragment shader.\n"); + return false; + } + + c->fs_palette = create_frag_shader_palette(c); + if (!c->fs_palette) { + debug_printf("Unable to create Palette-to-RGB fragment shader.\n"); + return false; + } + + c->fs_rgba = create_frag_shader_rgba(c); + if (!c->fs_rgba) { + debug_printf("Unable to create RGB-to-RGB fragment shader.\n"); + return false; + } return true; } +static void cleanup_shaders(struct vl_compositor *c) +{ + assert(c); + + c->pipe->delete_vs_state(c->pipe, c->vs); + c->pipe->delete_fs_state(c->pipe, c->fs_video_buffer); + c->pipe->delete_fs_state(c->pipe, c->fs_palette); + c->pipe->delete_fs_state(c->pipe, c->fs_rgba); +} + static bool init_pipe_state(struct vl_compositor *c) { @@ -223,6 +224,13 @@ 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[0] = 0; + c->viewport.translate[1] = 0; + 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; @@ -267,44 +275,8 @@ static void cleanup_pipe_state(struct vl_compositor *c) } static bool -init_shaders(struct vl_compositor *c) -{ - assert(c); - - if (!create_vert_shader(c)) { - debug_printf("Unable to create vertex shader.\n"); - return false; - } - if (!create_frag_shader_ycbcr_2_rgb(c)) { - debug_printf("Unable to create YCbCr-to-RGB fragment shader.\n"); - return false; - } - if (!create_frag_shader_palette_2_rgb(c)) { - debug_printf("Unable to create Palette-to-RGB fragment shader.\n"); - return false; - } - if (!create_frag_shader_rgb_2_rgb(c)) { - debug_printf("Unable to create RGB-to-RGB fragment shader.\n"); - return false; - } - - return true; -} - -static void cleanup_shaders(struct vl_compositor *c) -{ - assert(c); - - c->pipe->delete_vs_state(c->pipe, c->vertex_shader); - c->pipe->delete_fs_state(c->pipe, c->fragment_shader.ycbcr_2_rgb); - c->pipe->delete_fs_state(c->pipe, c->fragment_shader.palette_2_rgb); - c->pipe->delete_fs_state(c->pipe, c->fragment_shader.rgb_2_rgb); -} - -static bool init_buffers(struct vl_compositor *c) { - struct fragment_shader_consts fsc; struct pipe_vertex_element vertex_elems[2]; assert(c); @@ -338,18 +310,14 @@ init_buffers(struct vl_compositor *c) * 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->fs_const_buf = pipe_buffer_create + c->csc_matrix = pipe_buffer_create ( c->pipe->screen, PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STATIC, - sizeof(struct fragment_shader_consts) + sizeof(csc_matrix) ); - vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, fsc.matrix); - - vl_compositor_set_csc_matrix(c, fsc.matrix); - return true; } @@ -360,99 +328,27 @@ 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->fs_const_buf, NULL); + pipe_resource_reference(&c->csc_matrix, NULL); } -bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe) +static inline struct pipe_video_rect +default_rect(struct vl_compositor_layer *layer) { - unsigned i; - - assert(compositor); - - memset(compositor, 0, sizeof(struct vl_compositor)); - - compositor->pipe = pipe; - - if (!init_pipe_state(compositor)) - return false; - - if (!init_shaders(compositor)) { - cleanup_pipe_state(compositor); - return false; - } - if (!init_buffers(compositor)) { - cleanup_shaders(compositor); - cleanup_pipe_state(compositor); - return false; - } - - compositor->fb_state.width = 0; - compositor->fb_state.height = 0; - for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) - compositor->layers[i] = NULL; - compositor->dirty_layers = 0; - - return true; + struct pipe_resource *res = layer->sampler_views[0]->texture; + struct pipe_video_rect rect = { 0, 0, res->width0, res->height0 }; + return rect; } -void vl_compositor_cleanup(struct vl_compositor *compositor) -{ - assert(compositor); - - cleanup_buffers(compositor); - cleanup_shaders(compositor); - cleanup_pipe_state(compositor); -} - -void vl_compositor_set_layers(struct vl_compositor *compositor, - struct pipe_sampler_view *layers[], - struct pipe_sampler_view *palettes[], - struct pipe_video_rect *src_rects[], - struct pipe_video_rect *dst_rects[], - unsigned num_layers) -{ - unsigned i; - - assert(compositor); - assert(num_layers <= VL_COMPOSITOR_MAX_LAYERS); - - for (i = 0; i < num_layers; ++i) - { - assert((layers[i] && src_rects[i] && dst_rects[i]) || - (!layers[i] && !src_rects[i] && !dst_rects[i])); - - if (compositor->layers[i] != layers[i] || - compositor->palettes[i] != palettes[i] || - !u_video_rects_equal(&compositor->layer_src_rects[i], src_rects[i]) || - !u_video_rects_equal(&compositor->layer_dst_rects[i], dst_rects[i])) - { - pipe_sampler_view_reference(&compositor->layers[i], layers[i]); - pipe_sampler_view_reference(&compositor->palettes[i], palettes[i]); - compositor->layer_src_rects[i] = *src_rects[i]; - compositor->layer_dst_rects[i] = *dst_rects[i]; - compositor->dirty_layers |= 1 << i; - } - - if (layers[i]) - compositor->dirty_layers |= 1 << i; - } - - for (; i < VL_COMPOSITOR_MAX_LAYERS; ++i) { - pipe_sampler_view_reference(&compositor->layers[i], NULL); - pipe_sampler_view_reference(&compositor->palettes[i], NULL); - } -} - -static void gen_rect_verts(struct pipe_video_rect *src_rect, - struct vertex2f *src_inv_size, - struct pipe_video_rect *dst_rect, - struct vertex2f *dst_inv_size, - struct vertex4f *vb) +static void +gen_rect_verts(struct vertex4f *vb, + struct pipe_video_rect *src_rect, + struct vertex2f *src_inv_size, + struct pipe_video_rect *dst_rect, + struct vertex2f *dst_inv_size) { - assert(src_rect); - assert(src_inv_size); - assert((dst_rect && dst_inv_size) /*|| (!dst_rect && !dst_inv_size)*/); assert(vb); + assert(src_rect && src_inv_size); + assert(dst_rect && dst_inv_size); vb[0].x = dst_rect->x * dst_inv_size->x; vb[0].y = dst_rect->y * dst_inv_size->y; @@ -475,162 +371,252 @@ static void gen_rect_verts(struct pipe_video_rect *src_rect, vb[3].w = (src_rect->y + src_rect->h) * src_inv_size->y; } -static unsigned gen_data(struct vl_compositor *c, - struct pipe_sampler_view *src_surface, - struct pipe_video_rect *src_rect, - struct pipe_video_rect *dst_rect, - struct pipe_sampler_view *textures[VL_COMPOSITOR_MAX_LAYERS + 1][2], - void **frag_shaders) +static void +gen_vertex_data(struct vl_compositor *c, struct pipe_video_rect *dst_rect, struct vertex2f *dst_inv_size) { struct vertex4f *vb; struct pipe_transfer *buf_transfer; - unsigned num_rects = 0; unsigned i; assert(c); - assert(src_surface); - assert(src_rect); assert(dst_rect); - assert(textures); vb = pipe_buffer_map(c->pipe, c->vertex_buf.buffer, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, &buf_transfer); if (!vb) - return 0; - - { - struct vertex2f src_inv_size = { 1.0f / src_surface->texture->width0, 1.0f / src_surface->texture->height0}; - gen_rect_verts(src_rect, &src_inv_size, dst_rect, &c->fb_inv_size, vb); - textures[num_rects][0] = src_surface; - textures[num_rects][1] = NULL; - /* XXX: Hack, sort of */ - frag_shaders[num_rects] = c->fragment_shader.ycbcr_2_rgb; - ++num_rects; - vb += 4; - } + return; - for (i = 0; c->dirty_layers > 0; i++) { - assert(i < VL_COMPOSITOR_MAX_LAYERS); + for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; i++) { + if (c->used_layers & (1 << i)) { + struct pipe_sampler_view *sv = c->layers[i].sampler_views[0]; + struct vertex2f src_inv_size = {1.0f / sv->texture->width0, 1.0f / sv->texture->height0}; - if (c->dirty_layers & (1 << i)) { - struct vertex2f layer_inv_size = {1.0f / c->layers[i]->texture->width0, 1.0f / c->layers[i]->texture->height0}; - gen_rect_verts(&c->layer_src_rects[i], &layer_inv_size, &c->layer_dst_rects[i], &layer_inv_size, vb); - textures[num_rects][0] = c->layers[i]; - textures[num_rects][1] = c->palettes[i]; - - if (c->palettes[i]) - frag_shaders[num_rects] = c->fragment_shader.palette_2_rgb; + if (&c->layers[i].fs == c->fs_video_buffer) + gen_rect_verts(vb, &c->layers[i].src_rect, &src_inv_size, dst_rect, dst_inv_size); else - frag_shaders[num_rects] = c->fragment_shader.rgb_2_rgb; + gen_rect_verts(vb, &c->layers[i].src_rect, &src_inv_size, &c->layers[i].dst_rect, &src_inv_size); - ++num_rects; vb += 4; - c->dirty_layers &= ~(1 << i); } } pipe_buffer_unmap(c->pipe, buf_transfer); - - return num_rects; } -static void draw_layers(struct vl_compositor *c, - struct vl_ycbcr_sampler_views *src_sampler, - struct pipe_video_rect *src_rect, - struct pipe_video_rect *dst_rect) +static void +draw_layers(struct vl_compositor *c) { - unsigned num_rects; - struct pipe_sampler_view *surfaces[VL_COMPOSITOR_MAX_LAYERS + 1][2]; - void *frag_shaders[VL_COMPOSITOR_MAX_LAYERS + 1]; - unsigned i; + unsigned vb_index, i; assert(c); - assert(src_sampler); - assert(src_rect); - assert(dst_rect); - num_rects = gen_data(c, src_sampler->y, src_rect, dst_rect, surfaces, frag_shaders); + for (i = 0, vb_index = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) { + if (c->used_layers & (1 << i)) { + struct pipe_sampler_view **samplers = &c->layers[i].sampler_views[0]; + unsigned num_sampler_views = !samplers[1] ? 1 : !samplers[2] ? 2 : 3; - c->pipe->bind_blend_state(c->pipe, c->blend); - for (i = 0; i < num_rects; ++i) { - c->pipe->bind_fs_state(c->pipe, frag_shaders[i]); - if (i == 0) { - c->pipe->set_fragment_sampler_views(c->pipe, 3, &src_sampler->y); - } else { - c->pipe->set_fragment_sampler_views(c->pipe, surfaces[i][1] ? 2 : 1, &surfaces[i][0]); + c->pipe->bind_fs_state(c->pipe, c->layers[i].fs); + c->pipe->set_fragment_sampler_views(c->pipe, num_sampler_views, samplers); + util_draw_arrays(c->pipe, PIPE_PRIM_QUADS, vb_index * 4, 4); + vb_index++; } - - util_draw_arrays(c->pipe, PIPE_PRIM_QUADS, i * 4, 4); } } -void vl_compositor_render(struct vl_compositor *compositor, - struct vl_ycbcr_sampler_views *src_sampler, - struct pipe_video_rect *src_area, - struct pipe_surface *dst_surface, - struct pipe_video_rect *dst_area, - struct pipe_fence_handle **fence) +static void +vl_compositor_clear_layers(struct pipe_video_compositor *compositor) { - void *samplers[3]; + struct vl_compositor *c = (struct vl_compositor *)compositor; + unsigned i, j; assert(compositor); - assert(src_sampler); - assert(src_area); - assert(dst_surface); - assert(dst_area); - if (compositor->fb_state.width != dst_surface->width) { - compositor->fb_inv_size.x = 1.0f / dst_surface->width; - compositor->fb_state.width = dst_surface->width; - } - if (compositor->fb_state.height != dst_surface->height) { - compositor->fb_inv_size.y = 1.0f / dst_surface->height; - compositor->fb_state.height = dst_surface->height; + c->used_layers = 0; + for ( i = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) { + c->layers[i].fs = NULL; + for ( j = 0; j < 3; j++) + pipe_sampler_view_reference(&c->layers[i].sampler_views[j], NULL); } +} - compositor->fb_state.cbufs[0] = dst_surface; - - compositor->viewport.scale[0] = compositor->fb_state.width; - compositor->viewport.scale[1] = compositor->fb_state.height; - compositor->viewport.scale[2] = 1; - compositor->viewport.scale[3] = 1; - compositor->viewport.translate[0] = 0; - compositor->viewport.translate[1] = 0; - compositor->viewport.translate[2] = 0; - compositor->viewport.translate[3] = 0; - - samplers[0] = samplers[1] = samplers[2] = compositor->sampler; +static void +vl_compositor_destroy(struct pipe_video_compositor *compositor) +{ + struct vl_compositor *c = (struct vl_compositor *)compositor; + assert(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, 3, &samplers[0]); - compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader); - compositor->pipe->set_vertex_buffers(compositor->pipe, 1, &compositor->vertex_buf); - compositor->pipe->bind_vertex_elements_state(compositor->pipe, compositor->vertex_elems_state); - compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, compositor->fs_const_buf); + vl_compositor_clear_layers(compositor); - draw_layers(compositor, src_sampler, src_area, dst_area); + cleanup_buffers(c); + cleanup_shaders(c); + cleanup_pipe_state(c); - assert(!compositor->dirty_layers); - compositor->pipe->flush(compositor->pipe, fence); + FREE(compositor); } -void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat) +static void +vl_compositor_set_csc_matrix(struct pipe_video_compositor *compositor, const float matrix[16]) { + struct vl_compositor *c = (struct vl_compositor *)compositor; struct pipe_transfer *buf_transfer; assert(compositor); memcpy ( - pipe_buffer_map(compositor->pipe, compositor->fs_const_buf, + pipe_buffer_map(c->pipe, c->csc_matrix, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, &buf_transfer), - mat, - sizeof(struct fragment_shader_consts) + matrix, + sizeof(csc_matrix) ); - pipe_buffer_unmap(compositor->pipe, buf_transfer); + pipe_buffer_unmap(c->pipe, buf_transfer); +} + +static void +vl_compositor_set_buffer_layer(struct pipe_video_compositor *compositor, + unsigned layer, + struct pipe_video_buffer *buffer, + struct pipe_video_rect *src_rect, + struct pipe_video_rect *dst_rect) +{ + struct vl_compositor *c = (struct vl_compositor *)compositor; + assert(compositor && buffer); + + assert(layer < VL_COMPOSITOR_MAX_LAYERS); + + c->used_layers |= 1 << layer; + c->layers[layer].fs = c->fs_video_buffer; + buffer->get_sampler_views(buffer, c->layers[layer].sampler_views); + c->layers[layer].src_rect = src_rect ? *src_rect : default_rect(&c->layers[layer]); + c->layers[layer].dst_rect = dst_rect ? *dst_rect : default_rect(&c->layers[layer]); +} + +static void +vl_compositor_set_palette_layer(struct pipe_video_compositor *compositor, + unsigned layer, + struct pipe_sampler_view *indexes, + struct pipe_sampler_view *palette, + struct pipe_video_rect *src_rect, + struct pipe_video_rect *dst_rect) +{ + struct vl_compositor *c = (struct vl_compositor *)compositor; + assert(compositor && indexes && palette); + + assert(layer < VL_COMPOSITOR_MAX_LAYERS); + + c->used_layers |= 1 << layer; + c->layers[layer].fs = c->fs_palette; + 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); + c->layers[layer].src_rect = src_rect ? *src_rect : default_rect(&c->layers[layer]); + c->layers[layer].dst_rect = dst_rect ? *dst_rect : default_rect(&c->layers[layer]); +} + +static void +vl_compositor_set_rgba_layer(struct pipe_video_compositor *compositor, + unsigned layer, + struct pipe_sampler_view *rgba, + struct pipe_video_rect *src_rect, + struct pipe_video_rect *dst_rect) +{ + struct vl_compositor *c = (struct vl_compositor *)compositor; + assert(compositor && rgba); + + assert(layer < VL_COMPOSITOR_MAX_LAYERS); + + c->used_layers |= 1 << layer; + c->layers[layer].fs = c->fs_rgba; + 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); + c->layers[layer].src_rect = src_rect ? *src_rect : default_rect(&c->layers[layer]); + c->layers[layer].dst_rect = dst_rect ? *dst_rect : default_rect(&c->layers[layer]); +} + +static void +vl_compositor_render(struct pipe_video_compositor *compositor, + enum pipe_mpeg12_picture_type picture_type, + struct pipe_surface *dst_surface, + struct pipe_video_rect *dst_area, + struct pipe_fence_handle **fence) +{ + struct vl_compositor *c = (struct vl_compositor *)compositor; + struct vertex2f dst_inv_size; + void *samplers[3]; + + assert(compositor); + assert(dst_surface); + assert(dst_area); + + c->fb_state.width = dst_surface->width; + c->fb_state.height = dst_surface->height; + c->fb_state.cbufs[0] = dst_surface; + + c->viewport.scale[0] = dst_surface->width; + c->viewport.scale[1] = dst_surface->height; + + dst_inv_size.x = 1.0f / dst_surface->width; + dst_inv_size.y = 1.0f / dst_surface->height; + + samplers[0] = samplers[1] = samplers[2] = c->sampler; + + gen_vertex_data(c, dst_area, &dst_inv_size); + + c->pipe->set_framebuffer_state(c->pipe, &c->fb_state); + c->pipe->set_viewport_state(c->pipe, &c->viewport); + c->pipe->bind_fragment_sampler_states(c->pipe, 3, &samplers[0]); + 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->bind_blend_state(c->pipe, c->blend); + + draw_layers(c); + + c->pipe->flush(c->pipe, fence); +} + +struct pipe_video_compositor * +vl_compositor_init(struct pipe_video_context *vpipe, struct pipe_context *pipe) +{ + csc_matrix csc_matrix; + struct vl_compositor *compositor; + + compositor = CALLOC_STRUCT(vl_compositor); + + compositor->base.context = vpipe; + compositor->base.destroy = vl_compositor_destroy; + compositor->base.set_csc_matrix = vl_compositor_set_csc_matrix; + compositor->base.clear_layers = vl_compositor_clear_layers; + compositor->base.set_buffer_layer = vl_compositor_set_buffer_layer; + compositor->base.set_palette_layer = vl_compositor_set_palette_layer; + compositor->base.set_rgba_layer = vl_compositor_set_rgba_layer; + compositor->base.render_picture = vl_compositor_render; + + compositor->pipe = pipe; + + if (!init_pipe_state(compositor)) + return false; + + if (!init_shaders(compositor)) { + cleanup_pipe_state(compositor); + return false; + } + if (!init_buffers(compositor)) { + cleanup_shaders(compositor); + cleanup_pipe_state(compositor); + return false; + } + + vl_compositor_clear_layers(&compositor->base); + + vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, csc_matrix); + vl_compositor_set_csc_matrix(&compositor->base, csc_matrix); + + return &compositor->base; } |