Compare commits

...

1 Commits

Author SHA1 Message Date
Jasper St. Pierre
d8009fd826 Fix most of the Cogl deprecation warnings 2013-09-11 15:26:44 -04:00
25 changed files with 564 additions and 689 deletions

View File

@ -1,4 +1,7 @@
st_cflags = \ st_cflags = \
-DCLUTTER_ENABLE_EXPERIMENTAL_API \
-DCOGL_ENABLE_EXPERIMENTAL_API \
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
-I$(top_srcdir)/src \ -I$(top_srcdir)/src \
-DPREFIX=\""$(prefix)"\" \ -DPREFIX=\""$(prefix)"\" \
-DLIBDIR=\""$(libdir)"\" \ -DLIBDIR=\""$(libdir)"\" \

View File

@ -68,6 +68,9 @@ include Makefile-calendar-server.am
include Makefile-hotplug-sniffer.am include Makefile-hotplug-sniffer.am
gnome_shell_cflags = \ gnome_shell_cflags = \
-DCLUTTER_ENABLE_EXPERIMENTAL_API \
-DCOGL_ENABLE_EXPERIMENTAL_API \
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
$(GNOME_SHELL_CFLAGS) \ $(GNOME_SHELL_CFLAGS) \
-I$(srcdir)/tray \ -I$(srcdir)/tray \
-DVERSION=\"$(VERSION)\" \ -DVERSION=\"$(VERSION)\" \

View File

@ -28,8 +28,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#define COGL_ENABLE_EXPERIMENTAL_API
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <clutter/x11/clutter-x11.h> #include <clutter/x11/clutter-x11.h>
#include <gjs/gjs.h> #include <gjs/gjs.h>

View File

@ -217,7 +217,7 @@ typedef struct {
ClutterTextDirection direction; ClutterTextDirection direction;
} CreateFadedIconData; } CreateFadedIconData;
static CoglHandle static CoglTexture *
shell_app_create_faded_icon_cpu (StTextureCache *cache, shell_app_create_faded_icon_cpu (StTextureCache *cache,
const char *key, const char *key,
void *datap, void *datap,
@ -227,7 +227,7 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache,
ShellApp *app; ShellApp *app;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
int size; int size;
CoglHandle texture; CoglTexture *texture;
gint width, height, rowstride; gint width, height, rowstride;
guint8 n_channels; guint8 n_channels;
gboolean have_alpha; gboolean have_alpha;
@ -263,13 +263,13 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache,
} }
if (info == NULL) if (info == NULL)
return COGL_INVALID_HANDLE; return NULL;
pixbuf = gtk_icon_info_load_icon (info, NULL); pixbuf = gtk_icon_info_load_icon (info, NULL);
g_object_unref (info); g_object_unref (info);
if (pixbuf == NULL) if (pixbuf == NULL)
return COGL_INVALID_HANDLE; return NULL;
width = gdk_pixbuf_get_width (pixbuf); width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf); height = gdk_pixbuf_get_height (pixbuf);
@ -338,7 +338,7 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache,
ClutterActor * ClutterActor *
shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection direction) shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection direction)
{ {
CoglHandle texture; CoglTexture *texture;
ClutterActor *result; ClutterActor *result;
char *cache_key; char *cache_key;
CreateFadedIconData data; CreateFadedIconData data;
@ -367,7 +367,7 @@ shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection directio
NULL); NULL);
g_free (cache_key); g_free (cache_key);
if (texture != COGL_INVALID_HANDLE) if (texture != NULL)
{ {
result = clutter_texture_new (); result = clutter_texture_new ();
clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (result), texture); clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (result), texture);

View File

@ -35,8 +35,6 @@
#define SHELL_IS_INVERT_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_INVERT_LIGHTNESS_EFFECT)) #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 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 "shell-invert-lightness-effect.h"
#include <cogl/cogl.h> #include <cogl/cogl.h>
@ -124,6 +122,7 @@ shell_invert_lightness_effect_paint_target (ClutterOffscreenEffect *effect)
ShellInvertLightnessEffect *self = SHELL_INVERT_LIGHTNESS_EFFECT (effect); ShellInvertLightnessEffect *self = SHELL_INVERT_LIGHTNESS_EFFECT (effect);
ClutterActor *actor; ClutterActor *actor;
guint8 paint_opacity; guint8 paint_opacity;
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
paint_opacity = clutter_actor_get_paint_opacity (actor); 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, paint_opacity,
paint_opacity); paint_opacity);
cogl_push_source (self->pipeline); cogl_framebuffer_draw_rectangle (fb, self->pipeline,
0, 0, self->tex_width, self->tex_height);
cogl_rectangle (0, 0, self->tex_width, self->tex_height);
cogl_pop_source ();
} }
static void static void

View File

@ -21,7 +21,6 @@
#ifndef __SHELL_INVERT_LIGHTNESS_EFFECT_H__ #ifndef __SHELL_INVERT_LIGHTNESS_EFFECT_H__
#define __SHELL_INVERT_LIGHTNESS_EFFECT_H__ #define __SHELL_INVERT_LIGHTNESS_EFFECT_H__
#define COGL_ENABLE_EXPERIMENTAL_API
#include <clutter/clutter.h> #include <clutter/clutter.h>
G_BEGIN_DECLS G_BEGIN_DECLS

View File

@ -441,15 +441,19 @@ recorder_record_frame (ShellRecorder *recorder)
recorder->last_frame_time = now; recorder->last_frame_time = now;
size = recorder->area.width * recorder->area.height * 4; size = recorder->area.width * recorder->area.height * 4;
data = g_malloc (size);
data = g_malloc (recorder->area.width * 4 * recorder->area.height); if (!cogl_framebuffer_read_pixels (cogl_get_draw_framebuffer (),
cogl_read_pixels (recorder->area.x, recorder->area.x,
recorder->area.y, recorder->area.y,
recorder->area.width, recorder->area.width,
recorder->area.height, recorder->area.height,
COGL_READ_PIXELS_COLOR_BUFFER,
CLUTTER_CAIRO_FORMAT_ARGB32, CLUTTER_CAIRO_FORMAT_ARGB32,
data); data))
{
g_warning ("Could not retrieve pixel data");
g_free (data);
return;
}
buffer = gst_buffer_new(); buffer = gst_buffer_new();
gst_buffer_insert_memory (buffer, -1, gst_buffer_insert_memory (buffer, -1,

View File

@ -1,8 +1,5 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* -*- 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 <clutter/clutter.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <meta/display.h> #include <meta/display.h>

View File

@ -97,6 +97,7 @@ shell_slicer_paint_child (ShellSlicer *self)
float width, height, child_width, child_height; float width, height, child_width, child_height;
StAlign x_align, y_align; StAlign x_align, y_align;
double x_align_factor, y_align_factor; double x_align_factor, y_align_factor;
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
child = st_bin_get_child (ST_BIN (self)); 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_width = child_box.x2 - child_box.x1;
child_height = child_box.y2 - child_box.y1; child_height = child_box.y2 - child_box.y1;
cogl_push_matrix (); cogl_framebuffer_push_matrix (fb);
cogl_framebuffer_push_rectangle_clip (fb, 0, 0, width, height);
cogl_clip_push_rectangle (0, 0, width, height); cogl_framebuffer_translate (fb,
cogl_translate ((int)(0.5 + x_align_factor * (width - child_width)), (int)(0.5 + x_align_factor * (width - child_width)),
(int)(0.5 + y_align_factor * (height - child_height)), (int)(0.5 + y_align_factor * (height - child_height)),
0); 0);
clutter_actor_paint (child); clutter_actor_paint (child);
cogl_clip_pop (); cogl_framebuffer_pop_clip (fb);
cogl_framebuffer_pop_matrix (fb);
cogl_pop_matrix ();
} }
static void static void

View File

