diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c index 683e9f0a3..438802993 100644 --- a/src/st/st-theme-node-drawing.c +++ b/src/st/st-theme-node-drawing.c @@ -1478,6 +1478,19 @@ st_theme_node_render_resources (StThemeNodePaintState *state, else if (node->background_color.alpha > 0 || has_border) st_theme_node_prerender_shadow (state); } + + /* If we don't have cached textures yet, check whether we can cache + them. */ + if (!node->cached_textures) + { + if (state->prerendered_material == COGL_INVALID_HANDLE && + width >= node->box_shadow_min_width && + height >= node->box_shadow_min_height) + { + st_theme_node_paint_state_copy (&node->cached_state, state); + node->cached_textures = TRUE; + } + } } static void @@ -2371,12 +2384,22 @@ st_theme_node_paint (StThemeNode *node, return; if (st_theme_node_needs_new_box_shadow_for_size (state, node, width, height)) - st_theme_node_render_resources (state, node, width, height); + { + /* If we had the ability to cache textures on the node, then we + can just copy them over to the paint state and avoid all + rendering. We end up sharing textures a cross different + widgets. */ + if (node->rendered_once && node->cached_textures && + width >= node->box_shadow_min_width && height >= node->box_shadow_min_height) + st_theme_node_paint_state_copy (state, &node->cached_state); + else + st_theme_node_render_resources (state, node, width, height); + + node->rendered_once = TRUE; + } else st_theme_node_update_resources (state, node, width, height); - node->rendered_once = TRUE; - /* Rough notes about the relationship of borders and backgrounds in CSS3; * see http://www.w3.org/TR/css3-background/ for more accurate details. * diff --git a/src/st/st-theme-node-private.h b/src/st/st-theme-node-private.h index 9d6cf9417..aba58a343 100644 --- a/src/st/st-theme-node-private.h +++ b/src/st/st-theme-node-private.h @@ -100,6 +100,7 @@ struct _StThemeNode { guint text_shadow_computed : 1; guint link_type : 2; guint rendered_once : 1; + guint cached_textures : 1; int box_shadow_min_width; int box_shadow_min_height; @@ -109,6 +110,8 @@ struct _StThemeNode { CoglHandle background_texture; CoglHandle background_material; CoglHandle background_shadow_material; + + StThemeNodePaintState cached_state; }; struct _StThemeNodeClass { diff --git a/src/st/st-theme-node.c b/src/st/st-theme-node.c index 5250e8ac7..9bfa39f50 100644 --- a/src/st/st-theme-node.c +++ b/src/st/st-theme-node.c @@ -101,6 +101,8 @@ st_theme_node_dispose (GObject *gobject) g_signal_handlers_disconnect_by_func (node->theme, on_custom_stylesheets_changed, node); + st_theme_node_paint_state_free (&node->cached_state); + g_clear_object (&node->theme); G_OBJECT_CLASS (st_theme_node_parent_class)->dispose (gobject);