summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <[email protected]>2011-04-27 15:17:24 +0200
committerChristian König <[email protected]>2011-04-27 15:19:35 +0200
commit0d53cb2e83cafb7007068192674a8b5b57a27ca4 (patch)
tree238dd9872e89df7056a3fb2cda586d9213808796
parent6092fbed46302e2bdf6c6f2e229f4e393652e228 (diff)
[g3dvl] implement clearing of dirty destination surface areas
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.c83
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.h5
2 files changed, 75 insertions, 13 deletions
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index 2f2b32d7944..f6f7b65fd6b 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -31,6 +31,7 @@
#include <util/u_memory.h>
#include <util/u_draw.h>
+#include <util/u_surface.h>
#include <tgsi/tgsi_ureg.h>
@@ -303,6 +304,22 @@ static void cleanup_pipe_state(struct vl_compositor *c)
}
static bool
+create_vertex_buffer(struct vl_compositor *c)
+{
+ assert(c);
+
+ pipe_resource_reference(&c->vertex_buf.buffer, NULL);
+ c->vertex_buf.buffer = pipe_buffer_create
+ (
+ c->pipe->screen,
+ PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STREAM,
+ sizeof(struct vertex4f) * VL_COMPOSITOR_MAX_LAYERS * 4
+ );
+ return c->vertex_buf.buffer != NULL;
+}
+
+static bool
init_buffers(struct vl_compositor *c)
{
struct pipe_vertex_element vertex_elems[2];
@@ -314,13 +331,7 @@ init_buffers(struct vl_compositor *c)
*/
c->vertex_buf.stride = sizeof(struct vertex4f);
c->vertex_buf.buffer_offset = 0;
- c->vertex_buf.buffer = pipe_buffer_create
- (
- c->pipe->screen,
- PIPE_BIND_VERTEX_BUFFER,
- PIPE_USAGE_STREAM,
- sizeof(struct vertex4f) * (VL_COMPOSITOR_MAX_LAYERS + 1) * 4
- );
+ create_vertex_buffer(c);
vertex_elems[0].src_offset = 0;
vertex_elems[0].instance_divisor = 0;
@@ -431,13 +442,30 @@ gen_vertex_data(struct vl_compositor *c)
PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | PIPE_TRANSFER_DONTBLOCK,
&buf_transfer);
- if (!vb)
- return;
+ if (!vb) {
+ // If buffer is still locked from last draw create a new one
+ create_vertex_buffer(c);
+ vb = pipe_buffer_map(c->pipe, c->vertex_buf.buffer,
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &buf_transfer);
+ }
for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; i++) {
if (c->used_layers & (1 << i)) {
- gen_rect_verts(vb, &c->layers[i]);
+ struct vl_compositor_layer *layer = &c->layers[i];
+ gen_rect_verts(vb, layer);
vb += 4;
+
+ if (layer->clearing &&
+ c->dirty_tl.x >= layer->dst.tl.x &&
+ c->dirty_tl.y >= layer->dst.tl.y &&
+ c->dirty_br.x <= layer->dst.br.x &&
+ c->dirty_br.y <= layer->dst.br.y) {
+
+ // We clear the dirty area anyway, no need for clear_render_target
+ c->dirty_tl.x = c->dirty_tl.y = 1.0f;
+ c->dirty_br.x = c->dirty_br.y = 0.0f;
+ }
}
}
@@ -453,19 +481,37 @@ draw_layers(struct vl_compositor *c)
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];
+ struct vl_compositor_layer *layer = &c->layers[i];
+ struct pipe_sampler_view **samplers = &layer->sampler_views[0];
unsigned num_sampler_views = !samplers[1] ? 1 : !samplers[2] ? 2 : 3;
- c->pipe->bind_fs_state(c->pipe, c->layers[i].fs);
- c->pipe->bind_fragment_sampler_states(c->pipe, num_sampler_views, c->layers[i].samplers);
+ 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);
util_draw_arrays(c->pipe, PIPE_PRIM_QUADS, vb_index * 4, 4);
vb_index++;
+
+ // Remember the currently drawn area as dirty for the next draw command
+ c->dirty_tl.x = MIN2(layer->dst.tl.x, c->dirty_tl.x);
+ c->dirty_tl.y = MIN2(layer->dst.tl.y, c->dirty_tl.y);
+ c->dirty_br.x = MAX2(layer->dst.br.x, c->dirty_br.x);
+ c->dirty_br.y = MAX2(layer->dst.br.y, c->dirty_br.y);
}
}
}
static void
+vl_compositor_reset_dirty_area(struct pipe_video_compositor *compositor)
+{
+ struct vl_compositor *c = (struct vl_compositor *)compositor;
+
+ assert(compositor);
+
+ c->dirty_tl.x = c->dirty_tl.y = 0.0f;
+ c->dirty_br.x = c->dirty_br.y = 1.0f;
+}
+
+static void
vl_compositor_clear_layers(struct pipe_video_compositor *compositor)
{
struct vl_compositor *c = (struct vl_compositor *)compositor;
@@ -532,6 +578,7 @@ vl_compositor_set_buffer_layer(struct pipe_video_compositor *compositor,
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
c->used_layers |= 1 << layer;
+ c->layers[layer].clearing = true;
c->layers[layer].fs = c->fs_video_buffer;
sampler_views = buffer->get_sampler_view_components(buffer);
@@ -559,6 +606,7 @@ vl_compositor_set_palette_layer(struct pipe_video_compositor *compositor,
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
c->used_layers |= 1 << layer;
+ c->layers[layer].clearing = false;
c->layers[layer].fs = c->fs_palette;
c->layers[layer].samplers[0] = c->sampler_linear;
c->layers[layer].samplers[1] = c->sampler_nearest;
@@ -585,6 +633,7 @@ vl_compositor_set_rgba_layer(struct pipe_video_compositor *compositor,
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
c->used_layers |= 1 << layer;
+ c->layers[layer].clearing = false;
c->layers[layer].fs = c->fs_rgba;
c->layers[layer].samplers[0] = c->sampler_linear;
c->layers[layer].samplers[1] = NULL;
@@ -606,6 +655,7 @@ vl_compositor_render(struct pipe_video_compositor *compositor,
{
struct vl_compositor *c = (struct vl_compositor *)compositor;
struct pipe_scissor_state scissor;
+ float clearcolor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
assert(compositor);
assert(dst_surface);
@@ -631,6 +681,12 @@ vl_compositor_render(struct pipe_video_compositor *compositor,
gen_vertex_data(c);
+ if (c->dirty_tl.x < c->dirty_br.x || c->dirty_tl.y < c->dirty_br.y) {
+ util_clear_render_target(c->pipe, dst_surface, clearcolor, 0, 0, dst_surface->width, dst_surface->height);
+ c->dirty_tl.x = c->dirty_tl.y = 1.0f;
+ c->dirty_br.x = c->dirty_br.y = 0.0f;
+ }
+
c->pipe->set_scissor_state(c->pipe, &scissor);
c->pipe->set_framebuffer_state(c->pipe, &c->fb_state);
c->pipe->set_viewport_state(c->pipe, &c->viewport);
@@ -682,6 +738,7 @@ vl_compositor_init(struct pipe_video_context *vpipe, struct pipe_context *pipe)
vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, csc_matrix);
vl_compositor_set_csc_matrix(&compositor->base, csc_matrix);
+ vl_compositor_reset_dirty_area(&compositor->base);
return &compositor->base;
}
diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h
index 339ea415e8a..725dcc15a13 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.h
+++ b/src/gallium/auxiliary/vl/vl_compositor.h
@@ -40,8 +40,11 @@ struct pipe_context;
struct vl_compositor_layer
{
+ bool clearing;
+
void *fs;
void *samplers[3];
+
struct pipe_sampler_view *sampler_views[3];
struct {
struct vertex2f tl, br;
@@ -69,6 +72,8 @@ struct vl_compositor
void *fs_palette;
void *fs_rgba;
+ struct vertex2f dirty_tl, dirty_br;
+
unsigned used_layers:VL_COMPOSITOR_MAX_LAYERS;
struct vl_compositor_layer layers[VL_COMPOSITOR_MAX_LAYERS];
};