@ -387,19 +387,20 @@ st_box_layout_paint (ClutterActor *actor)
ClutterActorBox allocation_box; ClutterActorBox allocation_box;
ClutterActorBox content_box; ClutterActorBox content_box;
ClutterActor *child; ClutterActor *child;
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
get_border_paint_offsets (self, &x, &y); get_border_paint_offsets (self, &x, &y);
if (x != 0 || y != 0) if (x != 0 || y != 0)
{ {
cogl_push_matrix (); cogl_framebuffer_push_matrix (fb);
cogl_translate ((int)x, (int)y, 0); cogl_framebuffer_translate (fb, (int)x, (int)y, 0);
} }
st_widget_paint_background (ST_WIDGET (actor)); st_widget_paint_background (ST_WIDGET (actor));
if (x != 0 || y != 0) if (x != 0 || y != 0)
{ {
cogl_pop_matrix (); cogl_framebuffer_pop_matrix (fb);
} }
if (clutter_actor_get_n_children (actor) == 0) if (clutter_actor_get_n_children (actor) == 0)
@ -417,7 +418,8 @@ st_box_layout_paint (ClutterActor *actor)
* the borders and background stay in place; after drawing the borders and * the borders and background stay in place; after drawing the borders and
* background, we clip to the content area */ * background, we clip to the content area */
if (priv->hadjustment || priv->vadjustment) if (priv->hadjustment || priv->vadjustment)
cogl_clip_push_rectangle ((int)content_box.x1, cogl_framebuffer_push_rectangle_clip (fb,
(int)content_box.x1,
(int)content_box.y1, (int)content_box.y1,
(int)content_box.x2, (int)content_box.x2,
(int)content_box.y2); (int)content_box.y2);
@ -428,7 +430,7 @@ st_box_layout_paint (ClutterActor *actor)
clutter_actor_paint (child); clutter_actor_paint (child);
if (priv->hadjustment || priv->vadjustment) if (priv->hadjustment || priv->vadjustment)
cogl_clip_pop (); cogl_framebuffer_pop_clip (fb);
} }
static void static void
@ -442,19 +444,20 @@ st_box_layout_pick (ClutterActor *actor,
ClutterActorBox allocation_box; ClutterActorBox allocation_box;
ClutterActorBox content_box; ClutterActorBox content_box;
ClutterActor *child; ClutterActor *child;
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
get_border_paint_offsets (self, &x, &y); get_border_paint_offsets (self, &x, &y);
if (x != 0 || y != 0) if (x != 0 || y != 0)
{ {
cogl_push_matrix (); cogl_framebuffer_push_matrix (fb);
cogl_translate ((int)x, (int)y, 0); cogl_framebuffer_translate (fb, (int)x, (int)y, 0);
} }
CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->pick (actor, color); CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->pick (actor, color);
if (x != 0 || y != 0) if (x != 0 || y != 0)
{ {
cogl_pop_matrix (); cogl_framebuffer_pop_matrix (fb);
} }
if (clutter_actor_get_n_children (actor) == 0) if (clutter_actor_get_n_children (actor) == 0)
@ -469,7 +472,8 @@ st_box_layout_pick (ClutterActor *actor,
content_box.y2 += y; content_box.y2 += y;
if (priv->hadjustment || priv->vadjustment) if (priv->hadjustment || priv->vadjustment)
cogl_clip_push_rectangle ((int)content_box.x1, cogl_framebuffer_push_rectangle_clip (fb,
(int)content_box.x1,
(int)content_box.y1, (int)content_box.y1,
(int)content_box.x2, (int)content_box.x2,
(int)content_box.y2); (int)content_box.y2);
@ -480,7 +484,7 @@ st_box_layout_pick (ClutterActor *actor,
clutter_actor_paint (child); clutter_actor_paint (child);
if (priv->hadjustment || priv->vadjustment) if (priv->hadjustment || priv->vadjustment)
cogl_clip_pop (); cogl_framebuffer_pop_clip (fb);
} }
static gboolean static gboolean

View File

@ -39,8 +39,8 @@
G_DEFINE_TYPE(StDrawingArea, st_drawing_area, ST_TYPE_WIDGET); G_DEFINE_TYPE(StDrawingArea, st_drawing_area, ST_TYPE_WIDGET);
struct _StDrawingAreaPrivate { struct _StDrawingAreaPrivate {
CoglHandle texture; CoglTexture *texture;
CoglHandle material; CoglPipeline *pipeline;
cairo_t *context; cairo_t *context;
guint needs_repaint : 1; guint needs_repaint : 1;
guint in_repaint : 1; guint in_repaint : 1;
@ -61,17 +61,8 @@ st_drawing_area_dispose (GObject *object)
StDrawingArea *area = ST_DRAWING_AREA (object); StDrawingArea *area = ST_DRAWING_AREA (object);
StDrawingAreaPrivate *priv = area->priv; StDrawingAreaPrivate *priv = area->priv;
if (priv->material != COGL_INVALID_HANDLE) g_clear_pointer (&priv->pipeline, cogl_object_unref);
{ g_clear_pointer (&priv->texture, cogl_object_unref);
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_OBJECT_CLASS (st_drawing_area_parent_class)->dispose (object); G_OBJECT_CLASS (st_drawing_area_parent_class)->dispose (object);
} }
@ -85,8 +76,6 @@ st_drawing_area_paint (ClutterActor *self)
ClutterActorBox allocation_box; ClutterActorBox allocation_box;
ClutterActorBox content_box; ClutterActorBox content_box;
int width, height; int width, height;
CoglColor color;
guint8 paint_opacity;
(CLUTTER_ACTOR_CLASS (st_drawing_area_parent_class))->paint (self); (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); width = (int)(0.5 + content_box.x2 - content_box.x1);
height = (int)(0.5 + content_box.y2 - content_box.y1); height = (int)(0.5 + content_box.y2 - content_box.y1);
if (priv->material == COGL_INVALID_HANDLE) if (priv->pipeline == NULL)
priv->material = cogl_material_new (); {
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) || (width != cogl_texture_get_width (priv->texture) ||
height != cogl_texture_get_height (priv->texture))) height != cogl_texture_get_height (priv->texture)))
{ {
cogl_handle_unref (priv->texture); cogl_object_unref (priv->texture);
priv->texture = COGL_INVALID_HANDLE; priv->texture = NULL;
} }
if (width > 0 && height > 0) if (width > 0 && height > 0)
{ {
if (priv->texture == COGL_INVALID_HANDLE) if (priv->texture == NULL)
{ {
priv->texture = cogl_texture_new_with_size (width, height, priv->texture = cogl_texture_new_with_size (width, height,
COGL_TEXTURE_NONE, 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) if (priv->texture)
{ {
paint_opacity = clutter_actor_get_paint_opacity (self); CoglColor color;
cogl_color_set_from_4ub (&color, guint8 paint_opacity;
paint_opacity, paint_opacity, paint_opacity, paint_opacity); CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
cogl_material_set_color (priv->material, &color);
cogl_set_source (priv->material); paint_opacity = clutter_actor_get_paint_opacity (self);
cogl_rectangle_with_texture_coords (content_box.x1, content_box.y1, cogl_color_init_from_4ub (&color, paint_opacity, paint_opacity, paint_opacity, paint_opacity);
content_box.x2, content_box.y2, cogl_pipeline_set_color (priv->pipeline, &color);
0.0f, 0.0f, 1.0f, 1.0f);
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, area->priv = G_TYPE_INSTANCE_GET_PRIVATE (area, ST_TYPE_DRAWING_AREA,
StDrawingAreaPrivate); StDrawingAreaPrivate);
area->priv->texture = COGL_INVALID_HANDLE; area->priv->texture = NULL;
} }
/** /**

View File

@ -56,7 +56,7 @@ struct _StIconPrivate
gint theme_icon_size; /* icon size from theme node */ gint theme_icon_size; /* icon size from theme node */
gint icon_size; /* icon size we are using */ gint icon_size; /* icon size we are using */
CoglHandle shadow_material; CoglPipeline *shadow_pipeline;
float shadow_width; float shadow_width;
float shadow_height; float shadow_height;
StShadow *shadow_spec; StShadow *shadow_spec;
@ -141,23 +141,9 @@ st_icon_dispose (GObject *gobject)
priv->pending_texture = NULL; priv->pending_texture = NULL;
} }
if (priv->gicon) g_clear_object (&priv->gicon);
{ g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref);
g_object_unref (priv->gicon); g_clear_pointer (&priv->shadow_spec, st_shadow_unref);
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_OBJECT_CLASS (st_icon_parent_class)->dispose (gobject); G_OBJECT_CLASS (st_icon_parent_class)->dispose (gobject);
} }
@ -241,7 +227,7 @@ st_icon_paint (ClutterActor *actor)
if (priv->icon_texture) if (priv->icon_texture)
{ {
if (priv->shadow_material) if (priv->shadow_pipeline)
{ {
ClutterActorBox allocation; ClutterActorBox allocation;
float width, height; float width, height;
@ -250,7 +236,8 @@ st_icon_paint (ClutterActor *actor)
clutter_actor_box_get_size (&allocation, &width, &height); clutter_actor_box_get_size (&allocation, &width, &height);
_st_paint_shadow_with_opacity (priv->shadow_spec, _st_paint_shadow_with_opacity (priv->shadow_spec,
priv->shadow_material, priv->shadow_pipeline,
cogl_get_draw_framebuffer (),
&allocation, &allocation,
clutter_actor_get_paint_opacity (priv->icon_texture)); 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); StThemeNode *theme_node = st_widget_get_theme_node (widget);
StIconPrivate *priv = self->priv; StIconPrivate *priv = self->priv;
if (priv->shadow_spec) g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref);
{ g_clear_pointer (&priv->shadow_spec, st_shadow_unref);
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;
}
priv->shadow_spec = st_theme_node_get_shadow (theme_node, "icon-shadow"); 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->icon_size = DEFAULT_ICON_SIZE;
self->priv->prop_icon_size = -1; 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_width = -1;
self->priv->shadow_height = -1; self->priv->shadow_height = -1;
} }
static void static void
st_icon_update_shadow_material (StIcon *icon) st_icon_update_shadow_pipeline (StIcon *icon)
{ {
StIconPrivate *priv = icon->priv; StIconPrivate *priv = icon->priv;
if (priv->shadow_material) g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref);
{
cogl_handle_unref (priv->shadow_material);
priv->shadow_material = COGL_INVALID_HANDLE;
}
if (priv->shadow_spec) if (priv->shadow_spec)
{ {
CoglHandle material;
gint width, height; gint width, height;
clutter_texture_get_base_size (CLUTTER_TEXTURE (priv->icon_texture), clutter_texture_get_base_size (CLUTTER_TEXTURE (priv->icon_texture),
&width, &height); &width, &height);
material = _st_create_shadow_material_from_actor (priv->shadow_spec, priv->shadow_pipeline = _st_create_shadow_pipeline_from_actor (priv->shadow_spec, priv->icon_texture);
priv->icon_texture);
priv->shadow_material = material;
priv->shadow_width = width; priv->shadow_width = width;
priv->shadow_height = height; priv->shadow_height = height;
} }
@ -379,7 +350,7 @@ static void
on_pixbuf_changed (ClutterTexture *texture, on_pixbuf_changed (ClutterTexture *texture,
StIcon *icon) StIcon *icon)
{ {
st_icon_update_shadow_material (icon); st_icon_update_shadow_pipeline (icon);
} }
static void static void
@ -402,7 +373,7 @@ st_icon_finish_update (StIcon *icon)
/* Remove the temporary ref we added */ /* Remove the temporary ref we added */
g_object_unref (priv->icon_texture); 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" */ /* "pixbuf-change" is actually a misnomer for "texture-changed" */
g_signal_connect_object (priv->icon_texture, "pixbuf-change", g_signal_connect_object (priv->icon_texture, "pixbuf-change",

View File

@ -60,7 +60,7 @@ struct _StLabelPrivate
{ {
ClutterActor *label; ClutterActor *label;
CoglHandle text_shadow_material; CoglPipeline *text_shadow_pipeline;
float shadow_width; float shadow_width;
float shadow_height; float shadow_height;
}; };
@ -118,11 +118,7 @@ st_label_style_changed (StWidget *self)
{ {
StLabelPrivate *priv = ST_LABEL(self)->priv; StLabelPrivate *priv = ST_LABEL(self)->priv;
if (priv->text_shadow_material != COGL_INVALID_HANDLE) g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
{
cogl_handle_unref (priv->text_shadow_material);
priv->text_shadow_material = COGL_INVALID_HANDLE;
}
_st_set_text_from_style ((ClutterText *)priv->label, st_widget_get_theme_node (self)); _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; priv->label = NULL;
} }
if (priv->text_shadow_material != COGL_INVALID_HANDLE) g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
{
cogl_handle_unref (priv->text_shadow_material);
priv->text_shadow_material = COGL_INVALID_HANDLE;
}
G_OBJECT_CLASS (st_label_parent_class)->dispose (object); 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_get_allocation_box (priv->label, &allocation);
clutter_actor_box_get_size (&allocation, &width, &height); 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 || width != priv->shadow_width ||
height != priv->shadow_height) height != priv->shadow_height)
{ {
CoglHandle material; g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
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);
priv->shadow_width = width; priv->shadow_width = width;
priv->shadow_height = height; 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, _st_paint_shadow_with_opacity (shadow_spec,
priv->text_shadow_material, priv->text_shadow_pipeline,
cogl_get_draw_framebuffer (),
&allocation, &allocation,
clutter_actor_get_paint_opacity (priv->label)); 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, label->priv->label = g_object_new (CLUTTER_TYPE_TEXT,
"ellipsize", PANGO_ELLIPSIZE_END, "ellipsize", PANGO_ELLIPSIZE_END,
NULL); NULL);
label->priv->text_shadow_material = COGL_INVALID_HANDLE; label->priv->text_shadow_pipeline = NULL;
label->priv->shadow_width = -1.; label->priv->shadow_width = -1.;
label->priv->shadow_height = -1.; label->priv->shadow_height = -1.;
@ -357,11 +344,7 @@ st_label_set_text (StLabel *label,
if (clutter_text_get_editable (ctext) || if (clutter_text_get_editable (ctext) ||
g_strcmp0 (clutter_text_get_text (ctext), text) != 0) g_strcmp0 (clutter_text_get_text (ctext), text) != 0)
{ {
if (priv->text_shadow_material != COGL_INVALID_HANDLE) g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
{
cogl_handle_unref (priv->text_shadow_material);
priv->text_shadow_material = COGL_INVALID_HANDLE;
}
clutter_text_set_text (ctext, text); clutter_text_set_text (ctext, text);

View File

@ -162,47 +162,41 @@ _st_set_text_from_style (ClutterText *text,
} }
/** /**
* _st_create_texture_material: * _st_create_texture_pipeline:
* @src_texture: The CoglTexture for the material * @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. * single layer.
*/ */
CoglHandle CoglPipeline *
_st_create_texture_material (CoglHandle src_texture) _st_create_texture_pipeline (CoglTexture *src_texture)
{ {
static CoglHandle texture_material_template = COGL_INVALID_HANDLE; static CoglPipeline *texture_pipeline_template = NULL;
CoglHandle material; CoglPipeline *pipeline;
g_return_val_if_fail (src_texture != COGL_INVALID_HANDLE, g_return_val_if_fail (src_texture != NULL, NULL);
COGL_INVALID_HANDLE);
/* We use a material that has a dummy texture as a base for all /* The only state used in the pipeline that would affect the shader
texture materials. The idea is that only the Cogl texture object generation is the texture type on the layer. Therefore we create
would be different in the children so it is likely that Cogl will a template pipeline which sets this state and all texture
be able to share GL programs between all the textures. */ pipelines are created as a copy of this. That way Cogl can find
if (G_UNLIKELY (texture_material_template == COGL_INVALID_HANDLE)) 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 }; CoglContext *ctx =
CoglHandle dummy_texture; clutter_backend_get_cogl_context (clutter_get_default_backend ());
dummy_texture = texture_pipeline_template = cogl_pipeline_new (ctx);
cogl_texture_new_from_data (1, 1, cogl_pipeline_set_layer_null_texture (texture_pipeline_template,
COGL_TEXTURE_NONE, 0, /* layer */
COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_TEXTURE_TYPE_2D);
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);
} }
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 pipeline;
return material;
} }
/***** /*****
@ -345,21 +339,20 @@ blur_pixels (guchar *pixels_in,
return pixels_out; return pixels_out;
} }
CoglHandle CoglPipeline *
_st_create_shadow_material (StShadow *shadow_spec, _st_create_shadow_pipeline (StShadow *shadow_spec,
CoglHandle src_texture) CoglTexture *src_texture)
{ {
static CoglHandle shadow_material_template = COGL_INVALID_HANDLE; static CoglPipeline *shadow_pipeline_template = NULL;
CoglHandle material; CoglPipeline *pipeline;
CoglHandle texture; CoglTexture *texture;
guchar *pixels_in, *pixels_out; guchar *pixels_in, *pixels_out;
gint width_in, height_in, rowstride_in; gint width_in, height_in, rowstride_in;
gint width_out, height_out, rowstride_out; gint width_out, height_out, rowstride_out;
g_return_val_if_fail (shadow_spec != NULL, COGL_INVALID_HANDLE); g_return_val_if_fail (shadow_spec != NULL, NULL);
g_return_val_if_fail (src_texture != COGL_INVALID_HANDLE, g_return_val_if_fail (src_texture != NULL, NULL);
COGL_INVALID_HANDLE);
width_in = cogl_texture_get_width (src_texture); width_in = cogl_texture_get_width (src_texture);
height_in = cogl_texture_get_height (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); 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 * constant, but defer setting the latter until painting, so that we can
* take the actor's overall opacity into account. */ * 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])", "RGBA = MODULATE (CONSTANT, TEXTURE[A])",
NULL); NULL);
} }
material = cogl_material_copy (shadow_material_template); pipeline = cogl_pipeline_copy (shadow_pipeline_template);
cogl_pipeline_set_layer_texture (pipeline, 0, texture);
cogl_material_set_layer (material, 0, texture); cogl_object_unref (texture);
return pipeline;
cogl_handle_unref (texture);
return material;
} }
CoglHandle CoglPipeline *
_st_create_shadow_material_from_actor (StShadow *shadow_spec, _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
ClutterActor *actor) ClutterActor *actor)
{ {
CoglHandle shadow_material = COGL_INVALID_HANDLE; CoglPipeline *shadow_pipeline = NULL;
if (CLUTTER_IS_TEXTURE (actor)) if (CLUTTER_IS_TEXTURE (actor))
{ {
CoglHandle texture; CoglTexture *texture;
texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor)); 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 else
{ {
CoglHandle buffer, offscreen; CoglTexture *buffer;
CoglOffscreen *offscreen;
CoglFramebuffer *fb;
ClutterActorBox box; ClutterActorBox box;
CoglColor clear_color; CoglColor clear_color;
float width, height; float width, height;
CoglError *catch_error = NULL;
clutter_actor_get_allocation_box (actor, &box); clutter_actor_get_allocation_box (actor, &box);
clutter_actor_box_get_size (&box, &width, &height); clutter_actor_box_get_size (&box, &width, &height);
if (width == 0 || height == 0) if (width == 0 || height == 0)
return COGL_INVALID_HANDLE; return NULL;
buffer = cogl_texture_new_with_size (width, buffer = cogl_texture_new_with_size (width,
height, height,
COGL_TEXTURE_NO_SLICING, COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY); COGL_PIXEL_FORMAT_ANY);
if (buffer == COGL_INVALID_HANDLE) if (buffer == NULL)
return COGL_INVALID_HANDLE; 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); cogl_error_free (catch_error);
return COGL_INVALID_HANDLE; cogl_object_unref (buffer);
return NULL;
} }
cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0); cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
cogl_push_framebuffer (offscreen);
cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); /* XXX: There's no way to render a ClutterActor to an offscreen
cogl_translate (-box.x1, -box.y1, 0); * as it uses the implicit API. */
cogl_ortho (0, width, height, 0, 0, 1.0); 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); clutter_actor_paint (actor);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
cogl_pop_framebuffer (); 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,7 +618,8 @@ _st_create_shadow_cairo_pattern (StShadow *shadow_spec,
void void
_st_paint_shadow_with_opacity (StShadow *shadow_spec, _st_paint_shadow_with_opacity (StShadow *shadow_spec,
CoglHandle shadow_material, CoglPipeline *shadow_pipeline,
CoglFramebuffer *fb,
ClutterActorBox *box, ClutterActorBox *box,
guint8 paint_opacity) guint8 paint_opacity)
{ {
@ -618,21 +627,18 @@ _st_paint_shadow_with_opacity (StShadow *shadow_spec,
CoglColor color; CoglColor color;
g_return_if_fail (shadow_spec != NULL); 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); st_shadow_get_box (shadow_spec, box, &shadow_box);
cogl_color_set_from_4ub (&color, cogl_color_init_from_4ub (&color,
shadow_spec->color.red * paint_opacity / 255, shadow_spec->color.red * paint_opacity / 255,
shadow_spec->color.green * paint_opacity / 255, shadow_spec->color.green * paint_opacity / 255,
shadow_spec->color.blue * paint_opacity / 255, shadow_spec->color.blue * paint_opacity / 255,
shadow_spec->color.alpha * paint_opacity / 255); shadow_spec->color.alpha * paint_opacity / 255);
cogl_color_premultiply (&color); cogl_color_premultiply (&color);
cogl_pipeline_set_layer_combine_constant (shadow_pipeline, 0, &color);
cogl_material_set_layer_combine_constant (shadow_material, 0, &color); cogl_framebuffer_draw_rectangle (fb, shadow_pipeline,
shadow_box.x1, shadow_box.y1,
cogl_set_source (shadow_material); shadow_box.x2, shadow_box.y2);
cogl_rectangle_with_texture_coords (shadow_box.x1, shadow_box.y1,
shadow_box.x2, shadow_box.y2,
0, 0, 1, 1);
} }

View File

@ -59,18 +59,19 @@ void _st_actor_get_preferred_height (ClutterActor *actor,
void _st_set_text_from_style (ClutterText *text, void _st_set_text_from_style (ClutterText *text,
StThemeNode *theme_node); 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 */ /* Helper for widgets which need to draw additional shadows */
CoglHandle _st_create_shadow_material (StShadow *shadow_spec, CoglPipeline * _st_create_shadow_pipeline (StShadow *shadow_spec,
CoglHandle src_texture); CoglTexture *src_texture);
CoglHandle _st_create_shadow_material_from_actor (StShadow *shadow_spec, CoglPipeline * _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec,
ClutterActor *actor); ClutterActor *actor);
cairo_pattern_t *_st_create_shadow_cairo_pattern (StShadow *shadow_spec, cairo_pattern_t *_st_create_shadow_cairo_pattern (StShadow *shadow_spec,
cairo_pattern_t *src_pattern); cairo_pattern_t *src_pattern);
void _st_paint_shadow_with_opacity (StShadow *shadow_spec, void _st_paint_shadow_with_opacity (StShadow *shadow_spec,
CoglHandle shadow_material, CoglPipeline *shadow_pipeline,
CoglFramebuffer *fb,
ClutterActorBox *box, ClutterActorBox *box,
guint8 paint_opacity); guint8 paint_opacity);

View File

@ -190,7 +190,7 @@ st_shadow_get_box (StShadow *shadow,
struct _StShadowHelper { struct _StShadowHelper {
StShadow *shadow; StShadow *shadow;
CoglMaterial *material; CoglPipeline *pipeline;
gfloat width; gfloat width;
gfloat height; gfloat height;
@ -224,14 +224,14 @@ st_shadow_helper_update (StShadowHelper *helper,
clutter_actor_get_size (source, &width, &height); clutter_actor_get_size (source, &width, &height);
if (helper->material == NULL || if (helper->pipeline == NULL ||
helper->width != width || helper->width != width ||
helper->height != height) helper->height != height)
{ {
if (helper->material) if (helper->pipeline)
cogl_object_unref (helper->material); 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->width = width;
helper->height = height; helper->height = height;
} }
@ -250,8 +250,8 @@ st_shadow_helper_copy (StShadowHelper *helper)
copy = g_slice_new (StShadowHelper); copy = g_slice_new (StShadowHelper);
*copy = *helper; *copy = *helper;
if (copy->material) if (copy->pipeline)
cogl_object_ref (copy->material); cogl_object_ref (copy->pipeline);
st_shadow_ref (copy->shadow); st_shadow_ref (copy->shadow);
return copy; return copy;
@ -266,8 +266,8 @@ st_shadow_helper_copy (StShadowHelper *helper)
void void
st_shadow_helper_free (StShadowHelper *helper) st_shadow_helper_free (StShadowHelper *helper)
{ {
if (helper->material) if (helper->pipeline)
cogl_object_unref (helper->material); cogl_object_unref (helper->pipeline);
st_shadow_unref (helper->shadow); st_shadow_unref (helper->shadow);
g_slice_free (StShadowHelper, helper); g_slice_free (StShadowHelper, helper);
@ -293,7 +293,8 @@ st_shadow_helper_paint (StShadowHelper *helper,
clutter_actor_box_get_size (actor_box, &width, &height); clutter_actor_box_get_size (actor_box, &width, &height);
_st_paint_shadow_with_opacity (helper->shadow, _st_paint_shadow_with_opacity (helper->shadow,
helper->material, helper->pipeline,
cogl_get_draw_framebuffer (),
&allocation, &allocation,
paint_opacity); paint_opacity);
} }

View File

@ -60,7 +60,7 @@ static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE(StTextureCache, st_texture_cache, G_TYPE_OBJECT); G_DEFINE_TYPE(StTextureCache, st_texture_cache, G_TYPE_OBJECT);
/* We want to preserve the aspect ratio by default, also the default /* 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. * definitely don't want. Skip that by setting 0 opacity.
*/ */
static ClutterTexture * static ClutterTexture *
@ -73,7 +73,7 @@ create_default_texture (void)
/* Reverse the opacity we added while loading */ /* Reverse the opacity we added while loading */
static void 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); clutter_texture_set_cogl_texture (clutter_texture, cogl_texture);
g_object_set (clutter_texture, "opacity", 255, NULL); 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); G_CALLBACK (on_icon_theme_changed), self);
self->priv->keyed_cache = g_hash_table_new_full (g_str_hash, g_str_equal, 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, self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL); g_free, NULL);
self->priv->file_monitors = g_hash_table_new_full (g_str_hash, g_str_equal, 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); return g_simple_async_result_get_op_res_gpointer (simple);
} }
static CoglHandle static CoglTexture *
data_to_cogl_handle (const guchar *data, data_to_cogl_texture (const guchar *data,
gboolean has_alpha, gboolean has_alpha,
int width, int width,
int height, int height,
int rowstride, int rowstride,
gboolean add_padding) gboolean add_padding)
{ {
CoglHandle texture, offscreen; CoglTexture *texture;
CoglColor clear_color;
guint size; guint size;
size = MAX (width, height); size = MAX (width, height);
@ -543,13 +542,6 @@ data_to_cogl_handle (const guchar *data,
COGL_TEXTURE_NO_SLICING, COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY); 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, cogl_texture_set_region (texture,
0, 0, 0, 0,
(size - width) / 2, (size - height) / 2, (size - width) / 2, (size - height) / 2,
@ -561,11 +553,11 @@ data_to_cogl_handle (const guchar *data,
return texture; return texture;
} }
static CoglHandle static CoglTexture *
pixbuf_to_cogl_handle (GdkPixbuf *pixbuf, pixbuf_to_cogl_texture (GdkPixbuf *pixbuf,
gboolean add_padding) gboolean add_padding)
{ {
return data_to_cogl_handle (gdk_pixbuf_get_pixels (pixbuf), return data_to_cogl_texture (gdk_pixbuf_get_pixels (pixbuf),
gdk_pixbuf_get_has_alpha (pixbuf), gdk_pixbuf_get_has_alpha (pixbuf),
gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf), gdk_pixbuf_get_height (pixbuf),
@ -600,7 +592,7 @@ finish_texture_load (AsyncTextureLoadData *data,
{ {
GSList *iter; GSList *iter;
StTextureCache *cache; StTextureCache *cache;
CoglHandle texdata = NULL; CoglTexture *texdata = NULL;
cache = data->cache; cache = data->cache;
@ -609,7 +601,7 @@ finish_texture_load (AsyncTextureLoadData *data,
if (pixbuf == NULL) if (pixbuf == NULL)
goto out; 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) 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, if (!g_hash_table_lookup_extended (cache->priv->keyed_cache, data->key,
&orig_key, &value)) &orig_key, &value))
{ {
cogl_handle_ref (texdata); cogl_object_ref (texdata);
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (data->key), g_hash_table_insert (cache->priv->keyed_cache, g_strdup (data->key),
texdata); texdata);
} }
@ -632,7 +624,7 @@ finish_texture_load (AsyncTextureLoadData *data,
out: out:
if (texdata) if (texdata)
cogl_handle_unref (texdata); cogl_object_unref (texdata);
texture_load_data_free (data); texture_load_data_free (data);
} }
@ -723,7 +715,7 @@ st_texture_cache_reset_texture (StTextureCachePropertyBind *bind,
const char *propname) const char *propname)
{ {
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
CoglHandle texdata; CoglTexture *texdata;
g_object_get (bind->source, propname, &pixbuf, NULL); g_object_get (bind->source, propname, &pixbuf, NULL);
@ -731,11 +723,11 @@ st_texture_cache_reset_texture (StTextureCachePropertyBind *bind,
if (pixbuf != NULL) if (pixbuf != NULL)
{ {
texdata = pixbuf_to_cogl_handle (pixbuf, FALSE); texdata = pixbuf_to_cogl_texture (pixbuf, FALSE);
g_object_unref (pixbuf); g_object_unref (pixbuf);
clutter_texture_set_cogl_texture (bind->texture, texdata); 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); 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 * Create a #ClutterTexture which tracks the #GdkPixbuf value of a GObject property
* named by @property_name. Unlike other methods in StTextureCache, the underlying * 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 * If the source object is destroyed, the texture will continue to show the last
* value of the property. * 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 * Returns: (transfer full): A newly-referenced handle to the texture
*/ */
CoglHandle CoglTexture *
st_texture_cache_load (StTextureCache *cache, st_texture_cache_load (StTextureCache *cache,
const char *key, const char *key,
StTextureCachePolicy policy, StTextureCachePolicy policy,
@ -837,7 +829,7 @@ st_texture_cache_load (StTextureCache *cache,
void *data, void *data,
GError **error) GError **error)
{ {
CoglHandle texture; CoglTexture *texture;
texture = g_hash_table_lookup (cache->priv->keyed_cache, key); texture = g_hash_table_lookup (cache->priv->keyed_cache, key);
if (!texture) if (!texture)
@ -846,9 +838,10 @@ st_texture_cache_load (StTextureCache *cache,
if (texture) if (texture)
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texture); g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texture);
else else
return COGL_INVALID_HANDLE; return NULL;
} }
cogl_handle_ref (texture);
cogl_object_ref (texture);
return texture; return texture;
} }
@ -873,7 +866,7 @@ ensure_request (StTextureCache *cache,
AsyncTextureLoadData **request, AsyncTextureLoadData **request,
ClutterActor *texture) ClutterActor *texture)
{ {
CoglHandle texdata; CoglTexture *texdata;
AsyncTextureLoadData *pending; AsyncTextureLoadData *pending;
gboolean had_pending; gboolean had_pending;
@ -1005,7 +998,7 @@ static ClutterActor *
load_from_pixbuf (GdkPixbuf *pixbuf) load_from_pixbuf (GdkPixbuf *pixbuf)
{ {
ClutterTexture *texture; ClutterTexture *texture;
CoglHandle texdata; CoglTexture *texdata;
int width = gdk_pixbuf_get_width (pixbuf); int width = gdk_pixbuf_get_width (pixbuf);
int height = gdk_pixbuf_get_height (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); 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); set_texture_cogl_texture (texture, texdata);
cogl_handle_unref (texdata); cogl_object_unref (texdata);
return CLUTTER_ACTOR (texture); return CLUTTER_ACTOR (texture);
} }
@ -1256,7 +1249,7 @@ st_texture_cache_load_uri_async (StTextureCache *cache,
return CLUTTER_ACTOR (texture); return CLUTTER_ACTOR (texture);
} }
static CoglHandle static CoglTexture *
st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache, st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
StTextureCachePolicy policy, StTextureCachePolicy policy,
const gchar *uri, const gchar *uri,
@ -1264,7 +1257,7 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
int available_height, int available_height,
GError **error) GError **error)
{ {
CoglHandle texdata; CoglTexture *texdata;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
char *key; char *key;
@ -1278,17 +1271,17 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
if (!pixbuf) if (!pixbuf)
goto out; goto out;
texdata = pixbuf_to_cogl_handle (pixbuf, FALSE); texdata = pixbuf_to_cogl_texture (pixbuf, FALSE);
g_object_unref (pixbuf); g_object_unref (pixbuf);
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER) 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); g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texdata);
} }
} }
else else
cogl_handle_ref (texdata); cogl_object_ref (texdata);
ensure_monitor_for_uri (cache, uri); 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 * @cache: A #StTextureCache
* @file_path: Path to a file in supported image format * @file_path: Path to a file in supported image format
* *
* This function synchronously loads the given file path * This function synchronously loads the given file path
* into a COGL texture. On error, a warning is emitted * 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, st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
const gchar *file_path) const gchar *file_path)
{ {
CoglHandle texture; CoglTexture *texture;
GFile *file; GFile *file;
char *uri; char *uri;
GError *error = NULL; 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_warning ("Failed to load %s: %s", file_path, error->message);
g_clear_error (&error); g_clear_error (&error);
return COGL_INVALID_HANDLE; return NULL;
} }
return texture; return texture;
} }

