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 = \
-DCLUTTER_ENABLE_EXPERIMENTAL_API \
-DCOGL_ENABLE_EXPERIMENTAL_API \
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
-I$(top_srcdir)/src \
-DPREFIX=\""$(prefix)"\" \
-DLIBDIR=\""$(libdir)"\" \

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

@ -1,8 +1,5 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#define COGL_ENABLE_EXPERIMENTAL_API
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <meta/display.h>

View File

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

View File

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

View File

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

View File

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

View File

@ -60,7 +60,7 @@ struct _StLabelPrivate
{
ClutterActor *label;
CoglHandle text_shadow_material;
CoglPipeline *text_shadow_pipeline;
float shadow_width;
float shadow_height;
};
@ -118,11 +118,7 @@ st_label_style_changed (StWidget *self)
{
StLabelPrivate *priv = ST_LABEL(self)->priv;
if (priv->text_shadow_material != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->text_shadow_material);
priv->text_shadow_material = COGL_INVALID_HANDLE;
}
g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
_st_set_text_from_style ((ClutterText *)priv->label, st_widget_get_theme_node (self));
@ -192,11 +188,7 @@ st_label_dispose (GObject *object)
priv->label = NULL;
}
if (priv->text_shadow_material != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->text_shadow_material);
priv->text_shadow_material = COGL_INVALID_HANDLE;
}
g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
G_OBJECT_CLASS (st_label_parent_class)->dispose (object);
}
@ -218,26 +210,21 @@ st_label_paint (ClutterActor *actor)
clutter_actor_get_allocation_box (priv->label, &allocation);
clutter_actor_box_get_size (&allocation, &width, &height);
if (priv->text_shadow_material == COGL_INVALID_HANDLE ||
if (priv->text_shadow_pipeline == NULL ||
width != priv->shadow_width ||
height != priv->shadow_height)
{
CoglHandle material;
if (priv->text_shadow_material != COGL_INVALID_HANDLE)
cogl_handle_unref (priv->text_shadow_material);
material = _st_create_shadow_material_from_actor (shadow_spec,
priv->label);
g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
priv->shadow_width = width;
priv->shadow_height = height;
priv->text_shadow_material = material;
priv->text_shadow_pipeline = _st_create_shadow_pipeline_from_actor (shadow_spec, priv->label);
}
if (priv->text_shadow_material != COGL_INVALID_HANDLE)
if (priv->text_shadow_pipeline != NULL)
_st_paint_shadow_with_opacity (shadow_spec,
priv->text_shadow_material,
priv->text_shadow_pipeline,
cogl_get_draw_framebuffer (),
&allocation,
clutter_actor_get_paint_opacity (priv->label));
}
@ -292,7 +279,7 @@ st_label_init (StLabel *label)
label->priv->label = g_object_new (CLUTTER_TYPE_TEXT,
"ellipsize", PANGO_ELLIPSIZE_END,
NULL);
label->priv->text_shadow_material = COGL_INVALID_HANDLE;
label->priv->text_shadow_pipeline = NULL;
label->priv->shadow_width = -1.;
label->priv->shadow_height = -1.;
@ -357,11 +344,7 @@ st_label_set_text (StLabel *label,
if (clutter_text_get_editable (ctext) ||
g_strcmp0 (clutter_text_get_text (ctext), text) != 0)
{
if (priv->text_shadow_material != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->text_shadow_material);
priv->text_shadow_material = COGL_INVALID_HANDLE;
}
g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
clutter_text_set_text (ctext, text);

View File

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

View File

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

View File

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

View File

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

View File

@ -90,8 +90,8 @@ ClutterActor *st_texture_cache_load_uri_async (StTextureCache *cache,
int available_width,
int available_height);
CoglHandle st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
const gchar *file_path);
CoglTexture *st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
const gchar *file_path);
cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
const gchar *file_path);
@ -107,13 +107,13 @@ cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *ca
* texture handle for the given key, or set @error.
*
*/
typedef CoglHandle (*StTextureCacheLoader) (StTextureCache *cache, const char *key, void *data, GError **error);
typedef CoglTexture * (*StTextureCacheLoader) (StTextureCache *cache, const char *key, void *data, GError **error);
CoglHandle st_texture_cache_load (StTextureCache *cache,
const char *key,
StTextureCachePolicy policy,
StTextureCacheLoader load,
void *data,
GError **error);
CoglTexture * st_texture_cache_load (StTextureCache *cache,
const char *key,
StTextureCachePolicy policy,
StTextureCacheLoader load,
void *data,
GError **error);
#endif /* __ST_TEXTURE_CACHE_H__ */

View File

