From d0b870d3a9f4e5e90c42bfa2663b205a14c4b180 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Wed, 21 Aug 2013 01:52:16 +0100 Subject: [PATCH] tower: make sure not to blend when updating tower Each level in the tower is initialized by binding the texture for that level to an offscreen framebuffer and rendering the previous level as a textured rectangle. The problem was that we were blending the previous level with undefined data so argb32 windows with transparencies would result in artefacts. This makes sure to disable blending when drawing the textured rectangle. --- src/compositor/meta-texture-tower.c | 49 +++++++++++++++++++---------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c index bafd508b8..ced55510f 100644 --- a/src/compositor/meta-texture-tower.c +++ b/src/compositor/meta-texture-tower.c @@ -60,6 +60,7 @@ struct _MetaTextureTower CoglTexture *textures[MAX_TEXTURE_LEVELS]; CoglOffscreen *fbos[MAX_TEXTURE_LEVELS]; Box invalid[MAX_TEXTURE_LEVELS]; + CoglPipeline *pipeline_template; }; /** @@ -91,6 +92,9 @@ meta_texture_tower_free (MetaTextureTower *tower) { g_return_if_fail (tower != NULL); + if (tower->pipeline_template != NULL) + cogl_object_unref (tower->pipeline_template); + meta_texture_tower_set_base_texture (tower, NULL); g_slice_free (MetaTextureTower, tower); @@ -384,30 +388,43 @@ texture_tower_revalidate_fbo (MetaTextureTower *tower, int dest_texture_width = cogl_texture_get_width (dest_texture); int dest_texture_height = cogl_texture_get_height (dest_texture); Box *invalid = &tower->invalid[level]; - CoglMatrix modelview; + CoglFramebuffer *fb; + CoglError *catch_error = NULL; + CoglPipeline *pipeline; if (tower->fbos[level] == NULL) - tower->fbos[level] = cogl_offscreen_new_to_texture (dest_texture); + tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture); - if (tower->fbos[level] == NULL) - return FALSE; + fb = COGL_FRAMEBUFFER (tower->fbos[level]); - cogl_push_framebuffer (COGL_FRAMEBUFFER (tower->fbos[level])); + if (!cogl_framebuffer_allocate (fb, &catch_error)) + { + cogl_error_free (catch_error); + return FALSE; + } - cogl_ortho (0, dest_texture_width, dest_texture_height, 0, -1., 1.); + cogl_framebuffer_orthographic (fb, 0, 0, dest_texture_width, dest_texture_height, -1., 1.); - cogl_matrix_init_identity (&modelview); - cogl_set_modelview_matrix (&modelview); + if (!tower->pipeline_template) + { + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); + tower->pipeline_template = cogl_pipeline_new (ctx); + cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL); + } - cogl_set_source_texture (tower->textures[level - 1]); - cogl_rectangle_with_texture_coords (invalid->x1, invalid->y1, - invalid->x2, invalid->y2, - (2. * invalid->x1) / source_texture_width, - (2. * invalid->y1) / source_texture_height, - (2. * invalid->x2) / source_texture_width, - (2. * invalid->y2) / source_texture_height); + pipeline = cogl_pipeline_copy (tower->pipeline_template); + cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]); - cogl_pop_framebuffer (); + cogl_framebuffer_draw_textured_rectangle (fb, pipeline, + invalid->x1, invalid->y1, + invalid->x2, invalid->y2, + (2. * invalid->x1) / source_texture_width, + (2. * invalid->y1) / source_texture_height, + (2. * invalid->x2) / source_texture_width, + (2. * invalid->y2) / source_texture_height); + + cogl_object_unref (pipeline); } static void