diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index e87bfb7ec..b491dee8f 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -99,9 +99,10 @@ struct _ClutterTexturePrivate guint repeat_y : 1; guint in_dispose : 1; guint keep_aspect_ratio : 1; - guint load_async : 1; guint load_size_async : 1; guint load_data_async : 1; + guint load_async_set : 1; /* used to make load_async + possible */ ClutterTextureAsyncData *async_data; }; @@ -840,13 +841,26 @@ clutter_texture_set_property (GObject *object, priv->keep_aspect_ratio = g_value_get_boolean (value); break; case PROP_LOAD_ASYNC: - priv->load_async = g_value_get_boolean (value); + if (g_value_get_boolean (value)) + { + priv->load_data_async = TRUE; + priv->load_async_set = TRUE; + priv->load_size_async = TRUE; + } break; case PROP_LOAD_DATA_ASYNC: - priv->load_data_async = g_value_get_boolean (value); + if (g_value_get_boolean (value)) + { + priv->load_async_set = TRUE; + priv->load_data_async = TRUE; + } break; case PROP_LOAD_SIZE_ASYNC: - priv->load_size_async = g_value_get_boolean (value); + if (g_value_get_boolean (value)) + { + priv->load_async_set = TRUE; + priv->load_size_async = TRUE; + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -903,9 +917,6 @@ clutter_texture_get_property (GObject *object, case PROP_KEEP_ASPECT_RATIO: g_value_set_boolean (value, priv->keep_aspect_ratio); break; - case PROP_LOAD_ASYNC: - g_value_set_boolean (value, priv->load_async); - break; case PROP_LOAD_DATA_ASYNC: g_value_set_boolean (value, priv->load_data_async); break; @@ -1047,26 +1058,10 @@ clutter_texture_class_init (ClutterTextureClass *klass) FALSE, CLUTTER_PARAM_READWRITE)); - /** - * ClutterTexture:load-size-sync: - * - * When set to TRUE clutter will not block loading the size initially, - * when used in this manner the size of the actor will change (and the - * load-size-complete signal will be fired when the size is available). - * - * Since: 1.0 - */ - g_object_class_install_property - (gobject_class, PROP_LOAD_SIZE_ASYNC, - g_param_spec_boolean ("load-size-async", - "Load size asynchronously", - "If set to TRUE clutter will not block until it has " - "loaded the size of the file.", - FALSE, - CLUTTER_PARAM_READWRITE)); + /** - * ClutterTexture:load-async: + * ClutterTexture:load-data-async: * * Tries to load a texture from a filename by using a local thread * to perform the read operations. Threading is only enabled if @@ -1080,20 +1075,39 @@ clutter_texture_class_init (ClutterTextureClass *klass) * Since: 1.0 */ g_object_class_install_property - (gobject_class, PROP_LOAD_ASYNC, + (gobject_class, PROP_LOAD_DATA_ASYNC, g_param_spec_boolean ("load-data-async", "Load data asynchronously", "Load files inside a thread to avoid blocking when " "loading images.", FALSE, - CLUTTER_PARAM_READWRITE)); + CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /** + * ClutterTexture:load-size-sync: + * + * When set to TRUE clutter will not block loading the size initially, + * when used in this manner the size of the texture will initially be + * 0x0 when the size is available a "size-change" signal will be emitted. + * + * Since: 1.0 + */ + g_object_class_install_property + (gobject_class, PROP_LOAD_SIZE_ASYNC, + g_param_spec_boolean ("load-size-async", + "Load size asynchronously", + "If set to TRUE clutter will not block until it has " + "loaded the size of the file.", + FALSE, + CLUTTER_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /** * ClutterTexture:load-async: * * Load texture fully asynchronosuly, loading both the size and data - * in a separate thread. + * in a separate thread. Setting this to TRUE is equivalent of setting + * both load-data-async and load-size-async. * * Since: 1.0 */ @@ -1104,7 +1118,7 @@ clutter_texture_class_init (ClutterTextureClass *klass) "Load files inside a thread to avoid blocking when " "loading images.", FALSE, - CLUTTER_PARAM_WRITABLE)); + CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); /** * ClutterTexture::size-change: @@ -1690,9 +1704,11 @@ clutter_texture_async_load_complete (ClutterTexture *self, waste, flags, COGL_PIXEL_FORMAT_ANY); clutter_texture_set_cogl_texture (self, handle); - /*clutter_actor_set_size (self, cogl_texture_get_width (handle), - cogl_texture_get_height (handle));*/ - cogl_texture_unref (handle); + if (priv->load_size_async) + { + g_signal_emit (self, texture_signals[SIZE_CHANGE], 0, cogl_texture_get_width(handle), cogl_texture_get_height (handle)); + clutter_actor_queue_redraw (self); + } } g_signal_emit (self, texture_signals[LOAD_FINISHED], 0, error); @@ -1760,7 +1776,7 @@ clutter_texture_thread_func (gpointer user_data, gpointer pool_data) * idle handler now without the possibility of calling the * callback after it is aborted */ data->load_idle = - clutter_threads_add_idle (clutter_texture_thread_idle_func, data); + clutter_threads_add_idle_full (G_PRIORITY_LOW, clutter_texture_thread_idle_func, data, NULL); g_mutex_unlock (data->mutex); } @@ -1830,6 +1846,8 @@ clutter_texture_async_load (ClutterTexture *self, if (priv->load_size_async) { res = TRUE; + width = 0; + height = 0; } else { @@ -1920,7 +1938,7 @@ clutter_texture_set_from_file (ClutterTexture *texture, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (priv->load_async) + if (priv->load_data_async) return clutter_texture_async_load (texture, filename, error); if (!priv->no_slice) diff --git a/tests/interactive/test-texture-async.c b/tests/interactive/test-texture-async.c index 9983bac57..b6d29b049 100644 --- a/tests/interactive/test-texture-async.c +++ b/tests/interactive/test-texture-async.c @@ -2,42 +2,40 @@ #include #include -G_MODULE_EXPORT gint -test_texture_async_main (int argc, char *argv[]) + +static void size_change_cb (ClutterTexture *texture, + gint width, + gint height, + gpointer user_data) +{ + guint w,h; + clutter_actor_set_size (user_data, width, height); +} + + const gchar *path = "redhand.png"; + +static gboolean task (gpointer foo) { ClutterTimeline *timeline; ClutterAlpha *alpha; ClutterBehaviour *depth_behavior; - ClutterActor *stage; ClutterActor *image[4]; - ClutterColor stage_color = { 0x12, 0x34, 0x56, 0xff }; - GError *error; - const gchar *path = "redhand.png"; + ClutterActor *clone[4]; + ClutterActor *stage; gint i; - clutter_init (&argc, &argv); - stage = clutter_stage_get_default (); - clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); - clutter_stage_set_use_fog (CLUTTER_STAGE (stage), TRUE); - clutter_stage_set_fog (CLUTTER_STAGE (stage), 1.0, 10, -50); - - g_signal_connect (stage, - "button-press-event", G_CALLBACK (clutter_main_quit), - NULL); - - error = NULL; - path = argv[1]?argv[1]:"redhand.png"; - - if (!argv[1]) - g_print ("Hint: the redhand.png isn't a good test image for this test.\n" - "This test can take any clutter loadable image as an argument\n"); - +#if 0 for (i=0;i<4;i++) image[i] = g_object_new (CLUTTER_TYPE_TEXTURE, "filename", path, + "load-async", TRUE, + NULL); +#else + /*for (i=0;i<4;i++)*/ + image[0] = g_object_new (CLUTTER_TYPE_TEXTURE, + "filename", path, NULL); - /* image[1] = g_object_new (CLUTTER_TYPE_TEXTURE, "filename", path, "load-async", TRUE, @@ -46,26 +44,69 @@ test_texture_async_main (int argc, char *argv[]) "filename", path, "load-data-async", TRUE, NULL); + + /* this is a synonym of image[1], is image[1] really needed? (or is this needed? */ + image[3] = g_object_new (CLUTTER_TYPE_TEXTURE, "filename", path, "load-data-async", TRUE, "load-size-async", TRUE, - NULL);*/ + NULL); +#endif + for (i=0;i<4;i++) + { + clutter_container_add (CLUTTER_CONTAINER (stage), image[i], NULL); + } + for (i=0;i<4;i++) + { + clutter_actor_set_position (image[i], 50+i*100, 0+i*50); + clone[i]=clutter_clone_new (image[i]); + g_signal_connect (image[i], "size-change", size_change_cb, clone[i]); + clutter_container_add (CLUTTER_CONTAINER (stage), clone[i], NULL); + clutter_actor_set_position (clone[i], 50+i*100, 150+i*50+100); + } /* center the image */ - for (i=0;i<4;i++) + for (i=0; i<4; i++) { - clutter_actor_set_position (image[i], 50+i*100, 50+i*50); - clutter_container_add (CLUTTER_CONTAINER (stage), image[i], NULL); timeline = clutter_timeline_new (60*5, 60); alpha = clutter_alpha_new_full (timeline, CLUTTER_LINEAR); depth_behavior = clutter_behaviour_depth_new (alpha, -2500, 0); clutter_behaviour_apply (depth_behavior, image[i]); clutter_timeline_start (timeline); } - + return FALSE; +} + + +G_MODULE_EXPORT gint +test_texture_async_main (int argc, char *argv[]) +{ + ClutterActor *stage; + ClutterColor stage_color = { 0x12, 0x34, 0x56, 0xff }; + GError *error; + + clutter_init (&argc, &argv); + + stage = clutter_stage_get_default (); + clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); + clutter_actor_show (stage); + g_signal_connect (stage, + "button-press-event", G_CALLBACK (clutter_main_quit), + NULL); + + error = NULL; + + if (!argv[1]) + g_print ("Hint: the redhand.png isn't a good test image for this test.\n" + "This test can take any clutter loadable image as an argument\n"); + + path = argv[1]?argv[1]:"redhand.png"; + + + g_timeout_add (500, task, NULL); clutter_main ();