@ -66,10 +66,10 @@ elliptical_arc (cairo_t *cr,
cairo_restore (cr);
}
static CoglHandle
create_corner_material (StCornerSpec *corner)
static CoglTexture *
create_corner_texture (StCornerSpec *corner)
{
CoglHandle texture;
CoglTexture *texture;
cairo_t *cr;
cairo_surface_t *surface;
guint rowstride;
@ -173,7 +173,7 @@ create_corner_material (StCornerSpec *corner)
rowstride,
data);
g_free (data);
g_assert (texture != COGL_INVALID_HANDLE);
g_assert (texture != NULL);
return texture;
}
@ -190,13 +190,13 @@ corner_to_string (StCornerSpec *corner)
corner->border_width_2);
}
static CoglHandle
static CoglTexture *
load_corner (StTextureCache *cache,
const char *key,
void *datap,
GError **error)
{
return create_corner_material ((StCornerSpec *) datap);
return create_corner_texture ((StCornerSpec *) datap);
}
/* To match the CSS specification, we want the border to look like it was
@ -337,13 +337,14 @@ st_theme_node_get_corner_border_widths (StThemeNode *node,
}
}
static CoglHandle
static CoglPipeline *
st_theme_node_lookup_corner (StThemeNode *node,
float width,
float height,
StCorner corner_id)
{
CoglHandle texture, material;
CoglTexture *texture;
CoglPipeline *pipeline;
char *key;
StTextureCache *cache;
StCornerSpec corner;
@ -354,7 +355,7 @@ st_theme_node_lookup_corner (StThemeNode *node,
st_theme_node_reduce_border_radius (node, width, height, radius);
if (radius[corner_id] == 0)
return COGL_INVALID_HANDLE;
return NULL;
corner.radius = radius[corner_id];
corner.color = node->background_color;
@ -385,16 +386,16 @@ st_theme_node_lookup_corner (StThemeNode *node,
if (corner.color.alpha == 0 &&
corner.border_color_1.alpha == 0 &&
corner.border_color_2.alpha == 0)
return COGL_INVALID_HANDLE;
return NULL;
key = corner_to_string (&corner);
texture = st_texture_cache_load (cache, key, ST_TEXTURE_CACHE_POLICY_NONE, load_corner, &corner, NULL);
material = _st_create_texture_material (texture);
cogl_handle_unref (texture);
pipeline = _st_create_texture_pipeline (texture);
cogl_object_unref (texture);
g_free (key);
return material;
return pipeline;
}
static void
@ -934,13 +935,13 @@ paint_inset_box_shadow_to_cairo_context (StThemeNode *node,
* we need to use cairo. This function is a slow fallback path for those
* cases (gradients, background images, etc).
*/
static CoglHandle
static CoglTexture *
st_theme_node_prerender_background (StThemeNode *node,
float actor_width,
float actor_height)
{
StBorderImage *border_image;
CoglHandle texture;
CoglTexture *texture;
guint radius[4];
int i;
cairo_t *cr;
@ -1268,30 +1269,17 @@ st_theme_node_prerender_background (StThemeNode *node,
return texture;
}
static void st_theme_node_paint_borders (StThemeNodePaintState *state,
const ClutterActorBox *box,
guint8 paint_opacity);
void
st_theme_node_invalidate_border_image (StThemeNode *node)
{
if (node->border_slices_texture != COGL_INVALID_HANDLE)
{
cogl_handle_unref (node->border_slices_texture);
node->border_slices_texture = COGL_INVALID_HANDLE;
}
if (node->border_slices_material != COGL_INVALID_HANDLE)
{
cogl_handle_unref (node->border_slices_material);
node->border_slices_material = COGL_INVALID_HANDLE;
}
g_clear_pointer (&node->border_slices_texture, cogl_object_unref);
g_clear_pointer (&node->border_slices_pipeline, cogl_object_unref);
}
static gboolean
st_theme_node_load_border_image (StThemeNode *node)
{
if (node->border_slices_texture == COGL_INVALID_HANDLE)
if (node->border_slices_texture == NULL)
{
StBorderImage *border_image;
@ -1303,42 +1291,28 @@ st_theme_node_load_border_image (StThemeNode *node)
filename = st_border_image_get_filename (border_image);
node->border_slices_texture = st_texture_cache_load_file_to_cogl_texture (st_texture_cache_get_default (),
filename);
if (node->border_slices_texture == COGL_INVALID_HANDLE)
if (node->border_slices_texture == NULL)
goto out;
node->border_slices_material = _st_create_texture_material (node->border_slices_texture);
node->border_slices_pipeline = _st_create_texture_pipeline (node->border_slices_texture);
}
out:
return node->border_slices_texture != COGL_INVALID_HANDLE;
return node->border_slices_pipeline != NULL;
}
void
st_theme_node_invalidate_background_image (StThemeNode *node)
{
if (node->background_texture != COGL_INVALID_HANDLE)
{
cogl_handle_unref (node->background_texture);
node->background_texture = COGL_INVALID_HANDLE;
}
if (node->background_material != COGL_INVALID_HANDLE)
{
cogl_handle_unref (node->background_material);
node->background_material = COGL_INVALID_HANDLE;
}
if (node->background_shadow_material != COGL_INVALID_HANDLE)
{
cogl_handle_unref (node->background_shadow_material);
node->background_shadow_material = COGL_INVALID_HANDLE;
}
g_clear_pointer (&node->background_texture, cogl_object_unref);
g_clear_pointer (&node->background_pipeline, cogl_object_unref);
g_clear_pointer (&node->background_shadow_pipeline, cogl_object_unref);
}
static gboolean
st_theme_node_load_background_image (StThemeNode *node)
{
if (node->background_texture == COGL_INVALID_HANDLE)
if (node->background_texture == NULL)
{
const char *background_image;
StShadow *background_image_shadow_spec;
@ -1350,27 +1324,38 @@ st_theme_node_load_background_image (StThemeNode *node)
background_image_shadow_spec = st_theme_node_get_background_image_shadow (node);
node->background_texture = st_texture_cache_load_file_to_cogl_texture (st_texture_cache_get_default (),
background_image);
if (node->background_texture == COGL_INVALID_HANDLE)
if (node->background_texture == NULL)
goto out;
node->background_material = _st_create_texture_material (node->background_texture);
node->background_pipeline = _st_create_texture_pipeline (node->background_texture);
if (node->background_repeat)
cogl_material_set_layer_wrap_mode (node->background_material, 0, COGL_MATERIAL_WRAP_MODE_REPEAT);
cogl_pipeline_set_layer_wrap_mode (node->background_pipeline, 0, COGL_PIPELINE_WRAP_MODE_REPEAT);
if (background_image_shadow_spec)
{
node->background_shadow_material = _st_create_shadow_material (background_image_shadow_spec,
node->background_shadow_pipeline = _st_create_shadow_pipeline (background_image_shadow_spec,
node->background_texture);
}
}
out:
return node->background_texture != COGL_INVALID_HANDLE;
return node->background_texture != NULL;
}
static void st_theme_node_prerender_shadow (StThemeNodePaintState *state);
static CoglPipeline *
get_color_pipeline (guint8 r, guint8 g, guint8 b, guint8 a)
{
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
CoglPipeline *pipeline;
pipeline = cogl_pipeline_new (ctx);
cogl_pipeline_set_color4ub (pipeline, r, g, b, a);
return pipeline;
}
static void
st_theme_node_render_resources (StThemeNodePaintState *state,
StThemeNode *node,
@ -1438,13 +1423,13 @@ st_theme_node_render_resources (StThemeNodePaintState *state,
}
}
state->corner_material[ST_CORNER_TOPLEFT] =
state->corner_pipeline[ST_CORNER_TOPLEFT] =
st_theme_node_lookup_corner (node, width, height, ST_CORNER_TOPLEFT);
state->corner_material[ST_CORNER_TOPRIGHT] =
state->corner_pipeline[ST_CORNER_TOPRIGHT] =
st_theme_node_lookup_corner (node, width, height, ST_CORNER_TOPRIGHT);
state->corner_material[ST_CORNER_BOTTOMRIGHT] =
state->corner_pipeline[ST_CORNER_BOTTOMRIGHT] =
st_theme_node_lookup_corner (node, width, height, ST_CORNER_BOTTOMRIGHT);
state->corner_material[ST_CORNER_BOTTOMLEFT] =
state->corner_pipeline[ST_CORNER_BOTTOMLEFT] =
st_theme_node_lookup_corner (node, width, height, ST_CORNER_BOTTOMLEFT);
/* Use cairo to prerender the node if there is a gradient, or
@ -1463,17 +1448,17 @@ st_theme_node_render_resources (StThemeNodePaintState *state,
state->prerendered_texture = st_theme_node_prerender_background (node, width, height);
if (state->prerendered_texture)
state->prerendered_material = _st_create_texture_material (state->prerendered_texture);
state->prerendered_pipeline = _st_create_texture_pipeline (state->prerendered_texture);
else
state->prerendered_material = COGL_INVALID_HANDLE;
state->prerendered_pipeline = NULL;
if (box_shadow_spec && !has_inset_box_shadow)
{
if (st_theme_node_load_border_image (node))
state->box_shadow_material = _st_create_shadow_material (box_shadow_spec,
state->box_shadow_pipeline = _st_create_shadow_pipeline (box_shadow_spec,
node->border_slices_texture);
else if (state->prerendered_texture != COGL_INVALID_HANDLE)
state->box_shadow_material = _st_create_shadow_material (box_shadow_spec,
else if (state->prerendered_texture != NULL)
state->box_shadow_pipeline = _st_create_shadow_pipeline (box_shadow_spec,
state->prerendered_texture);
else if (node->background_color.alpha > 0 || has_border)
st_theme_node_prerender_shadow (state);
@ -1483,7 +1468,7 @@ st_theme_node_render_resources (StThemeNodePaintState *state,
them. */
if (!node->cached_textures)
{
if (state->prerendered_material == COGL_INVALID_HANDLE &&
if (state->prerendered_pipeline == NULL &&
width >= node->box_shadow_min_width &&
height >= node->box_shadow_min_height)
{
@ -1505,23 +1490,23 @@ st_theme_node_update_resources (StThemeNodePaintState *state,
g_return_if_fail (width > 0 && height > 0);
/* Free handles we can't reuse */
if (state->prerendered_texture != COGL_INVALID_HANDLE)
/* Free objects we can't reuse */
if (state->prerendered_texture != NULL)
{
cogl_handle_unref (state->prerendered_texture);
state->prerendered_texture = COGL_INVALID_HANDLE;
cogl_object_unref (state->prerendered_texture);
state->prerendered_texture = NULL;
had_prerendered_texture = TRUE;
}
if (state->prerendered_material != COGL_INVALID_HANDLE)
if (state->prerendered_pipeline != NULL)
{
cogl_handle_unref (state->prerendered_material);
state->prerendered_material = COGL_INVALID_HANDLE;
cogl_object_unref (state->prerendered_pipeline);
state->prerendered_pipeline = NULL;
if (node->border_slices_texture == COGL_INVALID_HANDLE &&
state->box_shadow_material != COGL_INVALID_HANDLE)
if (node->border_slices_texture == NULL &&
state->box_shadow_pipeline != NULL)
{
cogl_handle_unref (state->box_shadow_material);
state->box_shadow_material = COGL_INVALID_HANDLE;
cogl_object_unref (state->box_shadow_pipeline);
state->box_shadow_pipeline = NULL;
had_box_shadow = TRUE;
}
}
@ -1535,43 +1520,26 @@ st_theme_node_update_resources (StThemeNodePaintState *state,
if (had_prerendered_texture)
{
state->prerendered_texture = st_theme_node_prerender_background (node, width, height);
state->prerendered_material = _st_create_texture_material (state->prerendered_texture);
state->prerendered_pipeline = _st_create_texture_pipeline (state->prerendered_texture);
}
else
{
int corner_id;
for (corner_id = 0; corner_id < 4; corner_id++)
if (state->corner_material[corner_id] == COGL_INVALID_HANDLE)
state->corner_material[corner_id] =
if (state->corner_pipeline[corner_id] == NULL)
state->corner_pipeline[corner_id] =
st_theme_node_lookup_corner (node, width, height, corner_id);
}
if (had_box_shadow)
state->box_shadow_material = _st_create_shadow_material (box_shadow_spec,
state->box_shadow_pipeline = _st_create_shadow_pipeline (box_shadow_spec,
state->prerendered_texture);
}
static void
paint_material_with_opacity (CoglHandle material,
ClutterActorBox *box,
ClutterActorBox *coords,
guint8 paint_opacity)
{
cogl_material_set_color4ub (material,
paint_opacity, paint_opacity, paint_opacity, paint_opacity);
cogl_set_source (material);
if (coords)
cogl_rectangle_with_texture_coords (box->x1, box->y1, box->x2, box->y2,
coords->x1, coords->y1, coords->x2, coords->y2);
else
cogl_rectangle (box->x1, box->y1, box->x2, box->y2);
}
static void
st_theme_node_paint_borders (StThemeNodePaintState *state,
CoglFramebuffer *fb,
const ClutterActorBox *box,
guint8 paint_opacity)
{
@ -1624,10 +1592,7 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
if (alpha > 0)
{
cogl_set_source_color4ub (effective_border.red,
effective_border.green,
effective_border.blue,
alpha);
CoglPipeline *pipeline;
/* NORTH */
skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0;
@ -1670,7 +1635,12 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
rects[15] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
: height - border_width[ST_SIDE_BOTTOM];
cogl_rectangles (rects, 4);
pipeline = get_color_pipeline (effective_border.red,
effective_border.green,
effective_border.blue,
alpha);
cogl_framebuffer_draw_rectangles (fb, pipeline, rects, 4);
cogl_object_unref (pipeline);
}
}
@ -1679,35 +1649,40 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
{
for (corner_id = 0; corner_id < 4; corner_id++)
{
if (state->corner_material[corner_id] == COGL_INVALID_HANDLE)
CoglPipeline *pipeline = state->corner_pipeline[corner_id];
if (pipeline == NULL)
continue;
cogl_material_set_color4ub (state->corner_material[corner_id],
cogl_pipeline_set_color4ub (pipeline,
paint_opacity, paint_opacity,
paint_opacity, paint_opacity);
cogl_set_source (state->corner_material[corner_id]);
switch (corner_id)
{
case ST_CORNER_TOPLEFT:
cogl_rectangle_with_texture_coords (0, 0,
max_width_radius[ST_CORNER_TOPLEFT], max_width_radius[ST_CORNER_TOPLEFT],
0, 0, 0.5, 0.5);
cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
0, 0,
max_width_radius[ST_CORNER_TOPLEFT], max_width_radius[ST_CORNER_TOPLEFT],
0, 0, 0.5, 0.5);
break;
case ST_CORNER_TOPRIGHT:
cogl_rectangle_with_texture_coords (width - max_width_radius[ST_CORNER_TOPRIGHT], 0,
width, max_width_radius[ST_CORNER_TOPRIGHT],
0.5, 0, 1, 0.5);
cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
width - max_width_radius[ST_CORNER_TOPRIGHT], 0,
width, max_width_radius[ST_CORNER_TOPRIGHT],
0.5, 0, 1, 0.5);
break;
case ST_CORNER_BOTTOMRIGHT:
cogl_rectangle_with_texture_coords (width - max_width_radius[ST_CORNER_BOTTOMRIGHT], height - max_width_radius[ST_CORNER_BOTTOMRIGHT],
width, height,
0.5, 0.5, 1, 1);
cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
width - max_width_radius[ST_CORNER_BOTTOMRIGHT], height - max_width_radius[ST_CORNER_BOTTOMRIGHT],
width, height,
0.5, 0.5, 1, 1);
break;
case ST_CORNER_BOTTOMLEFT:
cogl_rectangle_with_texture_coords (0, height - max_width_radius[ST_CORNER_BOTTOMLEFT],
max_width_radius[ST_CORNER_BOTTOMLEFT], height,
0, 0.5, 0.5, 1);
cogl_framebuffer_draw_textured_rectangle (fb, pipeline,
0, height - max_width_radius[ST_CORNER_BOTTOMLEFT],
max_width_radius[ST_CORNER_BOTTOMLEFT], height,
0, 0.5, 0.5, 1);
break;
}
}
@ -1717,10 +1692,12 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
alpha = paint_opacity * node->background_color.alpha / 255;
if (alpha > 0)
{
cogl_set_source_color4ub (node->background_color.red,
node->background_color.green,
node->background_color.blue,
alpha);
CoglPipeline *pipeline;
pipeline = get_color_pipeline (node->background_color.red,
node->background_color.green,
node->background_color.blue,
alpha);
/* We add padding to each corner, so that all corners end up as if they
* had a border-radius of max_border_radius, which allows us to treat
@ -1803,8 +1780,9 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
verts[7] = height - border_width[ST_SIDE_BOTTOM];
}
break;
cogl_framebuffer_draw_rectangles (fb, pipeline, verts, 4);
}
cogl_rectangles (verts, n_rects);
}
/* Once we've drawn the borders and corners, if the corners are bigger
@ -1819,25 +1797,31 @@ st_theme_node_paint_borders (StThemeNodePaintState *state,
* necessary, then the main rectangle
*/
if (max_border_radius > border_width[ST_SIDE_TOP])
cogl_rectangle (MAX(max_border_radius, border_width[ST_SIDE_LEFT]),
border_width[ST_SIDE_TOP],
width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]),
max_border_radius);
cogl_framebuffer_draw_rectangle (fb, pipeline,
MAX(max_border_radius, border_width[ST_SIDE_LEFT]),
border_width[ST_SIDE_TOP],
width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]),
max_border_radius);
if (max_border_radius > border_width[ST_SIDE_BOTTOM])
cogl_rectangle (MAX(max_border_radius, border_width[ST_SIDE_LEFT]),
height - max_border_radius,
width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]),
height - border_width[ST_SIDE_BOTTOM]);
cogl_framebuffer_draw_rectangle (fb, pipeline,
MAX(max_border_radius, border_width[ST_SIDE_LEFT]),
height - max_border_radius,
width - MAX(max_border_radius, border_width[ST_SIDE_RIGHT]),
height - border_width[ST_SIDE_BOTTOM]);
cogl_rectangle (border_width[ST_SIDE_LEFT],
MAX(border_width[ST_SIDE_TOP], max_border_radius),
width - border_width[ST_SIDE_RIGHT],
height - MAX(border_width[ST_SIDE_BOTTOM], max_border_radius));
cogl_framebuffer_draw_rectangle (fb, pipeline,
border_width[ST_SIDE_LEFT],
MAX(border_width[ST_SIDE_TOP], max_border_radius),
width - border_width[ST_SIDE_RIGHT],
height - MAX(border_width[ST_SIDE_BOTTOM], max_border_radius));
cogl_object_unref (pipeline);
}
}
static void
st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
CoglFramebuffer *fb,
const ClutterActorBox *box,
guint8 paint_opacity)
{
@ -1943,16 +1927,14 @@ st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
right += xoffset;
/* Setup pipeline */
cogl_color_set_from_4ub (&color,
box_shadow_spec->color.red * paint_opacity / 255,
box_shadow_spec->color.green * paint_opacity / 255,
box_shadow_spec->color.blue * paint_opacity / 255,
box_shadow_spec->color.alpha * paint_opacity / 255);
cogl_color_init_from_4ub (&color,
box_shadow_spec->color.red * paint_opacity / 255,
box_shadow_spec->color.green * paint_opacity / 255,
box_shadow_spec->color.blue * paint_opacity / 255,
box_shadow_spec->color.alpha * paint_opacity / 255);
cogl_color_premultiply (&color);
cogl_material_set_layer_combine_constant (state->box_shadow_material, 0, &color);
cogl_set_source (state->box_shadow_material);
cogl_pipeline_set_layer_combine_constant (state->box_shadow_pipeline, 0, &color);
idx = 0;
@ -2080,36 +2062,8 @@ st_theme_node_paint_sliced_shadow (StThemeNodePaintState *state,
}
}
cogl_rectangles_with_texture_coords (rectangles, idx / 8);
#if 0
/* Visual feedback on shadow's 9-slice and orignal offscreen buffer,
for debug purposes */
cogl_rectangle (xend, yoffset, xend + shadow_width, yoffset + shadow_height);
cogl_set_source_color4ub (0xff, 0x0, 0x0, 0xff);
cogl_rectangle (xoffset, top, xend, top + 1);
cogl_rectangle (xoffset, bottom, xend, bottom + 1);
cogl_rectangle (left, yoffset, left + 1, yend);
cogl_rectangle (right, yoffset, right + 1, yend);
cogl_rectangle (xend, yoffset, xend + shadow_width, yoffset + 1);
cogl_rectangle (xend, yoffset + shadow_height, xend + shadow_width, yoffset + shadow_height + 1);
cogl_rectangle (xend, yoffset, xend + 1, yoffset + shadow_height);
cogl_rectangle (xend + shadow_width, yoffset, xend + shadow_width + 1, yoffset + shadow_height);
s_top *= shadow_height;
s_bottom *= shadow_height;
s_left *= shadow_width;
s_right *= shadow_width;
cogl_rectangle (xend, yoffset + s_top, xend + shadow_width, yoffset + s_top + 1);
cogl_rectangle (xend, yoffset + s_bottom, xend + shadow_width, yoffset + s_bottom + 1);
cogl_rectangle (xend + s_left, yoffset, xend + s_left + 1, yoffset + shadow_height);
cogl_rectangle (xend + s_right, yoffset, xend + s_right + 1, yoffset + shadow_height);
#endif
cogl_framebuffer_draw_textured_rectangles (fb, state->box_shadow_pipeline,
rectangles, idx / 4);
}
static void
@ -2119,7 +2073,8 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state)
guint border_radius[4];
int max_borders[4];
int center_radius, corner_id;
CoglHandle buffer, offscreen;
CoglTexture *buffer;
CoglOffscreen *offscreen;
/* Get infos from the node */
if (state->alloc_width < node->box_shadow_min_width ||
@ -2160,33 +2115,32 @@ st_theme_node_prerender_shadow (StThemeNodePaintState *state)
state->box_shadow_height,
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY);
offscreen = cogl_offscreen_new_to_texture (buffer);
offscreen = cogl_offscreen_new_with_texture (buffer);
if (offscreen != COGL_INVALID_HANDLE)
if (offscreen != NULL)
{
CoglFramebuffer *fb = COGL_FRAMEBUFFER (offscreen);
ClutterActorBox box = { 0, 0, state->box_shadow_width, state->box_shadow_height};
CoglColor clear_color;
cogl_push_framebuffer (offscreen);
cogl_ortho (0, state->box_shadow_width, state->box_shadow_height, 0, 0, 1.0);
cogl_framebuffer_orthographic (fb, 0, state->box_shadow_width, state->box_shadow_height, 0, 0, 1.0);
cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color);
cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
st_theme_node_paint_borders (state, fb, &box, 0xFF);
cogl_object_unref (offscreen);
cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
st_theme_node_paint_borders (state, &box, 0xFF);
cogl_pop_framebuffer ();
cogl_handle_unref (offscreen);
state->box_shadow_material = _st_create_shadow_material (st_theme_node_get_box_shadow (node),
state->box_shadow_pipeline = _st_create_shadow_pipeline (st_theme_node_get_box_shadow (node),
buffer);
}
cogl_handle_unref (buffer);
cogl_object_unref (buffer);
}
static void
st_theme_node_paint_sliced_border_image (StThemeNode *node,
float width,
float height,
CoglFramebuffer *fb,
guint8 paint_opacity)
{
gfloat ex, ey;
@ -2194,7 +2148,7 @@ st_theme_node_paint_sliced_border_image (StThemeNode *node,
gint border_left, border_right, border_top, border_bottom;
float img_width, img_height;
StBorderImage *border_image;
CoglHandle material;
CoglPipeline *pipeline;
border_image = st_theme_node_get_border_image (node);
g_assert (border_image != NULL);
@ -2218,11 +2172,8 @@ st_theme_node_paint_sliced_border_image (StThemeNode *node,
if (ey < 0)
ey = border_bottom; /* FIXME ? */
material = node->border_slices_material;
cogl_material_set_color4ub (material,
paint_opacity, paint_opacity, paint_opacity, paint_opacity);
cogl_set_source (material);
pipeline = node->border_slices_pipeline;
cogl_pipeline_set_color4ub (pipeline, paint_opacity, paint_opacity, paint_opacity, paint_opacity);
{
float rectangles[] =
@ -2273,12 +2224,14 @@ st_theme_node_paint_sliced_border_image (StThemeNode *node,
1.0, 1.0
};
cogl_rectangles_with_texture_coords (rectangles, 9);
cogl_framebuffer_draw_textured_rectangles (fb, pipeline,
rectangles, 9);
}
}
static void
st_theme_node_paint_outline (StThemeNode *node,
CoglFramebuffer *fb,
const ClutterActorBox *box,
guint8 paint_opacity)
@ -2287,6 +2240,7 @@ st_theme_node_paint_outline (StThemeNode *node,
int outline_width;
float rects[16];
ClutterColor outline_color, effective_outline;
CoglPipeline *pipeline;
width = box->x2 - box->x1;
height = box->y2 - box->y1;
@ -2298,10 +2252,10 @@ st_theme_node_paint_outline (StThemeNode *node,
st_theme_node_get_outline_color (node, &outline_color);
over (&outline_color, &node->background_color, &effective_outline);
cogl_set_source_color4ub (effective_outline.red,
effective_outline.green,
effective_outline.blue,
paint_opacity * effective_outline.alpha / 255);
pipeline = get_color_pipeline (effective_outline.red,
effective_outline.green,
effective_outline.blue,
paint_opacity * effective_outline.alpha / 255);
/* The outline is drawn just outside the border, which means just
* outside the allocation box. This means that in some situations
@ -2333,7 +2287,8 @@ st_theme_node_paint_outline (StThemeNode *node,
rects[14] = 0;
rects[15] = height;
cogl_rectangles (rects, 4);
cogl_framebuffer_draw_rectangles (fb, pipeline, rects, 16);
cogl_object_unref (pipeline);
}
static gboolean
@ -2373,9 +2328,13 @@ st_theme_node_needs_new_box_shadow_for_size (StThemeNodePaintState *state,
return FALSE;
}
/**
* st_theme_node_paint: (skip)
*/
void
st_theme_node_paint (StThemeNode *node,
StThemeNodePaintState *state,
CoglFramebuffer *fb,
const ClutterActorBox *box,
guint8 paint_opacity)
{
@ -2441,24 +2400,26 @@ st_theme_node_paint (StThemeNode *node,
* such that it's aligned to the outside edges)
*/
if (state->box_shadow_material)
if (state->box_shadow_pipeline)
{
if (state->alloc_width < node->box_shadow_min_width ||
state->alloc_height < node->box_shadow_min_height)
_st_paint_shadow_with_opacity (node->box_shadow,
state->box_shadow_material,
state->box_shadow_pipeline,
fb,
&allocation,
paint_opacity);
else
st_theme_node_paint_sliced_shadow (state,
fb,
&allocation,
paint_opacity);
}
if (state->prerendered_material != COGL_INVALID_HANDLE ||
if (state->prerendered_pipeline != NULL ||
st_theme_node_load_border_image (node))
{
if (state->prerendered_material != COGL_INVALID_HANDLE)
if (state->prerendered_pipeline != NULL)
{
ClutterActorBox paint_box;
@ -2466,23 +2427,24 @@ st_theme_node_paint (StThemeNode *node,
&allocation,
&paint_box);
paint_material_with_opacity (state->prerendered_material,
&paint_box,
NULL,
paint_opacity);
cogl_pipeline_set_color4ub (state->prerendered_pipeline,
paint_opacity, paint_opacity, paint_opacity, paint_opacity);
cogl_framebuffer_draw_rectangle (fb, state->prerendered_pipeline,
paint_box.x1, paint_box.y1,
paint_box.x2, paint_box.y2);
}
if (node->border_slices_material != COGL_INVALID_HANDLE)
st_theme_node_paint_sliced_border_image (node, width, height, paint_opacity);
if (node->border_slices_pipeline != NULL)
st_theme_node_paint_sliced_border_image (node, width, height, fb, paint_opacity);
}
else
{
st_theme_node_paint_borders (state, box, paint_opacity);
st_theme_node_paint_borders (state, fb, box, paint_opacity);
}
st_theme_node_paint_outline (node, box, paint_opacity);
st_theme_node_paint_outline (node, fb, box, paint_opacity);
if (state->prerendered_material == COGL_INVALID_HANDLE &&
if (state->prerendered_pipeline == NULL &&
st_theme_node_load_background_image (node))
{
ClutterActorBox background_box;
@ -2498,7 +2460,7 @@ st_theme_node_paint (StThemeNode *node,
get_background_position (node, &allocation, &background_box, &texture_coords);
if (has_visible_outline || node->background_repeat)
cogl_clip_push_rectangle (allocation.x1, allocation.y1, allocation.x2, allocation.y2);
cogl_framebuffer_push_rectangle_clip (fb, allocation.x1, allocation.y1, allocation.x2, allocation.y2);
/* CSS based drop shadows
*
@ -2513,19 +2475,23 @@ st_theme_node_paint (StThemeNode *node,
* there is nothing (like a border, or the edge of the background color)
* to logically confine it.
*/
if (node->background_shadow_material != COGL_INVALID_HANDLE)
if (node->background_shadow_pipeline != NULL)
_st_paint_shadow_with_opacity (node->background_image_shadow,
node->background_shadow_material,
node->background_shadow_pipeline,
fb,
&background_box,
paint_opacity);
paint_material_with_opacity (node->background_material,
&background_box,
&texture_coords,
paint_opacity);
cogl_pipeline_set_color4ub (node->background_pipeline,
paint_opacity, paint_opacity, paint_opacity, paint_opacity);
cogl_framebuffer_draw_textured_rectangle (fb, node->background_pipeline,
background_box.x1, background_box.y1,
background_box.x2, background_box.y2,
texture_coords.x1, texture_coords.x2,
texture_coords.y1, texture_coords.y2);
if (has_visible_outline || node->background_repeat)
cogl_clip_pop ();
cogl_framebuffer_pop_clip (fb);
}
}
@ -2535,16 +2501,11 @@ st_theme_node_paint_state_node_free_internal (StThemeNodePaintState *state,
{
int corner_id;
if (state->prerendered_texture != COGL_INVALID_HANDLE)
cogl_handle_unref (state->prerendered_texture);
if (state->prerendered_material != COGL_INVALID_HANDLE)
cogl_handle_unref (state->prerendered_material);
if (state->box_shadow_material != COGL_INVALID_HANDLE)
cogl_handle_unref (state->box_shadow_material);
g_clear_pointer (&state->prerendered_texture, cogl_object_unref);
g_clear_pointer (&state->prerendered_pipeline, cogl_object_unref);
g_clear_pointer (&state->box_shadow_pipeline, cogl_object_unref);
for (corner_id = 0; corner_id < 4; corner_id++)
if (state->corner_material[corner_id] != COGL_INVALID_HANDLE)
cogl_handle_unref (state->corner_material[corner_id]);
g_clear_pointer (&state->corner_pipeline[corner_id], cogl_object_unref);
if (unref_node)
st_theme_node_paint_state_set_node (state, NULL);
@ -2587,12 +2548,11 @@ st_theme_node_paint_state_init (StThemeNodePaintState *state)
state->alloc_width = 0;
state->alloc_height = 0;
state->node = NULL;
state->box_shadow_material = COGL_INVALID_HANDLE;
state->prerendered_texture = COGL_INVALID_HANDLE;
state->prerendered_material = COGL_INVALID_HANDLE;
state->box_shadow_pipeline = NULL;
state->prerendered_texture = NULL;
state->prerendered_pipeline = NULL;
for (corner_id = 0; corner_id < 4; corner_id++)
state->corner_material[corner_id] = COGL_INVALID_HANDLE;
state->corner_pipeline[corner_id] = NULL;
}
void
@ -2613,15 +2573,15 @@ st_theme_node_paint_state_copy (StThemeNodePaintState *state,
state->box_shadow_width = other->box_shadow_width;
state->box_shadow_height = other->box_shadow_height;
if (other->box_shadow_material)
state->box_shadow_material = cogl_handle_ref (other->box_shadow_material);
if (other->box_shadow_pipeline)
state->box_shadow_pipeline = cogl_object_ref (other->box_shadow_pipeline);
if (other->prerendered_texture)
state->prerendered_texture = cogl_handle_ref (other->prerendered_texture);
if (other->prerendered_material)
state->prerendered_material = cogl_handle_ref (other->prerendered_material);
state->prerendered_texture = cogl_object_ref (other->prerendered_texture);
if (other->prerendered_pipeline)
state->prerendered_pipeline = cogl_object_ref (other->prerendered_pipeline);
for (corner_id = 0; corner_id < 4; corner_id++)
if (other->corner_material[corner_id])
state->corner_material[corner_id] = cogl_handle_ref (other->corner_material[corner_id]);
if (other->corner_pipeline[corner_id])
state->corner_pipeline[corner_id] = cogl_object_ref (other->corner_pipeline[corner_id]);
}
void

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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