View File

@ -90,7 +90,7 @@ ClutterActor *st_texture_cache_load_uri_async (StTextureCache *cache,
int available_width, int available_width,
int available_height); int available_height);
CoglHandle st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache, CoglTexture *st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
const gchar *file_path); const gchar *file_path);
cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache, cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
@ -107,9 +107,9 @@ cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *ca
* texture handle for the given key, or set @error. * 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, CoglTexture * st_texture_cache_load (StTextureCache *cache,
const char *key, const char *key,
StTextureCachePolicy policy, StTextureCachePolicy policy,
StTextureCacheLoader load, StTextureCacheLoader load,

View File

@ -66,10 +66,10 @@ elliptical_arc (cairo_t *cr,
cairo_restore (cr); cairo_restore (cr);
} }
static CoglHandle static CoglTexture *
create_corner_material (StCornerSpec *corner) create_corner_texture (StCornerSpec *corner)
{ {
CoglHandle texture; CoglTexture *texture;
cairo_t *cr; cairo_t *cr;
cairo_surface_t *surface; cairo_surface_t *surface;
guint rowstride; guint rowstride;
@ -173,7 +173,7 @@ create_corner_material (StCornerSpec *corner)
rowstride, rowstride,
data); data);
g_free (data); g_free (data);
g_assert (texture != COGL_INVALID_HANDLE); g_assert (texture != NULL);
return texture; return texture;
} }
@ -190,13 +190,13 @@ corner_to_string (StCornerSpec *corner)
corner->border_width_2); corner->border_width_2);
} }
static CoglHandle static CoglTexture *
load_corner (StTextureCache *cache, load_corner (StTextureCache *cache,
const char *key, const char *key,
void *datap, void *datap,
GError **error) 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 /* 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, st_theme_node_lookup_corner (StThemeNode *node,
float width, float width,
float height, float height,
StCorner corner_id) StCorner corner_id)
{ {
CoglHandle texture, material; CoglTexture *texture;
CoglPipeline *pipeline;
char *key; char *key;
StTextureCache *cache; StTextureCache *cache;
StCornerSpec corner; StCornerSpec corner;
@ -354,7 +355,7 @@ st_theme_node_lookup_corner (StThemeNode *node,
st_theme_node_reduce_border_radius (node, width, height, radius); st_theme_node_reduce_border_radius (node, width, height, radius);
if (radius[corner_id] == 0) if (radius[corner_id] == 0)
return COGL_INVALID_HANDLE; return NULL;
corner.radius = radius[corner_id]; corner.radius = radius[corner_id];
corner.color = node->background_color; corner.color = node->background_color;
@ -385,16 +386,16 @@ st_theme_node_lookup_corner (StThemeNode *node,
if (corner.color.alpha == 0 && if (corner.color.alpha == 0 &&
corner.border_color_1.alpha == 0 && corner.border_color_1.alpha == 0 &&
corner.border_color_2.alpha == 0) corner.border_color_2.alpha == 0)
return COGL_INVALID_HANDLE; return NULL;
key = corner_to_string (&corner); key = corner_to_string (&corner);
texture = st_texture_cache_load (cache, key, ST_TEXTURE_CACHE_POLICY_NONE, load_corner, &corner, NULL); texture = st_texture_cache_load (cache, key, ST_TEXTURE_CACHE_POLICY_NONE, load_corner, &corner, NULL);
material = _st_create_texture_material (texture); pipeline = _st_create_texture_pipeline (texture);
cogl_handle_unref (texture); cogl_object_unref (texture);
g_free (key); g_free (key);
return material; return pipeline;
} }
static void 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 * we need to use cairo. This function is a slow fallback path for those
* cases (gradients, background images, etc). * cases (gradients, background images, etc).
*/ */
static CoglHandle static CoglTexture *
st_theme_node_prerender_background (StThemeNode *node, st_theme_node_prerender_background (StThemeNode *node,
float actor_width, float actor_width,
float actor_height) float actor_height)
{ {
StBorderImage *border_image; StBorderImage *border_image;
CoglHandle texture; CoglTexture *texture;
guint radius[4]; guint radius[4];
int i; int i;
cairo_t *cr; cairo_t *cr;
@ -1268,30 +1269,17 @@ st_theme_node_prerender_background (StThemeNode *node,
return texture; return texture;
} }
static void st_theme_node_paint_borders (StThemeNodePaintState *state,
const ClutterActorBox *box,
guint8 paint_opacity);
void void
st_theme_node_invalidate_border_image (StThemeNode *node) st_theme_node_invalidate_border_image (StThemeNode *node)
{ {
if (node->border_slices_texture != COGL_INVALID_HANDLE) g_clear_pointer (&node->border_slices_texture, cogl_object_unref);
{ g_clear_pointer (&node->border_slices_pipeline, cogl_object_unref);
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;
}
} }
static gboolean static gboolean
st_theme_node_load_border_image (StThemeNode *node) 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; StBorderImage *border_image;
@ -1303,42 +1291,28 @@ st_theme_node_load_border_image (StThemeNode *node)
filename = st_border_image_get_filename (border_image); 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 (), node->border_slices_texture = st_texture_cache_load_file_to_cogl_texture (st_texture_cache_get_default (),
filename); filename);
if (node->border_slices_texture == COGL_INVALID_HANDLE) if (node->border_slices_texture == NULL)
goto out; 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: out:
return node->border_slices_texture != COGL_INVALID_HANDLE; return node->border_slices_pipeline != NULL;
} }
void void
st_theme_node_invalidate_background_image (StThemeNode *node) st_theme_node_invalidate_background_image (StThemeNode *node)
{ {
if (node->background_texture != COGL_INVALID_HANDLE) g_clear_pointer (&node->background_texture, cogl_object_unref);
{ g_clear_pointer (&node->background_pipeline, cogl_object_unref);
cogl_handle_unref (node->background_texture); g_clear_pointer (&node->background_shadow_pipeline, cogl_object_unref);
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;
}
} }
static gboolean static gboolean
st_theme_node_load_background_image (StThemeNode *node) st_theme_node_load_background_image (StThemeNode *node)
{ {
if (node->background_texture == COGL_INVALID_HANDLE) if (node->background_texture == NULL)
{ {
const char *background_image; const char *background_image;
StShadow *background_image_shadow_spec; 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); 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 (), node->background_texture = st_texture_cache_load_file_to_cogl_texture (st_texture_cache_get_default (),
background_image); background_image);
if (node->background_texture == COGL_INVALID_HANDLE) if (node->background_texture == NULL)
goto out; 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) 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) 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); node->background_texture);
} }
} }
out: out:
return node->background_texture != COGL_INVALID_HANDLE; return node->background_texture != NULL;
} }
static void st_theme_node_prerender_shadow (StThemeNodePaintState *state); 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 static void
st_theme_node_render_resources (StThemeNodePaintState *state, st_theme_node_render_resources (StThemeNodePaintState *state,
StThemeNode *node, 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); 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); 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); 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); st_theme_node_lookup_corner (node, width, height, ST_CORNER_BOTTOMLEFT);
/* Use cairo to prerender the node if there is a gradient, or /* 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); state->prerendered_texture = st_theme_node_prerender_background (node, width, height);
if (state->prerendered_texture) 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 else
state->prerendered_material = COGL_INVALID_HANDLE; state->prerendered_pipeline = NULL;
if (box_shadow_spec && !has_inset_box_shadow) if (box_shadow_spec && !has_inset_box_shadow)
{ {
if (st_theme_node_load_border_image (node)) 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); node->border_slices_texture);
else if (state->prerendered_texture != COGL_INVALID_HANDLE) else if (state->prerendered_texture != NULL)
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); state->prerendered_texture);
else if (node->background_color.alpha > 0 || has_border) else if (node->background_color.alpha > 0 || has_border)
st_theme_node_prerender_shadow (state); st_theme_node_prerender_shadow (state);
@ -1483,7 +1468,7 @@ st_theme_node_render_resources (StThemeNodePaintState *state,
them. */ them. */
if (!node->cached_textures) if (!node->cached_textures)
{ {
if (state->prerendered_material == COGL_INVALID_HANDLE && if (state->prerendered_pipeline == NULL &&
width >= node->box_shadow_min_width && width >= node->box_shadow_min_width &&
height >= node->box_shadow_min_height) 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); g_return_if_fail (width > 0 && height > 0);
/* Free handles we can't reuse */ /* Free objects we can't reuse */
if (state->prerendered_texture != COGL_INVALID_HANDLE) if (state->prerendered_texture != NULL)
{ {
cogl_handle_unref (state->prerendered_texture); cogl_object_unref (state->prerendered_texture);
state->prerendered_texture = COGL_INVALID_HANDLE; state->prerendered_texture = NULL;
had_prerendered_texture = TRUE; had_prerendered_texture = TRUE;
} }
if (state->prerendered_material != COGL_INVALID_HANDLE) if (state->prerendered_pipeline != NULL)
{ {
cogl_handle_unref (state->prerendered_material); cogl_object_unref (state->prerendered_pipeline);
state->prerendered_material = COGL_INVALID_HANDLE; state->prerendered_pipeline = NULL;
if (node->border_slices_texture == COGL_INVALID_HANDLE && if (node->border_slices_texture == NULL &&
state->box_shadow_material != COGL_INVALID_HANDLE) state->box_shadow_pipeline != NULL)
{ {
cogl_handle_unref (state->box_shadow_material); cogl_object_unref (state->box_shadow_pipeline);
state->box_shadow_material = COGL_INVALID_HANDLE; state->box_shadow_pipeline = NULL;
had_box_shadow = TRUE; had_box_shadow = TRUE;
} }
} }
@ -1535,43 +1520,26 @@ st_theme_node_update_resources (StThemeNodePaintState *state,
if (had_prerendered_texture) if (had_prerendered_texture)
{ {
state->prerendered_texture = st_theme_node_prerender_background (node, width, height); 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 else
{ {
int corner_id; int corner_id;
for (corner_id = 0; corner_id < 4; corner_id++) for (corner_id = 0; corner_id < 4; corner_id++)
if (state->corner_material[corner_id] == COGL_INVALID_HANDLE) if (state->corner_pipeline[corner_id] == NULL)
state->corner_material[corner_id] = state->corner_pipeline[corner_id] =
st_theme_node_lookup_corner (node, width, height, corner_id); st_theme_node_lookup_corner (node, width, height, corner_id);
} }
if (had_box_shadow) 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); 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 static void
st_theme_node_paint_borders (StThemeNodePaintState *state, st_theme_node_paint_borders (StThemeNodePaintState *state,
CoglFramebuffer *fb,
const ClutterActorBox *box, const ClutterActorBox *box,
guint8 paint_opacity) guint8 paint_opacity)
{ {
@ -1624,10 +1592,7 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
if (alpha > 0) if (alpha > 0)
{ {
cogl_set_source_color4ub (effective_border.red, CoglPipeline *pipeline;
effective_border.green,
effective_border.blue,
alpha);
/* NORTH */ /* NORTH */
skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0; 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] rects[15] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
: height - border_width[ST_SIDE_BOTTOM]; : 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,33 +1649,38 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
{ {
for (corner_id = 0; corner_id < 4; corner_id++) 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; continue;
cogl_material_set_color4ub (state->corner_material[corner_id], cogl_pipeline_set_color4ub (pipeline,
paint_opacity, paint_opacity, paint_opacity, paint_opacity,
paint_opacity, paint_opacity); paint_opacity, paint_opacity);
cogl_set_source (state->corner_material[corner_id]);
switch (corner_id) switch (corner_id)
{ {
case ST_CORNER_TOPLEFT: case ST_CORNER_TOPLEFT:
cogl_rectangle_with_texture_coords (0, 0, cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
0, 0,
max_width_radius[ST_CORNER_TOPLEFT], max_width_radius[ST_CORNER_TOPLEFT], max_width_radius[ST_CORNER_TOPLEFT], max_width_radius[ST_CORNER_TOPLEFT],
0, 0, 0.5, 0.5); 0, 0, 0.5, 0.5);
break; break;
case ST_CORNER_TOPRIGHT: case ST_CORNER_TOPRIGHT:
cogl_rectangle_with_texture_coords (width - max_width_radius[ST_CORNER_TOPRIGHT], 0, cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
width - max_width_radius[ST_CORNER_TOPRIGHT], 0,
width, max_width_radius[ST_CORNER_TOPRIGHT], width, max_width_radius[ST_CORNER_TOPRIGHT],
0.5, 0, 1, 0.5); 0.5, 0, 1, 0.5);
break; break;
case ST_CORNER_BOTTOMRIGHT: case ST_CORNER_BOTTOMRIGHT:
cogl_rectangle_with_texture_coords (width - max_width_radius[ST_CORNER_BOTTOMRIGHT], height - max_width_radius[ST_CORNER_BOTTOMRIGHT], cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
width - max_width_radius[ST_CORNER_BOTTOMRIGHT], height - max_width_radius[ST_CORNER_BOTTOMRIGHT],
width, height, width, height,
0.5, 0.5, 1, 1); 0.5, 0.5, 1, 1);
break; break;
case ST_CORNER_BOTTOMLEFT: case ST_CORNER_BOTTOMLEFT:
cogl_rectangle_with_texture_coords (0, height - max_width_radius[ST_CORNER_BOTTOMLEFT], cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
0, height - max_width_radius[ST_CORNER_BOTTOMLEFT],
max_width_radius[ST_CORNER_BOTTOMLEFT], height, max_width_radius[ST_CORNER_BOTTOMLEFT], height,
0, 0.5, 0.5, 1); 0, 0.5, 0.5, 1);
break; break;
@ -1717,7 +1692,9 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
alpha = paint_opacity * node->background_color.alpha / 255; alpha = paint_opacity * node->background_color.alpha / 255;
if (alpha > 0) if (alpha > 0)
{ {
cogl_set_source_color4ub (node->background_color.red, CoglPipeline *pipeline;
pipeline = get_color_pipeline (node->background_color.red,
node->background_color.green, node->background_color.green,
node->background_color.blue, node->background_color.blue,
alpha); alpha);
@ -1803,8 +1780,9 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
verts[7] = height - border_width[ST_SIDE_BOTTOM]; verts[7] = height - border_width[ST_SIDE_BOTTOM];
} }
break; 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 /* 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 * necessary, then the main rectangle
*/ */
if (max_border_radius > border_width[ST_SIDE_TOP]) if (max_border_radius > border_width[ST_SIDE_TOP])
cogl_rectangle (MAX(max_border_radius, border_width[ST_SIDE_LEFT]), cogl_framebuffer_draw_rectangle (fb, pipeline,
MAX(max_border_radius, border_width[ST_SIDE_LEFT]),
border_width[ST_SIDE_TOP], border_width[ST_SIDE_TOP],
width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]), width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]),
max_border_radius); max_border_radius);
if (max_border_radius > border_width[ST_SIDE_BOTTOM]) if (max_border_radius > border_width[ST_SIDE_BOTTOM])
cogl_rectangle (MAX(max_border_radius, border_width[ST_SIDE_LEFT]), cogl_framebuffer_draw_rectangle (fb, pipeline,
MAX(max_border_radius, border_width[ST_SIDE_LEFT]),
height - max_border_radius, height - max_border_radius,
width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]), width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]),
height - border_width[ST_SIDE_BOTTOM]); height - border_width[ST_SIDE_BOTTOM]);
cogl_rectangle (border_width[ST_SIDE_LEFT], cogl_framebuffer_draw_rectangle (fb, pipeline,
border_width[ST_SIDE_LEFT],
MAX(border_width[ST_SIDE_TOP], max_border_radius), MAX(border_width[ST_SIDE_TOP], max_border_radius),
width - border_width[ST_SIDE_RIGHT], width - border_width[ST_SIDE_RIGHT],
height - MAX(border_width[ST_SIDE_BOTTOM], max_border_radius)); height - MAX(border_width[ST_SIDE_BOTTOM], max_border_radius));
cogl_object_unref (pipeline);
} }
} }
static void static void
st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state, st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
CoglFramebuffer *fb,
const ClutterActorBox *box, const ClutterActorBox *box,
guint8 paint_opacity) guint8 paint_opacity)
{ {
@ -1943,16 +1927,14 @@ st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
right += xoffset; right += xoffset;
/* Setup pipeline */ /* Setup pipeline */
cogl_color_set_from_4ub (&color, cogl_color_init_from_4ub (&color,
box_shadow_spec->color.red * paint_opacity / 255, box_shadow_spec->color.red * paint_opacity / 255,
box_shadow_spec->color.green * paint_opacity / 255, box_shadow_spec->color.green * paint_opacity / 255,
box_shadow_spec->color.blue * paint_opacity / 255, box_shadow_spec->color.blue * paint_opacity / 255,
box_shadow_spec->color.alpha * paint_opacity / 255); box_shadow_spec->color.alpha * paint_opacity / 255);
cogl_color_premultiply (&color); cogl_color_premultiply (&color);
cogl_material_set_layer_combine_constant (state->box_shadow_material, 0, &color); cogl_pipeline_set_layer_combine_constant (state->box_shadow_pipeline, 0, &color);
cogl_set_source (state->box_shadow_material);
idx = 0; idx = 0;
@ -2080,36 +2062,8 @@ st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
} }
} }
cogl_rectangles_with_texture_coords (rectangles, idx / 8); cogl_framebuffer_draw_textured_rectangles (fb, state->box_shadow_pipeline,
rectangles, idx / 4);
#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
} }
static void static void
@ -2119,7 +2073,8 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state)
guint border_radius[4]; guint border_radius[4];
int max_borders[4]; int max_borders[4];
int center_radius, corner_id; int center_radius, corner_id;
CoglHandle buffer, offscreen; CoglTexture *buffer;
CoglOffscreen *offscreen;
/* Get infos from the node */ /* Get infos from the node */
if (state->alloc_width < node->box_shadow_min_width || if (state->alloc_width < node->box_shadow_min_width ||
@ -2160,33 +2115,32 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state)
state->box_shadow_height, state->box_shadow_height,
COGL_TEXTURE_NO_SLICING, COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY); 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}; ClutterActorBox box = { 0, 0, state->box_shadow_width, state->box_shadow_height};
CoglColor clear_color; CoglColor clear_color;
cogl_push_framebuffer (offscreen); cogl_framebuffer_orthographic (fb, 0, state->box_shadow_width, state->box_shadow_height, 0, 0, 1.0);
cogl_ortho (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); state->box_shadow_pipeline = _st_create_shadow_pipeline (st_theme_node_get_box_shadow (node),
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),
buffer); buffer);
} }
cogl_handle_unref (buffer);
cogl_object_unref (buffer);
} }
static void static void
st_theme_node_paint_sliced_border_image (StThemeNode *node, st_theme_node_paint_sliced_border_image (StThemeNode *node,
float width, float width,
float height, float height,
CoglFramebuffer *fb,
guint8 paint_opacity) guint8 paint_opacity)
{ {
gfloat ex, ey; 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; gint border_left, border_right, border_top, border_bottom;
float img_width, img_height; float img_width, img_height;
StBorderImage *border_image; StBorderImage *border_image;
CoglHandle material; CoglPipeline *pipeline;
border_image = st_theme_node_get_border_image (node); border_image = st_theme_node_get_border_image (node);
g_assert (border_image != NULL); g_assert (border_image != NULL);
@ -2218,11 +2172,8 @@ st_theme_node_paint_sliced_border_image (StThemeNode *node,
if (ey < 0) if (ey < 0)
ey = border_bottom; /* FIXME ? */ ey = border_bottom; /* FIXME ? */
material = node->border_slices_material; pipeline = node->border_slices_pipeline;
cogl_material_set_color4ub (material, cogl_pipeline_set_color4ub (pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity);
paint_opacity, paint_opacity, paint_opacity, paint_opacity);
cogl_set_source (material);
{ {
float rectangles[] = float rectangles[] =
@ -2273,12 +2224,14 @@ st_theme_node_paint_sliced_border_image (StThemeNode *node,
1.0, 1.0 1.0, 1.0
}; };
cogl_rectangles_with_texture_coords (rectangles, 9); cogl_framebuffer_draw_textured_rectangles (fb, pipeline,
rectangles, 9);
} }
} }
static void static void
st_theme_node_paint_outline (StThemeNode *node, st_theme_node_paint_outline (StThemeNode *node,
CoglFramebuffer *fb,
const ClutterActorBox *box, const ClutterActorBox *box,
guint8 paint_opacity) guint8 paint_opacity)
@ -2287,6 +2240,7 @@ st_theme_node_paint_outline (StThemeNode *node,
int outline_width; int outline_width;
float rects[16]; float rects[16];
ClutterColor outline_color, effective_outline; ClutterColor outline_color, effective_outline;
CoglPipeline *pipeline;
width = box->x2 - box->x1; width = box->x2 - box->x1;
height = box->y2 - box->y1; height = box->y2 - box->y1;
@ -2298,7 +2252,7 @@ st_theme_node_paint_outline (StThemeNode *node,
st_theme_node_get_outline_color (node, &outline_color); st_theme_node_get_outline_color (node, &outline_color);
over (&outline_color, &node->background_color, &effective_outline); over (&outline_color, &node->background_color, &effective_outline);
cogl_set_source_color4ub (effective_outline.red, pipeline = get_color_pipeline (effective_outline.red,
effective_outline.green, effective_outline.green,
effective_outline.blue, effective_outline.blue,
paint_opacity * effective_outline.alpha / 255); paint_opacity * effective_outline.alpha / 255);
@ -2333,7 +2287,8 @@ st_theme_node_paint_outline (StThemeNode *node,
rects[14] = 0; rects[14] = 0;
rects[15] = height; rects[15] = height;
cogl_rectangles (rects, 4); cogl_framebuffer_draw_rectangles (fb, pipeline, rects, 16);
cogl_object_unref (pipeline);
} }
static gboolean static gboolean
@ -2373,9 +2328,13 @@ st_theme_node_needs_new_box_shadow_for_size (StThemeNodePaintState *state,
return FALSE; return FALSE;
} }
/**
* st_theme_node_paint: (skip)
*/
void void
st_theme_node_paint (StThemeNode *node, st_theme_node_paint (StThemeNode *node,
StThemeNodePaintState *state, StThemeNodePaintState *state,
CoglFramebuffer *fb,
const ClutterActorBox *box, const ClutterActorBox *box,
guint8 paint_opacity) guint8 paint_opacity)
{ {
@ -2441,24 +2400,26 @@ st_theme_node_paint (StThemeNode *node,
* such that it's aligned to the outside edges) * 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 || if (state->alloc_width < node->box_shadow_min_width ||
state->alloc_height < node->box_shadow_min_height) state->alloc_height < node->box_shadow_min_height)
_st_paint_shadow_with_opacity (node->box_shadow, _st_paint_shadow_with_opacity (node->box_shadow,
state->box_shadow_material, state->box_shadow_pipeline,
fb,
&allocation, &allocation,
paint_opacity); paint_opacity);
else else
st_theme_node_paint_sliced_shadow (state, st_theme_node_paint_sliced_shadow (state,
fb,
&allocation, &allocation,
paint_opacity); paint_opacity);
} }
if (state->prerendered_material != COGL_INVALID_HANDLE || if (state->prerendered_pipeline != NULL ||
st_theme_node_load_border_image (node)) st_theme_node_load_border_image (node))
{ {
if (state->prerendered_material != COGL_INVALID_HANDLE) if (state->prerendered_pipeline != NULL)
{ {
ClutterActorBox paint_box; ClutterActorBox paint_box;
@ -2466,23 +2427,24 @@ st_theme_node_paint (StThemeNode *node,
&allocation, &allocation,
&paint_box); &paint_box);
paint_material_with_opacity (state->prerendered_material, cogl_pipeline_set_color4ub (state->prerendered_pipeline,
&paint_box, paint_opacity, paint_opacity, paint_opacity, paint_opacity);
NULL, cogl_framebuffer_draw_rectangle (fb, state->prerendered_pipeline,
paint_opacity); paint_box.x1, paint_box.y1,
paint_box.x2, paint_box.y2);
} }
if (node->border_slices_material != COGL_INVALID_HANDLE) if (node->border_slices_pipeline != NULL)
st_theme_node_paint_sliced_border_image (node, width, height, paint_opacity); st_theme_node_paint_sliced_border_image (node, width, height, fb, paint_opacity);
} }
else 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)) st_theme_node_load_background_image (node))
{ {
ClutterActorBox background_box; ClutterActorBox background_box;
@ -2498,7 +2460,7 @@ st_theme_node_paint (StThemeNode *node,
get_background_position (node, &allocation, &background_box, &texture_coords); get_background_position (node, &allocation, &background_box, &texture_coords);
if (has_visible_outline || node->background_repeat) 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 /* 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) * there is nothing (like a border, or the edge of the background color)
* to logically confine it. * 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, _st_paint_shadow_with_opacity (node->background_image_shadow,
node->background_shadow_material, node->background_shadow_pipeline,
fb,
&background_box, &background_box,
paint_opacity); paint_opacity);
paint_material_with_opacity (node->background_material, cogl_pipeline_set_color4ub (node->background_pipeline,
&background_box, paint_opacity, paint_opacity, paint_opacity, paint_opacity);
&texture_coords, cogl_framebuffer_draw_textured_rectangle (fb, node->background_pipeline,
paint_opacity); 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) 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; int corner_id;
if (state->prerendered_texture != COGL_INVALID_HANDLE) g_clear_pointer (&state->prerendered_texture, cogl_object_unref);
cogl_handle_unref (state->prerendered_texture); g_clear_pointer (&state->prerendered_pipeline, cogl_object_unref);
if (state->prerendered_material != COGL_INVALID_HANDLE) g_clear_pointer (&state->box_shadow_pipeline, cogl_object_unref);
cogl_handle_unref (state->prerendered_material);
if (state->box_shadow_material != COGL_INVALID_HANDLE)
cogl_handle_unref (state->box_shadow_material);
for (corner_id = 0; corner_id < 4; corner_id++) for (corner_id = 0; corner_id < 4; corner_id++)
if (state->corner_material[corner_id] != COGL_INVALID_HANDLE) g_clear_pointer (&state->corner_pipeline[corner_id], cogl_object_unref);
cogl_handle_unref (state->corner_material[corner_id]);
if (unref_node) if (unref_node)
st_theme_node_paint_state_set_node (state, NULL); 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_width = 0;
state->alloc_height = 0; state->alloc_height = 0;
state->node = NULL; state->node = NULL;
state->box_shadow_material = COGL_INVALID_HANDLE; state->box_shadow_pipeline = NULL;
state->prerendered_texture = COGL_INVALID_HANDLE; state->prerendered_texture = NULL;
state->prerendered_material = COGL_INVALID_HANDLE; state->prerendered_pipeline = NULL;
for (corner_id = 0; corner_id < 4; corner_id++) for (corner_id = 0; corner_id < 4; corner_id++)
state->corner_material[corner_id] = COGL_INVALID_HANDLE; state->corner_pipeline[corner_id] = NULL;
} }
void void
@ -2613,15 +2573,15 @@ st_theme_node_paint_state_copy (StThemeNodePaintState *state,
state->box_shadow_width = other->box_shadow_width; state->box_shadow_width = other->box_shadow_width;
state->box_shadow_height = other->box_shadow_height; state->box_shadow_height = other->box_shadow_height;
if (other->box_shadow_material) if (other->box_shadow_pipeline)
state->box_shadow_material = cogl_handle_ref (other->box_shadow_material); state->box_shadow_pipeline = cogl_object_ref (other->box_shadow_pipeline);
if (other->prerendered_texture) if (other->prerendered_texture)
state->prerendered_texture = cogl_handle_ref (other->prerendered_texture); state->prerendered_texture = cogl_object_ref (other->prerendered_texture);
if (other->prerendered_material) if (other->prerendered_pipeline)
state->prerendered_material = cogl_handle_ref (other->prerendered_material); state->prerendered_pipeline = cogl_object_ref (other->prerendered_pipeline);
for (corner_id = 0; corner_id < 4; corner_id++) for (corner_id = 0; corner_id < 4; corner_id++)
if (other->corner_material[corner_id]) if (other->corner_pipeline[corner_id])
state->corner_material[corner_id] = cogl_handle_ref (other->corner_material[corner_id]); state->corner_pipeline[corner_id] = cogl_object_ref (other->corner_pipeline[corner_id]);
} }
void void

View File

@ -105,11 +105,11 @@ struct _StThemeNode {
int box_shadow_min_width; int box_shadow_min_width;
int box_shadow_min_height; int box_shadow_min_height;
CoglHandle border_slices_texture; CoglTexture *border_slices_texture;
CoglHandle border_slices_material; CoglPipeline *border_slices_pipeline;
CoglHandle background_texture; CoglTexture *background_texture;
CoglHandle background_material; CoglPipeline *background_pipeline;
CoglHandle background_shadow_material; CoglPipeline *background_shadow_pipeline;
StThemeNodePaintState cached_state; StThemeNodePaintState cached_state;
}; };

View File

@ -36,13 +36,13 @@ struct _StThemeNodeTransitionPrivate {
StThemeNodePaintState old_paint_state; StThemeNodePaintState old_paint_state;
StThemeNodePaintState new_paint_state; StThemeNodePaintState new_paint_state;
CoglHandle old_texture; CoglTexture *old_texture;
CoglHandle new_texture; CoglTexture *new_texture;
CoglHandle old_offscreen; CoglOffscreen *old_offscreen;
CoglHandle new_offscreen; CoglOffscreen *new_offscreen;
CoglHandle material; CoglPipeline *pipeline;
ClutterTimeline *timeline; ClutterTimeline *timeline;
@ -237,9 +237,10 @@ setup_framebuffers (StThemeNodeTransition *transition,
StThemeNodeTransitionPrivate *priv = transition->priv; StThemeNodeTransitionPrivate *priv = transition->priv;
CoglColor clear_color = { 0, 0, 0, 0 }; CoglColor clear_color = { 0, 0, 0, 0 };
guint width, height; guint width, height;
CoglFramebuffer *fb;
/* template material to avoid unnecessary shader compilation */ /* template pipeline to avoid unnecessary shader compilation */
static CoglHandle material_template = COGL_INVALID_HANDLE; static CoglPipeline *pipeline_template = NULL;
width = priv->offscreen_box.x2 - priv->offscreen_box.x1; width = priv->offscreen_box.x2 - priv->offscreen_box.x1;
height = priv->offscreen_box.y2 - priv->offscreen_box.y1; 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); g_return_val_if_fail (height > 0, FALSE);
if (priv->old_texture) 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, priv->old_texture = cogl_texture_new_with_size (width, height,
COGL_TEXTURE_NO_SLICING, COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY); COGL_PIXEL_FORMAT_ANY);
if (priv->new_texture) 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, priv->new_texture = cogl_texture_new_with_size (width, height,
COGL_TEXTURE_NO_SLICING, COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY); COGL_PIXEL_FORMAT_ANY);
g_return_val_if_fail (priv->old_texture != COGL_INVALID_HANDLE, FALSE); g_return_val_if_fail (priv->old_texture != NULL, FALSE);
g_return_val_if_fail (priv->new_texture != COGL_INVALID_HANDLE, FALSE); g_return_val_if_fail (priv->new_texture != NULL, FALSE);
if (priv->old_offscreen) if (priv->old_offscreen)
cogl_handle_unref (priv->old_offscreen); cogl_object_unref (priv->old_offscreen);
priv->old_offscreen = cogl_offscreen_new_to_texture (priv->old_texture); priv->old_offscreen = cogl_offscreen_new_with_texture (priv->old_texture);
if (priv->new_offscreen) if (priv->new_offscreen)
cogl_handle_unref (priv->new_offscreen); cogl_object_unref (priv->new_offscreen);
priv->new_offscreen = cogl_offscreen_new_to_texture (priv->new_texture); 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->old_offscreen != NULL, FALSE);
g_return_val_if_fail (priv->new_offscreen != COGL_INVALID_HANDLE, 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, pipeline_template = cogl_pipeline_new (ctx);
"RGBA = REPLACE (TEXTURE)",
NULL); cogl_pipeline_set_layer_combine (pipeline_template, 0, "RGBA = REPLACE (TEXTURE)", NULL);
cogl_material_set_layer_combine (material_template, 1, cogl_pipeline_set_layer_combine (pipeline_template, 1, "RGBA = INTERPOLATE (PREVIOUS, TEXTURE, CONSTANT[A])", NULL);
"RGBA = INTERPOLATE (PREVIOUS, " cogl_pipeline_set_layer_combine (pipeline_template, 2, "RGBA = MODULATE (PREVIOUS, PRIMARY)", NULL);
"TEXTURE, "
"CONSTANT[A])",
NULL);
cogl_material_set_layer_combine (material_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_pipeline_set_layer_texture (priv->pipeline, 0, priv->new_texture);
cogl_material_set_layer (priv->material, 1, priv->old_texture); cogl_pipeline_set_layer_texture (priv->pipeline, 1, priv->old_texture);
cogl_push_framebuffer (priv->old_offscreen); fb = COGL_FRAMEBUFFER (priv->old_offscreen);
cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color);
cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2, cogl_framebuffer_orthographic (fb,
priv->offscreen_box.x1, priv->offscreen_box.x2,
priv->offscreen_box.y2, priv->offscreen_box.y1, priv->offscreen_box.y2, priv->offscreen_box.y1,
0.0, 1.0); 0.0, 1.0);
st_theme_node_paint (priv->old_theme_node, &priv->old_paint_state, allocation, 255); st_theme_node_paint (priv->old_theme_node, &priv->old_paint_state, fb, allocation, 255);
cogl_pop_framebuffer ();
cogl_push_framebuffer (priv->new_offscreen); fb = COGL_FRAMEBUFFER (priv->new_offscreen);
cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color);
cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2, cogl_framebuffer_orthographic (fb,
priv->offscreen_box.x1, priv->offscreen_box.x2,
priv->offscreen_box.y2, priv->offscreen_box.y1, priv->offscreen_box.y2, priv->offscreen_box.y1,
0.0, 1.0); 0.0, 1.0);
st_theme_node_paint (priv->new_theme_node, &priv->new_paint_state, allocation, 255); st_theme_node_paint (priv->new_theme_node, &priv->new_paint_state, fb, allocation, 255);
cogl_pop_framebuffer ();
return TRUE; return TRUE;
} }
void void
st_theme_node_transition_paint (StThemeNodeTransition *transition, st_theme_node_transition_paint (StThemeNodeTransition *transition,
CoglFramebuffer *fb,
ClutterActorBox *allocation, ClutterActorBox *allocation,
guint8 paint_opacity) guint8 paint_opacity)
{ {
@ -347,16 +343,16 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition,
return; return;
} }
cogl_color_set_from_4f (&constant, 0., 0., 0., cogl_color_init_from_4f (&constant, 0., 0., 0.,
clutter_timeline_get_progress (priv->timeline)); clutter_timeline_get_progress (priv->timeline));
cogl_material_set_layer_combine_constant (priv->material, 1, &constant); 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,
paint_opacity, paint_opacity); paint_opacity, paint_opacity);
cogl_set_source (priv->material); cogl_framebuffer_draw_multitextured_rectangle (fb, priv->pipeline,
cogl_rectangle_with_multitexture_coords (priv->offscreen_box.x1, priv->offscreen_box.x1,
priv->offscreen_box.y1, priv->offscreen_box.y1,
priv->offscreen_box.x2, priv->offscreen_box.x2,
priv->offscreen_box.y2, priv->offscreen_box.y2,
@ -368,47 +364,16 @@ st_theme_node_transition_dispose (GObject *object)
{ {
StThemeNodeTransitionPrivate *priv = ST_THEME_NODE_TRANSITION (object)->priv; StThemeNodeTransitionPrivate *priv = ST_THEME_NODE_TRANSITION (object)->priv;
if (priv->old_theme_node) g_clear_object (&priv->old_theme_node);
{ g_clear_object (&priv->new_theme_node);
g_object_unref (priv->old_theme_node);
priv->old_theme_node = NULL;
}
if (priv->new_theme_node) g_clear_pointer (&priv->old_texture, cogl_object_unref);
{ g_clear_pointer (&priv->new_texture, cogl_object_unref);
g_object_unref (priv->new_theme_node);
priv->new_theme_node = NULL;
}
if (priv->old_texture) g_clear_pointer (&priv->old_offscreen, cogl_object_unref);
{ g_clear_pointer (&priv->new_offscreen, cogl_object_unref);
cogl_handle_unref (priv->old_texture);
priv->old_texture = NULL;
}
if (priv->new_texture) g_clear_pointer (&priv->pipeline, cogl_object_unref);
{
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;
}
if (priv->timeline) if (priv->timeline)
{ {

View File

@ -63,6 +63,7 @@ void st_theme_node_transition_update (StThemeNodeTransition *transition,
StThemeNode *new_node); StThemeNode *new_node);
void st_theme_node_transition_paint (StThemeNodeTransition *transition, void st_theme_node_transition_paint (StThemeNodeTransition *transition,
CoglFramebuffer *fb,
ClutterActorBox *allocation, ClutterActorBox *allocation,
guint8 paint_opacity); guint8 paint_opacity);

View File

@ -49,11 +49,6 @@ static void
st_theme_node_init (StThemeNode *node) st_theme_node_init (StThemeNode *node)
{ {
node->transition_duration = -1; 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); st_theme_node_paint_state_init (&node->cached_state);
} }
@ -160,16 +155,11 @@ st_theme_node_finalize (GObject *object)
if (node->background_image) if (node->background_image)
g_free (node->background_image); g_free (node->background_image);
if (node->background_texture != COGL_INVALID_HANDLE) g_clear_pointer (&node->background_texture, cogl_object_unref);
cogl_handle_unref (node->background_texture); g_clear_pointer (&node->background_pipeline, cogl_object_unref);
if (node->background_material != COGL_INVALID_HANDLE) g_clear_pointer (&node->background_shadow_pipeline, cogl_object_unref);
cogl_handle_unref (node->background_material); g_clear_pointer (&node->border_slices_texture, cogl_object_unref);
if (node->background_shadow_material != COGL_INVALID_HANDLE) g_clear_pointer (&node->border_slices_pipeline, cogl_object_unref);
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_OBJECT_CLASS (st_theme_node_parent_class)->finalize (object); G_OBJECT_CLASS (st_theme_node_parent_class)->finalize (object);
} }

View File

@ -105,10 +105,10 @@ struct _StThemeNodePaintState {
float box_shadow_width; float box_shadow_width;
float box_shadow_height; float box_shadow_height;
CoglHandle box_shadow_material; CoglPipeline *box_shadow_pipeline;
CoglHandle prerendered_texture; CoglTexture *prerendered_texture;
CoglHandle prerendered_material; CoglPipeline *prerendered_pipeline;
CoglHandle corner_material[4]; CoglPipeline *corner_pipeline[4];
}; };
GType st_theme_node_get_type (void) G_GNUC_CONST; 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, void st_theme_node_paint (StThemeNode *node,
StThemeNodePaintState *state, StThemeNodePaintState *state,
CoglFramebuffer *fb,
const ClutterActorBox *box, const ClutterActorBox *box,
guint8 paint_opacity); guint8 paint_opacity);

View File

@ -465,6 +465,7 @@ st_widget_paint_background (StWidget *widget)
StThemeNode *theme_node; StThemeNode *theme_node;
ClutterActorBox allocation; ClutterActorBox allocation;
guint8 opacity; guint8 opacity;
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
theme_node = st_widget_get_theme_node (widget); theme_node = st_widget_get_theme_node (widget);
@ -474,11 +475,13 @@ st_widget_paint_background (StWidget *widget)
if (widget->priv->transition_animation) if (widget->priv->transition_animation)
st_theme_node_transition_paint (widget->priv->transition_animation, st_theme_node_transition_paint (widget->priv->transition_animation,
fb,
&allocation, &allocation,
opacity); opacity);
else else
st_theme_node_paint (theme_node, st_theme_node_paint (theme_node,
current_paint_state (widget), current_paint_state (widget),
fb,
&allocation, &allocation,
opacity); opacity);
} }