Reduce our internal dependence on the Cogl 1.x api

Since Cogl has started restricting what cogl 1.x api is exposed when
COGL_ENABLE_EXPERIMENTAL_2_0_API is defined and since we build all
Clutter internals with COGL_ENABLE_EXPERIMENTAL_2_0_API defined this
patch makes a first pass at reducing our internal use of the Cogl 1.x
api.

The most notable api that's no longer exposed to us internally is
the cogl_material_ api so this switches all Clutter internals to use the
cogl_pipeline_ api instead. This patch also makes quite a bit of
progress removing internal uses of CoglHandle although there is still
more to go.
This commit is contained in:
Robert Bragg 2012-02-21 15:55:51 +00:00
parent eff95eba4a
commit a8e631543e
12 changed files with 270 additions and 157 deletions

View File

@ -118,6 +118,7 @@ source_h = \
$(srcdir)/clutter-types.h \ $(srcdir)/clutter-types.h \
$(srcdir)/clutter-units.h \ $(srcdir)/clutter-units.h \
$(srcdir)/clutter-util.h \ $(srcdir)/clutter-util.h \
$(srcdir)/clutter-cogl-compat.h \
$(NULL) $(NULL)
source_c = \ source_c = \

View File

@ -0,0 +1,52 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2012 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __CLUTTER_COGL_COMPAT_H__
#define __CLUTTER_COGL_COMPAT_H__
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
G_BEGIN_DECLS
/* XXX: Some public Clutter apis depend on Cogl types that have been
* removed from the Cogl 2.0 experimental api.
*
* If somone has opted to use the Cogl 2.0 experimental api by
* defining COGL_ENABLE_EXPERIMENTAL_2_0_API then we need to define
* some place holder typdefs for compatability.
*
* NB: we build all clutter internals with COGL_ENABLE_EXPERIMENTAL_2_0_API
* defined.
*/
#ifdef COGL_ENABLE_EXPERIMENTAL_2_0_API
/* CoglMaterial has been replaced with CoglPipeline in Cogl 2.0 */
typedef struct _CoglMaterial CoglMaterial;
#endif
G_END_DECLS
#endif /* __CLUTTER_COGL_COMPAT_H__ */

View File

