1
0
Fork 0
mutter-performance-source/tests/test-fbo.c
Neil Roberts 167475e422 Bug 1015 - Cloning unparented actors with FBOs doesn't work with
new layout code

	* clutter/clutter-texture.c (clutter_texture_new_from_actor): Now
	parents the source actor if it doesn't already have a parent so
	that it will get an allocation during layout.

	* tests/test-fbo.c: One of the tests tries to ensure that the
	ClutterTexture clone keeps the source actor alive by derefing
	it. However as actors have a floating reference then test-fbo
	doesn't have its own reference once the source is parented so
	unrefing just steals the parent's reference and causes
	badness. The test now claims the floating reference before cloning
	the source so that it can safely be unref'd later.
2008-07-04 10:44:18 +00:00

190 lines
5.4 KiB
C

/*#define TEST_GROUP */
#include <clutter/clutter.h>
#include <errno.h>
#include <stdlib.h>
#include <glib.h>
ClutterActor*
make_source(void)
{
ClutterActor *source, *actor;
GError *error = NULL;
ClutterColor yellow = {0xff, 0xff, 0x00, 0xff};
source = clutter_group_new();
actor = clutter_texture_new_from_file ("redhand.png", &error);
if (!actor)
g_error("pixbuf load failed: %s", error ? error->message : "Unknown");
clutter_group_add (source, actor);
actor = clutter_label_new_with_text ("Sans Bold 50px", "Clutter");
clutter_label_set_color (CLUTTER_LABEL (actor), &yellow);
clutter_actor_set_y (actor, clutter_actor_get_height(source) + 5);
clutter_group_add (source, actor);
return source;
}
ClutterShader*
make_shader(void)
{
ClutterShader *shader;
shader = clutter_shader_new ();
clutter_shader_set_fragment_source (shader,
"uniform float radius ;"
"uniform sampler2D rectTexture;"
"uniform float x_step, y_step;"
""
"void main()"
"{"
" vec4 color = texture2D(rectTexture, gl_TexCoord[0].st);"
" float u;"
" float v;"
" int count = 1;"
" for (u=-radius;u<radius;u++)"
" for (v=-radius;v<radius;v++)"
" {"
" color += texture2D(rectTexture, "
" vec2(gl_TexCoord[0].s + u"
" * 2.0 * x_step,"
" gl_TexCoord[0].t + v"
" * 2.0 * y_step));"
" count ++;"
" }"
""
" gl_FragColor = color / float(count);"
" gl_FragColor = gl_FragColor * gl_Color;"
"}",
-1
);
return shader;
}
gint
main (gint argc,
gchar *argv[])
{
ClutterColor blue = {0x33, 0x44, 0x55, 0xff};
ClutterActor *fbo;
ClutterActor *onscreen_source, *offscreen_source, *trans_source;
ClutterActor *foo_source;
ClutterActor *stage;
ClutterActor *clone;
ClutterShader *shader;
gint padx, pady;
gint fbo_width, fbo_height;
clutter_init (&argc, &argv);
if (clutter_feature_available (CLUTTER_FEATURE_OFFSCREEN) == FALSE)
g_error("This test requires CLUTTER_FEATURE_OFFSCREEN");
stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &blue);
/* Create the first source */
onscreen_source = make_source();
clutter_actor_show_all (onscreen_source);
clutter_group_add (stage, onscreen_source);
/* Basic sizing for alignment */
fbo_width = clutter_actor_get_width (onscreen_source);
fbo_height = clutter_actor_get_height (onscreen_source);
padx = fbo_width + 10;
pady = fbo_height + 10;
clutter_actor_set_size (stage, padx*4, pady*2);
/* Second hand from fbo onscreen */
if ((fbo = clutter_texture_new_from_actor (onscreen_source)) == NULL)
g_error("onscreen fbo creation failed");
clutter_actor_set_position (fbo, padx, 0);
clutter_group_add (stage, fbo);
/* apply a shader to it */
shader = make_shader();
clutter_actor_set_shader (fbo, shader);
clutter_actor_set_shader_param (fbo, "radius", 2.0);
clutter_actor_set_shader_param (fbo, "x_step",
1.0f / clutter_util_next_p2 (fbo_width));
clutter_actor_set_shader_param (fbo, "y_step",
1.0f / clutter_util_next_p2 (fbo_height));
/* Third from cloning the fbo texture */
clone = clutter_clone_texture_new (CLUTTER_TEXTURE(fbo));
clutter_container_add_actor (CLUTTER_CONTAINER (stage), clone);
clutter_actor_set_position (clone, padx*2, 0);
/* Forth - an offscreen source */
offscreen_source = make_source();
clutter_actor_show_all (offscreen_source); /* need to show() offscreen */
if ((fbo = clutter_texture_new_from_actor (offscreen_source)) == NULL)
g_error("offscreen fbo creation failed");
clutter_actor_set_position (fbo, padx*3, 0);
clutter_group_add (stage, fbo);
/* 5th transformed */
trans_source = make_source();
clutter_actor_show_all (trans_source); /* need to show() offscreen */
clutter_actor_set_scale (trans_source, 2.5, 2.5);
if ((fbo = clutter_texture_new_from_actor (trans_source)) == NULL)
g_error("transformed fbo creation failed");
clutter_actor_set_position (fbo, 0, pady);
clutter_group_add (stage, fbo);
/* 6th resized bigger, but after fbo creation */
trans_source = make_source();
clutter_actor_show_all (trans_source); /* need to show() offscreen */
if ((fbo = clutter_texture_new_from_actor (trans_source)) == NULL)
g_error("transformed fbo creation failed");
/* rotate after */
clutter_actor_move_anchor_point_from_gravity (trans_source,
CLUTTER_GRAVITY_CENTER);
clutter_actor_set_rotation (trans_source, CLUTTER_Z_AXIS, 90.0, 0, 0, 0);
clutter_actor_set_position (fbo, padx, pady);
clutter_group_add (stage, fbo);
/* non visual breaks */
foo_source = make_source();
g_object_ref_sink (foo_source);
clutter_actor_show_all (foo_source);
if ((fbo = clutter_texture_new_from_actor (foo_source)) == NULL)
g_error("foo fbo creation failed");
g_object_unref (foo_source); /* fbo should keep it around */
clutter_actor_set_position (fbo, padx*3, pady);
clutter_group_add (stage, fbo);
/* TODO:
* Check realize/unrealize
* get_pixbuf()
* set_rgba on fbo texture.
*/
clutter_actor_show_all (stage);
clutter_main ();
return 0;
}