static void 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 (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, blend); c->pipe->set_viewport_state(c->pipe, &layer->viewport); 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++; if (dirty) { // Remember the currently drawn area as dirty for the next draw command 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); dirty->y1 = MAX2(drawn.y1, dirty->y1); } } } }
static void gen_vertex_data(struct vl_compositor *c, struct vl_compositor_state *s, struct u_rect *dirty) { struct vertex2f *vb; struct pipe_transfer *buf_transfer; unsigned i; assert(c); vb = pipe_buffer_map(c->pipe, c->vertex_buf.buffer, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE | PIPE_TRANSFER_DONTBLOCK, &buf_transfer); 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_RANGE, &buf_transfer); } for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; i++) { if (s->used_layers & (1 << i)) { struct vl_compositor_layer *layer = &s->layers[i]; gen_rect_verts(vb, layer); vb += 20; if (!layer->viewport_valid) { layer->viewport.scale[0] = c->fb_state.width; layer->viewport.scale[1] = c->fb_state.height; layer->viewport.translate[0] = 0; layer->viewport.translate[1] = 0; } if (dirty && layer->clearing) { struct u_rect drawn = calc_drawn_area(s, layer); if ( dirty->x0 >= drawn.x0 && dirty->y0 >= drawn.y0 && dirty->x1 <= drawn.x1 && dirty->y1 <= drawn.y1) { // We clear the dirty area anyway, no need for clear_render_target dirty->x0 = dirty->y0 = MAX_DIRTY; dirty->x1 = dirty->y1 = MIN_DIRTY; } } } } pipe_buffer_unmap(c->pipe, buf_transfer); }
static void gen_vertex_data(struct vl_compositor *c, struct vl_compositor_state *s, struct u_rect *dirty) { struct vertex2f *vb; unsigned i; assert(c); /* Allocate new memory for vertices. */ u_upload_alloc(c->upload, 0, c->vertex_buf.stride * VL_COMPOSITOR_MAX_LAYERS * 4, /* size */ &c->vertex_buf.buffer_offset, &c->vertex_buf.buffer, (void**)&vb); for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; i++) { if (s->used_layers & (1 << i)) { struct vl_compositor_layer *layer = &s->layers[i]; gen_rect_verts(vb, layer); vb += 20; if (!layer->viewport_valid) { layer->viewport.scale[0] = c->fb_state.width; layer->viewport.scale[1] = c->fb_state.height; layer->viewport.translate[0] = 0; layer->viewport.translate[1] = 0; } if (dirty && layer->clearing) { struct u_rect drawn = calc_drawn_area(s, layer); if ( dirty->x0 >= drawn.x0 && dirty->y0 >= drawn.y0 && dirty->x1 <= drawn.x1 && dirty->y1 <= drawn.y1) { // We clear the dirty area anyway, no need for clear_render_target dirty->x0 = dirty->y0 = MAX_DIRTY; dirty->x1 = dirty->y1 = MIN_DIRTY; } } } } u_upload_unmap(c->upload); }