From: Matthew Allum Date: Tue, 19 Sep 2006 19:27:16 +0000 (+0000) Subject: 2006-09-19 Matthew Allum X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=94c0e54bc3abc8444d817a7ca75333e2dfc58230;p=profile%2Fivi%2Fclutter.git 2006-09-19 Matthew Allum * clutter/clutter-actor.c: (redraw_update_idle), (clutter_actor_queue_redraw): * clutter/clutter-main.c: (clutter_redraw): Remove now uneeded locks ( new gst and texture code makes redundant ) * clutter/clutter-texture.c: * clutter/clutter-texture.h: Redo clutter texture as to not keep a reference to underlying texture. --- diff --git a/ChangeLog b/ChangeLog index 42bd692..d5c44f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2006-09-19 Matthew Allum + + * clutter/clutter-actor.c: (redraw_update_idle), + (clutter_actor_queue_redraw): + * clutter/clutter-main.c: (clutter_redraw): + Remove now uneeded locks + ( new gst and texture code makes redundant ) + + * clutter/clutter-texture.c: + * clutter/clutter-texture.h: + Redo clutter texture as to not keep a reference + to underlying texture. + 2006-09-15 Matthew Allum More fixes from Bastien Nocera (#155): diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index e43eb2b..c12c00f 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -100,16 +100,12 @@ redraw_update_idle (gpointer data) { ClutterMainContext *ctx = CLUTTER_CONTEXT(); - clutter_threads_enter(); - if (ctx->update_idle) { g_source_remove (ctx->update_idle); ctx->update_idle = 0; } - clutter_threads_leave(); - clutter_redraw (); return FALSE; @@ -764,16 +760,12 @@ clutter_actor_queue_redraw (ClutterActor *self) { ClutterMainContext *ctx = CLUTTER_CONTEXT(); - clutter_threads_enter(); - if (!ctx->update_idle) { ctx->update_idle = g_idle_add_full (-100 , /* very high priority */ redraw_update_idle, NULL, NULL); } - - clutter_threads_leave(); } /** diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index c603afe..933397d 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -269,8 +269,6 @@ clutter_redraw (void) CLUTTER_DBG("@@@ Redraw enter @@@"); - clutter_threads_enter (); - if (clutter_want_fps ()) { if (!timer) @@ -319,8 +317,6 @@ clutter_redraw (void) } } - clutter_threads_leave (); - CLUTTER_DBG("@@@ Redraw leave @@@"); } diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index 348e5c2..2262dc4 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -29,6 +29,13 @@ * * #ClutterTexture is a base class for displaying and manipulating pixel * buffer type data. + * + * The #clutter_texture_set_from_data and #clutter_texture_set_pixbuf are + * used to copy image data into texture memory and subsequently realize the + * the texture. Unrealizing/hiding frees image data from texture memory moving + * to main system memory. Re-realizing then performs the opposite operation. + * This process allows basic management of commonly limited available texture + * memory. */ #include "clutter-texture.h" @@ -57,12 +64,13 @@ ClutterTextureTileDimention; struct ClutterTexturePrivate { - GdkPixbuf *pixbuf; gint width, height; GLenum pixel_format; GLenum pixel_type; GLenum target_type; + GdkPixbuf *local_pixbuf; /* non video memory copy */ + gboolean sync_actor_size; gint max_tile_waste; guint filter_quality; @@ -73,7 +81,6 @@ struct ClutterTexturePrivate ClutterTextureTileDimention *x_tiles, *y_tiles; gint n_x_tiles, n_y_tiles; GLuint *tiles; - }; enum @@ -99,9 +106,6 @@ enum static int texture_signals[LAST_SIGNAL] = { 0 }; -static void -init_tiles (ClutterTexture *texture); - static gboolean can_create (int width, int height, @@ -176,7 +180,7 @@ tile_dimension (int to_fill, } static void -init_tiles (ClutterTexture *texture) +texture_init_tiles (ClutterTexture *texture) { ClutterTexturePrivate *priv; gint x_pot, y_pot; @@ -325,33 +329,21 @@ texture_render_to_gl_quad (ClutterTexture *texture, } static void -clutter_texture_unrealize (ClutterActor *actor) +texture_free_gl_resources (ClutterTexture *texture) { - ClutterTexture *texture; ClutterTexturePrivate *priv; - texture = CLUTTER_TEXTURE(actor); priv = texture->priv; - if (priv->tiles == NULL) - return; - - CLUTTER_MARK(); - - clutter_threads_enter (); - - /* Free up texture memory */ - if (!priv->tiled) - glDeleteTextures(1, priv->tiles); - else - glDeleteTextures(priv->n_x_tiles * priv->n_y_tiles, priv->tiles); - - clutter_threads_leave (); - CLUTTER_MARK(); if (priv->tiles) { + if (!priv->tiled) + glDeleteTextures(1, priv->tiles); + else + glDeleteTextures(priv->n_x_tiles * priv->n_y_tiles, priv->tiles); + g_free(priv->tiles); priv->tiles = NULL; } @@ -367,12 +359,16 @@ clutter_texture_unrealize (ClutterActor *actor) g_free(priv->y_tiles); priv->y_tiles = NULL; } - - CLUTTER_DBG("Texture unrealized"); } static void -clutter_texture_sync_pixbuf (ClutterTexture *texture) +texture_upload_data (ClutterTexture *texture, + const guchar *data, + gboolean has_alpha, + gint width, + gint height, + gint rowstride, + gint bpp) { ClutterTexturePrivate *priv; int x, y, i = 0; @@ -380,15 +376,13 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture) priv = texture->priv; - g_return_if_fail (priv->pixbuf != NULL); + g_return_if_fail (data != NULL); CLUTTER_MARK(); if (!priv->tiled) { - /* Single Texture - * - */ + /* Single Texture */ if (!priv->tiles) { priv->tiles = g_new (GLuint, 1); @@ -416,16 +410,14 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture) glTexParameteri(priv->target_type, GL_TEXTURE_MIN_FILTER, priv->filter_quality ? GL_LINEAR : GL_NEAREST); - glPixelStorei (GL_UNPACK_ROW_LENGTH, - gdk_pixbuf_get_width(priv->pixbuf)); - glPixelStorei (GL_UNPACK_ALIGNMENT, - gdk_pixbuf_get_n_channels (priv->pixbuf)); + glPixelStorei (GL_UNPACK_ROW_LENGTH, priv->width); + glPixelStorei (GL_UNPACK_ALIGNMENT, 4); if (create_textures) { gint width, height; - width = priv->width; + width = priv->width; height = priv->height; if (priv->target_type == GL_TEXTURE_2D) /* POT */ @@ -434,11 +426,10 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture) height = clutter_util_next_p2(priv->height); } - /* NOTE: Change to GL_RGB for non alpha textures */ glTexImage2D(priv->target_type, 0, - (gdk_pixbuf_get_n_channels (priv->pixbuf) == 4) ? - GL_RGBA : GL_RGB, + /* (has_alpha) ? GL_RGBA : GL_RGB, */ + GL_RGBA, width, height, 0, @@ -446,14 +437,13 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture) priv->pixel_type, NULL); } - + glTexSubImage2D (priv->target_type, 0, 0, 0, priv->width, priv->height, priv->pixel_format, priv->pixel_type, - gdk_pixbuf_get_pixels(priv->pixbuf)); - + data); return; } @@ -463,7 +453,7 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture) priv->width, priv->height); g_return_if_fail (priv->x_tiles != NULL && priv->y_tiles != NULL); - + if (priv->tiles == NULL) { priv->tiles = g_new (GLuint, priv->n_x_tiles * priv->n_y_tiles); @@ -474,20 +464,16 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture) for (x=0; x < priv->n_x_tiles; x++) for (y=0; y < priv->n_y_tiles; y++) { - GdkPixbuf *pixtmp; - int src_h, src_w; + guchar *tmp; + gint src_h, src_w, dy; src_w = priv->x_tiles[x].size; src_h = priv->y_tiles[y].size; - pixtmp - = gdk_pixbuf_new(GDK_COLORSPACE_RGB, - (gdk_pixbuf_get_n_channels (priv->pixbuf) == 4) ? - TRUE : FALSE, - 8, - priv->x_tiles[x].size, - priv->y_tiles[y].size); - + /* fixme - gslice ? */ + tmp = g_malloc (sizeof(guchar) * priv->x_tiles[x].size + * priv->y_tiles[y].size * bpp); + /* clip */ if (priv->x_tiles[x].pos + src_w > priv->width) { @@ -507,13 +493,13 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture) priv->x_tiles[x].size, priv->y_tiles[y].size); - gdk_pixbuf_copy_area(priv->pixbuf, - priv->x_tiles[x].pos, - priv->y_tiles[y].pos, - src_w, - src_h, - pixtmp, - 0,0); + for (dy = 0; dy < src_h; dy++) + { + memcpy (tmp + (dy * src_w * bpp), + data + ((priv->y_tiles[y].pos + dy) * rowstride) + + (priv->x_tiles[x].pos * bpp), + (src_w * bpp)); + } #ifdef CLUTTER_DUMP_TILES { @@ -544,24 +530,23 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture) priv->filter_quality ? GL_LINEAR : GL_NEAREST); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glPixelStorei (GL_UNPACK_ROW_LENGTH, gdk_pixbuf_get_width(pixtmp)); - glPixelStorei (GL_UNPACK_ALIGNMENT, - gdk_pixbuf_get_n_channels (priv->pixbuf)); + + glPixelStorei (GL_UNPACK_ROW_LENGTH, priv->width); + glPixelStorei (GL_UNPACK_ALIGNMENT, 4); if (create_textures) { glTexImage2D(priv->target_type, 0, - (gdk_pixbuf_get_n_channels (priv->pixbuf) == 4) ? + (bpp == 4) ? GL_RGBA : GL_RGB, priv->x_tiles[x].size, priv->y_tiles[y].size, 0, priv->pixel_format, priv->pixel_type, - gdk_pixbuf_get_pixels(pixtmp)); + tmp); } else { @@ -573,39 +558,72 @@ clutter_texture_sync_pixbuf (ClutterTexture *texture) priv->y_tiles[y].size, priv->pixel_format, priv->pixel_type, - gdk_pixbuf_get_pixels(pixtmp)); + tmp); } - g_object_unref(pixtmp); + g_free(tmp); i++; } } static void +clutter_texture_unrealize (ClutterActor *actor) +{ + ClutterTexture *texture; + ClutterTexturePrivate *priv; + + texture = CLUTTER_TEXTURE(actor); + priv = texture->priv; + + if (priv->tiles == NULL) + return; + + CLUTTER_MARK(); + + /* Move image data from video to main memory + */ + if (priv->local_pixbuf == NULL) + priv->local_pixbuf = clutter_texture_get_pixbuf (texture); + + texture_free_gl_resources (texture); + + CLUTTER_DBG("Texture unrealized"); +} + +static void clutter_texture_realize (ClutterActor *actor) { - ClutterTexture *texture; + ClutterTexture *texture; + ClutterTexturePrivate *priv; texture = CLUTTER_TEXTURE(actor); + priv = texture->priv; CLUTTER_MARK(); - if (texture->priv->pixbuf == NULL) + if (priv->local_pixbuf != NULL) + { + /* Move any local image data we have from unrealization + * back into video memory. + */ + clutter_texture_set_pixbuf (texture, priv->local_pixbuf); + g_object_unref (priv->local_pixbuf); + priv->local_pixbuf = NULL; + } + else { - /* Dont allow realization with no pixbuf */ - CLUTTER_DBG("*** Texture has no pixbuf cannot realize ***"); + /* Dont allow realization with no pixbuf - note set_pixbuf/data + * will set realize flags. + */ + CLUTTER_DBG("*** Texture has no image data cannot realize ***"); CLUTTER_DBG("*** flags %i ***", actor->flags); CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); CLUTTER_DBG("*** flags %i ***", actor->flags); return; } - CLUTTER_DBG("Texture realized"); - - if (texture->priv->tiled) - init_tiles(texture); - clutter_texture_sync_pixbuf (texture); + CLUTTER_DBG("Texture realized"); } static void @@ -653,19 +671,19 @@ clutter_texture_paint (ClutterActor *self) static void clutter_texture_dispose (GObject *object) { - ClutterTexture *self = CLUTTER_TEXTURE(object); + ClutterTexture *texture = CLUTTER_TEXTURE(object); ClutterTexturePrivate *priv; - priv = self->priv; + priv = texture->priv; if (priv != NULL) { - clutter_actor_unrealize (CLUTTER_ACTOR(self)); + texture_free_gl_resources (texture); - if (priv->pixbuf != NULL) + if (priv->local_pixbuf != NULL) { - g_object_unref (priv->pixbuf); - priv->pixbuf = NULL; + g_object_unref (priv->local_pixbuf); + priv->local_pixbuf = NULL; } } @@ -755,7 +773,11 @@ clutter_texture_get_property (GObject *object, switch (prop_id) { case PROP_PIXBUF: - g_value_set_pointer (value, priv->pixbuf); + { + GdkPixbuf *pixb; + pixb = clutter_texture_get_pixbuf (texture); + g_value_set_pointer (value, pixb); + } break; case PROP_USE_TILES: g_value_set_boolean (value, priv->tiled); @@ -930,14 +952,8 @@ clutter_texture_init (ClutterTexture *self) { ClutterTexturePrivate *priv; - priv = g_new0 (ClutterTexturePrivate, 1); + priv = g_new0 (ClutterTexturePrivate, 1); - /* FIXME: It seems defaults via props do not get set - * on all props for sub classes ( ie labels ). - * Should they be ? - * - * Setting them here also to be sure + safe. - */ priv->max_tile_waste = 64; priv->filter_quality = 0; priv->tiled = TRUE; @@ -945,7 +961,6 @@ clutter_texture_init (ClutterTexture *self) priv->pixel_format = GL_RGBA; priv->repeat_x = FALSE; priv->repeat_y = FALSE; - priv->pixbuf = NULL; if (clutter_feature_available (CLUTTER_FEATURE_TEXTURE_RECTANGLE)) { @@ -958,131 +973,250 @@ clutter_texture_init (ClutterTexture *self) self->priv = priv; } +static void +pixbuf_destroy_notify (guchar *pixels, gpointer data) +{ + g_free (pixels); +} + /** * clutter_texture_get_pixbuf: * @texture: A #ClutterTexture * - * Gets the underlying #GdkPixbuf for the #ClutterTexture. + * Gets a #GdkPixbuf representation of the #ClutterTexture data. + * The created #GdkPixbuf is not owned by the texture but the caller. * - * Return value: The underlying #GdkPixbuf + * Return value: A #GdkPixbuf **/ GdkPixbuf* clutter_texture_get_pixbuf (ClutterTexture* texture) { - return texture->priv->pixbuf; + ClutterTexturePrivate *priv; + GdkPixbuf *pixbuf = NULL; + guchar *pixels = NULL; + + priv = texture->priv; + + if (priv->tiles == NULL) + return NULL; + + if (!priv->tiled) + { + pixels = g_malloc (priv->width * priv->height * 4); + + if (pixels == NULL) + return NULL; + + glBindTexture(priv->target_type, priv->tiles[0]); + + glPixelStorei (GL_UNPACK_ROW_LENGTH, priv->width); + glPixelStorei (GL_UNPACK_ALIGNMENT, 4); + + /* read data from gl text and return as pixbuf */ + glGetTexImage (priv->target_type, + 0, + priv->pixel_format, + priv->pixel_type, + (GLvoid*)pixels); + + pixbuf = gdk_pixbuf_new_from_data ((const guchar*)pixels, + GDK_COLORSPACE_RGB, + (priv->pixel_format == GL_RGBA), + 8, + priv->width, + priv->height, + priv->width * 4, + pixbuf_destroy_notify, + NULL); + } + else + { + int x,y,i; + + i = 0; + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, + (priv->pixel_format == GL_RGBA), + 8, + priv->width, + priv->height); + + for (x=0; x < priv->n_x_tiles; x++) + for (y=0; y < priv->n_y_tiles; y++) + { + GdkPixbuf *tmp_pixb; + gint src_h, src_w; + + src_w = priv->x_tiles[x].size; + src_h = priv->y_tiles[y].size; + + pixels = g_malloc (src_w * src_h *4); + + glBindTexture(priv->target_type, priv->tiles[i]); + + glPixelStorei (GL_UNPACK_ROW_LENGTH, src_w); + glPixelStorei (GL_UNPACK_ALIGNMENT, 4); + + glGetTexImage (priv->target_type, + 0, + priv->pixel_format, + priv->pixel_type, + (GLvoid*)pixels); + + tmp_pixb + = gdk_pixbuf_new_from_data ((const guchar*)pixels, + GDK_COLORSPACE_RGB, + (priv->pixel_format == GL_RGBA), + 8, + src_w, + src_h, + src_w * 4, + pixbuf_destroy_notify, + NULL); + + gdk_pixbuf_copy_area (tmp_pixb, + 0, + 0, + src_w, + src_h, + pixbuf, + priv->x_tiles[x].pos, + priv->x_tiles[y].pos); + + g_object_unref (tmp_pixb); + + i++; + } + + } + + return pixbuf; } /** - * clutter_texture_set_pixbuf: + * clutter_texture_set_from_data: * @texture: A #ClutterTexture - * @pixbuf: A #GdkPixbuf + * @data: Image data in RGB type colorspace. + * @has_alpha: Set to TRUE if image data has a alpha channel. + * @width: Width in pixels of image data. + * @height: Height in pixels of image data + * @rowstride: Distance in bytes between row starts. + * @bpp: bytes per pixel ( Currently only 4 supported ) * - * Sets the underlying #GdkPixbuf for the #ClutterTexture + * Sets #ClutterTexture image data. * + * Since 0.2. This function is likely to change in future versions. **/ void -clutter_texture_set_pixbuf (ClutterTexture *texture, GdkPixbuf *pixbuf) +clutter_texture_set_from_data (ClutterTexture *texture, + const guchar *data, + gboolean has_alpha, + gint width, + gint height, + gint rowstride, + gint bpp) { ClutterTexturePrivate *priv; gboolean texture_dirty = TRUE; priv = texture->priv; - g_return_if_fail (pixbuf != NULL); - - if (priv->pixbuf != NULL) - { - texture_dirty = (gdk_pixbuf_get_width (pixbuf) - != gdk_pixbuf_get_width (priv->pixbuf) - || - gdk_pixbuf_get_height (pixbuf) - != gdk_pixbuf_get_height (priv->pixbuf) - || - gdk_pixbuf_get_n_channels (pixbuf) - != gdk_pixbuf_get_n_channels (priv->pixbuf)); - - g_object_unref(priv->pixbuf); - - /* If the actual pixbuf has changed size/format destroy - * existing textures ready for recreation. If - * size matches we can reuse. - */ - if (texture_dirty) - { - clutter_actor_unrealize (CLUTTER_ACTOR(texture)); - } - else - { - /* If texture realised sync things for change */ - if (CLUTTER_ACTOR_IS_REALIZED(CLUTTER_ACTOR(texture))) - { - priv->pixbuf = pixbuf; - - /* FIXME: better locking stratergy - */ - clutter_threads_enter(); - clutter_texture_sync_pixbuf (texture); - clutter_threads_leave(); - } - } - } + g_return_if_fail (data != NULL); + g_return_if_fail (bpp == 4); - clutter_threads_enter(); - - priv->pixbuf = pixbuf; - priv->width = gdk_pixbuf_get_width (pixbuf); - priv->height = gdk_pixbuf_get_height (pixbuf); + /* FIXME: check other image props */ + texture_dirty = (width != priv->width || height != priv->height); - g_object_ref (pixbuf); + priv->width = width; + priv->height = height; - if (gdk_pixbuf_get_n_channels (pixbuf) == 3) - priv->pixel_format = GL_RGB; - else + if (has_alpha) priv->pixel_format = GL_RGBA; + else + priv->pixel_format = GL_RGB; - /* Force tiling if pixbuf is too big for single texture */ - if (priv->tiled == FALSE && texture_dirty) + if (texture_dirty) { - if (priv->target_type == GL_TEXTURE_RECTANGLE_ARB - && !can_create_rect_arb (priv->width, - priv->height, - priv->pixel_format, - priv->pixel_type)) + texture_free_gl_resources (texture); + + if (priv->tiled == FALSE) { - /* If we cant create NPOT tex of this size fall back to tiles */ - priv->tiled = TRUE; - priv->target_type = GL_TEXTURE_2D; - } - else if (priv->target_type == GL_TEXTURE_2D - && !can_create(clutter_util_next_p2(priv->width), - clutter_util_next_p2(priv->height), - priv->pixel_format, - priv->pixel_type)) - { - priv->tiled = TRUE; + if (priv->target_type == GL_TEXTURE_RECTANGLE_ARB + && !can_create_rect_arb (priv->width, + priv->height, + priv->pixel_format, + priv->pixel_type)) + { + /* If we cant create NPOT tex of this size fall back to tiles */ + priv->tiled = TRUE; + priv->target_type = GL_TEXTURE_2D; + } + else if (priv->target_type == GL_TEXTURE_2D + && !can_create(clutter_util_next_p2(priv->width), + clutter_util_next_p2(priv->height), + priv->pixel_format, + priv->pixel_type)) + { + priv->tiled = TRUE; + } } - } - clutter_threads_leave(); - if (priv->sync_actor_size) - clutter_actor_set_size (CLUTTER_ACTOR(texture), - priv->width, - priv->height); + /* Figure our tiling etc */ + if (priv->tiled) + texture_init_tiles (texture); + } CLUTTER_DBG("set size %ix%i\n", priv->width, priv->height); - if (texture_dirty) - g_signal_emit (texture, texture_signals[SIGNAL_SIZE_CHANGE], - 0, priv->width, priv->height); + texture_upload_data (texture, data, has_alpha, + width, height, rowstride, bpp); - if (priv->tiled && texture_dirty) - init_tiles (texture); + CLUTTER_ACTOR_SET_FLAGS (CLUTTER_ACTOR(texture), CLUTTER_ACTOR_REALIZED); + if (texture_dirty) + { + g_signal_emit (texture, texture_signals[SIGNAL_SIZE_CHANGE], + 0, priv->width, priv->height); + + if (priv->sync_actor_size) + clutter_actor_set_size (CLUTTER_ACTOR(texture), + priv->width, + priv->height); + } + + /* rename signal */ g_signal_emit (texture, texture_signals[SIGNAL_PIXBUF_CHANGE], 0); /* If resized actor may need resizing but paint() will do this */ if (CLUTTER_ACTOR_IS_MAPPED (CLUTTER_ACTOR(texture))) clutter_actor_queue_redraw (CLUTTER_ACTOR(texture)); + +} + +/** + * clutter_texture_set_pixbuf: + * @texture: A #ClutterTexture + * @pixbuf: A #GdkPixbuf + * + * Sets a #ClutterTexture image data from a #GdkPixbuf + * + **/ +void +clutter_texture_set_pixbuf (ClutterTexture *texture, GdkPixbuf *pixbuf) +{ + ClutterTexturePrivate *priv; + + priv = texture->priv; + + g_return_if_fail (pixbuf != NULL); + + clutter_texture_set_from_data (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), + 4); } /** @@ -1129,7 +1263,7 @@ clutter_texture_new (void) * Gets the size in pixels of the untransformed underlying texture pixbuf data. * **/ -void +void /* FIXME: rename to get_image_size */ clutter_texture_get_base_size (ClutterTexture *texture, gint *width, gint *height) diff --git a/clutter/clutter-texture.h b/clutter/clutter-texture.h index 10ae83e..29bf2d9 100644 --- a/clutter/clutter-texture.h +++ b/clutter/clutter-texture.h @@ -81,13 +81,22 @@ ClutterActor *clutter_texture_new_from_pixbuf (GdkPixbuf *pixbuf); ClutterActor *clutter_texture_new (void); +void +clutter_texture_set_from_data (ClutterTexture *texture, + const guchar *data, + gboolean has_alpha, + gint width, + gint height, + gint rowstride, + gint bpp); + void clutter_texture_set_pixbuf (ClutterTexture *texture, GdkPixbuf *pixbuf); GdkPixbuf *clutter_texture_get_pixbuf (ClutterTexture* texture); void clutter_texture_get_base_size (ClutterTexture *texture, - gint *width, - gint *height); + gint *width, + gint *height); /* Below mainly for subclassed texture based actors */