@ -124,10 +124,10 @@ clutter_offscreen_effect_set_actor (ClutterActorMeta *meta,
meta_class->set_actor (meta, actor); meta_class->set_actor (meta, actor);
/* clear out the previous state */ /* clear out the previous state */
if (priv->offscreen != COGL_INVALID_HANDLE) if (priv->offscreen != NULL)
{ {
cogl_handle_unref (priv->offscreen); cogl_handle_unref (priv->offscreen);
priv->offscreen = COGL_INVALID_HANDLE; priv->offscreen = NULL;
} }
/* we keep a back pointer here, to avoid going through the ActorMeta */ /* we keep a back pointer here, to avoid going through the ActorMeta */
@ -162,7 +162,7 @@ update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height)
if (priv->fbo_width == fbo_width && if (priv->fbo_width == fbo_width &&
priv->fbo_height == fbo_height && priv->fbo_height == fbo_height &&
priv->offscreen != COGL_INVALID_HANDLE) priv->offscreen != NULL)
return TRUE; return TRUE;
if (priv->target == NULL) if (priv->target == NULL)
@ -181,15 +181,15 @@ update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height)
COGL_PIPELINE_FILTER_NEAREST); COGL_PIPELINE_FILTER_NEAREST);
} }
if (priv->texture != COGL_INVALID_HANDLE) if (priv->texture != NULL)
{ {
cogl_handle_unref (priv->texture); cogl_handle_unref (priv->texture);
priv->texture = COGL_INVALID_HANDLE; priv->texture = NULL;
} }
priv->texture = priv->texture =
clutter_offscreen_effect_create_texture (self, fbo_width, fbo_height); clutter_offscreen_effect_create_texture (self, fbo_width, fbo_height);
if (priv->texture == COGL_INVALID_HANDLE) if (priv->texture == NULL)
return FALSE; return FALSE;
cogl_pipeline_set_layer_texture (priv->target, 0, priv->texture); cogl_pipeline_set_layer_texture (priv->target, 0, priv->texture);
@ -197,11 +197,11 @@ update_fbo (ClutterEffect *effect, int fbo_width, int fbo_height)
priv->fbo_width = fbo_width; priv->fbo_width = fbo_width;
priv->fbo_height = fbo_height; priv->fbo_height = fbo_height;
if (priv->offscreen != COGL_INVALID_HANDLE) if (priv->offscreen != NULL)
cogl_handle_unref (priv->offscreen); cogl_handle_unref (priv->offscreen);
priv->offscreen = cogl_offscreen_new_to_texture (priv->texture); priv->offscreen = cogl_offscreen_new_to_texture (priv->texture);
if (priv->offscreen == COGL_INVALID_HANDLE) if (priv->offscreen == NULL)
{ {
g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC); g_warning ("%s: Unable to create an Offscreen buffer", G_STRLOC);
@ -397,7 +397,7 @@ clutter_offscreen_effect_post_paint (ClutterEffect *effect)
ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect); ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect);
ClutterOffscreenEffectPrivate *priv = self->priv; ClutterOffscreenEffectPrivate *priv = self->priv;
if (priv->offscreen == COGL_INVALID_HANDLE || if (priv->offscreen == NULL ||
priv->target == NULL || priv->target == NULL ||
priv->actor == NULL) priv->actor == NULL)
return; return;
@ -508,7 +508,7 @@ CoglHandle
clutter_offscreen_effect_get_texture (ClutterOffscreenEffect *effect) clutter_offscreen_effect_get_texture (ClutterOffscreenEffect *effect)
{ {
g_return_val_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect), g_return_val_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect),
COGL_INVALID_HANDLE); NULL);
return effect->priv->texture; return effect->priv->texture;
} }
@ -574,7 +574,7 @@ clutter_offscreen_effect_create_texture (ClutterOffscreenEffect *effect,
gfloat height) gfloat height)
{ {
g_return_val_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect), g_return_val_if_fail (CLUTTER_IS_OFFSCREEN_EFFECT (effect),
COGL_INVALID_HANDLE); NULL);
return CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->create_texture (effect, return CLUTTER_OFFSCREEN_EFFECT_GET_CLASS (effect)->create_texture (effect,
width, width,
@ -610,7 +610,7 @@ clutter_offscreen_effect_get_target_size (ClutterOffscreenEffect *effect,
priv = effect->priv; priv = effect->priv;
if (priv->texture == COGL_INVALID_HANDLE) if (priv->texture == NULL)
return FALSE; return FALSE;
if (width) if (width)

View File

@ -31,6 +31,7 @@
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <clutter/clutter-effect.h> #include <clutter/clutter-effect.h>
#include <clutter/clutter-cogl-compat.h>
G_BEGIN_DECLS G_BEGIN_DECLS

View File

@ -1259,18 +1259,7 @@ clutter_path_node_distance (const ClutterKnot *start,
t = (end->x - start->x) * (end->x - start->x) + t = (end->x - start->x) * (end->x - start->x) +
(end->y - start->y) * (end->y - start->y); (end->y - start->y) * (end->y - start->y);
/* return sqrtf (t);
* If we are using limited precision sqrti implementation, fallback on
* clib sqrt if the precission would be less than 10%
*/
#if INT_MAX > COGL_SQRTI_ARG_10_PERCENT
if (t <= COGL_SQRTI_ARG_10_PERCENT)
return cogl_sqrti (t);
else
return COGL_FLOAT_TO_INT (sqrtf(t));
#else
return cogl_sqrti (t);
#endif
} }
static void static void

View File

@ -113,10 +113,14 @@
#include "config.h" #include "config.h"
#endif #endif
#include "clutter-shader-effect.h" /* XXX: This file depends on the cogl_program_ api with has been
* removed for Cogl 2.0 so we undef COGL_ENABLE_EXPERIMENTAL_2_0_API
* for this file for now */
#undef COGL_ENABLE_EXPERIMENTAL_2_0_API
#include "cogl/cogl.h" #include "cogl/cogl.h"
#include "clutter-shader-effect.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-enum-types.h" #include "clutter-enum-types.h"
#include "clutter-feature.h" #include "clutter-feature.h"
@ -418,7 +422,7 @@ clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect)
/* associate the program to the offscreen target material */ /* associate the program to the offscreen target material */
material = clutter_offscreen_effect_get_target (effect); material = clutter_offscreen_effect_get_target (effect);
cogl_material_set_user_program (material, priv->program); cogl_pipeline_set_user_program (material, priv->program);
out: out:
/* paint the offscreen buffer */ /* paint the offscreen buffer */

View File

@ -5,6 +5,18 @@
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <cairo.h> #include <cairo.h>
/* XXX: Some of the private parts in this header expect the
* CoglFramebuffer typedef from Cogl, but its possible for this header
* to be included without the experimental Cogl api having been
* selected by defining COGL_ENABLE_EXPERIMENTAL_API or
* COGL_ENABLE_EXPERIMENTAL_2_0_API.
*
* We declare a place holder type ourselves in this case...
*/
#ifndef COGL_ENABLE_EXPERIMENTAL_API
typedef struct _CoglFramebuffer CoglFramebuffer;
#endif
G_BEGIN_DECLS G_BEGIN_DECLS
#define CLUTTER_TYPE_STAGE_WINDOW (clutter_stage_window_get_type ()) #define CLUTTER_TYPE_STAGE_WINDOW (clutter_stage_window_get_type ())

View File

@ -44,6 +44,17 @@
#include "config.h" #include "config.h"
#endif #endif
/* This file depends on the glib enum types which aren't exposed
* by cogl.h when COGL_ENABLE_EXPERIMENTAL_2_0_API is defined.
*
* Undefining COGL_ENABLE_EXPERIMENTAL_2_0_API will still expose
* us experimental api but will also expose Cogl 1.x api too...
*/
#undef COGL_ENABLE_EXPERIMENTAL_2_0_API
#include <cogl/cogl.h>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
/* sadly, we are still using ClutterShader internally */ /* sadly, we are still using ClutterShader internally */
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS #define CLUTTER_DISABLE_DEPRECATION_WARNINGS
@ -79,12 +90,12 @@ struct _ClutterTexturePrivate
gint image_width; gint image_width;
gint image_height; gint image_height;
CoglHandle material; CoglPipeline *pipeline;
ClutterActor *fbo_source; ClutterActor *fbo_source;
CoglHandle fbo_handle; CoglHandle fbo_handle;
CoglHandle pick_material; CoglPipeline *pick_pipeline;
gchar *filename; gchar *filename;
@ -100,7 +111,7 @@ struct _ClutterTexturePrivate
guint load_async_set : 1; /* used to make load_async possible */ guint load_async_set : 1; /* used to make load_async possible */
guint pick_with_alpha : 1; guint pick_with_alpha : 1;
guint pick_with_alpha_supported : 1; guint pick_with_alpha_supported : 1;
guint seen_create_pick_material_warning : 1; guint seen_create_pick_pipeline_warning : 1;
}; };
#define ASYNC_STATE_LOCKED 1 #define ASYNC_STATE_LOCKED 1
@ -173,7 +184,7 @@ static guint repaint_upload_func = 0;
static GList *upload_list = NULL; static GList *upload_list = NULL;
static GMutex upload_list_mutex; static GMutex upload_list_mutex;
static CoglMaterial *texture_template_material = NULL; static CoglPipeline *texture_template_pipeline = NULL;
static void static void
texture_fbo_free_resources (ClutterTexture *texture); texture_fbo_free_resources (ClutterTexture *texture);
@ -192,13 +203,13 @@ static const struct
clutter_texture_quality_filters[] = clutter_texture_quality_filters[] =
{ {
/* CLUTTER_TEXTURE_QUALITY_LOW */ /* CLUTTER_TEXTURE_QUALITY_LOW */
{ COGL_MATERIAL_FILTER_NEAREST, COGL_MATERIAL_FILTER_NEAREST }, { COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST },
/* CLUTTER_TEXTURE_QUALITY_MEDIUM */ /* CLUTTER_TEXTURE_QUALITY_MEDIUM */
{ COGL_MATERIAL_FILTER_LINEAR, COGL_MATERIAL_FILTER_LINEAR }, { COGL_PIPELINE_FILTER_LINEAR, COGL_PIPELINE_FILTER_LINEAR },
/* CLUTTER_TEXTURE_QUALITY_HIGH */ /* CLUTTER_TEXTURE_QUALITY_HIGH */
{ COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR, COGL_MATERIAL_FILTER_LINEAR } { COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, COGL_PIPELINE_FILTER_LINEAR }
}; };
static inline void static inline void
@ -220,12 +231,12 @@ texture_free_gl_resources (ClutterTexture *texture)
{ {
ClutterTexturePrivate *priv = texture->priv; ClutterTexturePrivate *priv = texture->priv;
if (priv->material != COGL_INVALID_HANDLE) if (priv->pipeline != NULL)
{ {
/* We want to keep the layer so that the filter settings will /* We want to keep the layer so that the filter settings will
remain but we want to free its resources so we clear the remain but we want to free its resources so we clear the
texture handle */ texture handle */
cogl_material_set_layer (priv->material, 0, COGL_INVALID_HANDLE); cogl_pipeline_set_layer_texture (priv->pipeline, 0, NULL);
} }
} }
@ -238,14 +249,14 @@ clutter_texture_unrealize (ClutterActor *actor)
texture = CLUTTER_TEXTURE(actor); texture = CLUTTER_TEXTURE(actor);
priv = texture->priv; priv = texture->priv;
if (priv->material == COGL_INVALID_HANDLE) if (priv->pipeline == NULL)
return; return;
if (priv->fbo_source != NULL) if (priv->fbo_source != NULL)
{ {
/* Free up our fbo handle and texture resources, realize will recreate */ /* Free up our fbo handle and texture resources, realize will recreate */
cogl_handle_unref (priv->fbo_handle); cogl_object_unref (priv->fbo_handle);
priv->fbo_handle = COGL_INVALID_HANDLE; priv->fbo_handle = NULL;
texture_free_gl_resources (texture); texture_free_gl_resources (texture);
return; return;
} }
@ -277,15 +288,15 @@ clutter_texture_realize (ClutterActor *actor)
flags, flags,
COGL_PIXEL_FORMAT_RGBA_8888_PRE); COGL_PIXEL_FORMAT_RGBA_8888_PRE);
cogl_material_set_layer (priv->material, 0, tex); cogl_pipeline_set_layer_texture (priv->pipeline, 0, tex);
priv->fbo_handle = cogl_offscreen_new_to_texture (tex); priv->fbo_handle = cogl_offscreen_new_to_texture (tex);
/* The material now has a reference to the texture so it will /* The pipeline now has a reference to the texture so it will
stick around */ stick around */
cogl_handle_unref (tex); cogl_object_unref (tex);
if (priv->fbo_handle == COGL_INVALID_HANDLE) if (priv->fbo_handle == NULL)
{ {
g_warning ("%s: Offscreen texture creation failed", G_STRLOC); g_warning ("%s: Offscreen texture creation failed", G_STRLOC);
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
@ -582,37 +593,37 @@ gen_texcoords_and_draw_cogl_rectangle (ClutterActor *self)
0, 0, t_w, t_h); 0, 0, t_w, t_h);
} }
static CoglHandle static CoglPipeline *
create_pick_material (ClutterActor *self) create_pick_pipeline (ClutterActor *self)
{ {
ClutterTexture *texture = CLUTTER_TEXTURE (self); ClutterTexture *texture = CLUTTER_TEXTURE (self);
ClutterTexturePrivate *priv = texture->priv; ClutterTexturePrivate *priv = texture->priv;
CoglHandle pick_material = cogl_material_copy (texture_template_material); CoglPipeline *pick_pipeline = cogl_pipeline_copy (texture_template_pipeline);
GError *error = NULL; GError *error = NULL;
if (!cogl_material_set_layer_combine (pick_material, 0, if (!cogl_pipeline_set_layer_combine (pick_pipeline, 0,
"RGBA = " "RGBA = "
" MODULATE (CONSTANT, TEXTURE[A])", " MODULATE (CONSTANT, TEXTURE[A])",
&error)) &error))
{ {
if (!priv->seen_create_pick_material_warning) if (!priv->seen_create_pick_pipeline_warning)
g_warning ("Error setting up texture combine for shaped " g_warning ("Error setting up texture combine for shaped "
"texture picking: %s", error->message); "texture picking: %s", error->message);
priv->seen_create_pick_material_warning = TRUE; priv->seen_create_pick_pipeline_warning = TRUE;
g_error_free (error); g_error_free (error);
cogl_handle_unref (pick_material); cogl_object_unref (pick_pipeline);
return COGL_INVALID_HANDLE; return NULL;
} }
cogl_material_set_blend (pick_material, cogl_pipeline_set_blend (pick_pipeline,
"RGBA = ADD (SRC_COLOR[RGBA], 0)", "RGBA = ADD (SRC_COLOR[RGBA], 0)",
NULL); NULL);
cogl_material_set_alpha_test_function (pick_material, cogl_pipeline_set_alpha_test_function (pick_pipeline,
COGL_MATERIAL_ALPHA_FUNC_EQUAL, COGL_PIPELINE_ALPHA_FUNC_EQUAL,
1.0); 1.0);
return pick_material; return pick_pipeline;
} }
static void static void
@ -629,10 +640,10 @@ clutter_texture_pick (ClutterActor *self,
{ {
CoglColor pick_color; CoglColor pick_color;
if (priv->pick_material == COGL_INVALID_HANDLE) if (priv->pick_pipeline == NULL)
priv->pick_material = create_pick_material (self); priv->pick_pipeline = create_pick_pipeline (self);
if (priv->pick_material == COGL_INVALID_HANDLE) if (priv->pick_pipeline == NULL)
{ {
priv->pick_with_alpha_supported = FALSE; priv->pick_with_alpha_supported = FALSE;
CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->pick (self, CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->pick (self,
@ -640,7 +651,7 @@ clutter_texture_pick (ClutterActor *self,
return; return;
} }
if (priv->fbo_handle != COGL_INVALID_HANDLE) if (priv->fbo_handle != NULL)
update_fbo (self); update_fbo (self);
cogl_color_init_from_4ub (&pick_color, cogl_color_init_from_4ub (&pick_color,
@ -648,11 +659,11 @@ clutter_texture_pick (ClutterActor *self,
color->green, color->green,
color->blue, color->blue,
0xff); 0xff);
cogl_material_set_layer_combine_constant (priv->pick_material, cogl_pipeline_set_layer_combine_constant (priv->pick_pipeline,
0, &pick_color); 0, &pick_color);
cogl_material_set_layer (priv->pick_material, 0, cogl_pipeline_set_layer_texture (priv->pick_pipeline, 0,
clutter_texture_get_cogl_texture (texture)); clutter_texture_get_cogl_texture (texture));
cogl_set_source (priv->pick_material); cogl_set_source (priv->pick_pipeline);
gen_texcoords_and_draw_cogl_rectangle (self); gen_texcoords_and_draw_cogl_rectangle (self);
} }
else else
@ -671,15 +682,15 @@ clutter_texture_paint (ClutterActor *self)
clutter_actor_get_name (self) ? clutter_actor_get_name (self) clutter_actor_get_name (self) ? clutter_actor_get_name (self)
: "unknown"); : "unknown");
if (priv->fbo_handle != COGL_INVALID_HANDLE) if (priv->fbo_handle != NULL)
update_fbo (self); update_fbo (self);
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_set_source (priv->pipeline);
gen_texcoords_and_draw_cogl_rectangle (self); gen_texcoords_and_draw_cogl_rectangle (self);
} }
@ -692,7 +703,7 @@ clutter_texture_get_paint_volume (ClutterActor *self,
priv = CLUTTER_TEXTURE (self)->priv; priv = CLUTTER_TEXTURE (self)->priv;
if (priv->material == NULL) if (priv->pipeline == NULL)
return FALSE; return FALSE;
if (priv->image_width == 0 || priv->image_height == 0) if (priv->image_width == 0 || priv->image_height == 0)
@ -713,7 +724,7 @@ clutter_texture_async_data_free (ClutterTextureAsyncData *data)
g_free (data->load_filename); g_free (data->load_filename);
if (data->load_bitmap != NULL) if (data->load_bitmap != NULL)
cogl_handle_unref (data->load_bitmap); cogl_object_unref (data->load_bitmap);
if (data->load_error != NULL) if (data->load_error != NULL)
g_error_free (data->load_error); g_error_free (data->load_error);
@ -771,16 +782,16 @@ clutter_texture_dispose (GObject *object)
clutter_texture_async_load_cancel (texture); clutter_texture_async_load_cancel (texture);
if (priv->material != COGL_INVALID_HANDLE) if (priv->pipeline != NULL)
{ {
cogl_handle_unref (priv->material); cogl_object_unref (priv->pipeline);
priv->material = COGL_INVALID_HANDLE; priv->pipeline = NULL;
} }
if (priv->pick_material != COGL_INVALID_HANDLE) if (priv->pick_pipeline != NULL)
{ {
cogl_handle_unref (priv->pick_material); cogl_object_unref (priv->pick_pipeline);
priv->pick_material = COGL_INVALID_HANDLE; priv->pick_pipeline = NULL;
} }
G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object); G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object);
@ -1272,26 +1283,28 @@ clutter_texture_init (ClutterTexture *self)
priv->repeat_x = FALSE; priv->repeat_x = FALSE;
priv->repeat_y = FALSE; priv->repeat_y = FALSE;
priv->sync_actor_size = TRUE; priv->sync_actor_size = TRUE;
priv->fbo_handle = COGL_INVALID_HANDLE; priv->fbo_handle = NULL;
priv->pick_material = COGL_INVALID_HANDLE; priv->pick_pipeline = NULL;
priv->keep_aspect_ratio = FALSE; priv->keep_aspect_ratio = FALSE;
priv->pick_with_alpha = FALSE; priv->pick_with_alpha = FALSE;
priv->pick_with_alpha_supported = TRUE; priv->pick_with_alpha_supported = TRUE;
priv->seen_create_pick_material_warning = FALSE; priv->seen_create_pick_pipeline_warning = FALSE;
if (G_UNLIKELY (texture_template_material == NULL)) if (G_UNLIKELY (texture_template_pipeline == NULL))
{ {
CoglPipeline *pipeline; CoglPipeline *pipeline;
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
texture_template_material = cogl_material_new (); texture_template_pipeline = cogl_pipeline_new (ctx);
pipeline = COGL_PIPELINE (texture_template_material); pipeline = COGL_PIPELINE (texture_template_pipeline);
cogl_pipeline_set_layer_null_texture (pipeline, cogl_pipeline_set_layer_null_texture (pipeline,
0, /* layer_index */ 0, /* layer_index */
COGL_TEXTURE_TYPE_2D); COGL_TEXTURE_TYPE_2D);
} }
g_assert (texture_template_material != NULL); g_assert (texture_template_pipeline != NULL);
priv->material = cogl_material_copy (texture_template_material); priv->pipeline = cogl_pipeline_copy (texture_template_pipeline);
} }
/** /**
@ -1310,9 +1323,9 @@ clutter_texture_init (ClutterTexture *self)
CoglHandle CoglHandle
clutter_texture_get_cogl_material (ClutterTexture *texture) clutter_texture_get_cogl_material (ClutterTexture *texture)
{ {
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), COGL_INVALID_HANDLE); g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), NULL);
return texture->priv->material; return texture->priv->pipeline;
} }
/** /**
@ -1336,25 +1349,57 @@ void
clutter_texture_set_cogl_material (ClutterTexture *texture, clutter_texture_set_cogl_material (ClutterTexture *texture,
CoglHandle cogl_material) CoglHandle cogl_material)
{ {
CoglPipeline *cogl_pipeline = cogl_material;
CoglHandle cogl_texture; CoglHandle cogl_texture;
g_return_if_fail (CLUTTER_IS_TEXTURE (texture)); g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
cogl_handle_ref (cogl_material); cogl_object_ref (cogl_pipeline);
if (texture->priv->material) if (texture->priv->pipeline)
cogl_handle_unref (texture->priv->material); cogl_object_unref (texture->priv->pipeline);
texture->priv->material = cogl_material; texture->priv->pipeline = cogl_pipeline;
/* XXX: We are re-asserting the first layer of the new material to ensure the /* XXX: We are re-asserting the first layer of the new pipeline to ensure the
* priv state is in sync with the contents of the material. */ * priv state is in sync with the contents of the pipeline. */
cogl_texture = clutter_texture_get_cogl_texture (texture); cogl_texture = clutter_texture_get_cogl_texture (texture);
clutter_texture_set_cogl_texture (texture, cogl_texture); clutter_texture_set_cogl_texture (texture, cogl_texture);
/* XXX: If we add support for more material layers, this will need /* XXX: If we add support for more pipeline layers, this will need
* extending */ * extending */
} }
typedef struct _GetLayerState
{
gboolean has_layer;
int first_layer;
} GetLayerState;
static gboolean
layer_cb (CoglPipeline *pipeline, int layer, void *user_data)
{
GetLayerState *state = user_data;
state->has_layer = TRUE;
state->first_layer = layer;
/* We only care about the first layer. */
return FALSE;
}
static gboolean
get_first_layer_index (CoglPipeline *pipeline, int *layer_index)
{
GetLayerState state = { FALSE };
cogl_pipeline_foreach_layer (pipeline,
layer_cb,
&state);
if (state.has_layer)
*layer_index = state.first_layer;
return state.has_layer;
}
/** /**
* clutter_texture_get_cogl_texture: * clutter_texture_get_cogl_texture:
* @texture: A #ClutterTexture * @texture: A #ClutterTexture
@ -1377,27 +1422,16 @@ CoglHandle
clutter_texture_get_cogl_texture (ClutterTexture *texture) clutter_texture_get_cogl_texture (ClutterTexture *texture)
{ {
ClutterTexturePrivate *priv; ClutterTexturePrivate *priv;
CoglMaterialLayerType layer_type; int layer_index;
const GList *layers;
int n_layers;
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), COGL_INVALID_HANDLE); g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), NULL);
priv = texture->priv; priv = texture->priv;
layers = cogl_material_get_layers (priv->material); if (get_first_layer_index (priv->pipeline, &layer_index))
if (layers == NULL) return cogl_pipeline_get_layer_texture (priv->pipeline, layer_index);
return COGL_INVALID_HANDLE; else
return NULL;
n_layers = g_list_length ((GList *)layers);
if (n_layers == 0)
return COGL_INVALID_HANDLE;
layer_type = cogl_material_layer_get_type (layers->data);
if (layer_type != COGL_MATERIAL_LAYER_TYPE_TEXTURE)
return COGL_INVALID_HANDLE;
return cogl_material_layer_get_texture (layers->data);
} }
/** /**
@ -1434,7 +1468,7 @@ clutter_texture_set_cogl_texture (ClutterTexture *texture,
/* Reference the new texture now in case it is the same one we are /* Reference the new texture now in case it is the same one we are
already using */ already using */
cogl_handle_ref (cogl_tex); cogl_object_ref (cogl_tex);
/* Remove FBO if exisiting */ /* Remove FBO if exisiting */
if (priv->fbo_source) if (priv->fbo_source)
@ -1444,15 +1478,15 @@ clutter_texture_set_cogl_texture (ClutterTexture *texture,
texture_free_gl_resources (texture); texture_free_gl_resources (texture);
/* Use the new texture */ /* Use the new texture */
if (priv->material == NULL) if (priv->pipeline == NULL)
priv->material = cogl_material_copy (texture_template_material); priv->pipeline = cogl_pipeline_copy (texture_template_pipeline);
g_assert (priv->material != NULL); g_assert (priv->pipeline != NULL);
cogl_material_set_layer (priv->material, 0, cogl_tex); cogl_pipeline_set_layer_texture (priv->pipeline, 0, cogl_tex);
/* The material now holds a reference to the texture so we can /* The pipeline now holds a reference to the texture so we can
safely release the reference we claimed above */ safely release the reference we claimed above */
cogl_handle_unref (cogl_tex); cogl_object_unref (cogl_tex);
size_changed = (width != priv->image_width || height != priv->image_height); size_changed = (width != priv->image_width || height != priv->image_height);
priv->image_width = width; priv->image_width = width;
@ -1515,7 +1549,7 @@ clutter_texture_set_from_data (ClutterTexture *texture,
GError **error) GError **error)
{ {
ClutterTexturePrivate *priv = texture->priv; ClutterTexturePrivate *priv = texture->priv;
CoglHandle new_texture = COGL_INVALID_HANDLE; CoglHandle new_texture = NULL;
CoglTextureFlags flags = COGL_TEXTURE_NONE; CoglTextureFlags flags = COGL_TEXTURE_NONE;
if (priv->no_slice) if (priv->no_slice)
@ -1531,7 +1565,7 @@ clutter_texture_set_from_data (ClutterTexture *texture,
rowstride, rowstride,
data); data);
if (G_UNLIKELY (new_texture == COGL_INVALID_HANDLE)) if (G_UNLIKELY (new_texture == NULL))
{ {
GError *inner_error = NULL; GError *inner_error = NULL;
@ -1554,7 +1588,7 @@ clutter_texture_set_from_data (ClutterTexture *texture,
clutter_texture_set_cogl_texture (texture, new_texture); clutter_texture_set_cogl_texture (texture, new_texture);
cogl_handle_unref (new_texture); cogl_object_unref (new_texture);
g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, NULL); g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, NULL);
@ -1752,7 +1786,7 @@ clutter_texture_async_load_complete (ClutterTexture *self,
cogl_texture_get_height (handle)); cogl_texture_get_height (handle));
} }
cogl_handle_unref (handle); cogl_object_unref (handle);
} }
g_signal_emit (self, texture_signals[LOAD_FINISHED], 0, error); g_signal_emit (self, texture_signals[LOAD_FINISHED], 0, error);
@ -2000,7 +2034,7 @@ clutter_texture_set_from_file (ClutterTexture *texture,
GError **error) GError **error)
{ {
ClutterTexturePrivate *priv; ClutterTexturePrivate *priv;
CoglHandle new_texture = COGL_INVALID_HANDLE; CoglHandle new_texture = NULL;
GError *internal_error = NULL; GError *internal_error = NULL;
CoglTextureFlags flags = COGL_TEXTURE_NONE; CoglTextureFlags flags = COGL_TEXTURE_NONE;
@ -2020,7 +2054,7 @@ clutter_texture_set_from_file (ClutterTexture *texture,
&internal_error); &internal_error);
/* If COGL didn't give an error then make one up */ /* If COGL didn't give an error then make one up */
if (internal_error == NULL && new_texture == COGL_INVALID_HANDLE) if (internal_error == NULL && new_texture == NULL)
{ {
g_set_error (&internal_error, CLUTTER_TEXTURE_ERROR, g_set_error (&internal_error, CLUTTER_TEXTURE_ERROR,
CLUTTER_TEXTURE_ERROR_BAD_FORMAT, CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
@ -2042,7 +2076,7 @@ clutter_texture_set_from_file (ClutterTexture *texture,
clutter_texture_set_cogl_texture (texture, new_texture); clutter_texture_set_cogl_texture (texture, new_texture);
cogl_handle_unref (new_texture); cogl_object_unref (new_texture);
g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, NULL); g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, NULL);
@ -2084,12 +2118,12 @@ clutter_texture_set_filter_quality (ClutterTexture *texture,
{ {
gint min_filter, mag_filter; gint min_filter, mag_filter;
min_filter = mag_filter = COGL_MATERIAL_FILTER_LINEAR; min_filter = mag_filter = COGL_PIPELINE_FILTER_LINEAR;
clutter_texture_quality_to_filters (filter_quality, clutter_texture_quality_to_filters (filter_quality,
&min_filter, &min_filter,
&mag_filter); &mag_filter);
cogl_material_set_layer_filters (priv->material, 0, cogl_pipeline_set_layer_filters (priv->pipeline, 0,
min_filter, mag_filter); min_filter, mag_filter);
clutter_actor_queue_redraw (CLUTTER_ACTOR (texture)); clutter_actor_queue_redraw (CLUTTER_ACTOR (texture));
@ -2112,21 +2146,24 @@ ClutterTextureQuality
clutter_texture_get_filter_quality (ClutterTexture *texture) clutter_texture_get_filter_quality (ClutterTexture *texture)
{ {
ClutterTexturePrivate *priv; ClutterTexturePrivate *priv;
const GList *layers; int layer_index;
CoglMaterialFilter min_filter, mag_filter; CoglPipelineFilter min_filter, mag_filter;
int i; int i;
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), 0); g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), 0);
priv = texture->priv; priv = texture->priv;
layers = cogl_material_get_layers (priv->material); if (get_first_layer_index (priv->pipeline, &layer_index))
if (layers == NULL) {
min_filter = cogl_pipeline_get_layer_min_filter (priv->pipeline,
layer_index);
mag_filter = cogl_pipeline_get_layer_mag_filter (priv->pipeline,
layer_index);
}
else
return CLUTTER_TEXTURE_QUALITY_MEDIUM; return CLUTTER_TEXTURE_QUALITY_MEDIUM;
min_filter = cogl_material_layer_get_min_filter (layers->data);
mag_filter = cogl_material_layer_get_mag_filter (layers->data);
for (i = 0; i < G_N_ELEMENTS (clutter_texture_quality_filters); i++) for (i = 0; i < G_N_ELEMENTS (clutter_texture_quality_filters); i++)
if (clutter_texture_quality_filters[i].min_filter == min_filter if (clutter_texture_quality_filters[i].min_filter == min_filter
&& clutter_texture_quality_filters[i].mag_filter == mag_filter) && clutter_texture_quality_filters[i].mag_filter == mag_filter)
@ -2160,7 +2197,7 @@ clutter_texture_get_max_tile_waste (ClutterTexture *texture)
cogl_texture = clutter_texture_get_cogl_texture (texture); cogl_texture = clutter_texture_get_cogl_texture (texture);
if (cogl_texture == COGL_INVALID_HANDLE) if (cogl_texture == NULL)
return priv->no_slice ? -1 : COGL_TEXTURE_MAX_WASTE; return priv->no_slice ? -1 : COGL_TEXTURE_MAX_WASTE;
else else
return cogl_texture_get_max_waste (cogl_texture); return cogl_texture_get_max_waste (cogl_texture);
@ -2288,7 +2325,7 @@ clutter_texture_set_area_from_rgb_data (ClutterTexture *texture,
* up having a texture even if we couldn't realize yet. * up having a texture even if we couldn't realize yet.
*/ */
cogl_texture = clutter_texture_get_cogl_texture (texture); cogl_texture = clutter_texture_get_cogl_texture (texture);
if (cogl_texture == COGL_INVALID_HANDLE) if (cogl_texture == NULL)
{ {
g_warning ("Failed to realize actor '%s'", g_warning ("Failed to realize actor '%s'",
_clutter_actor_get_debug_name (CLUTTER_ACTOR (texture))); _clutter_actor_get_debug_name (CLUTTER_ACTOR (texture)));
@ -2355,8 +2392,8 @@ on_fbo_source_size_change (GObject *object,
CoglHandle tex; CoglHandle tex;
/* tear down the FBO */ /* tear down the FBO */
if (priv->fbo_handle != COGL_INVALID_HANDLE) if (priv->fbo_handle != NULL)
cogl_handle_unref (priv->fbo_handle); cogl_object_unref (priv->fbo_handle);
texture_free_gl_resources (texture); texture_free_gl_resources (texture);
@ -2370,15 +2407,15 @@ on_fbo_source_size_change (GObject *object,
flags, flags,
COGL_PIXEL_FORMAT_RGBA_8888_PRE); COGL_PIXEL_FORMAT_RGBA_8888_PRE);
cogl_material_set_layer (priv->material, 0, tex); cogl_pipeline_set_layer_texture (priv->pipeline, 0, tex);
priv->fbo_handle = cogl_offscreen_new_to_texture (tex); priv->fbo_handle = cogl_offscreen_new_to_texture (tex);
/* The material now has a reference to the texture so it will /* The pipeline now has a reference to the texture so it will
stick around */ stick around */
cogl_handle_unref (tex); cogl_object_unref (tex);
if (priv->fbo_handle == COGL_INVALID_HANDLE) if (priv->fbo_handle == NULL)
{ {
g_warning ("%s: Offscreen texture creation failed", G_STRLOC); g_warning ("%s: Offscreen texture creation failed", G_STRLOC);
return; return;
@ -2652,10 +2689,10 @@ texture_fbo_free_resources (ClutterTexture *texture)
priv->fbo_source = NULL; priv->fbo_source = NULL;
} }
if (priv->fbo_handle != COGL_INVALID_HANDLE) if (priv->fbo_handle != NULL)
{ {
cogl_handle_unref (priv->fbo_handle); cogl_object_unref (priv->fbo_handle);
priv->fbo_handle = COGL_INVALID_HANDLE; priv->fbo_handle = NULL;
} }
} }
@ -2809,7 +2846,7 @@ clutter_texture_get_pixel_format (ClutterTexture *texture)
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), COGL_PIXEL_FORMAT_ANY); g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), COGL_PIXEL_FORMAT_ANY);
cogl_texture = clutter_texture_get_cogl_texture (texture); cogl_texture = clutter_texture_get_cogl_texture (texture);
if (cogl_texture == COGL_INVALID_HANDLE) if (cogl_texture == NULL)
return COGL_PIXEL_FORMAT_ANY; return COGL_PIXEL_FORMAT_ANY;
return cogl_texture_get_format (cogl_texture); return cogl_texture_get_format (cogl_texture);
@ -3014,13 +3051,13 @@ clutter_texture_set_pick_with_alpha (ClutterTexture *texture,
if (priv->pick_with_alpha == pick_with_alpha) if (priv->pick_with_alpha == pick_with_alpha)
return; return;
if (!pick_with_alpha && priv->pick_material != COGL_INVALID_HANDLE) if (!pick_with_alpha && priv->pick_pipeline != NULL)
{ {
cogl_handle_unref (priv->pick_material); cogl_object_unref (priv->pick_pipeline);
priv->pick_material = COGL_INVALID_HANDLE; priv->pick_pipeline = NULL;
} }
/* NB: the pick material is created lazily when we first pick */ /* NB: the pick pipeline is created lazily when we first pick */
priv->pick_with_alpha = pick_with_alpha; priv->pick_with_alpha = pick_with_alpha;
/* NB: actors are expected to call clutter_actor_queue_redraw when /* NB: actors are expected to call clutter_actor_queue_redraw when

View File

@ -31,6 +31,10 @@
#define CLUTTER_DISABLE_DEPRECATION_WARNINGS #define CLUTTER_DISABLE_DEPRECATION_WARNINGS
/* This file depends on the cogl-fixed api which isn't exposed when
* COGL_ENABLE_EXPERIMENTAL_2_0_API is defined...
*/
#undef COGL_ENABLE_EXPERIMENTAL_2_0_API
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <glib-object.h> #include <glib-object.h>

View File

@ -57,6 +57,10 @@
#include <glib.h> #include <glib.h>
#include <glib/gi18n-lib.h> #include <glib/gi18n-lib.h>
/* This file depends on the cogl 1.x api which isn't exposed when
* COGL_ENABLE_EXPERIMENTAL_2_0_API is defined...
*/
#undef COGL_ENABLE_EXPERIMENTAL_2_0_API
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include "clutter-shader.h" #include "clutter-shader.h"

View File

@ -801,13 +801,13 @@ void
clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture, clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
Pixmap pixmap) Pixmap pixmap)
{ {
Window root; Window root;
int x, y; int x, y;
unsigned int width, height, border_width, depth; unsigned int width, height, border_width, depth;
Status status = 0; Status status = 0;
gboolean new_pixmap = FALSE, new_pixmap_width = FALSE; gboolean new_pixmap = FALSE, new_pixmap_width = FALSE;
gboolean new_pixmap_height = FALSE, new_pixmap_depth = FALSE; gboolean new_pixmap_height = FALSE, new_pixmap_depth = FALSE;
CoglHandle material; CoglPipeline *pipeline;
ClutterX11TexturePixmapPrivate *priv; ClutterX11TexturePixmapPrivate *priv;
@ -817,9 +817,10 @@ clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
/* Get rid of the existing Cogl texture early because it may try to /* Get rid of the existing Cogl texture early because it may try to
use the pixmap which we might destroy */ use the pixmap which we might destroy */
material = clutter_texture_get_cogl_material (CLUTTER_TEXTURE (texture)); pipeline = (CoglPipeline *)
if (material) clutter_texture_get_cogl_material (CLUTTER_TEXTURE (texture));
cogl_material_set_layer (material, 0, COGL_INVALID_HANDLE); if (pipeline)
cogl_pipeline_set_layer_texture (pipeline, 0, NULL);
if (pixmap != None) if (pixmap != None)
{ {

View File

@ -1,5 +1,13 @@
#include "config.h" #include "config.h"
/* XXX: we currently include config.h above as a hack so we can
* determine if we are running with GLES2 or not but since Clutter
* uses the experimental Cogl api that will also define
* COGL_ENABLE_EXPERIMENTAL_2_0_API. The cogl_material_ api isn't
* exposed if COGL_ENABLE_EXPERIMENTAL_2_0_API is defined though so we
* undef it before cogl.h is included */
#undef COGL_ENABLE_EXPERIMENTAL_2_0_API
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <string.h> #include <string.h>