diff --git a/src/st/st-entry.c b/src/st/st-entry.c index c99fe9477..b16b3ac89 100644 --- a/src/st/st-entry.c +++ b/src/st/st-entry.c @@ -823,7 +823,7 @@ st_entry_paint_node (ClutterActor *actor, { StEntryPrivate *priv = ST_ENTRY_PRIV (actor); - st_widget_paint_background (ST_WIDGET (actor), node); + st_widget_paint_background (ST_WIDGET (actor), node, paint_context); if (priv->shadow_spec) { @@ -842,7 +842,8 @@ st_entry_paint_node (ClutterActor *actor, g_clear_object (&priv->text_shadow_pipeline); pipeline = _st_create_shadow_pipeline_from_actor (priv->shadow_spec, - priv->entry); + priv->entry, + paint_context); priv->shadow_width = width; priv->shadow_height = height; diff --git a/src/st/st-icon.c b/src/st/st-icon.c index 34848e82b..942dbcc86 100644 --- a/src/st/st-icon.c +++ b/src/st/st-icon.c @@ -78,7 +78,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (StIcon, st_icon, ST_TYPE_WIDGET) static void st_icon_update (StIcon *icon); static gboolean st_icon_update_icon_size (StIcon *icon); -static void st_icon_update_shadow_pipeline (StIcon *icon); +static void st_icon_update_shadow_pipeline (StIcon *icon, + ClutterPaintContext *paint_context); static void st_icon_clear_shadow_pipeline (StIcon *icon); static GIcon *default_gicon = NULL; @@ -207,11 +208,11 @@ st_icon_paint_node (ClutterActor *actor, StIcon *icon = ST_ICON (actor); StIconPrivate *priv = icon->priv; - st_widget_paint_background (ST_WIDGET (actor), node); + st_widget_paint_background (ST_WIDGET (actor), node, paint_context); if (priv->icon_texture) { - st_icon_update_shadow_pipeline (icon); + st_icon_update_shadow_pipeline (icon, paint_context); if (priv->shadow_pipeline) { @@ -416,7 +417,8 @@ st_icon_clear_shadow_pipeline (StIcon *icon) } static void -st_icon_update_shadow_pipeline (StIcon *icon) +st_icon_update_shadow_pipeline (StIcon *icon, + ClutterPaintContext *paint_context) { StIconPrivate *priv = icon->priv; @@ -437,7 +439,8 @@ st_icon_update_shadow_pipeline (StIcon *icon) priv->shadow_pipeline = _st_create_shadow_pipeline_from_actor (priv->shadow_spec, - priv->icon_texture); + priv->icon_texture, + paint_context); if (priv->shadow_pipeline) graphene_size_init (&priv->shadow_size, width, height); diff --git a/src/st/st-label.c b/src/st/st-label.c index d9cf4e276..a98380bb7 100644 --- a/src/st/st-label.c +++ b/src/st/st-label.c @@ -211,7 +211,7 @@ st_label_paint_node (ClutterActor *actor, { StLabelPrivate *priv = ST_LABEL (actor)->priv; - st_widget_paint_background (ST_WIDGET (actor), node); + st_widget_paint_background (ST_WIDGET (actor), node, paint_context); if (priv->shadow_spec) { @@ -237,7 +237,8 @@ st_label_paint_node (ClutterActor *actor, priv->shadow_height = height; priv->text_shadow_pipeline = _st_create_shadow_pipeline_from_actor (priv->shadow_spec, - priv->label); + priv->label, + paint_context); } if (priv->text_shadow_pipeline != NULL) diff --git a/src/st/st-private.c b/src/st/st-private.c index 5caabcd07..b997fa1dc 100644 --- a/src/st/st-private.c +++ b/src/st/st-private.c @@ -376,9 +376,10 @@ blur_pixels (guchar *pixels_in, } CoglPipeline * -_st_create_shadow_pipeline (StShadow *shadow_spec, - CoglTexture *src_texture, - float resource_scale) +_st_create_shadow_pipeline (StShadow *shadow_spec, + ClutterPaintContext *paint_context, + CoglTexture *src_texture, + float resource_scale) { ClutterBackend *backend = clutter_get_default_backend (); CoglContext *ctx = clutter_backend_get_cogl_context (backend); @@ -386,7 +387,8 @@ _st_create_shadow_pipeline (StShadow *shadow_spec, g_autoptr (ClutterPaintNode) blur_node = NULL; g_autoptr (CoglOffscreen) offscreen = NULL; g_autoptr (GError) error = NULL; - ClutterPaintContext *paint_context; + ClutterPaintContext *nested_paint_context; + ClutterColorState *color_state; CoglFramebuffer *fb; CoglPipeline *pipeline; CoglTexture *texture; @@ -472,10 +474,14 @@ _st_create_shadow_pipeline (StShadow *shadow_spec, .y2 = src_height + sampling_radius, }); - paint_context = - clutter_paint_context_new_for_framebuffer (fb, NULL, CLUTTER_PAINT_FLAG_NONE); - clutter_paint_node_paint (blur_node, paint_context); - clutter_paint_context_destroy (paint_context); + color_state = clutter_paint_context_get_color_state (paint_context); + nested_paint_context = + clutter_paint_context_new_for_framebuffer (fb, NULL, CLUTTER_PAINT_FLAG_NONE, + color_state); + clutter_paint_context_push_color_state (nested_paint_context, color_state); + clutter_paint_node_paint (blur_node, nested_paint_context); + clutter_paint_context_pop_color_state (nested_paint_context); + clutter_paint_context_destroy (nested_paint_context); if (G_UNLIKELY (shadow_pipeline_template == NULL)) { @@ -498,14 +504,16 @@ _st_create_shadow_pipeline (StShadow *shadow_spec, } CoglPipeline * -_st_create_shadow_pipeline_from_actor (StShadow *shadow_spec, - ClutterActor *actor) +_st_create_shadow_pipeline_from_actor (StShadow *shadow_spec, + ClutterActor *actor, + ClutterPaintContext *paint_context) { ClutterContent *image = NULL; CoglPipeline *shadow_pipeline = NULL; float resource_scale; float width, height; - ClutterPaintContext *paint_context; + ClutterColorState *color_state; + ClutterPaintContext *nested_paint_context; g_return_val_if_fail (clutter_actor_has_allocation (actor), NULL); @@ -528,8 +536,12 @@ _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec, if (texture && cogl_texture_get_width (texture) == width && cogl_texture_get_height (texture) == height) - shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, texture, - resource_scale); + { + shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, + paint_context, + texture, + resource_scale); + } } if (shadow_pipeline == NULL) @@ -570,17 +582,22 @@ _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec, clutter_actor_set_opacity_override (actor, 255); - paint_context = + color_state = clutter_actor_get_color_state (actor); + nested_paint_context = clutter_paint_context_new_for_framebuffer (fb, NULL, - CLUTTER_PAINT_FLAG_NONE); - clutter_actor_paint (actor, paint_context); - clutter_paint_context_destroy (paint_context); + CLUTTER_PAINT_FLAG_NONE, + color_state); + clutter_paint_context_push_color_state (nested_paint_context, color_state); + clutter_actor_paint (actor, nested_paint_context); + clutter_paint_context_pop_color_state (nested_paint_context); + clutter_paint_context_destroy (nested_paint_context); clutter_actor_set_opacity_override (actor, -1); g_object_unref (fb); shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, + paint_context, g_steal_pointer (&buffer), resource_scale); } diff --git a/src/st/st-private.h b/src/st/st-private.h index 6e5c1197a..2ed84a257 100644 --- a/src/st/st-private.h +++ b/src/st/st-private.h @@ -58,11 +58,13 @@ void _st_set_text_from_style (ClutterText *text, CoglPipeline * _st_create_texture_pipeline (CoglTexture *src_texture); /* Helper for widgets which need to draw additional shadows */ -CoglPipeline * _st_create_shadow_pipeline (StShadow *shadow_spec, - CoglTexture *src_texture, - float resource_scale); -CoglPipeline * _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec, - ClutterActor *actor); +CoglPipeline * _st_create_shadow_pipeline (StShadow *shadow_spec, + ClutterPaintContext *paint_context, + CoglTexture *src_texture, + float resource_scale); +CoglPipeline * _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec, + ClutterActor *actor, + ClutterPaintContext *paint_context); cairo_pattern_t *_st_create_shadow_cairo_pattern (StShadow *shadow_spec, cairo_pattern_t *src_pattern); diff --git a/src/st/st-shadow.c b/src/st/st-shadow.c index a406b6153..c7d1aa932 100644 --- a/src/st/st-shadow.c +++ b/src/st/st-shadow.c @@ -218,12 +218,14 @@ st_shadow_helper_new (StShadow *shadow) * st_shadow_helper_update: * @helper: a #StShadowHelper * @source: a #ClutterActor + * @paint_context: a #ClutterPaintContext * * Update @helper from @source. */ void -st_shadow_helper_update (StShadowHelper *helper, - ClutterActor *source) +st_shadow_helper_update (StShadowHelper *helper, + ClutterActor *source, + ClutterPaintContext *paint_context) { gfloat width, height; @@ -236,7 +238,9 @@ st_shadow_helper_update (StShadowHelper *helper, if (helper->pipeline) g_object_unref (helper->pipeline); - helper->pipeline = _st_create_shadow_pipeline_from_actor (helper->shadow, source); + helper->pipeline = _st_create_shadow_pipeline_from_actor (helper->shadow, + source, + paint_context); helper->width = width; helper->height = height; } diff --git a/src/st/st-shadow.h b/src/st/st-shadow.h index f7703f943..e201b6e06 100644 --- a/src/st/st-shadow.h +++ b/src/st/st-shadow.h @@ -81,8 +81,9 @@ StShadowHelper *st_shadow_helper_new (StShadow *shadow); StShadowHelper *st_shadow_helper_copy (StShadowHelper *helper); void st_shadow_helper_free (StShadowHelper *helper); -void st_shadow_helper_update (StShadowHelper *helper, - ClutterActor *source); +void st_shadow_helper_update (StShadowHelper *helper, + ClutterActor *source, + ClutterPaintContext *paint_context); void st_shadow_helper_paint (StShadowHelper *helper, ClutterPaintNode *node, diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c index 2e114caf7..778ebd9bd 100644 --- a/src/st/st-theme-node-drawing.c +++ b/src/st/st-theme-node-drawing.c @@ -1499,8 +1499,9 @@ st_theme_node_invalidate_background_image (StThemeNode *node) } static gboolean -st_theme_node_load_background_image (StThemeNode *node, - gfloat resource_scale) +st_theme_node_load_background_image (StThemeNode *node, + ClutterPaintContext *paint_context, + float resource_scale) { if (node->background_texture == NULL) { @@ -1528,6 +1529,7 @@ st_theme_node_load_background_image (StThemeNode *node, if (background_image_shadow_spec) { node->background_shadow_pipeline = _st_create_shadow_pipeline (background_image_shadow_spec, + paint_context, node->background_texture, resource_scale); } @@ -1564,11 +1566,13 @@ st_theme_node_invalidate_resources_for_file (StThemeNode *node, } static void st_theme_node_compute_maximum_borders (StThemeNodePaintState *state); -static void st_theme_node_prerender_shadow (StThemeNodePaintState *state); +static void st_theme_node_prerender_shadow (StThemeNodePaintState *state, + ClutterPaintContext *paint_context); static void st_theme_node_render_resources (StThemeNodePaintState *state, StThemeNode *node, + ClutterPaintContext *paint_context, float width, float height, float resource_scale) @@ -1603,14 +1607,16 @@ st_theme_node_render_resources (StThemeNodePaintState *state, if (st_theme_node_load_border_image (node, resource_scale)) state->box_shadow_pipeline = _st_create_shadow_pipeline (box_shadow_spec, + paint_context, node->border_slices_texture, state->resource_scale); else if (state->prerendered_texture != NULL) state->box_shadow_pipeline = _st_create_shadow_pipeline (box_shadow_spec, + paint_context, state->prerendered_texture, state->resource_scale); else - st_theme_node_prerender_shadow (state); + st_theme_node_prerender_shadow (state, paint_context); } /* If we don't have cached textures yet, check whether we can cache @@ -1630,6 +1636,7 @@ st_theme_node_render_resources (StThemeNodePaintState *state, static void st_theme_node_update_resources (StThemeNodePaintState *state, StThemeNode *node, + ClutterPaintContext *paint_context, float width, float height, float resource_scale) @@ -1665,6 +1672,7 @@ st_theme_node_update_resources (StThemeNodePaintState *state, if (had_box_shadow) state->box_shadow_pipeline = _st_create_shadow_pipeline (box_shadow_spec, + paint_context, state->prerendered_texture, state->resource_scale); } @@ -2411,7 +2419,8 @@ st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state, } static void -st_theme_node_prerender_shadow (StThemeNodePaintState *state) +st_theme_node_prerender_shadow (StThemeNodePaintState *state, + ClutterPaintContext *paint_context) { StThemeNode *node = state->node; CoglContext *ctx; @@ -2436,7 +2445,8 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state) if (cogl_framebuffer_allocate (framebuffer, &error)) { g_autoptr (ClutterPaintNode) root_node = NULL; - ClutterPaintContext *paint_context; + ClutterColorState *color_state; + ClutterPaintContext *nested_paint_context; CoglColor clear_color; ClutterActorBox box = { 0, 0, state->box_shadow_width, state->box_shadow_height}; @@ -2454,14 +2464,19 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state) st_theme_node_paint_borders (state, root_node, &box, ST_PAINT_BORDERS_MODE_SILHOUETTE, 0xff); - paint_context = + color_state = clutter_paint_context_get_color_state (paint_context); + nested_paint_context = clutter_paint_context_new_for_framebuffer (framebuffer, NULL, - CLUTTER_PAINT_FLAG_NONE); - clutter_paint_node_paint (root_node, paint_context); - clutter_paint_context_destroy (paint_context); + CLUTTER_PAINT_FLAG_NONE, + color_state); + clutter_paint_context_push_color_state (nested_paint_context, color_state); + clutter_paint_node_paint (root_node, nested_paint_context); + clutter_paint_context_pop_color_state (nested_paint_context); + clutter_paint_context_destroy (nested_paint_context); state->box_shadow_pipeline = _st_create_shadow_pipeline (st_theme_node_get_box_shadow (node), + paint_context, buffer, state->resource_scale); } @@ -2719,6 +2734,7 @@ st_theme_node_needs_new_box_shadow_for_size (StThemeNodePaintState *state, void st_theme_node_paint (StThemeNode *node, StThemeNodePaintState *state, + ClutterPaintContext *paint_context, ClutterPaintNode *root, const ClutterActorBox *box, guint8 paint_opacity, @@ -2755,13 +2771,17 @@ st_theme_node_paint (StThemeNode *node, fabsf (resource_scale - state->resource_scale) < FLT_EPSILON) st_theme_node_paint_state_copy (state, &node->cached_state); else - st_theme_node_render_resources (state, node, width, height, resource_scale); + st_theme_node_render_resources (state, node, paint_context, + width, height, resource_scale); node->rendered_once = TRUE; } else if (state->alloc_width != width || state->alloc_height != height || fabsf (state->resource_scale - resource_scale) > FLT_EPSILON) - st_theme_node_update_resources (state, node, width, height, resource_scale); + { + st_theme_node_update_resources (state, node, paint_context, + width, height, resource_scale); + } /* Rough notes about the relationship of borders and backgrounds in CSS3; * see http://www.w3.org/TR/css3-background/ for more accurate details. @@ -2834,7 +2854,7 @@ st_theme_node_paint (StThemeNode *node, st_theme_node_paint_outline (node, root, box, paint_opacity); if (state->prerendered_pipeline == NULL && - st_theme_node_load_background_image (node, resource_scale)) + st_theme_node_load_background_image (node, paint_context, resource_scale)) { ClutterActorBox background_box; ClutterActorBox texture_coords; diff --git a/src/st/st-theme-node-transition.c b/src/st/st-theme-node-transition.c index 4d1ca3f8d..237e150e9 100644 --- a/src/st/st-theme-node-transition.c +++ b/src/st/st-theme-node-transition.c @@ -244,6 +244,7 @@ st_theme_node_transition_get_paint_box (StThemeNodeTransition *transition, static gboolean setup_framebuffers (StThemeNodeTransition *transition, + ClutterPaintContext *paint_context, ClutterPaintNode *node, const ClutterActorBox *allocation, float resource_scale) @@ -335,6 +336,7 @@ setup_framebuffers (StThemeNodeTransition *transition, clutter_paint_node_add_child (node, old_layer_node); st_theme_node_paint (priv->old_theme_node, &priv->old_paint_state, + paint_context, old_layer_node, allocation, 255, resource_scale); new_layer_node = clutter_layer_node_new_to_framebuffer (priv->new_offscreen, @@ -346,6 +348,7 @@ setup_framebuffers (StThemeNodeTransition *transition, priv->offscreen_box.x2, priv->offscreen_box.y2, 0.0, 1.0); st_theme_node_paint (priv->new_theme_node, &priv->new_paint_state, + paint_context, new_layer_node, allocation, 255, resource_scale); g_clear_object (&noop_pipeline); @@ -355,6 +358,7 @@ setup_framebuffers (StThemeNodeTransition *transition, void st_theme_node_transition_paint (StThemeNodeTransition *transition, + ClutterPaintContext *paint_context, ClutterPaintNode *node, ClutterActorBox *allocation, guint8 paint_opacity, @@ -382,6 +386,7 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition, calculate_offscreen_box (transition, allocation); priv->needs_setup = clutter_actor_box_get_area (&priv->offscreen_box) == 0 || !setup_framebuffers (transition, + paint_context, node, allocation, resource_scale); diff --git a/src/st/st-theme-node-transition.h b/src/st/st-theme-node-transition.h index e5eff47fb..6a468f663 100644 --- a/src/st/st-theme-node-transition.h +++ b/src/st/st-theme-node-transition.h @@ -42,6 +42,7 @@ void st_theme_node_transition_update (StThemeNodeTransition *transition, StThemeNode *new_node); void st_theme_node_transition_paint (StThemeNodeTransition *transition, + ClutterPaintContext *paint_context, ClutterPaintNode *node, ClutterActorBox *allocation, guint8 paint_opacity, diff --git a/src/st/st-theme-node.h b/src/st/st-theme-node.h index 2ad7b5fd3..df923d7b5 100644 --- a/src/st/st-theme-node.h +++ b/src/st/st-theme-node.h @@ -342,6 +342,7 @@ gboolean st_theme_node_paint_equal (StThemeNode *node, */ void st_theme_node_paint (StThemeNode *node, StThemeNodePaintState *state, + ClutterPaintContext *paint_context, ClutterPaintNode *root, const ClutterActorBox *box, guint8 paint_opacity, diff --git a/src/st/st-viewport.c b/src/st/st-viewport.c index 239894ccc..a05e04274 100644 --- a/src/st/st-viewport.c +++ b/src/st/st-viewport.c @@ -421,7 +421,7 @@ st_viewport_paint_node (ClutterActor *actor, node = transform_node; } - st_widget_paint_background (ST_WIDGET (actor), node); + st_widget_paint_background (ST_WIDGET (actor), node, paint_context); } static void diff --git a/src/st/st-widget.c b/src/st/st-widget.c index 066eeb99c..150775a10 100644 --- a/src/st/st-widget.c +++ b/src/st/st-widget.c @@ -418,8 +418,9 @@ st_widget_allocate (ClutterActor *actor, * painting children. */ void -st_widget_paint_background (StWidget *widget, - ClutterPaintNode *node) +st_widget_paint_background (StWidget *widget, + ClutterPaintNode *node, + ClutterPaintContext *paint_context) { StWidgetPrivate *priv = st_widget_get_instance_private (widget); StThemeNode *theme_node; @@ -437,6 +438,7 @@ st_widget_paint_background (StWidget *widget, if (priv->transition_animation) st_theme_node_transition_paint (priv->transition_animation, + paint_context, node, &allocation, opacity, @@ -444,6 +446,7 @@ st_widget_paint_background (StWidget *widget, else st_theme_node_paint (theme_node, current_paint_state (widget), + paint_context, node, &allocation, opacity, @@ -455,7 +458,7 @@ st_widget_paint_node (ClutterActor *actor, ClutterPaintNode *node, ClutterPaintContext *paint_context) { - st_widget_paint_background (ST_WIDGET (actor), node); + st_widget_paint_background (ST_WIDGET (actor), node, paint_context); } static void diff --git a/src/st/st-widget.h b/src/st/st-widget.h index 40866357d..58abe09df 100644 --- a/src/st/st-widget.h +++ b/src/st/st-widget.h @@ -143,8 +143,9 @@ StThemeNode * st_widget_get_theme_node (StWidget *widg StThemeNode * st_widget_peek_theme_node (StWidget *widget); GList * st_widget_get_focus_chain (StWidget *widget); -void st_widget_paint_background (StWidget *widget, - ClutterPaintNode *node); +void st_widget_paint_background (StWidget *widget, + ClutterPaintNode *node, + ClutterPaintContext *paint_context); /* debug methods */ char *st_describe_actor (ClutterActor *actor);