Compare commits
	
		
			1 Commits
		
	
	
		
			3.11.91
			...
			wip/cogl-d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | d8009fd826 | 
| @@ -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)"\"		\ | ||||
|   | ||||
| @@ -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)\"		\ | ||||
|   | ||||
| @@ -28,8 +28,6 @@ | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #define CLUTTER_ENABLE_EXPERIMENTAL_API | ||||
| #define COGL_ENABLE_EXPERIMENTAL_API | ||||
| #include <clutter/clutter.h> | ||||
| #include <clutter/x11/clutter-x11.h> | ||||
| #include <gjs/gjs.h> | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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 <cogl/cogl.h> | ||||
| @@ -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 | ||||
|   | ||||
| @@ -21,7 +21,6 @@ | ||||
| #ifndef __SHELL_INVERT_LIGHTNESS_EFFECT_H__ | ||||
| #define __SHELL_INVERT_LIGHTNESS_EFFECT_H__ | ||||
|  | ||||
| #define COGL_ENABLE_EXPERIMENTAL_API | ||||
| #include <clutter/clutter.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
| @@ -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 <clutter/clutter.h> | ||||
| #include <cogl/cogl.h> | ||||
| #include <meta/display.h> | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -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", | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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__ */ | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
| }; | ||||
|   | ||||
| @@ -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) | ||||
|     { | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user