Skip to content
Commits on Source (5)
......@@ -108,6 +108,7 @@ paint_node_update(struct weston_paint_node *pnode)
struct weston_matrix *mat = &pnode->buffer_to_output_matrix;
weston_view_buffer_to_output_matrix(pnode->view, pnode->output, mat);
weston_matrix_invert(&pnode->output_to_buffer_matrix, mat);
pnode->needs_filtering = weston_matrix_needs_filtering(mat);
}
......
......@@ -475,6 +475,7 @@ struct weston_paint_node {
/* Mutable members: */
struct weston_matrix buffer_to_output_matrix;
struct weston_matrix output_to_buffer_matrix;
bool needs_filtering;
/* struct weston_output::paint_node_z_order_list */
......
......@@ -152,30 +152,6 @@ weston_matrix_to_pixman_transform(pixman_transform_t *pt,
pt->matrix[2][2] = pixman_double_to_fixed(wm->d[15]);
}
static void
pixman_renderer_compute_transform(pixman_transform_t *transform_out,
struct weston_view *ev,
struct weston_output *output)
{
struct weston_matrix matrix;
/* Set up the source transformation based on the surface
position, the output position/transform/scale and the client
specified buffer transform/scale */
matrix = output->inverse_matrix;
if (ev->transform.enabled) {
weston_matrix_multiply(&matrix, &ev->transform.inverse);
} else {
weston_matrix_translate(&matrix,
-ev->geometry.x, -ev->geometry.y, 0);
}
weston_matrix_multiply(&matrix, &ev->surface->surface_to_buffer_matrix);
weston_matrix_to_pixman_transform(transform_out, &matrix);
}
static bool
view_transformation_is_translation(struct weston_view *view)
{
......@@ -315,24 +291,24 @@ composite_clipped(struct weston_output *output,
/** Paint an intersected region
*
* \param ev The view to be painted.
* \param output The output being painted.
* \param pnode The paint node to be painted.
* \param repaint_output The region to be painted in output coordinates.
* \param source_clip The region of the source image to use, in source image
* coordinates. If NULL, use the whole source image.
* \param pixman_op Compositing operator, either SRC or OVER.
*/
static void
repaint_region(struct weston_view *ev, struct weston_output *output,
repaint_region(struct weston_paint_node *pnode,
pixman_region32_t *repaint_output,
pixman_region32_t *source_clip,
pixman_op_t pixman_op)
{
struct weston_output *output = pnode->output;
struct weston_view *ev = pnode->view;
struct pixman_renderer *pr =
(struct pixman_renderer *) output->compositor->renderer;
struct pixman_surface_state *ps = get_surface_state(ev->surface);
struct pixman_output_state *po = get_output_state(output);
struct weston_buffer_viewport *vp = &ev->surface->buffer_viewport;
pixman_image_t *target_image;
pixman_transform_t transform;
pixman_filter_t filter;
......@@ -347,9 +323,10 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
/* Clip rendering to the damaged output region */
pixman_image_set_clip_region32(target_image, repaint_output);
pixman_renderer_compute_transform(&transform, ev, output);
weston_matrix_to_pixman_transform(&transform,
&pnode->output_to_buffer_matrix);
if (ev->transform.enabled || output->current_scale != vp->buffer.scale)
if (pnode->needs_filtering)
filter = PIXMAN_FILTER_BILINEAR;
else
filter = PIXMAN_FILTER_NEAREST;
......@@ -392,10 +369,13 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
}
static void
draw_view_translated(struct weston_view *view, struct weston_output *output,
draw_node_translated(struct weston_paint_node *pnode,
pixman_region32_t *repaint_global)
{
struct weston_surface *surface = view->surface;
struct weston_output *output = pnode->output;
struct weston_surface *surface = pnode->surface;
struct weston_view *view = pnode->view;
/* non-opaque region in surface coordinates: */
pixman_region32_t surface_blend;
/* region to be painted in output coordinates: */
......@@ -422,7 +402,7 @@ draw_view_translated(struct weston_view *view, struct weston_output *output,
output,
&repaint_output);
repaint_region(view, output, &repaint_output, NULL,
repaint_region(pnode, &repaint_output, NULL,
PIXMAN_OP_SRC);
}
}
......@@ -435,8 +415,7 @@ draw_view_translated(struct weston_view *view, struct weston_output *output,
output,
&repaint_output);
repaint_region(view, output, &repaint_output, NULL,
PIXMAN_OP_OVER);
repaint_region(pnode, &repaint_output, NULL, PIXMAN_OP_OVER);
}
pixman_region32_fini(&surface_blend);
......@@ -444,11 +423,12 @@ draw_view_translated(struct weston_view *view, struct weston_output *output,
}
static void
draw_view_source_clipped(struct weston_view *view,
struct weston_output *output,
draw_node_source_clipped(struct weston_paint_node *pnode,
pixman_region32_t *repaint_global)
{
struct weston_surface *surface = view->surface;
struct weston_surface *surface = pnode->surface;
struct weston_output *output = pnode->output;
struct weston_view *view = pnode->view;
pixman_region32_t surf_region;
pixman_region32_t buffer_region;
pixman_region32_t repaint_output;
......@@ -472,8 +452,7 @@ draw_view_source_clipped(struct weston_view *view,
weston_region_global_to_output(&repaint_output, output,
&repaint_output);
repaint_region(view, output, &repaint_output, &buffer_region,
PIXMAN_OP_OVER);
repaint_region(pnode, &repaint_output, &buffer_region, PIXMAN_OP_OVER);
pixman_region32_fini(&repaint_output);
pixman_region32_fini(&buffer_region);
......@@ -526,7 +505,7 @@ draw_paint_node(struct weston_paint_node *pnode,
* Also the boundingbox is accurate rather than an
* approximation.
*/
draw_view_translated(pnode->view, pnode->output, &repaint);
draw_node_translated(pnode, &repaint);
} else {
/* The complex case: the view transformation does not allow
* converting opaque etc. regions into global coordinate space.
......@@ -535,7 +514,7 @@ draw_paint_node(struct weston_paint_node *pnode,
* to be used whole. Source clipping does not work with
* PIXMAN_OP_SRC.
*/
draw_view_source_clipped(pnode->view, pnode->output, &repaint);
draw_node_source_clipped(pnode, &repaint);
}
out:
......
......@@ -524,13 +524,14 @@ compress_bands(pixman_box32_t *inrects, int nrects, pixman_box32_t **outrects)
}
static int
texture_region(struct weston_view *ev,
texture_region(struct weston_paint_node *pnode,
pixman_region32_t *region,
pixman_region32_t *surf_region)
{
struct gl_surface_state *gs = get_surface_state(ev->surface);
struct gl_surface_state *gs = get_surface_state(pnode->surface);
struct weston_buffer *buffer = gs->buffer_ref.buffer;
struct weston_compositor *ec = ev->surface->compositor;
struct weston_compositor *ec = pnode->surface->compositor;
struct weston_view *ev = pnode->view;
struct gl_renderer *gr = get_renderer(ec);
GLfloat *v, inv_width, inv_height;
unsigned int *vtxcnt, nvtx = 0;
......@@ -808,9 +809,9 @@ gl_renderer_do_capture_tasks(struct gl_renderer *gr,
}
static void
gl_renderer_send_shader_error(struct weston_view *view)
gl_renderer_send_shader_error(struct weston_paint_node *pnode)
{
struct wl_resource *resource = view->surface->resource;
struct wl_resource *resource = pnode->surface->resource;
if (!resource)
return;
......@@ -884,12 +885,12 @@ triangle_fan_debug(struct gl_renderer *gr,
static void
repaint_region(struct gl_renderer *gr,
struct weston_view *ev,
struct weston_output *output,
struct weston_paint_node *pnode,
pixman_region32_t *region,
pixman_region32_t *surf_region,
const struct gl_shader_config *sconf)
{
struct weston_output *output = pnode->output;
GLfloat *v;
unsigned int *vtxcnt;
int i, first, nfans;
......@@ -902,7 +903,7 @@ repaint_region(struct gl_renderer *gr,
* polygon for each pair, and store it as a triangle fan if
* it has a non-zero area (at least 3 vertices, actually).
*/
nfans = texture_region(ev, region, surf_region);
nfans = texture_region(pnode, region, surf_region);
v = gr->vertices.data;
vtxcnt = gr->vtxcnt.data;
......@@ -916,7 +917,7 @@ repaint_region(struct gl_renderer *gr,
glEnableVertexAttribArray(1);
if (!gl_renderer_use_program(gr, sconf)) {
gl_renderer_send_shader_error(ev);
gl_renderer_send_shader_error(pnode);
/* continue drawing with the fallback shader */
}
......@@ -1057,17 +1058,18 @@ censor_override(struct gl_shader_config *sconf,
*/
static void
maybe_censor_override(struct gl_shader_config *sconf,
struct weston_output *output,
struct weston_view *ev)
struct weston_paint_node *pnode)
{
struct gl_surface_state *gs = get_surface_state(ev->surface);
struct weston_output *output = pnode->output;
struct weston_surface *surface = pnode->surface;
struct gl_surface_state *gs = get_surface_state(surface);
struct weston_buffer *buffer = gs->buffer_ref.buffer;
bool recording_censor =
(output->disable_planes > 0) &&
(ev->surface->desired_protection > WESTON_HDCP_DISABLE);
(surface->desired_protection > WESTON_HDCP_DISABLE);
bool unprotected_censor =
(ev->surface->desired_protection > output->current_protection);
(surface->desired_protection > output->current_protection);
if (buffer->direct_display) {
censor_override(sconf, output);
......@@ -1076,7 +1078,7 @@ maybe_censor_override(struct gl_shader_config *sconf,
/* When not in enforced mode, the client is notified of the protection */
/* change, so content censoring is not required */
if (ev->surface->protection_mode !=
if (surface->protection_mode !=
WESTON_SURFACE_PROTECTION_MODE_ENFORCED)
return;
......@@ -1192,7 +1194,7 @@ draw_paint_node(struct weston_paint_node *pnode,
else
pixman_region32_copy(&surface_opaque, &pnode->surface->opaque);
maybe_censor_override(&sconf, pnode->output, pnode->view);
maybe_censor_override(&sconf, pnode);
if (pixman_region32_not_empty(&surface_opaque)) {
struct gl_shader_config alt = sconf;
......@@ -1211,15 +1213,13 @@ draw_paint_node(struct weston_paint_node *pnode,
else
glDisable(GL_BLEND);
repaint_region(gr, pnode->view, pnode->output,
&repaint, &surface_opaque, &alt);
repaint_region(gr, pnode, &repaint, &surface_opaque, &alt);
gs->used_in_output_repaint = true;
}
if (pixman_region32_not_empty(&surface_blend)) {
glEnable(GL_BLEND);
repaint_region(gr, pnode->view, pnode->output,
&repaint, &surface_blend, &sconf);
repaint_region(gr, pnode, &repaint, &surface_blend, &sconf);
gs->used_in_output_repaint = true;
}
......