Compare commits
	
		
			1 Commits
		
	
	
		
			3.17.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