[PATCH weston 03/13] Update the OpenGL renderer to handle views

Jason Ekstrand jason at jlekstrand.net
Sun Oct 13 05:38:13 CEST 2013


Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
---
 src/gl-renderer.c | 102 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 57 insertions(+), 45 deletions(-)

diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index ae69f22..f5eb5c2 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -193,7 +193,7 @@ gl_renderer_print_egl_error_state(void)
  * polygon area.
  */
 static int
-calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
+calculate_edges(struct weston_view *ev, pixman_box32_t *rect,
 		pixman_box32_t *surf_rect, GLfloat *ex, GLfloat *ey)
 {
 
@@ -213,8 +213,8 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
 
 	/* transform surface to screen space: */
 	for (i = 0; i < surf.n; i++)
-		weston_surface_to_global_float(es, surf.x[i], surf.y[i],
-					       &surf.x[i], &surf.y[i]);
+		weston_view_to_global_float(ev, surf.x[i], surf.y[i],
+					    &surf.x[i], &surf.y[i]);
 
 	/* find bounding box: */
 	min_x = max_x = surf.x[0];
@@ -238,9 +238,8 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
 	 * there will be only four edges.  We just need to clip the surface
 	 * vertices to the clip rect bounds:
 	 */
-	if (!es->transform.enabled) {
+	if (!ev->transform.enabled)
 		return clip_simple(&ctx, &surf, ex, ey);
-	}
 
 	/* Transformed case: use a general polygon clipping algorithm to
 	 * clip the surface rectangle with each side of 'rect'.
@@ -257,11 +256,11 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
 }
 
 static int
-texture_region(struct weston_surface *es, pixman_region32_t *region,
+texture_region(struct weston_view *ev, pixman_region32_t *region,
 		pixman_region32_t *surf_region)
 {
-	struct gl_surface_state *gs = get_surface_state(es);
-	struct weston_compositor *ec = es->compositor;
+	struct gl_surface_state *gs = get_surface_state(ev->surface);
+	struct weston_compositor *ec = ev->surface->compositor;
 	struct gl_renderer *gr = get_renderer(ec);
 	GLfloat *v, inv_width, inv_height;
 	unsigned int *vtxcnt, nvtx = 0;
@@ -302,18 +301,20 @@ texture_region(struct weston_surface *es, pixman_region32_t *region,
 			 * form the intersection of the clip rect and the transformed
 			 * surface.
 			 */
-			n = calculate_edges(es, rect, surf_rect, ex, ey);
+			n = calculate_edges(ev, rect, surf_rect, ex, ey);
 			if (n < 3)
 				continue;
 
 			/* emit edge points: */
 			for (k = 0; k < n; k++) {
-				weston_surface_from_global_float(es, ex[k], ey[k], &sx, &sy);
+				weston_view_from_global_float(ev, ex[k], ey[k],
+							      &sx, &sy);
 				/* position: */
 				*(v++) = ex[k];
 				*(v++) = ey[k];
 				/* texcoord: */
-				weston_surface_to_buffer_float(es, sx, sy,
+				weston_surface_to_buffer_float(ev->surface,
+							       sx, sy,
 							       &bx, &by);
 				*(v++) = bx * inv_width;
 				if (gs->y_inverted) {
@@ -331,9 +332,9 @@ texture_region(struct weston_surface *es, pixman_region32_t *region,
 }
 
 static void
-triangle_fan_debug(struct weston_surface *surface, int first, int count)
+triangle_fan_debug(struct weston_view *view, int first, int count)
 {
-	struct weston_compositor *compositor = surface->compositor;
+	struct weston_compositor *compositor = view->surface->compositor;
 	struct gl_renderer *gr = get_renderer(compositor);
 	int i;
 	GLushort *buffer;
@@ -371,10 +372,10 @@ triangle_fan_debug(struct weston_surface *surface, int first, int count)
 }
 
 static void
-repaint_region(struct weston_surface *es, pixman_region32_t *region,
+repaint_region(struct weston_view *ev, pixman_region32_t *region,
 		pixman_region32_t *surf_region)
 {
-	struct weston_compositor *ec = es->compositor;
+	struct weston_compositor *ec = ev->surface->compositor;
 	struct gl_renderer *gr = get_renderer(ec);
 	GLfloat *v;
 	unsigned int *vtxcnt;
@@ -388,7 +389,7 @@ repaint_region(struct weston_surface *es, pixman_region32_t *region,
 	 * polygon for each pair, and store it as a triangle fan if
 	 * it has a non-zero area (at least 3 vertices1, actually).
 	 */
-	nfans = texture_region(es, region, surf_region);
+	nfans = texture_region(ev, region, surf_region);
 
 	v = gr->vertices.data;
 	vtxcnt = gr->vtxcnt.data;
@@ -404,7 +405,7 @@ repaint_region(struct weston_surface *es, pixman_region32_t *region,
 	for (i = 0, first = 0; i < nfans; i++) {
 		glDrawArrays(GL_TRIANGLE_FAN, first, vtxcnt[i]);
 		if (gr->fan_debug)
-			triangle_fan_debug(es, first, vtxcnt[i]);
+			triangle_fan_debug(ev, first, vtxcnt[i]);
 		first += vtxcnt[i];
 	}
 
@@ -464,28 +465,28 @@ use_shader(struct gl_renderer *gr, struct gl_shader *shader)
 
 static void
 shader_uniforms(struct gl_shader *shader,
-		       struct weston_surface *surface,
-		       struct weston_output *output)
+		struct weston_view *view,
+		struct weston_output *output)
 {
 	int i;
-	struct gl_surface_state *gs = get_surface_state(surface);
+	struct gl_surface_state *gs = get_surface_state(view->surface);
 
 	glUniformMatrix4fv(shader->proj_uniform,
 			   1, GL_FALSE, output->matrix.d);
 	glUniform4fv(shader->color_uniform, 1, gs->color);
-	glUniform1f(shader->alpha_uniform, surface->alpha);
+	glUniform1f(shader->alpha_uniform, view->alpha);
 
 	for (i = 0; i < gs->num_textures; i++)
 		glUniform1i(shader->tex_uniforms[i], i);
 }
 
 static void
-draw_surface(struct weston_surface *es, struct weston_output *output,
-	     pixman_region32_t *damage) /* in global coordinates */
+draw_view(struct weston_view *ev, struct weston_output *output,
+	  pixman_region32_t *damage) /* in global coordinates */
 {
-	struct weston_compositor *ec = es->compositor;
+	struct weston_compositor *ec = ev->surface->compositor;
 	struct gl_renderer *gr = get_renderer(ec);
-	struct gl_surface_state *gs = get_surface_state(es);
+	struct gl_surface_state *gs = get_surface_state(ev->surface);
 	/* repaint bounding region in global coordinates: */
 	pixman_region32_t repaint;
 	/* non-opaque region in surface coordinates: */
@@ -495,8 +496,8 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
 
 	pixman_region32_init(&repaint);
 	pixman_region32_intersect(&repaint,
-				  &es->transform.boundingbox, damage);
-	pixman_region32_subtract(&repaint, &repaint, &es->clip);
+				  &ev->transform.boundingbox, damage);
+	pixman_region32_subtract(&repaint, &repaint, &ev->clip);
 
 	if (!pixman_region32_not_empty(&repaint))
 		goto out;
@@ -505,13 +506,14 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
 
 	if (gr->fan_debug) {
 		use_shader(gr, &gr->solid_shader);
-		shader_uniforms(&gr->solid_shader, es, output);
+		shader_uniforms(&gr->solid_shader, ev, output);
 	}
 
 	use_shader(gr, gs->shader);
-	shader_uniforms(gs->shader, es, output);
+	shader_uniforms(gs->shader, ev, output);
 
-	if (es->transform.enabled || output->zoom.active || output->current_scale != es->buffer_scale)
+	if (ev->transform.enabled || output->zoom.active ||
+	    output->current_scale != ev->surface->buffer_scale)
 		filter = GL_LINEAR;
 	else
 		filter = GL_NEAREST;
@@ -525,10 +527,11 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
 
 	/* blended region is whole surface minus opaque region: */
 	pixman_region32_init_rect(&surface_blend, 0, 0,
-				  es->geometry.width, es->geometry.height);
-	pixman_region32_subtract(&surface_blend, &surface_blend, &es->opaque);
+				  ev->geometry.width, ev->geometry.height);
+	pixman_region32_subtract(&surface_blend, &surface_blend, &ev->surface->opaque);
 
-	if (pixman_region32_not_empty(&es->opaque)) {
+	/* XXX: Should we be using ev->transform.opaque here? */
+	if (pixman_region32_not_empty(&ev->surface->opaque)) {
 		if (gs->shader == &gr->texture_shader_rgba) {
 			/* Special case for RGBA textures with possibly
 			 * bad data in alpha channel: use the shader
@@ -536,21 +539,21 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
 			 * Xwayland surfaces need this.
 			 */
 			use_shader(gr, &gr->texture_shader_rgbx);
-			shader_uniforms(&gr->texture_shader_rgbx, es, output);
+			shader_uniforms(&gr->texture_shader_rgbx, ev, output);
 		}
 
-		if (es->alpha < 1.0)
+		if (ev->alpha < 1.0)
 			glEnable(GL_BLEND);
 		else
 			glDisable(GL_BLEND);
 
-		repaint_region(es, &repaint, &es->opaque);
+		repaint_region(ev, &repaint, &ev->surface->opaque);
 	}
 
 	if (pixman_region32_not_empty(&surface_blend)) {
 		use_shader(gr, gs->shader);
 		glEnable(GL_BLEND);
-		repaint_region(es, &repaint, &surface_blend);
+		repaint_region(ev, &repaint, &surface_blend);
 	}
 
 	pixman_region32_fini(&surface_blend);
@@ -560,14 +563,14 @@ out:
 }
 
 static void
-repaint_surfaces(struct weston_output *output, pixman_region32_t *damage)
+repaint_views(struct weston_output *output, pixman_region32_t *damage)
 {
 	struct weston_compositor *compositor = output->compositor;
-	struct weston_surface *surface;
+	struct weston_view *view;
 
-	wl_list_for_each_reverse(surface, &compositor->surface_list, link)
-		if (surface->plane == &compositor->primary_plane)
-			draw_surface(surface, output, damage);
+	wl_list_for_each_reverse(view, &compositor->view_list, link)
+		if (view->plane == &compositor->primary_plane)
+			draw_view(view, output, damage);
 }
 
 
@@ -762,7 +765,7 @@ gl_renderer_repaint_output(struct weston_output *output,
 		pixman_region32_subtract(&undamaged, &output->region,
 					 output_damage);
 		gr->fan_debug = 0;
-		repaint_surfaces(output, &undamaged);
+		repaint_views(output, &undamaged);
 		gr->fan_debug = 1;
 		pixman_region32_fini(&undamaged);
 	}
@@ -775,7 +778,7 @@ gl_renderer_repaint_output(struct weston_output *output,
 
 	pixman_region32_union(&total_damage, &buffer_damage, output_damage);
 
-	repaint_surfaces(output, &total_damage);
+	repaint_views(output, &total_damage);
 
 	pixman_region32_fini(&total_damage);
 	pixman_region32_fini(&buffer_damage);
@@ -830,6 +833,8 @@ gl_renderer_flush_damage(struct weston_surface *surface)
 	struct gl_renderer *gr = get_renderer(surface->compositor);
 	struct gl_surface_state *gs = get_surface_state(surface);
 	struct weston_buffer *buffer = gs->buffer_ref.buffer;
+	struct weston_view *view;
+	int texture_used;
 	GLenum format;
 	int pixel_type;
 
@@ -850,7 +855,14 @@ gl_renderer_flush_damage(struct weston_surface *surface)
 	 * hold the reference to the buffer, in case the surface
 	 * migrates back to the primary plane.
 	 */
-	if (surface->plane != &surface->compositor->primary_plane)
+	texture_used = 0;
+	wl_list_for_each(view, &surface->views, surface_link) {
+		if (view->plane == &surface->compositor->primary_plane) {
+			texture_used = 1;
+			break;
+		}
+	}
+	if (!texture_used)
 		return;
 
 	if (!pixman_region32_not_empty(&gs->texture_damage))
-- 
1.8.3.1



More information about the wayland-devel mailing list