diff --git a/src/Makefile-st.am b/src/Makefile-st.am index 7cbdfd894..040334e6d 100644 --- a/src/Makefile-st.am +++ b/src/Makefile-st.am @@ -1,4 +1,7 @@ st_cflags = \ + -DCLUTTER_ENABLE_EXPERIMENTAL_API \ + -DCOGL_ENABLE_EXPERIMENTAL_API \ + -DCOGL_ENABLE_EXPERIMENTAL_2_0_API \ -I$(top_srcdir)/src \ -DPREFIX=\""$(prefix)"\" \ -DLIBDIR=\""$(libdir)"\" \ diff --git a/src/Makefile.am b/src/Makefile.am index 8041052d7..5f61fe5dc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -68,6 +68,9 @@ include Makefile-calendar-server.am include Makefile-hotplug-sniffer.am gnome_shell_cflags = \ + -DCLUTTER_ENABLE_EXPERIMENTAL_API \ + -DCOGL_ENABLE_EXPERIMENTAL_API \ + -DCOGL_ENABLE_EXPERIMENTAL_2_0_API \ $(GNOME_SHELL_CFLAGS) \ -I$(srcdir)/tray \ -DVERSION=\"$(VERSION)\" \ diff --git a/src/gnome-shell-plugin.c b/src/gnome-shell-plugin.c index 631e37323..0df570b49 100644 --- a/src/gnome-shell-plugin.c +++ b/src/gnome-shell-plugin.c @@ -28,8 +28,6 @@ #include #include -#define CLUTTER_ENABLE_EXPERIMENTAL_API -#define COGL_ENABLE_EXPERIMENTAL_API #include #include #include diff --git a/src/shell-app.c b/src/shell-app.c index 1f5017d26..d2a90a954 100644 --- a/src/shell-app.c +++ b/src/shell-app.c @@ -217,7 +217,7 @@ typedef struct { ClutterTextDirection direction; } CreateFadedIconData; -static CoglHandle +static CoglTexture * shell_app_create_faded_icon_cpu (StTextureCache *cache, const char *key, void *datap, @@ -227,7 +227,7 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache, ShellApp *app; GdkPixbuf *pixbuf; int size; - CoglHandle texture; + CoglTexture *texture; gint width, height, rowstride; guint8 n_channels; gboolean have_alpha; @@ -263,13 +263,13 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache, } if (info == NULL) - return COGL_INVALID_HANDLE; + return NULL; pixbuf = gtk_icon_info_load_icon (info, NULL); g_object_unref (info); if (pixbuf == NULL) - return COGL_INVALID_HANDLE; + return NULL; width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); @@ -338,7 +338,7 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache, ClutterActor * shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection direction) { - CoglHandle texture; + CoglTexture *texture; ClutterActor *result; char *cache_key; CreateFadedIconData data; @@ -367,7 +367,7 @@ shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection directio NULL); g_free (cache_key); - if (texture != COGL_INVALID_HANDLE) + if (texture != NULL) { result = clutter_texture_new (); clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (result), texture); diff --git a/src/shell-invert-lightness-effect.c b/src/shell-invert-lightness-effect.c index 4d6c27e3f..b3a2ca44f 100644 --- a/src/shell-invert-lightness-effect.c +++ b/src/shell-invert-lightness-effect.c @@ -35,8 +35,6 @@ #define SHELL_IS_INVERT_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_INVERT_LIGHTNESS_EFFECT)) #define SHELL_INVERT_LIGHTNESS_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_INVERT_LIGHTNESS_EFFEC, ShellInvertLightnessEffectClass)) -#define CLUTTER_ENABLE_EXPERIMENTAL_API - #include "shell-invert-lightness-effect.h" #include @@ -124,6 +122,7 @@ shell_invert_lightness_effect_paint_target (ClutterOffscreenEffect *effect) ShellInvertLightnessEffect *self = SHELL_INVERT_LIGHTNESS_EFFECT (effect); ClutterActor *actor; guint8 paint_opacity; + CoglFramebuffer *fb = cogl_get_draw_framebuffer (); actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); paint_opacity = clutter_actor_get_paint_opacity (actor); @@ -133,11 +132,8 @@ shell_invert_lightness_effect_paint_target (ClutterOffscreenEffect *effect) paint_opacity, paint_opacity, paint_opacity); - cogl_push_source (self->pipeline); - - cogl_rectangle (0, 0, self->tex_width, self->tex_height); - - cogl_pop_source (); + cogl_framebuffer_draw_rectangle (fb, self->pipeline, + 0, 0, self->tex_width, self->tex_height); } static void diff --git a/src/shell-invert-lightness-effect.h b/src/shell-invert-lightness-effect.h index a7bedd5d1..3d7cf3a6d 100644 --- a/src/shell-invert-lightness-effect.h +++ b/src/shell-invert-lightness-effect.h @@ -21,7 +21,6 @@ #ifndef __SHELL_INVERT_LIGHTNESS_EFFECT_H__ #define __SHELL_INVERT_LIGHTNESS_EFFECT_H__ -#define COGL_ENABLE_EXPERIMENTAL_API #include G_BEGIN_DECLS diff --git a/src/shell-recorder.c b/src/shell-recorder.c index 23f2c072c..f88ca554c 100644 --- a/src/shell-recorder.c +++ b/src/shell-recorder.c @@ -441,15 +441,19 @@ recorder_record_frame (ShellRecorder *recorder) recorder->last_frame_time = now; size = recorder->area.width * recorder->area.height * 4; - - data = g_malloc (recorder->area.width * 4 * recorder->area.height); - cogl_read_pixels (recorder->area.x, - recorder->area.y, - recorder->area.width, - recorder->area.height, - COGL_READ_PIXELS_COLOR_BUFFER, - CLUTTER_CAIRO_FORMAT_ARGB32, - data); + data = g_malloc (size); + if (!cogl_framebuffer_read_pixels (cogl_get_draw_framebuffer (), + recorder->area.x, + recorder->area.y, + recorder->area.width, + recorder->area.height, + CLUTTER_CAIRO_FORMAT_ARGB32, + data)) + { + g_warning ("Could not retrieve pixel data"); + g_free (data); + return; + } buffer = gst_buffer_new(); gst_buffer_insert_memory (buffer, -1, diff --git a/src/shell-screenshot.c b/src/shell-screenshot.c index 991a55450..db1fd9e93 100644 --- a/src/shell-screenshot.c +++ b/src/shell-screenshot.c @@ -1,8 +1,5 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -#define COGL_ENABLE_EXPERIMENTAL_API -#define CLUTTER_ENABLE_EXPERIMENTAL_API - #include #include #include diff --git a/src/shell-slicer.c b/src/shell-slicer.c index 2d2cb849d..a33a22249 100644 --- a/src/shell-slicer.c +++ b/src/shell-slicer.c @@ -97,6 +97,7 @@ shell_slicer_paint_child (ShellSlicer *self) float width, height, child_width, child_height; StAlign x_align, y_align; double x_align_factor, y_align_factor; + CoglFramebuffer *fb = cogl_get_draw_framebuffer (); child = st_bin_get_child (ST_BIN (self)); @@ -115,18 +116,17 @@ shell_slicer_paint_child (ShellSlicer *self) child_width = child_box.x2 - child_box.x1; child_height = child_box.y2 - child_box.y1; - cogl_push_matrix (); - - cogl_clip_push_rectangle (0, 0, width, height); - cogl_translate ((int)(0.5 + x_align_factor * (width - child_width)), - (int)(0.5 + y_align_factor * (height - child_height)), - 0); + cogl_framebuffer_push_matrix (fb); + cogl_framebuffer_push_rectangle_clip (fb, 0, 0, width, height); + cogl_framebuffer_translate (fb, + (int)(0.5 + x_align_factor * (width - child_width)), + (int)(0.5 + y_align_factor * (height - child_height)), + 0); clutter_actor_paint (child); - cogl_clip_pop (); - - cogl_pop_matrix (); + cogl_framebuffer_pop_clip (fb); + cogl_framebuffer_pop_matrix (fb); } static void diff --git a/src/st/st-box-layout.c b/src/st/st-box-layout.c index 91e93a568..0078d53bf 100644 --- a/src/st/st-box-layout.c +++ b/src/st/st-box-layout.c @@ -387,19 +387,20 @@ st_box_layout_paint (ClutterActor *actor) ClutterActorBox allocation_box; ClutterActorBox content_box; ClutterActor *child; + CoglFramebuffer *fb = cogl_get_draw_framebuffer (); get_border_paint_offsets (self, &x, &y); if (x != 0 || y != 0) { - cogl_push_matrix (); - cogl_translate ((int)x, (int)y, 0); + cogl_framebuffer_push_matrix (fb); + cogl_framebuffer_translate (fb, (int)x, (int)y, 0); } st_widget_paint_background (ST_WIDGET (actor)); if (x != 0 || y != 0) { - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (fb); } if (clutter_actor_get_n_children (actor) == 0) @@ -417,10 +418,11 @@ st_box_layout_paint (ClutterActor *actor) * the borders and background stay in place; after drawing the borders and * background, we clip to the content area */ if (priv->hadjustment || priv->vadjustment) - cogl_clip_push_rectangle ((int)content_box.x1, - (int)content_box.y1, - (int)content_box.x2, - (int)content_box.y2); + cogl_framebuffer_push_rectangle_clip (fb, + (int)content_box.x1, + (int)content_box.y1, + (int)content_box.x2, + (int)content_box.y2); for (child = clutter_actor_get_first_child (actor); child != NULL; @@ -428,7 +430,7 @@ st_box_layout_paint (ClutterActor *actor) clutter_actor_paint (child); if (priv->hadjustment || priv->vadjustment) - cogl_clip_pop (); + cogl_framebuffer_pop_clip (fb); } static void @@ -442,19 +444,20 @@ st_box_layout_pick (ClutterActor *actor, ClutterActorBox allocation_box; ClutterActorBox content_box; ClutterActor *child; + CoglFramebuffer *fb = cogl_get_draw_framebuffer (); get_border_paint_offsets (self, &x, &y); if (x != 0 || y != 0) { - cogl_push_matrix (); - cogl_translate ((int)x, (int)y, 0); + cogl_framebuffer_push_matrix (fb); + cogl_framebuffer_translate (fb, (int)x, (int)y, 0); } CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->pick (actor, color); if (x != 0 || y != 0) { - cogl_pop_matrix (); + cogl_framebuffer_pop_matrix (fb); } if (clutter_actor_get_n_children (actor) == 0) @@ -469,10 +472,11 @@ st_box_layout_pick (ClutterActor *actor, content_box.y2 += y; if (priv->hadjustment || priv->vadjustment) - cogl_clip_push_rectangle ((int)content_box.x1, - (int)content_box.y1, - (int)content_box.x2, - (int)content_box.y2); + cogl_framebuffer_push_rectangle_clip (fb, + (int)content_box.x1, + (int)content_box.y1, + (int)content_box.x2, + (int)content_box.y2); for (child = clutter_actor_get_first_child (actor); child != NULL; @@ -480,7 +484,7 @@ st_box_layout_pick (ClutterActor *actor, clutter_actor_paint (child); if (priv->hadjustment || priv->vadjustment) - cogl_clip_pop (); + cogl_framebuffer_pop_clip (fb); } static gboolean diff --git a/src/st/st-drawing-area.c b/src/st/st-drawing-area.c index f044cbf31..5faf7dd8c 100644 --- a/src/st/st-drawing-area.c +++ b/src/st/st-drawing-area.c @@ -39,8 +39,8 @@ G_DEFINE_TYPE(StDrawingArea, st_drawing_area, ST_TYPE_WIDGET); struct _StDrawingAreaPrivate { - CoglHandle texture; - CoglHandle material; + CoglTexture *texture; + CoglPipeline *pipeline; cairo_t *context; guint needs_repaint : 1; guint in_repaint : 1; @@ -61,17 +61,8 @@ st_drawing_area_dispose (GObject *object) StDrawingArea *area = ST_DRAWING_AREA (object); StDrawingAreaPrivate *priv = area->priv; - if (priv->material != COGL_INVALID_HANDLE) - { - cogl_handle_unref (priv->material); - priv->material = COGL_INVALID_HANDLE; - } - - if (priv->texture != COGL_INVALID_HANDLE) - { - cogl_handle_unref (priv->texture); - priv->texture = COGL_INVALID_HANDLE; - } + g_clear_pointer (&priv->pipeline, cogl_object_unref); + g_clear_pointer (&priv->texture, cogl_object_unref); G_OBJECT_CLASS (st_drawing_area_parent_class)->dispose (object); } @@ -85,8 +76,6 @@ st_drawing_area_paint (ClutterActor *self) ClutterActorBox allocation_box; ClutterActorBox content_box; int width, height; - CoglColor color; - guint8 paint_opacity; (CLUTTER_ACTOR_CLASS (st_drawing_area_parent_class))->paint (self); @@ -96,20 +85,25 @@ st_drawing_area_paint (ClutterActor *self) width = (int)(0.5 + content_box.x2 - content_box.x1); height = (int)(0.5 + content_box.y2 - content_box.y1); - if (priv->material == COGL_INVALID_HANDLE) - priv->material = cogl_material_new (); + if (priv->pipeline == NULL) + { + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); - if (priv->texture != COGL_INVALID_HANDLE && + priv->pipeline = cogl_pipeline_new (ctx); + } + + if (priv->texture != NULL && (width != cogl_texture_get_width (priv->texture) || height != cogl_texture_get_height (priv->texture))) { - cogl_handle_unref (priv->texture); - priv->texture = COGL_INVALID_HANDLE; + cogl_object_unref (priv->texture); + priv->texture = NULL; } if (width > 0 && height > 0) { - if (priv->texture == COGL_INVALID_HANDLE) + if (priv->texture == NULL) { priv->texture = cogl_texture_new_with_size (width, height, COGL_TEXTURE_NONE, @@ -141,19 +135,21 @@ st_drawing_area_paint (ClutterActor *self) } } - cogl_material_set_layer (priv->material, 0, priv->texture); + cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->texture); if (priv->texture) { - paint_opacity = clutter_actor_get_paint_opacity (self); - cogl_color_set_from_4ub (&color, - paint_opacity, paint_opacity, paint_opacity, paint_opacity); - cogl_material_set_color (priv->material, &color); + CoglColor color; + guint8 paint_opacity; + CoglFramebuffer *fb = cogl_get_draw_framebuffer (); - cogl_set_source (priv->material); - cogl_rectangle_with_texture_coords (content_box.x1, content_box.y1, - content_box.x2, content_box.y2, - 0.0f, 0.0f, 1.0f, 1.0f); + paint_opacity = clutter_actor_get_paint_opacity (self); + cogl_color_init_from_4ub (&color, paint_opacity, paint_opacity, paint_opacity, paint_opacity); + cogl_pipeline_set_color (priv->pipeline, &color); + + cogl_framebuffer_draw_rectangle (fb, priv->pipeline, + content_box.x1, content_box.y1, + content_box.x2, content_box.y2); } } @@ -195,7 +191,7 @@ st_drawing_area_init (StDrawingArea *area) { area->priv = G_TYPE_INSTANCE_GET_PRIVATE (area, ST_TYPE_DRAWING_AREA, StDrawingAreaPrivate); - area->priv->texture = COGL_INVALID_HANDLE; + area->priv->texture = NULL; } /** diff --git a/src/st/st-icon.c b/src/st/st-icon.c index fac474af9..2b7b7ecb8 100644 --- a/src/st/st-icon.c +++ b/src/st/st-icon.c @@ -56,7 +56,7 @@ struct _StIconPrivate gint theme_icon_size; /* icon size from theme node */ gint icon_size; /* icon size we are using */ - CoglHandle shadow_material; + CoglPipeline *shadow_pipeline; float shadow_width; float shadow_height; StShadow *shadow_spec; @@ -141,23 +141,9 @@ st_icon_dispose (GObject *gobject) priv->pending_texture = NULL; } - if (priv->gicon) - { - g_object_unref (priv->gicon); - priv->gicon = NULL; - } - - if (priv->shadow_material) - { - cogl_handle_unref (priv->shadow_material); - priv->shadow_material = COGL_INVALID_HANDLE; - } - - if (priv->shadow_spec) - { - st_shadow_unref (priv->shadow_spec); - priv->shadow_spec = NULL; - } + g_clear_object (&priv->gicon); + g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref); + g_clear_pointer (&priv->shadow_spec, st_shadow_unref); G_OBJECT_CLASS (st_icon_parent_class)->dispose (gobject); } @@ -241,7 +227,7 @@ st_icon_paint (ClutterActor *actor) if (priv->icon_texture) { - if (priv->shadow_material) + if (priv->shadow_pipeline) { ClutterActorBox allocation; float width, height; @@ -250,7 +236,8 @@ st_icon_paint (ClutterActor *actor) clutter_actor_box_get_size (&allocation, &width, &height); _st_paint_shadow_with_opacity (priv->shadow_spec, - priv->shadow_material, + priv->shadow_pipeline, + cogl_get_draw_framebuffer (), &allocation, clutter_actor_get_paint_opacity (priv->icon_texture)); } @@ -266,17 +253,8 @@ st_icon_style_changed (StWidget *widget) StThemeNode *theme_node = st_widget_get_theme_node (widget); StIconPrivate *priv = self->priv; - if (priv->shadow_spec) - { - st_shadow_unref (priv->shadow_spec); - priv->shadow_spec = NULL; - } - - if (priv->shadow_material) - { - cogl_handle_unref (priv->shadow_material); - priv->shadow_material = COGL_INVALID_HANDLE; - } + g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref); + g_clear_pointer (&priv->shadow_spec, st_shadow_unref); priv->shadow_spec = st_theme_node_get_shadow (theme_node, "icon-shadow"); @@ -343,33 +321,26 @@ st_icon_init (StIcon *self) self->priv->icon_size = DEFAULT_ICON_SIZE; self->priv->prop_icon_size = -1; - self->priv->shadow_material = COGL_INVALID_HANDLE; + self->priv->shadow_pipeline = NULL; self->priv->shadow_width = -1; self->priv->shadow_height = -1; } static void -st_icon_update_shadow_material (StIcon *icon) +st_icon_update_shadow_pipeline (StIcon *icon) { StIconPrivate *priv = icon->priv; - if (priv->shadow_material) - { - cogl_handle_unref (priv->shadow_material); - priv->shadow_material = COGL_INVALID_HANDLE; - } + g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref); if (priv->shadow_spec) { - CoglHandle material; gint width, height; clutter_texture_get_base_size (CLUTTER_TEXTURE (priv->icon_texture), &width, &height); - material = _st_create_shadow_material_from_actor (priv->shadow_spec, - priv->icon_texture); - priv->shadow_material = material; + priv->shadow_pipeline = _st_create_shadow_pipeline_from_actor (priv->shadow_spec, priv->icon_texture); priv->shadow_width = width; priv->shadow_height = height; } @@ -379,7 +350,7 @@ static void on_pixbuf_changed (ClutterTexture *texture, StIcon *icon) { - st_icon_update_shadow_material (icon); + st_icon_update_shadow_pipeline (icon); } static void @@ -402,7 +373,7 @@ st_icon_finish_update (StIcon *icon) /* Remove the temporary ref we added */ g_object_unref (priv->icon_texture); - st_icon_update_shadow_material (icon); + st_icon_update_shadow_pipeline (icon); /* "pixbuf-change" is actually a misnomer for "texture-changed" */ g_signal_connect_object (priv->icon_texture, "pixbuf-change", diff --git a/src/st/st-label.c b/src/st/st-label.c index 9833b8337..2d887d82c 100644 --- a/src/st/st-label.c +++ b/src/st/st-label.c @@ -60,7 +60,7 @@ struct _StLabelPrivate { ClutterActor *label; - CoglHandle text_shadow_material; + CoglPipeline *text_shadow_pipeline; float shadow_width; float shadow_height; }; @@ -118,11 +118,7 @@ st_label_style_changed (StWidget *self) { StLabelPrivate *priv = ST_LABEL(self)->priv; - if (priv->text_shadow_material != COGL_INVALID_HANDLE) - { - cogl_handle_unref (priv->text_shadow_material); - priv->text_shadow_material = COGL_INVALID_HANDLE; - } + g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref); _st_set_text_from_style ((ClutterText *)priv->label, st_widget_get_theme_node (self)); @@ -192,11 +188,7 @@ st_label_dispose (GObject *object) priv->label = NULL; } - if (priv->text_shadow_material != COGL_INVALID_HANDLE) - { - cogl_handle_unref (priv->text_shadow_material); - priv->text_shadow_material = COGL_INVALID_HANDLE; - } + g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref); G_OBJECT_CLASS (st_label_parent_class)->dispose (object); } @@ -218,26 +210,21 @@ st_label_paint (ClutterActor *actor) clutter_actor_get_allocation_box (priv->label, &allocation); clutter_actor_box_get_size (&allocation, &width, &height); - if (priv->text_shadow_material == COGL_INVALID_HANDLE || + if (priv->text_shadow_pipeline == NULL || width != priv->shadow_width || height != priv->shadow_height) { - CoglHandle material; - - if (priv->text_shadow_material != COGL_INVALID_HANDLE) - cogl_handle_unref (priv->text_shadow_material); - - material = _st_create_shadow_material_from_actor (shadow_spec, - priv->label); + g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref); priv->shadow_width = width; priv->shadow_height = height; - priv->text_shadow_material = material; + priv->text_shadow_pipeline = _st_create_shadow_pipeline_from_actor (shadow_spec, priv->label); } - if (priv->text_shadow_material != COGL_INVALID_HANDLE) + if (priv->text_shadow_pipeline != NULL) _st_paint_shadow_with_opacity (shadow_spec, - priv->text_shadow_material, + priv->text_shadow_pipeline, + cogl_get_draw_framebuffer (), &allocation, clutter_actor_get_paint_opacity (priv->label)); } @@ -292,7 +279,7 @@ st_label_init (StLabel *label) label->priv->label = g_object_new (CLUTTER_TYPE_TEXT, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - label->priv->text_shadow_material = COGL_INVALID_HANDLE; + label->priv->text_shadow_pipeline = NULL; label->priv->shadow_width = -1.; label->priv->shadow_height = -1.; @@ -357,11 +344,7 @@ st_label_set_text (StLabel *label, if (clutter_text_get_editable (ctext) || g_strcmp0 (clutter_text_get_text (ctext), text) != 0) { - if (priv->text_shadow_material != COGL_INVALID_HANDLE) - { - cogl_handle_unref (priv->text_shadow_material); - priv->text_shadow_material = COGL_INVALID_HANDLE; - } + g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref); clutter_text_set_text (ctext, text); diff --git a/src/st/st-private.c b/src/st/st-private.c index e3307b087..7a347e55c 100644 --- a/src/st/st-private.c +++ b/src/st/st-private.c @@ -162,47 +162,41 @@ _st_set_text_from_style (ClutterText *text, } /** - * _st_create_texture_material: - * @src_texture: The CoglTexture for the material + * _st_create_texture_pipeline: + * @src_texture: The CoglTexture for the pipeline * - * Creates a simple material which contains the given texture as a + * Creates a simple pipeline which contains the given texture as a * single layer. */ -CoglHandle -_st_create_texture_material (CoglHandle src_texture) +CoglPipeline * +_st_create_texture_pipeline (CoglTexture *src_texture) { - static CoglHandle texture_material_template = COGL_INVALID_HANDLE; - CoglHandle material; + static CoglPipeline *texture_pipeline_template = NULL; + CoglPipeline *pipeline; - g_return_val_if_fail (src_texture != COGL_INVALID_HANDLE, - COGL_INVALID_HANDLE); + g_return_val_if_fail (src_texture != NULL, NULL); - /* We use a material that has a dummy texture as a base for all - texture materials. The idea is that only the Cogl texture object - would be different in the children so it is likely that Cogl will - be able to share GL programs between all the textures. */ - if (G_UNLIKELY (texture_material_template == COGL_INVALID_HANDLE)) + /* The only state used in the pipeline that would affect the shader + generation is the texture type on the layer. Therefore we create + a template pipeline which sets this state and all texture + pipelines are created as a copy of this. That way Cogl can find + the shader state for the pipeline more quickly by looking at the + pipeline ancestry instead of resorting to the shader cache. */ + if (G_UNLIKELY (texture_pipeline_template == NULL)) { - static const guint8 white_pixel[] = { 0xff, 0xff, 0xff, 0xff }; - CoglHandle dummy_texture; + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); - dummy_texture = - cogl_texture_new_from_data (1, 1, - COGL_TEXTURE_NONE, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - COGL_PIXEL_FORMAT_ANY, - 4, white_pixel); - - texture_material_template = cogl_material_new (); - cogl_material_set_layer (texture_material_template, 0, dummy_texture); - cogl_handle_unref (dummy_texture); + texture_pipeline_template = cogl_pipeline_new (ctx); + cogl_pipeline_set_layer_null_texture (texture_pipeline_template, + 0, /* layer */ + COGL_TEXTURE_TYPE_2D); } - material = cogl_material_copy (texture_material_template); + pipeline = cogl_pipeline_copy (texture_pipeline_template); + cogl_pipeline_set_layer_texture (pipeline, 0, src_texture); - cogl_material_set_layer (material, 0, src_texture); - - return material; + return pipeline; } /***** @@ -345,21 +339,20 @@ blur_pixels (guchar *pixels_in, return pixels_out; } -CoglHandle -_st_create_shadow_material (StShadow *shadow_spec, - CoglHandle src_texture) +CoglPipeline * +_st_create_shadow_pipeline (StShadow *shadow_spec, + CoglTexture *src_texture) { - static CoglHandle shadow_material_template = COGL_INVALID_HANDLE; + static CoglPipeline *shadow_pipeline_template = NULL; - CoglHandle material; - CoglHandle texture; - guchar *pixels_in, *pixels_out; - gint width_in, height_in, rowstride_in; - gint width_out, height_out, rowstride_out; + CoglPipeline *pipeline; + CoglTexture *texture; + guchar *pixels_in, *pixels_out; + gint width_in, height_in, rowstride_in; + gint width_out, height_out, rowstride_out; - g_return_val_if_fail (shadow_spec != NULL, COGL_INVALID_HANDLE); - g_return_val_if_fail (src_texture != COGL_INVALID_HANDLE, - COGL_INVALID_HANDLE); + g_return_val_if_fail (shadow_spec != NULL, NULL); + g_return_val_if_fail (src_texture != NULL, NULL); width_in = cogl_texture_get_width (src_texture); height_in = cogl_texture_get_height (src_texture); @@ -385,84 +378,99 @@ _st_create_shadow_material (StShadow *shadow_spec, g_free (pixels_out); - if (G_UNLIKELY (shadow_material_template == COGL_INVALID_HANDLE)) + if (G_UNLIKELY (shadow_pipeline_template == NULL)) { - shadow_material_template = cogl_material_new (); + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); - /* We set up the material to blend the shadow texture with the combine + shadow_pipeline_template = cogl_pipeline_new (ctx); + + /* We set up the pipeline to blend the shadow texture with the combine * constant, but defer setting the latter until painting, so that we can * take the actor's overall opacity into account. */ - cogl_material_set_layer_combine (shadow_material_template, 0, + cogl_pipeline_set_layer_combine (shadow_pipeline_template, 0, "RGBA = MODULATE (CONSTANT, TEXTURE[A])", NULL); } - material = cogl_material_copy (shadow_material_template); - - cogl_material_set_layer (material, 0, texture); - - cogl_handle_unref (texture); - - return material; + pipeline = cogl_pipeline_copy (shadow_pipeline_template); + cogl_pipeline_set_layer_texture (pipeline, 0, texture); + cogl_object_unref (texture); + return pipeline; } -CoglHandle -_st_create_shadow_material_from_actor (StShadow *shadow_spec, +CoglPipeline * +_st_create_shadow_pipeline_from_actor (StShadow *shadow_spec, ClutterActor *actor) { - CoglHandle shadow_material = COGL_INVALID_HANDLE; + CoglPipeline *shadow_pipeline = NULL; if (CLUTTER_IS_TEXTURE (actor)) { - CoglHandle texture; + CoglTexture *texture; texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor)); - shadow_material = _st_create_shadow_material (shadow_spec, texture); + shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, texture); } else { - CoglHandle buffer, offscreen; + CoglTexture *buffer; + CoglOffscreen *offscreen; + CoglFramebuffer *fb; ClutterActorBox box; CoglColor clear_color; float width, height; + CoglError *catch_error = NULL; clutter_actor_get_allocation_box (actor, &box); clutter_actor_box_get_size (&box, &width, &height); if (width == 0 || height == 0) - return COGL_INVALID_HANDLE; + return NULL; buffer = cogl_texture_new_with_size (width, height, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); - if (buffer == COGL_INVALID_HANDLE) - return COGL_INVALID_HANDLE; + if (buffer == NULL) + return NULL; - offscreen = cogl_offscreen_new_to_texture (buffer); + offscreen = cogl_offscreen_new_with_texture (buffer); + fb = COGL_FRAMEBUFFER (offscreen); - if (offscreen == COGL_INVALID_HANDLE) + if (!cogl_framebuffer_allocate (fb, &catch_error)) { - cogl_handle_unref (buffer); - return COGL_INVALID_HANDLE; + cogl_error_free (catch_error); + cogl_object_unref (buffer); + return NULL; } - cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0); - cogl_push_framebuffer (offscreen); - cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); - cogl_translate (-box.x1, -box.y1, 0); - cogl_ortho (0, width, height, 0, 0, 1.0); + cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0); + + /* XXX: There's no way to render a ClutterActor to an offscreen + * as it uses the implicit API. */ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + cogl_push_framebuffer (fb); + G_GNUC_END_IGNORE_DEPRECATIONS; + + cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color); + cogl_framebuffer_translate (fb, -box.x1, -box.y1, 0); + cogl_framebuffer_orthographic (fb, 0, width, height, 0, 0, 1.0); clutter_actor_paint (actor); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; cogl_pop_framebuffer (); - cogl_handle_unref (offscreen); + G_GNUC_END_IGNORE_DEPRECATIONS; - shadow_material = _st_create_shadow_material (shadow_spec, buffer); + cogl_object_unref (fb); - cogl_handle_unref (buffer); + shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, buffer); + + cogl_object_unref (buffer); } - return shadow_material; + return shadow_pipeline; } /** @@ -610,29 +618,27 @@ _st_create_shadow_cairo_pattern (StShadow *shadow_spec, void _st_paint_shadow_with_opacity (StShadow *shadow_spec, - CoglHandle shadow_material, + CoglPipeline *shadow_pipeline, + CoglFramebuffer *fb, ClutterActorBox *box, guint8 paint_opacity) { ClutterActorBox shadow_box; - CoglColor color; + CoglColor color; g_return_if_fail (shadow_spec != NULL); - g_return_if_fail (shadow_material != COGL_INVALID_HANDLE); + g_return_if_fail (shadow_pipeline != NULL); st_shadow_get_box (shadow_spec, box, &shadow_box); - cogl_color_set_from_4ub (&color, - shadow_spec->color.red * paint_opacity / 255, - shadow_spec->color.green * paint_opacity / 255, - shadow_spec->color.blue * paint_opacity / 255, - shadow_spec->color.alpha * paint_opacity / 255); + cogl_color_init_from_4ub (&color, + shadow_spec->color.red * paint_opacity / 255, + shadow_spec->color.green * paint_opacity / 255, + shadow_spec->color.blue * paint_opacity / 255, + shadow_spec->color.alpha * paint_opacity / 255); cogl_color_premultiply (&color); - - cogl_material_set_layer_combine_constant (shadow_material, 0, &color); - - cogl_set_source (shadow_material); - cogl_rectangle_with_texture_coords (shadow_box.x1, shadow_box.y1, - shadow_box.x2, shadow_box.y2, - 0, 0, 1, 1); + cogl_pipeline_set_layer_combine_constant (shadow_pipeline, 0, &color); + cogl_framebuffer_draw_rectangle (fb, shadow_pipeline, + shadow_box.x1, shadow_box.y1, + shadow_box.x2, shadow_box.y2); } diff --git a/src/st/st-private.h b/src/st/st-private.h index 05fa63483..5c44998aa 100644 --- a/src/st/st-private.h +++ b/src/st/st-private.h @@ -59,18 +59,19 @@ void _st_actor_get_preferred_height (ClutterActor *actor, void _st_set_text_from_style (ClutterText *text, StThemeNode *theme_node); -CoglHandle _st_create_texture_material (CoglHandle src_texture); +CoglPipeline * _st_create_texture_pipeline (CoglTexture *src_texture); /* Helper for widgets which need to draw additional shadows */ -CoglHandle _st_create_shadow_material (StShadow *shadow_spec, - CoglHandle src_texture); -CoglHandle _st_create_shadow_material_from_actor (StShadow *shadow_spec, - ClutterActor *actor); +CoglPipeline * _st_create_shadow_pipeline (StShadow *shadow_spec, + CoglTexture *src_texture); +CoglPipeline * _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec, + ClutterActor *actor); cairo_pattern_t *_st_create_shadow_cairo_pattern (StShadow *shadow_spec, cairo_pattern_t *src_pattern); void _st_paint_shadow_with_opacity (StShadow *shadow_spec, - CoglHandle shadow_material, + CoglPipeline *shadow_pipeline, + CoglFramebuffer *fb, ClutterActorBox *box, guint8 paint_opacity); diff --git a/src/st/st-shadow.c b/src/st/st-shadow.c index 4a2ff001d..605d39493 100644 --- a/src/st/st-shadow.c +++ b/src/st/st-shadow.c @@ -190,7 +190,7 @@ st_shadow_get_box (StShadow *shadow, struct _StShadowHelper { StShadow *shadow; - CoglMaterial *material; + CoglPipeline *pipeline; gfloat width; gfloat height; @@ -224,14 +224,14 @@ st_shadow_helper_update (StShadowHelper *helper, clutter_actor_get_size (source, &width, &height); - if (helper->material == NULL || + if (helper->pipeline == NULL || helper->width != width || helper->height != height) { - if (helper->material) - cogl_object_unref (helper->material); + if (helper->pipeline) + cogl_object_unref (helper->pipeline); - helper->material = _st_create_shadow_material_from_actor (helper->shadow, source); + helper->pipeline = _st_create_shadow_pipeline_from_actor (helper->shadow, source); helper->width = width; helper->height = height; } @@ -250,8 +250,8 @@ st_shadow_helper_copy (StShadowHelper *helper) copy = g_slice_new (StShadowHelper); *copy = *helper; - if (copy->material) - cogl_object_ref (copy->material); + if (copy->pipeline) + cogl_object_ref (copy->pipeline); st_shadow_ref (copy->shadow); return copy; @@ -266,8 +266,8 @@ st_shadow_helper_copy (StShadowHelper *helper) void st_shadow_helper_free (StShadowHelper *helper) { - if (helper->material) - cogl_object_unref (helper->material); + if (helper->pipeline) + cogl_object_unref (helper->pipeline); st_shadow_unref (helper->shadow); g_slice_free (StShadowHelper, helper); @@ -293,7 +293,8 @@ st_shadow_helper_paint (StShadowHelper *helper, clutter_actor_box_get_size (actor_box, &width, &height); _st_paint_shadow_with_opacity (helper->shadow, - helper->material, + helper->pipeline, + cogl_get_draw_framebuffer (), &allocation, paint_opacity); } diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c index 17cb0689d..dd9a67ba4 100644 --- a/src/st/st-texture-cache.c +++ b/src/st/st-texture-cache.c @@ -60,7 +60,7 @@ static guint signals[LAST_SIGNAL] = { 0, }; G_DEFINE_TYPE(StTextureCache, st_texture_cache, G_TYPE_OBJECT); /* We want to preserve the aspect ratio by default, also the default - * material for an empty texture is full opacity white, which we + * pipeline for an empty texture is full opacity white, which we * definitely don't want. Skip that by setting 0 opacity. */ static ClutterTexture * @@ -73,7 +73,7 @@ create_default_texture (void) /* Reverse the opacity we added while loading */ static void -set_texture_cogl_texture (ClutterTexture *clutter_texture, CoglHandle cogl_texture) +set_texture_cogl_texture (ClutterTexture *clutter_texture, CoglTexture *cogl_texture) { clutter_texture_set_cogl_texture (clutter_texture, cogl_texture); g_object_set (clutter_texture, "opacity", 255, NULL); @@ -144,7 +144,7 @@ st_texture_cache_init (StTextureCache *self) G_CALLBACK (on_icon_theme_changed), self); self->priv->keyed_cache = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, cogl_handle_unref); + g_free, cogl_object_unref); self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); self->priv->file_monitors = g_hash_table_new_full (g_str_hash, g_str_equal, @@ -516,16 +516,15 @@ load_pixbuf_async_finish (StTextureCache *cache, GAsyncResult *result, GError ** return g_simple_async_result_get_op_res_gpointer (simple); } -static CoglHandle -data_to_cogl_handle (const guchar *data, - gboolean has_alpha, - int width, - int height, - int rowstride, - gboolean add_padding) +static CoglTexture * +data_to_cogl_texture (const guchar *data, + gboolean has_alpha, + int width, + int height, + int rowstride, + gboolean add_padding) { - CoglHandle texture, offscreen; - CoglColor clear_color; + CoglTexture *texture; guint size; size = MAX (width, height); @@ -543,13 +542,6 @@ data_to_cogl_handle (const guchar *data, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); - offscreen = cogl_offscreen_new_to_texture (texture); - cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0); - cogl_push_framebuffer (offscreen); - cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); - cogl_pop_framebuffer (); - cogl_handle_unref (offscreen); - cogl_texture_set_region (texture, 0, 0, (size - width) / 2, (size - height) / 2, @@ -561,16 +553,16 @@ data_to_cogl_handle (const guchar *data, return texture; } -static CoglHandle -pixbuf_to_cogl_handle (GdkPixbuf *pixbuf, +static CoglTexture * +pixbuf_to_cogl_texture (GdkPixbuf *pixbuf, gboolean add_padding) { - return data_to_cogl_handle (gdk_pixbuf_get_pixels (pixbuf), - gdk_pixbuf_get_has_alpha (pixbuf), - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf), - gdk_pixbuf_get_rowstride (pixbuf), - add_padding); + return data_to_cogl_texture (gdk_pixbuf_get_pixels (pixbuf), + gdk_pixbuf_get_has_alpha (pixbuf), + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + gdk_pixbuf_get_rowstride (pixbuf), + add_padding); } static cairo_surface_t * @@ -600,7 +592,7 @@ finish_texture_load (AsyncTextureLoadData *data, { GSList *iter; StTextureCache *cache; - CoglHandle texdata = NULL; + CoglTexture *texdata = NULL; cache = data->cache; @@ -609,7 +601,7 @@ finish_texture_load (AsyncTextureLoadData *data, if (pixbuf == NULL) goto out; - texdata = pixbuf_to_cogl_handle (pixbuf, data->enforced_square); + texdata = pixbuf_to_cogl_texture (pixbuf, data->enforced_square); if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE) { @@ -618,7 +610,7 @@ finish_texture_load (AsyncTextureLoadData *data, if (!g_hash_table_lookup_extended (cache->priv->keyed_cache, data->key, &orig_key, &value)) { - cogl_handle_ref (texdata); + cogl_object_ref (texdata); g_hash_table_insert (cache->priv->keyed_cache, g_strdup (data->key), texdata); } @@ -632,7 +624,7 @@ finish_texture_load (AsyncTextureLoadData *data, out: if (texdata) - cogl_handle_unref (texdata); + cogl_object_unref (texdata); texture_load_data_free (data); } @@ -723,7 +715,7 @@ st_texture_cache_reset_texture (StTextureCachePropertyBind *bind, const char *propname) { GdkPixbuf *pixbuf; - CoglHandle texdata; + CoglTexture *texdata; g_object_get (bind->source, propname, &pixbuf, NULL); @@ -731,11 +723,11 @@ st_texture_cache_reset_texture (StTextureCachePropertyBind *bind, if (pixbuf != NULL) { - texdata = pixbuf_to_cogl_handle (pixbuf, FALSE); + texdata = pixbuf_to_cogl_texture (pixbuf, FALSE); g_object_unref (pixbuf); clutter_texture_set_cogl_texture (bind->texture, texdata); - cogl_handle_unref (texdata); + cogl_object_unref (texdata); clutter_actor_set_opacity (CLUTTER_ACTOR (bind->texture), 255); } @@ -778,7 +770,7 @@ st_texture_cache_free_bind (gpointer data) * * Create a #ClutterTexture which tracks the #GdkPixbuf value of a GObject property * named by @property_name. Unlike other methods in StTextureCache, the underlying - * CoglHandle is not shared by default with other invocations to this method. + * #CoglTexture is not shared by default with other invocations to this method. * * If the source object is destroyed, the texture will continue to show the last * value of the property. @@ -829,7 +821,7 @@ st_texture_cache_bind_pixbuf_property (StTextureCache *cache, * * Returns: (transfer full): A newly-referenced handle to the texture */ -CoglHandle +CoglTexture * st_texture_cache_load (StTextureCache *cache, const char *key, StTextureCachePolicy policy, @@ -837,7 +829,7 @@ st_texture_cache_load (StTextureCache *cache, void *data, GError **error) { - CoglHandle texture; + CoglTexture *texture; texture = g_hash_table_lookup (cache->priv->keyed_cache, key); if (!texture) @@ -846,9 +838,10 @@ st_texture_cache_load (StTextureCache *cache, if (texture) g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texture); else - return COGL_INVALID_HANDLE; + return NULL; } - cogl_handle_ref (texture); + + cogl_object_ref (texture); return texture; } @@ -873,7 +866,7 @@ ensure_request (StTextureCache *cache, AsyncTextureLoadData **request, ClutterActor *texture) { - CoglHandle texdata; + CoglTexture *texdata; AsyncTextureLoadData *pending; gboolean had_pending; @@ -1005,7 +998,7 @@ static ClutterActor * load_from_pixbuf (GdkPixbuf *pixbuf) { ClutterTexture *texture; - CoglHandle texdata; + CoglTexture *texdata; int width = gdk_pixbuf_get_width (pixbuf); int height = gdk_pixbuf_get_height (pixbuf); @@ -1013,11 +1006,11 @@ load_from_pixbuf (GdkPixbuf *pixbuf) clutter_actor_set_size (CLUTTER_ACTOR (texture), width, height); - texdata = pixbuf_to_cogl_handle (pixbuf, FALSE); + texdata = pixbuf_to_cogl_texture (pixbuf, FALSE); set_texture_cogl_texture (texture, texdata); - cogl_handle_unref (texdata); + cogl_object_unref (texdata); return CLUTTER_ACTOR (texture); } @@ -1256,7 +1249,7 @@ st_texture_cache_load_uri_async (StTextureCache *cache, return CLUTTER_ACTOR (texture); } -static CoglHandle +static CoglTexture * st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache, StTextureCachePolicy policy, const gchar *uri, @@ -1264,7 +1257,7 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache, int available_height, GError **error) { - CoglHandle texdata; + CoglTexture *texdata; GdkPixbuf *pixbuf; char *key; @@ -1278,17 +1271,17 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache, if (!pixbuf) goto out; - texdata = pixbuf_to_cogl_handle (pixbuf, FALSE); + texdata = pixbuf_to_cogl_texture (pixbuf, FALSE); g_object_unref (pixbuf); if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER) { - cogl_handle_ref (texdata); + cogl_object_ref (texdata); g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texdata); } } else - cogl_handle_ref (texdata); + cogl_object_ref (texdata); ensure_monitor_for_uri (cache, uri); @@ -1339,21 +1332,21 @@ out: } /** - * st_texture_cache_load_file_to_cogl_texture: + * st_texture_cache_load_file_to_cogl_texture: (skip) * @cache: A #StTextureCache * @file_path: Path to a file in supported image format * * This function synchronously loads the given file path * into a COGL texture. On error, a warning is emitted - * and %COGL_INVALID_HANDLE is returned. + * and %NULL is returned. * - * Returns: (transfer full): a new #CoglHandle + * Returns: (transfer full): a new #CoglTexture */ -CoglHandle +CoglTexture * st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache, const gchar *file_path) { - CoglHandle texture; + CoglTexture *texture; GFile *file; char *uri; GError *error = NULL; @@ -1370,7 +1363,7 @@ st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache, { g_warning ("Failed to load %s: %s", file_path, error->message); g_clear_error (&error); - return COGL_INVALID_HANDLE; + return NULL; } return texture; } diff --git a/src/st/st-texture-cache.h b/src/st/st-texture-cache.h index fa9746c49..a88bbf35a 100644 --- a/src/st/st-texture-cache.h +++ b/src/st/st-texture-cache.h @@ -90,8 +90,8 @@ ClutterActor *st_texture_cache_load_uri_async (StTextureCache *cache, int available_width, int available_height); -CoglHandle st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache, - const gchar *file_path); +CoglTexture *st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache, + const gchar *file_path); cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache, const gchar *file_path); @@ -107,13 +107,13 @@ cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *ca * texture handle for the given key, or set @error. * */ -typedef CoglHandle (*StTextureCacheLoader) (StTextureCache *cache, const char *key, void *data, GError **error); +typedef CoglTexture * (*StTextureCacheLoader) (StTextureCache *cache, const char *key, void *data, GError **error); -CoglHandle st_texture_cache_load (StTextureCache *cache, - const char *key, - StTextureCachePolicy policy, - StTextureCacheLoader load, - void *data, - GError **error); +CoglTexture * st_texture_cache_load (StTextureCache *cache, + const char *key, + StTextureCachePolicy policy, + StTextureCacheLoader load, + void *data, + GError **error); #endif /* __ST_TEXTURE_CACHE_H__ */ diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c index dc5b817a9..e31630f87 100644 --- a/src/st/st-theme-node-drawing.c +++ b/src/st/st-theme-node-drawing.c @@ -66,10 +66,10 @@ elliptical_arc (cairo_t *cr, cairo_restore (cr); } -static CoglHandle -create_corner_material (StCornerSpec *corner) +static CoglTexture * +create_corner_texture (StCornerSpec *corner) { - CoglHandle texture; + CoglTexture *texture; cairo_t *cr; cairo_surface_t *surface; guint rowstride; @@ -173,7 +173,7 @@ create_corner_material (StCornerSpec *corner) rowstride, data); g_free (data); - g_assert (texture != COGL_INVALID_HANDLE); + g_assert (texture != NULL); return texture; } @@ -190,13 +190,13 @@ corner_to_string (StCornerSpec *corner) corner->border_width_2); } -static CoglHandle +static CoglTexture * load_corner (StTextureCache *cache, const char *key, void *datap, GError **error) { - return create_corner_material ((StCornerSpec *) datap); + return create_corner_texture ((StCornerSpec *) datap); } /* To match the CSS specification, we want the border to look like it was @@ -337,13 +337,14 @@ st_theme_node_get_corner_border_widths (StThemeNode *node, } } -static CoglHandle +static CoglPipeline * st_theme_node_lookup_corner (StThemeNode *node, float width, float height, StCorner corner_id) { - CoglHandle texture, material; + CoglTexture *texture; + CoglPipeline *pipeline; char *key; StTextureCache *cache; StCornerSpec corner; @@ -354,7 +355,7 @@ st_theme_node_lookup_corner (StThemeNode *node, st_theme_node_reduce_border_radius (node, width, height, radius); if (radius[corner_id] == 0) - return COGL_INVALID_HANDLE; + return NULL; corner.radius = radius[corner_id]; corner.color = node->background_color; @@ -385,16 +386,16 @@ st_theme_node_lookup_corner (StThemeNode *node, if (corner.color.alpha == 0 && corner.border_color_1.alpha == 0 && corner.border_color_2.alpha == 0) - return COGL_INVALID_HANDLE; + return NULL; key = corner_to_string (&corner); texture = st_texture_cache_load (cache, key, ST_TEXTURE_CACHE_POLICY_NONE, load_corner, &corner, NULL); - material = _st_create_texture_material (texture); - cogl_handle_unref (texture); + pipeline = _st_create_texture_pipeline (texture); + cogl_object_unref (texture); g_free (key); - return material; + return pipeline; } static void @@ -934,13 +935,13 @@ paint_inset_box_shadow_to_cairo_context (StThemeNode *node, * we need to use cairo. This function is a slow fallback path for those * cases (gradients, background images, etc). */ -static CoglHandle +static CoglTexture * st_theme_node_prerender_background (StThemeNode *node, float actor_width, float actor_height) { StBorderImage *border_image; - CoglHandle texture; + CoglTexture *texture; guint radius[4]; int i; cairo_t *cr; @@ -1268,30 +1269,17 @@ st_theme_node_prerender_background (StThemeNode *node, return texture; } -static void st_theme_node_paint_borders (StThemeNodePaintState *state, - const ClutterActorBox *box, - guint8 paint_opacity); - void st_theme_node_invalidate_border_image (StThemeNode *node) { - if (node->border_slices_texture != COGL_INVALID_HANDLE) - { - cogl_handle_unref (node->border_slices_texture); - node->border_slices_texture = COGL_INVALID_HANDLE; - } - - if (node->border_slices_material != COGL_INVALID_HANDLE) - { - cogl_handle_unref (node->border_slices_material); - node->border_slices_material = COGL_INVALID_HANDLE; - } + g_clear_pointer (&node->border_slices_texture, cogl_object_unref); + g_clear_pointer (&node->border_slices_pipeline, cogl_object_unref); } static gboolean st_theme_node_load_border_image (StThemeNode *node) { - if (node->border_slices_texture == COGL_INVALID_HANDLE) + if (node->border_slices_texture == NULL) { StBorderImage *border_image; @@ -1303,42 +1291,28 @@ st_theme_node_load_border_image (StThemeNode *node) filename = st_border_image_get_filename (border_image); node->border_slices_texture = st_texture_cache_load_file_to_cogl_texture (st_texture_cache_get_default (), filename); - if (node->border_slices_texture == COGL_INVALID_HANDLE) + if (node->border_slices_texture == NULL) goto out; - node->border_slices_material = _st_create_texture_material (node->border_slices_texture); + node->border_slices_pipeline = _st_create_texture_pipeline (node->border_slices_texture); } out: - return node->border_slices_texture != COGL_INVALID_HANDLE; + return node->border_slices_pipeline != NULL; } void st_theme_node_invalidate_background_image (StThemeNode *node) { - if (node->background_texture != COGL_INVALID_HANDLE) - { - cogl_handle_unref (node->background_texture); - node->background_texture = COGL_INVALID_HANDLE; - } - - if (node->background_material != COGL_INVALID_HANDLE) - { - cogl_handle_unref (node->background_material); - node->background_material = COGL_INVALID_HANDLE; - } - - if (node->background_shadow_material != COGL_INVALID_HANDLE) - { - cogl_handle_unref (node->background_shadow_material); - node->background_shadow_material = COGL_INVALID_HANDLE; - } + g_clear_pointer (&node->background_texture, cogl_object_unref); + g_clear_pointer (&node->background_pipeline, cogl_object_unref); + g_clear_pointer (&node->background_shadow_pipeline, cogl_object_unref); } static gboolean st_theme_node_load_background_image (StThemeNode *node) { - if (node->background_texture == COGL_INVALID_HANDLE) + if (node->background_texture == NULL) { const char *background_image; StShadow *background_image_shadow_spec; @@ -1350,27 +1324,38 @@ st_theme_node_load_background_image (StThemeNode *node) background_image_shadow_spec = st_theme_node_get_background_image_shadow (node); node->background_texture = st_texture_cache_load_file_to_cogl_texture (st_texture_cache_get_default (), background_image); - if (node->background_texture == COGL_INVALID_HANDLE) + if (node->background_texture == NULL) goto out; - node->background_material = _st_create_texture_material (node->background_texture); + node->background_pipeline = _st_create_texture_pipeline (node->background_texture); if (node->background_repeat) - cogl_material_set_layer_wrap_mode (node->background_material, 0, COGL_MATERIAL_WRAP_MODE_REPEAT); + cogl_pipeline_set_layer_wrap_mode (node->background_pipeline, 0, COGL_PIPELINE_WRAP_MODE_REPEAT); if (background_image_shadow_spec) { - node->background_shadow_material = _st_create_shadow_material (background_image_shadow_spec, + node->background_shadow_pipeline = _st_create_shadow_pipeline (background_image_shadow_spec, node->background_texture); } } out: - return node->background_texture != COGL_INVALID_HANDLE; + return node->background_texture != NULL; } static void st_theme_node_prerender_shadow (StThemeNodePaintState *state); +static CoglPipeline * +get_color_pipeline (guint8 r, guint8 g, guint8 b, guint8 a) +{ + CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); + CoglPipeline *pipeline; + + pipeline = cogl_pipeline_new (ctx); + cogl_pipeline_set_color4ub (pipeline, r, g, b, a); + return pipeline; +} + static void st_theme_node_render_resources (StThemeNodePaintState *state, StThemeNode *node, @@ -1438,13 +1423,13 @@ st_theme_node_render_resources (StThemeNodePaintState *state, } } - state->corner_material[ST_CORNER_TOPLEFT] = + state->corner_pipeline[ST_CORNER_TOPLEFT] = st_theme_node_lookup_corner (node, width, height, ST_CORNER_TOPLEFT); - state->corner_material[ST_CORNER_TOPRIGHT] = + state->corner_pipeline[ST_CORNER_TOPRIGHT] = st_theme_node_lookup_corner (node, width, height, ST_CORNER_TOPRIGHT); - state->corner_material[ST_CORNER_BOTTOMRIGHT] = + state->corner_pipeline[ST_CORNER_BOTTOMRIGHT] = st_theme_node_lookup_corner (node, width, height, ST_CORNER_BOTTOMRIGHT); - state->corner_material[ST_CORNER_BOTTOMLEFT] = + state->corner_pipeline[ST_CORNER_BOTTOMLEFT] = st_theme_node_lookup_corner (node, width, height, ST_CORNER_BOTTOMLEFT); /* Use cairo to prerender the node if there is a gradient, or @@ -1463,17 +1448,17 @@ st_theme_node_render_resources (StThemeNodePaintState *state, state->prerendered_texture = st_theme_node_prerender_background (node, width, height); if (state->prerendered_texture) - state->prerendered_material = _st_create_texture_material (state->prerendered_texture); + state->prerendered_pipeline = _st_create_texture_pipeline (state->prerendered_texture); else - state->prerendered_material = COGL_INVALID_HANDLE; + state->prerendered_pipeline = NULL; if (box_shadow_spec && !has_inset_box_shadow) { if (st_theme_node_load_border_image (node)) - state->box_shadow_material = _st_create_shadow_material (box_shadow_spec, + state->box_shadow_pipeline = _st_create_shadow_pipeline (box_shadow_spec, node->border_slices_texture); - else if (state->prerendered_texture != COGL_INVALID_HANDLE) - state->box_shadow_material = _st_create_shadow_material (box_shadow_spec, + else if (state->prerendered_texture != NULL) + state->box_shadow_pipeline = _st_create_shadow_pipeline (box_shadow_spec, state->prerendered_texture); else if (node->background_color.alpha > 0 || has_border) st_theme_node_prerender_shadow (state); @@ -1483,7 +1468,7 @@ st_theme_node_render_resources (StThemeNodePaintState *state, them. */ if (!node->cached_textures) { - if (state->prerendered_material == COGL_INVALID_HANDLE && + if (state->prerendered_pipeline == NULL && width >= node->box_shadow_min_width && height >= node->box_shadow_min_height) { @@ -1505,23 +1490,23 @@ st_theme_node_update_resources (StThemeNodePaintState *state, g_return_if_fail (width > 0 && height > 0); - /* Free handles we can't reuse */ - if (state->prerendered_texture != COGL_INVALID_HANDLE) + /* Free objects we can't reuse */ + if (state->prerendered_texture != NULL) { - cogl_handle_unref (state->prerendered_texture); - state->prerendered_texture = COGL_INVALID_HANDLE; + cogl_object_unref (state->prerendered_texture); + state->prerendered_texture = NULL; had_prerendered_texture = TRUE; } - if (state->prerendered_material != COGL_INVALID_HANDLE) + if (state->prerendered_pipeline != NULL) { - cogl_handle_unref (state->prerendered_material); - state->prerendered_material = COGL_INVALID_HANDLE; + cogl_object_unref (state->prerendered_pipeline); + state->prerendered_pipeline = NULL; - if (node->border_slices_texture == COGL_INVALID_HANDLE && - state->box_shadow_material != COGL_INVALID_HANDLE) + if (node->border_slices_texture == NULL && + state->box_shadow_pipeline != NULL) { - cogl_handle_unref (state->box_shadow_material); - state->box_shadow_material = COGL_INVALID_HANDLE; + cogl_object_unref (state->box_shadow_pipeline); + state->box_shadow_pipeline = NULL; had_box_shadow = TRUE; } } @@ -1535,43 +1520,26 @@ st_theme_node_update_resources (StThemeNodePaintState *state, if (had_prerendered_texture) { state->prerendered_texture = st_theme_node_prerender_background (node, width, height); - state->prerendered_material = _st_create_texture_material (state->prerendered_texture); + state->prerendered_pipeline = _st_create_texture_pipeline (state->prerendered_texture); } else { int corner_id; for (corner_id = 0; corner_id < 4; corner_id++) - if (state->corner_material[corner_id] == COGL_INVALID_HANDLE) - state->corner_material[corner_id] = + if (state->corner_pipeline[corner_id] == NULL) + state->corner_pipeline[corner_id] = st_theme_node_lookup_corner (node, width, height, corner_id); } if (had_box_shadow) - state->box_shadow_material = _st_create_shadow_material (box_shadow_spec, + state->box_shadow_pipeline = _st_create_shadow_pipeline (box_shadow_spec, state->prerendered_texture); } -static void -paint_material_with_opacity (CoglHandle material, - ClutterActorBox *box, - ClutterActorBox *coords, - guint8 paint_opacity) -{ - cogl_material_set_color4ub (material, - paint_opacity, paint_opacity, paint_opacity, paint_opacity); - - cogl_set_source (material); - - if (coords) - cogl_rectangle_with_texture_coords (box->x1, box->y1, box->x2, box->y2, - coords->x1, coords->y1, coords->x2, coords->y2); - else - cogl_rectangle (box->x1, box->y1, box->x2, box->y2); -} - static void st_theme_node_paint_borders (StThemeNodePaintState *state, + CoglFramebuffer *fb, const ClutterActorBox *box, guint8 paint_opacity) { @@ -1624,10 +1592,7 @@ st_theme_node_paint_borders (StThemeNodePaintState *state, if (alpha > 0) { - cogl_set_source_color4ub (effective_border.red, - effective_border.green, - effective_border.blue, - alpha); + CoglPipeline *pipeline; /* NORTH */ skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0; @@ -1670,7 +1635,12 @@ st_theme_node_paint_borders (StThemeNodePaintState *state, rects[15] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT] : height - border_width[ST_SIDE_BOTTOM]; - cogl_rectangles (rects, 4); + pipeline = get_color_pipeline (effective_border.red, + effective_border.green, + effective_border.blue, + alpha); + cogl_framebuffer_draw_rectangles (fb, pipeline, rects, 4); + cogl_object_unref (pipeline); } } @@ -1679,35 +1649,40 @@ st_theme_node_paint_borders (StThemeNodePaintState *state, { for (corner_id = 0; corner_id < 4; corner_id++) { - if (state->corner_material[corner_id] == COGL_INVALID_HANDLE) + CoglPipeline *pipeline = state->corner_pipeline[corner_id]; + + if (pipeline == NULL) continue; - cogl_material_set_color4ub (state->corner_material[corner_id], + cogl_pipeline_set_color4ub (pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity); - cogl_set_source (state->corner_material[corner_id]); switch (corner_id) { case ST_CORNER_TOPLEFT: - cogl_rectangle_with_texture_coords (0, 0, - max_width_radius[ST_CORNER_TOPLEFT], max_width_radius[ST_CORNER_TOPLEFT], - 0, 0, 0.5, 0.5); + cogl_framebuffer_draw_textured_rectangle (fb, pipeline, + 0, 0, + max_width_radius[ST_CORNER_TOPLEFT], max_width_radius[ST_CORNER_TOPLEFT], + 0, 0, 0.5, 0.5); break; case ST_CORNER_TOPRIGHT: - cogl_rectangle_with_texture_coords (width - max_width_radius[ST_CORNER_TOPRIGHT], 0, - width, max_width_radius[ST_CORNER_TOPRIGHT], - 0.5, 0, 1, 0.5); + cogl_framebuffer_draw_textured_rectangle (fb, pipeline, + width - max_width_radius[ST_CORNER_TOPRIGHT], 0, + width, max_width_radius[ST_CORNER_TOPRIGHT], + 0.5, 0, 1, 0.5); break; case ST_CORNER_BOTTOMRIGHT: - cogl_rectangle_with_texture_coords (width - max_width_radius[ST_CORNER_BOTTOMRIGHT], height - max_width_radius[ST_CORNER_BOTTOMRIGHT], - width, height, - 0.5, 0.5, 1, 1); + cogl_framebuffer_draw_textured_rectangle (fb, pipeline, + width - max_width_radius[ST_CORNER_BOTTOMRIGHT], height - max_width_radius[ST_CORNER_BOTTOMRIGHT], + width, height, + 0.5, 0.5, 1, 1); break; case ST_CORNER_BOTTOMLEFT: - cogl_rectangle_with_texture_coords (0, height - max_width_radius[ST_CORNER_BOTTOMLEFT], - max_width_radius[ST_CORNER_BOTTOMLEFT], height, - 0, 0.5, 0.5, 1); + cogl_framebuffer_draw_textured_rectangle (fb, pipeline, + 0, height - max_width_radius[ST_CORNER_BOTTOMLEFT], + max_width_radius[ST_CORNER_BOTTOMLEFT], height, + 0, 0.5, 0.5, 1); break; } } @@ -1717,10 +1692,12 @@ st_theme_node_paint_borders (StThemeNodePaintState *state, alpha = paint_opacity * node->background_color.alpha / 255; if (alpha > 0) { - cogl_set_source_color4ub (node->background_color.red, - node->background_color.green, - node->background_color.blue, - alpha); + CoglPipeline *pipeline; + + pipeline = get_color_pipeline (node->background_color.red, + node->background_color.green, + node->background_color.blue, + alpha); /* We add padding to each corner, so that all corners end up as if they * had a border-radius of max_border_radius, which allows us to treat @@ -1803,8 +1780,9 @@ st_theme_node_paint_borders (StThemeNodePaintState *state, verts[7] = height - border_width[ST_SIDE_BOTTOM]; } break; + + cogl_framebuffer_draw_rectangles (fb, pipeline, verts, 4); } - cogl_rectangles (verts, n_rects); } /* Once we've drawn the borders and corners, if the corners are bigger @@ -1819,25 +1797,31 @@ st_theme_node_paint_borders (StThemeNodePaintState *state, * necessary, then the main rectangle */ if (max_border_radius > border_width[ST_SIDE_TOP]) - cogl_rectangle (MAX(max_border_radius, border_width[ST_SIDE_LEFT]), - border_width[ST_SIDE_TOP], - width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]), - max_border_radius); + cogl_framebuffer_draw_rectangle (fb, pipeline, + MAX(max_border_radius, border_width[ST_SIDE_LEFT]), + border_width[ST_SIDE_TOP], + width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]), + max_border_radius); if (max_border_radius > border_width[ST_SIDE_BOTTOM]) - cogl_rectangle (MAX(max_border_radius, border_width[ST_SIDE_LEFT]), - height - max_border_radius, - width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]), - height - border_width[ST_SIDE_BOTTOM]); + cogl_framebuffer_draw_rectangle (fb, pipeline, + MAX(max_border_radius, border_width[ST_SIDE_LEFT]), + height - max_border_radius, + width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]), + height - border_width[ST_SIDE_BOTTOM]); - cogl_rectangle (border_width[ST_SIDE_LEFT], - MAX(border_width[ST_SIDE_TOP], max_border_radius), - width - border_width[ST_SIDE_RIGHT], - height - MAX(border_width[ST_SIDE_BOTTOM], max_border_radius)); + cogl_framebuffer_draw_rectangle (fb, pipeline, + border_width[ST_SIDE_LEFT], + MAX(border_width[ST_SIDE_TOP], max_border_radius), + width - border_width[ST_SIDE_RIGHT], + height - MAX(border_width[ST_SIDE_BOTTOM], max_border_radius)); + + cogl_object_unref (pipeline); } } static void st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state, + CoglFramebuffer *fb, const ClutterActorBox *box, guint8 paint_opacity) { @@ -1943,16 +1927,14 @@ st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state, right += xoffset; /* Setup pipeline */ - cogl_color_set_from_4ub (&color, - box_shadow_spec->color.red * paint_opacity / 255, - box_shadow_spec->color.green * paint_opacity / 255, - box_shadow_spec->color.blue * paint_opacity / 255, - box_shadow_spec->color.alpha * paint_opacity / 255); + cogl_color_init_from_4ub (&color, + box_shadow_spec->color.red * paint_opacity / 255, + box_shadow_spec->color.green * paint_opacity / 255, + box_shadow_spec->color.blue * paint_opacity / 255, + box_shadow_spec->color.alpha * paint_opacity / 255); cogl_color_premultiply (&color); - cogl_material_set_layer_combine_constant (state->box_shadow_material, 0, &color); - - cogl_set_source (state->box_shadow_material); + cogl_pipeline_set_layer_combine_constant (state->box_shadow_pipeline, 0, &color); idx = 0; @@ -2080,36 +2062,8 @@ st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state, } } - cogl_rectangles_with_texture_coords (rectangles, idx / 8); - -#if 0 - /* Visual feedback on shadow's 9-slice and orignal offscreen buffer, - for debug purposes */ - cogl_rectangle (xend, yoffset, xend + shadow_width, yoffset + shadow_height); - - cogl_set_source_color4ub (0xff, 0x0, 0x0, 0xff); - - cogl_rectangle (xoffset, top, xend, top + 1); - cogl_rectangle (xoffset, bottom, xend, bottom + 1); - cogl_rectangle (left, yoffset, left + 1, yend); - cogl_rectangle (right, yoffset, right + 1, yend); - - cogl_rectangle (xend, yoffset, xend + shadow_width, yoffset + 1); - cogl_rectangle (xend, yoffset + shadow_height, xend + shadow_width, yoffset + shadow_height + 1); - cogl_rectangle (xend, yoffset, xend + 1, yoffset + shadow_height); - cogl_rectangle (xend + shadow_width, yoffset, xend + shadow_width + 1, yoffset + shadow_height); - - s_top *= shadow_height; - s_bottom *= shadow_height; - s_left *= shadow_width; - s_right *= shadow_width; - - cogl_rectangle (xend, yoffset + s_top, xend + shadow_width, yoffset + s_top + 1); - cogl_rectangle (xend, yoffset + s_bottom, xend + shadow_width, yoffset + s_bottom + 1); - cogl_rectangle (xend + s_left, yoffset, xend + s_left + 1, yoffset + shadow_height); - cogl_rectangle (xend + s_right, yoffset, xend + s_right + 1, yoffset + shadow_height); - -#endif + cogl_framebuffer_draw_textured_rectangles (fb, state->box_shadow_pipeline, + rectangles, idx / 4); } static void @@ -2119,7 +2073,8 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state) guint border_radius[4]; int max_borders[4]; int center_radius, corner_id; - CoglHandle buffer, offscreen; + CoglTexture *buffer; + CoglOffscreen *offscreen; /* Get infos from the node */ if (state->alloc_width < node->box_shadow_min_width || @@ -2160,33 +2115,32 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state) state->box_shadow_height, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); - offscreen = cogl_offscreen_new_to_texture (buffer); + offscreen = cogl_offscreen_new_with_texture (buffer); - if (offscreen != COGL_INVALID_HANDLE) + if (offscreen != NULL) { + CoglFramebuffer *fb = COGL_FRAMEBUFFER (offscreen); ClutterActorBox box = { 0, 0, state->box_shadow_width, state->box_shadow_height}; CoglColor clear_color; - cogl_push_framebuffer (offscreen); - cogl_ortho (0, state->box_shadow_width, state->box_shadow_height, 0, 0, 1.0); + cogl_framebuffer_orthographic (fb, 0, state->box_shadow_width, state->box_shadow_height, 0, 0, 1.0); + cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color); + cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0); + st_theme_node_paint_borders (state, fb, &box, 0xFF); + cogl_object_unref (offscreen); - cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0); - cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); - - st_theme_node_paint_borders (state, &box, 0xFF); - cogl_pop_framebuffer (); - cogl_handle_unref (offscreen); - - state->box_shadow_material = _st_create_shadow_material (st_theme_node_get_box_shadow (node), + state->box_shadow_pipeline = _st_create_shadow_pipeline (st_theme_node_get_box_shadow (node), buffer); } - cogl_handle_unref (buffer); + + cogl_object_unref (buffer); } static void st_theme_node_paint_sliced_border_image (StThemeNode *node, float width, float height, + CoglFramebuffer *fb, guint8 paint_opacity) { gfloat ex, ey; @@ -2194,7 +2148,7 @@ st_theme_node_paint_sliced_border_image (StThemeNode *node, gint border_left, border_right, border_top, border_bottom; float img_width, img_height; StBorderImage *border_image; - CoglHandle material; + CoglPipeline *pipeline; border_image = st_theme_node_get_border_image (node); g_assert (border_image != NULL); @@ -2218,11 +2172,8 @@ st_theme_node_paint_sliced_border_image (StThemeNode *node, if (ey < 0) ey = border_bottom; /* FIXME ? */ - material = node->border_slices_material; - cogl_material_set_color4ub (material, - paint_opacity, paint_opacity, paint_opacity, paint_opacity); - - cogl_set_source (material); + pipeline = node->border_slices_pipeline; + cogl_pipeline_set_color4ub (pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity); { float rectangles[] = @@ -2273,12 +2224,14 @@ st_theme_node_paint_sliced_border_image (StThemeNode *node, 1.0, 1.0 }; - cogl_rectangles_with_texture_coords (rectangles, 9); + cogl_framebuffer_draw_textured_rectangles (fb, pipeline, + rectangles, 9); } } static void st_theme_node_paint_outline (StThemeNode *node, + CoglFramebuffer *fb, const ClutterActorBox *box, guint8 paint_opacity) @@ -2287,6 +2240,7 @@ st_theme_node_paint_outline (StThemeNode *node, int outline_width; float rects[16]; ClutterColor outline_color, effective_outline; + CoglPipeline *pipeline; width = box->x2 - box->x1; height = box->y2 - box->y1; @@ -2298,10 +2252,10 @@ st_theme_node_paint_outline (StThemeNode *node, st_theme_node_get_outline_color (node, &outline_color); over (&outline_color, &node->background_color, &effective_outline); - cogl_set_source_color4ub (effective_outline.red, - effective_outline.green, - effective_outline.blue, - paint_opacity * effective_outline.alpha / 255); + pipeline = get_color_pipeline (effective_outline.red, + effective_outline.green, + effective_outline.blue, + paint_opacity * effective_outline.alpha / 255); /* The outline is drawn just outside the border, which means just * outside the allocation box. This means that in some situations @@ -2333,7 +2287,8 @@ st_theme_node_paint_outline (StThemeNode *node, rects[14] = 0; rects[15] = height; - cogl_rectangles (rects, 4); + cogl_framebuffer_draw_rectangles (fb, pipeline, rects, 16); + cogl_object_unref (pipeline); } static gboolean @@ -2373,9 +2328,13 @@ st_theme_node_needs_new_box_shadow_for_size (StThemeNodePaintState *state, return FALSE; } +/** + * st_theme_node_paint: (skip) + */ void st_theme_node_paint (StThemeNode *node, StThemeNodePaintState *state, + CoglFramebuffer *fb, const ClutterActorBox *box, guint8 paint_opacity) { @@ -2441,24 +2400,26 @@ st_theme_node_paint (StThemeNode *node, * such that it's aligned to the outside edges) */ - if (state->box_shadow_material) + if (state->box_shadow_pipeline) { if (state->alloc_width < node->box_shadow_min_width || state->alloc_height < node->box_shadow_min_height) _st_paint_shadow_with_opacity (node->box_shadow, - state->box_shadow_material, + state->box_shadow_pipeline, + fb, &allocation, paint_opacity); else st_theme_node_paint_sliced_shadow (state, + fb, &allocation, paint_opacity); } - if (state->prerendered_material != COGL_INVALID_HANDLE || + if (state->prerendered_pipeline != NULL || st_theme_node_load_border_image (node)) { - if (state->prerendered_material != COGL_INVALID_HANDLE) + if (state->prerendered_pipeline != NULL) { ClutterActorBox paint_box; @@ -2466,23 +2427,24 @@ st_theme_node_paint (StThemeNode *node, &allocation, &paint_box); - paint_material_with_opacity (state->prerendered_material, - &paint_box, - NULL, - paint_opacity); + cogl_pipeline_set_color4ub (state->prerendered_pipeline, + paint_opacity, paint_opacity, paint_opacity, paint_opacity); + cogl_framebuffer_draw_rectangle (fb, state->prerendered_pipeline, + paint_box.x1, paint_box.y1, + paint_box.x2, paint_box.y2); } - if (node->border_slices_material != COGL_INVALID_HANDLE) - st_theme_node_paint_sliced_border_image (node, width, height, paint_opacity); + if (node->border_slices_pipeline != NULL) + st_theme_node_paint_sliced_border_image (node, width, height, fb, paint_opacity); } else { - st_theme_node_paint_borders (state, box, paint_opacity); + st_theme_node_paint_borders (state, fb, box, paint_opacity); } - st_theme_node_paint_outline (node, box, paint_opacity); + st_theme_node_paint_outline (node, fb, box, paint_opacity); - if (state->prerendered_material == COGL_INVALID_HANDLE && + if (state->prerendered_pipeline == NULL && st_theme_node_load_background_image (node)) { ClutterActorBox background_box; @@ -2498,7 +2460,7 @@ st_theme_node_paint (StThemeNode *node, get_background_position (node, &allocation, &background_box, &texture_coords); if (has_visible_outline || node->background_repeat) - cogl_clip_push_rectangle (allocation.x1, allocation.y1, allocation.x2, allocation.y2); + cogl_framebuffer_push_rectangle_clip (fb, allocation.x1, allocation.y1, allocation.x2, allocation.y2); /* CSS based drop shadows * @@ -2513,19 +2475,23 @@ st_theme_node_paint (StThemeNode *node, * there is nothing (like a border, or the edge of the background color) * to logically confine it. */ - if (node->background_shadow_material != COGL_INVALID_HANDLE) + if (node->background_shadow_pipeline != NULL) _st_paint_shadow_with_opacity (node->background_image_shadow, - node->background_shadow_material, + node->background_shadow_pipeline, + fb, &background_box, paint_opacity); - paint_material_with_opacity (node->background_material, - &background_box, - &texture_coords, - paint_opacity); + cogl_pipeline_set_color4ub (node->background_pipeline, + paint_opacity, paint_opacity, paint_opacity, paint_opacity); + cogl_framebuffer_draw_textured_rectangle (fb, node->background_pipeline, + background_box.x1, background_box.y1, + background_box.x2, background_box.y2, + texture_coords.x1, texture_coords.x2, + texture_coords.y1, texture_coords.y2); if (has_visible_outline || node->background_repeat) - cogl_clip_pop (); + cogl_framebuffer_pop_clip (fb); } } @@ -2535,16 +2501,11 @@ st_theme_node_paint_state_node_free_internal (StThemeNodePaintState *state, { int corner_id; - if (state->prerendered_texture != COGL_INVALID_HANDLE) - cogl_handle_unref (state->prerendered_texture); - if (state->prerendered_material != COGL_INVALID_HANDLE) - cogl_handle_unref (state->prerendered_material); - if (state->box_shadow_material != COGL_INVALID_HANDLE) - cogl_handle_unref (state->box_shadow_material); - + g_clear_pointer (&state->prerendered_texture, cogl_object_unref); + g_clear_pointer (&state->prerendered_pipeline, cogl_object_unref); + g_clear_pointer (&state->box_shadow_pipeline, cogl_object_unref); for (corner_id = 0; corner_id < 4; corner_id++) - if (state->corner_material[corner_id] != COGL_INVALID_HANDLE) - cogl_handle_unref (state->corner_material[corner_id]); + g_clear_pointer (&state->corner_pipeline[corner_id], cogl_object_unref); if (unref_node) st_theme_node_paint_state_set_node (state, NULL); @@ -2587,12 +2548,11 @@ st_theme_node_paint_state_init (StThemeNodePaintState *state) state->alloc_width = 0; state->alloc_height = 0; state->node = NULL; - state->box_shadow_material = COGL_INVALID_HANDLE; - state->prerendered_texture = COGL_INVALID_HANDLE; - state->prerendered_material = COGL_INVALID_HANDLE; - + state->box_shadow_pipeline = NULL; + state->prerendered_texture = NULL; + state->prerendered_pipeline = NULL; for (corner_id = 0; corner_id < 4; corner_id++) - state->corner_material[corner_id] = COGL_INVALID_HANDLE; + state->corner_pipeline[corner_id] = NULL; } void @@ -2613,15 +2573,15 @@ st_theme_node_paint_state_copy (StThemeNodePaintState *state, state->box_shadow_width = other->box_shadow_width; state->box_shadow_height = other->box_shadow_height; - if (other->box_shadow_material) - state->box_shadow_material = cogl_handle_ref (other->box_shadow_material); + if (other->box_shadow_pipeline) + state->box_shadow_pipeline = cogl_object_ref (other->box_shadow_pipeline); if (other->prerendered_texture) - state->prerendered_texture = cogl_handle_ref (other->prerendered_texture); - if (other->prerendered_material) - state->prerendered_material = cogl_handle_ref (other->prerendered_material); + state->prerendered_texture = cogl_object_ref (other->prerendered_texture); + if (other->prerendered_pipeline) + state->prerendered_pipeline = cogl_object_ref (other->prerendered_pipeline); for (corner_id = 0; corner_id < 4; corner_id++) - if (other->corner_material[corner_id]) - state->corner_material[corner_id] = cogl_handle_ref (other->corner_material[corner_id]); + if (other->corner_pipeline[corner_id]) + state->corner_pipeline[corner_id] = cogl_object_ref (other->corner_pipeline[corner_id]); } void diff --git a/src/st/st-theme-node-private.h b/src/st/st-theme-node-private.h index aba58a343..b60849232 100644 --- a/src/st/st-theme-node-private.h +++ b/src/st/st-theme-node-private.h @@ -105,11 +105,11 @@ struct _StThemeNode { int box_shadow_min_width; int box_shadow_min_height; - CoglHandle border_slices_texture; - CoglHandle border_slices_material; - CoglHandle background_texture; - CoglHandle background_material; - CoglHandle background_shadow_material; + CoglTexture *border_slices_texture; + CoglPipeline *border_slices_pipeline; + CoglTexture *background_texture; + CoglPipeline *background_pipeline; + CoglPipeline *background_shadow_pipeline; StThemeNodePaintState cached_state; }; diff --git a/src/st/st-theme-node-transition.c b/src/st/st-theme-node-transition.c index a84c8871d..0bb6ec190 100644 --- a/src/st/st-theme-node-transition.c +++ b/src/st/st-theme-node-transition.c @@ -36,13 +36,13 @@ struct _StThemeNodeTransitionPrivate { StThemeNodePaintState old_paint_state; StThemeNodePaintState new_paint_state; - CoglHandle old_texture; - CoglHandle new_texture; + CoglTexture *old_texture; + CoglTexture *new_texture; - CoglHandle old_offscreen; - CoglHandle new_offscreen; + CoglOffscreen *old_offscreen; + CoglOffscreen *new_offscreen; - CoglHandle material; + CoglPipeline *pipeline; ClutterTimeline *timeline; @@ -237,9 +237,10 @@ setup_framebuffers (StThemeNodeTransition *transition, StThemeNodeTransitionPrivate *priv = transition->priv; CoglColor clear_color = { 0, 0, 0, 0 }; guint width, height; + CoglFramebuffer *fb; - /* template material to avoid unnecessary shader compilation */ - static CoglHandle material_template = COGL_INVALID_HANDLE; + /* template pipeline to avoid unnecessary shader compilation */ + static CoglPipeline *pipeline_template = NULL; width = priv->offscreen_box.x2 - priv->offscreen_box.x1; height = priv->offscreen_box.y2 - priv->offscreen_box.y1; @@ -248,77 +249,72 @@ setup_framebuffers (StThemeNodeTransition *transition, g_return_val_if_fail (height > 0, FALSE); if (priv->old_texture) - cogl_handle_unref (priv->old_texture); + cogl_object_unref (priv->old_texture); priv->old_texture = cogl_texture_new_with_size (width, height, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); if (priv->new_texture) - cogl_handle_unref (priv->new_texture); + cogl_object_unref (priv->new_texture); priv->new_texture = cogl_texture_new_with_size (width, height, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); - g_return_val_if_fail (priv->old_texture != COGL_INVALID_HANDLE, FALSE); - g_return_val_if_fail (priv->new_texture != COGL_INVALID_HANDLE, FALSE); + g_return_val_if_fail (priv->old_texture != NULL, FALSE); + g_return_val_if_fail (priv->new_texture != NULL, FALSE); if (priv->old_offscreen) - cogl_handle_unref (priv->old_offscreen); - priv->old_offscreen = cogl_offscreen_new_to_texture (priv->old_texture); + cogl_object_unref (priv->old_offscreen); + priv->old_offscreen = cogl_offscreen_new_with_texture (priv->old_texture); if (priv->new_offscreen) - cogl_handle_unref (priv->new_offscreen); - priv->new_offscreen = cogl_offscreen_new_to_texture (priv->new_texture); + cogl_object_unref (priv->new_offscreen); + priv->new_offscreen = cogl_offscreen_new_with_texture (priv->new_texture); - g_return_val_if_fail (priv->old_offscreen != COGL_INVALID_HANDLE, FALSE); - g_return_val_if_fail (priv->new_offscreen != COGL_INVALID_HANDLE, FALSE); + g_return_val_if_fail (priv->old_offscreen != NULL, FALSE); + g_return_val_if_fail (priv->new_offscreen != NULL, FALSE); - if (priv->material == NULL) + if (priv->pipeline == NULL) { - if (G_UNLIKELY (material_template == COGL_INVALID_HANDLE)) + if (G_UNLIKELY (pipeline_template == NULL)) { - material_template = cogl_material_new (); + CoglContext *ctx = + clutter_backend_get_cogl_context (clutter_get_default_backend ()); - cogl_material_set_layer_combine (material_template, 0, - "RGBA = REPLACE (TEXTURE)", - NULL); - cogl_material_set_layer_combine (material_template, 1, - "RGBA = INTERPOLATE (PREVIOUS, " - "TEXTURE, " - "CONSTANT[A])", - NULL); - cogl_material_set_layer_combine (material_template, 2, - "RGBA = MODULATE (PREVIOUS, " - "PRIMARY)", - NULL); + pipeline_template = cogl_pipeline_new (ctx); + + cogl_pipeline_set_layer_combine (pipeline_template, 0, "RGBA = REPLACE (TEXTURE)", NULL); + cogl_pipeline_set_layer_combine (pipeline_template, 1, "RGBA = INTERPOLATE (PREVIOUS, TEXTURE, CONSTANT[A])", NULL); + cogl_pipeline_set_layer_combine (pipeline_template, 2, "RGBA = MODULATE (PREVIOUS, PRIMARY)", NULL); } - priv->material = cogl_material_copy (material_template); + priv->pipeline = cogl_pipeline_copy (pipeline_template); } - cogl_material_set_layer (priv->material, 0, priv->new_texture); - cogl_material_set_layer (priv->material, 1, priv->old_texture); + cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->new_texture); + cogl_pipeline_set_layer_texture (priv->pipeline, 1, priv->old_texture); - cogl_push_framebuffer (priv->old_offscreen); - cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); - cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2, - priv->offscreen_box.y2, priv->offscreen_box.y1, - 0.0, 1.0); - st_theme_node_paint (priv->old_theme_node, &priv->old_paint_state, allocation, 255); - cogl_pop_framebuffer (); + fb = COGL_FRAMEBUFFER (priv->old_offscreen); + cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color); + cogl_framebuffer_orthographic (fb, + priv->offscreen_box.x1, priv->offscreen_box.x2, + priv->offscreen_box.y2, priv->offscreen_box.y1, + 0.0, 1.0); + st_theme_node_paint (priv->old_theme_node, &priv->old_paint_state, fb, allocation, 255); - cogl_push_framebuffer (priv->new_offscreen); - cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); - cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2, - priv->offscreen_box.y2, priv->offscreen_box.y1, - 0.0, 1.0); - st_theme_node_paint (priv->new_theme_node, &priv->new_paint_state, allocation, 255); - cogl_pop_framebuffer (); + fb = COGL_FRAMEBUFFER (priv->new_offscreen); + cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color); + cogl_framebuffer_orthographic (fb, + priv->offscreen_box.x1, priv->offscreen_box.x2, + priv->offscreen_box.y2, priv->offscreen_box.y1, + 0.0, 1.0); + st_theme_node_paint (priv->new_theme_node, &priv->new_paint_state, fb, allocation, 255); return TRUE; } void st_theme_node_transition_paint (StThemeNodeTransition *transition, + CoglFramebuffer *fb, ClutterActorBox *allocation, guint8 paint_opacity) { @@ -347,20 +343,20 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition, return; } - cogl_color_set_from_4f (&constant, 0., 0., 0., - clutter_timeline_get_progress (priv->timeline)); - cogl_material_set_layer_combine_constant (priv->material, 1, &constant); + cogl_color_init_from_4f (&constant, 0., 0., 0., + clutter_timeline_get_progress (priv->timeline)); + cogl_pipeline_set_layer_combine_constant (priv->pipeline, 1, &constant); - cogl_material_set_color4ub (priv->material, + cogl_pipeline_set_color4ub (priv->pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity); - cogl_set_source (priv->material); - cogl_rectangle_with_multitexture_coords (priv->offscreen_box.x1, - priv->offscreen_box.y1, - priv->offscreen_box.x2, - priv->offscreen_box.y2, - tex_coords, 8); + cogl_framebuffer_draw_multitextured_rectangle (fb, priv->pipeline, + priv->offscreen_box.x1, + priv->offscreen_box.y1, + priv->offscreen_box.x2, + priv->offscreen_box.y2, + tex_coords, 8); } static void @@ -368,47 +364,16 @@ st_theme_node_transition_dispose (GObject *object) { StThemeNodeTransitionPrivate *priv = ST_THEME_NODE_TRANSITION (object)->priv; - if (priv->old_theme_node) - { - g_object_unref (priv->old_theme_node); - priv->old_theme_node = NULL; - } + g_clear_object (&priv->old_theme_node); + g_clear_object (&priv->new_theme_node); - if (priv->new_theme_node) - { - g_object_unref (priv->new_theme_node); - priv->new_theme_node = NULL; - } + g_clear_pointer (&priv->old_texture, cogl_object_unref); + g_clear_pointer (&priv->new_texture, cogl_object_unref); - if (priv->old_texture) - { - cogl_handle_unref (priv->old_texture); - priv->old_texture = NULL; - } + g_clear_pointer (&priv->old_offscreen, cogl_object_unref); + g_clear_pointer (&priv->new_offscreen, cogl_object_unref); - if (priv->new_texture) - { - cogl_handle_unref (priv->new_texture); - priv->new_texture = NULL; - } - - if (priv->old_offscreen) - { - cogl_handle_unref (priv->old_offscreen); - priv->old_offscreen = NULL; - } - - if (priv->new_offscreen) - { - cogl_handle_unref (priv->new_offscreen); - priv->new_offscreen = NULL; - } - - if (priv->material) - { - cogl_handle_unref (priv->material); - priv->material = NULL; - } + g_clear_pointer (&priv->pipeline, cogl_object_unref); if (priv->timeline) { diff --git a/src/st/st-theme-node-transition.h b/src/st/st-theme-node-transition.h index e78389e45..2a50d8ff8 100644 --- a/src/st/st-theme-node-transition.h +++ b/src/st/st-theme-node-transition.h @@ -63,6 +63,7 @@ void st_theme_node_transition_update (StThemeNodeTransition *transition, StThemeNode *new_node); void st_theme_node_transition_paint (StThemeNodeTransition *transition, + CoglFramebuffer *fb, ClutterActorBox *allocation, guint8 paint_opacity); diff --git a/src/st/st-theme-node.c b/src/st/st-theme-node.c index 22b383373..cdfe27985 100644 --- a/src/st/st-theme-node.c +++ b/src/st/st-theme-node.c @@ -49,11 +49,6 @@ static void st_theme_node_init (StThemeNode *node) { node->transition_duration = -1; - node->background_texture = COGL_INVALID_HANDLE; - node->background_material = COGL_INVALID_HANDLE; - node->background_shadow_material = COGL_INVALID_HANDLE; - node->border_slices_texture = COGL_INVALID_HANDLE; - node->border_slices_material = COGL_INVALID_HANDLE; st_theme_node_paint_state_init (&node->cached_state); } @@ -160,16 +155,11 @@ st_theme_node_finalize (GObject *object) if (node->background_image) g_free (node->background_image); - if (node->background_texture != COGL_INVALID_HANDLE) - cogl_handle_unref (node->background_texture); - if (node->background_material != COGL_INVALID_HANDLE) - cogl_handle_unref (node->background_material); - if (node->background_shadow_material != COGL_INVALID_HANDLE) - cogl_handle_unref (node->background_shadow_material); - if (node->border_slices_texture != COGL_INVALID_HANDLE) - cogl_handle_unref (node->border_slices_texture); - if (node->border_slices_material != COGL_INVALID_HANDLE) - cogl_handle_unref (node->border_slices_material); + g_clear_pointer (&node->background_texture, cogl_object_unref); + g_clear_pointer (&node->background_pipeline, cogl_object_unref); + g_clear_pointer (&node->background_shadow_pipeline, cogl_object_unref); + g_clear_pointer (&node->border_slices_texture, cogl_object_unref); + g_clear_pointer (&node->border_slices_pipeline, cogl_object_unref); G_OBJECT_CLASS (st_theme_node_parent_class)->finalize (object); } diff --git a/src/st/st-theme-node.h b/src/st/st-theme-node.h index 5fffa6343..8bf78c55c 100644 --- a/src/st/st-theme-node.h +++ b/src/st/st-theme-node.h @@ -105,10 +105,10 @@ struct _StThemeNodePaintState { float box_shadow_width; float box_shadow_height; - CoglHandle box_shadow_material; - CoglHandle prerendered_texture; - CoglHandle prerendered_material; - CoglHandle corner_material[4]; + CoglPipeline *box_shadow_pipeline; + CoglTexture *prerendered_texture; + CoglPipeline *prerendered_pipeline; + CoglPipeline *corner_pipeline[4]; }; GType st_theme_node_get_type (void) G_GNUC_CONST; @@ -268,6 +268,7 @@ gboolean st_theme_node_paint_equal (StThemeNode *node, void st_theme_node_paint (StThemeNode *node, StThemeNodePaintState *state, + CoglFramebuffer *fb, const ClutterActorBox *box, guint8 paint_opacity); diff --git a/src/st/st-widget.c b/src/st/st-widget.c index 15f45f6b0..a52267427 100644 --- a/src/st/st-widget.c +++ b/src/st/st-widget.c @@ -465,6 +465,7 @@ st_widget_paint_background (StWidget *widget) StThemeNode *theme_node; ClutterActorBox allocation; guint8 opacity; + CoglFramebuffer *fb = cogl_get_draw_framebuffer (); theme_node = st_widget_get_theme_node (widget); @@ -474,11 +475,13 @@ st_widget_paint_background (StWidget *widget) if (widget->priv->transition_animation) st_theme_node_transition_paint (widget->priv->transition_animation, + fb, &allocation, opacity); else st_theme_node_paint (theme_node, current_paint_state (widget), + fb, &allocation, opacity); }