2006-05-29 04:59:36 -04:00
|
|
|
/*
|
|
|
|
* Clutter.
|
|
|
|
*
|
|
|
|
* An OpenGL based 'interactive canvas' library.
|
|
|
|
*
|
|
|
|
* Authored By Matthew Allum <mallum@openedhand.com>
|
|
|
|
*
|
|
|
|
* Copyright (C) 2006 OpenedHand
|
|
|
|
*
|
|
|
|
* 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
|
2010-03-01 07:56:10 -05:00
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*
|
2006-05-29 04:59:36 -04:00
|
|
|
*/
|
|
|
|
|
2006-06-21 18:34:25 -04:00
|
|
|
/**
|
|
|
|
* SECTION:clutter-texture
|
|
|
|
* @short_description: An actor for displaying and manipulating images.
|
|
|
|
*
|
|
|
|
* #ClutterTexture is a base class for displaying and manipulating pixel
|
|
|
|
* buffer type data.
|
2006-09-19 15:27:16 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* The clutter_texture_set_from_rgb_data() and
|
|
|
|
* clutter_texture_set_from_file() functions are used to copy image
|
|
|
|
* data into texture memory and subsequently realize the texture.
|
2007-05-25 06:56:09 -04:00
|
|
|
*
|
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
Bug #815 - Split up request, allocation, and paint box
* clutter/clutter-actor.[ch]: Rework the size allocation,
request and paint area. Now ::request_coords() is called
::allocate(), and ::query_coords() has been split into
::get_preferred_width() and ::get_preferred_height(). See
the documentation and the layout test on how to implement
a container and layout manager with the new API. (#915,
based on a patch by Havoc Pennington, Lucas Rocha and Johan
Bilien)
* clutter/clutter-clone-texture.c: Port CloneTexture to
the new size negotiation API; it just means forwarding
the requests to the parent texture.
* clutter/clutter-deprecated.h: Add deprecated and replaced
API.
* clutter/clutter-entry.c: Port Entry to the new size
negotiation API.
* clutter/clutter-group.c: Port Group to the new size
negotiation API; the semantics of the Group actor do not
change.
* clutter/clutter-label.c: Port Label to the new size
negotiation API, and vastly simplify the code.
* clutter/clutter-main.[ch]: Add API for executing a
relayout when needed.
* clutter/clutter-private.h: Add new Stage private API.
* clutter/clutter-rectangle.c: Update the get_abs_opacity()
call to get_paint_opacity().
* clutter/clutter-stage.c:
(clutter_stage_get_preferred_width),
(clutter_stage_get_preferred_height),
(clutter_stage_allocate),
(clutter_stage_class_init): Port Stage to the new size
negotiation API.
* clutter/clutter-texture.c: Port Texture to the new size
negotiation API.
* clutter/clutter-types.h: Add ClutterRequestMode enumeration.
* clutter/x11/clutter-stage-x11.c: Port the X11 stage
implementation to the new size negotiation API.
* tests/Makefile.am: Add the layout manager test case.
* tests/test-opacity.c: Update.
* tests/test-project.c: Update.
* tests/test-layout.c: Test case for a layout manager implemented
using the new size negotiation API; the layout manager handles
both transformed and untransformed children.
2008-06-10 13:07:52 -04:00
|
|
|
* Note: a ClutterTexture will scale its contents to fit the bounding
|
|
|
|
* box requested using clutter_actor_set_size(). To display an area of
|
|
|
|
* a texture without scaling, you should set the clip area using
|
|
|
|
* clutter_actor_set_clip().
|
2006-06-21 18:34:25 -04:00
|
|
|
*/
|
|
|
|
|
2007-10-12 04:17:00 -04:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2007-04-27 17:13:06 -04:00
|
|
|
#include "config.h"
|
2007-10-12 04:17:00 -04:00
|
|
|
#endif
|
2007-04-27 17:13:06 -04:00
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
#include "clutter-texture.h"
|
2010-11-18 13:23:49 -05:00
|
|
|
|
|
|
|
#include "clutter-actor-private.h"
|
|
|
|
#include "clutter-debug.h"
|
|
|
|
#include "clutter-enum-types.h"
|
|
|
|
#include "clutter-feature.h"
|
2006-05-29 04:59:36 -04:00
|
|
|
#include "clutter-main.h"
|
|
|
|
#include "clutter-marshal.h"
|
2006-11-21 Emmanuele Bassi <ebassi@openedhand.com>
* configure.ac: Enable debug messages also when
--enable-debug is set to "minimum".
* clutter/Makefile.am:
* clutter/clutter-debug.h: Move all debugging macros inside
this private header; make all debug macros depend on the
CLUTTER_ENABLE_DEBUG compile time define, controlled by
the --enable-debug configure switch; add G_LOG_DOMAIN define.
* clutter/clutter-main.c: Clean up the debug stuff; add
command line argument parsing using GOption; the debug
messages now are triggered like this:
CLUTTER_DEBUG=section:section:... clutter-app
or like this:
clutter-app --clutter-debug=section:section:...
where "section" is one of the sections listed in clutter-main.c,
or "all", for all sections; each section is bound to a flag,
which can be used to define a domain when adding a debug note
using the CLUTTER_NOTE() macro; the old CLUTTER_DBG() macro is
just a wrapper around that, under the CLUTTER_DEBUG_MISC domain;
CLUTTER_NOTE() is used like this:
CLUTTER_NOTE (DOMAIN, log-function);
where log function is g_printerr(), g_message(), g_warning(),
g_critical() or directly g_log() - for instance:
CLUTTER_NOTE (PANGO, g_warning ("Cache miss: %d", glyph));
will print the warning only if the "pango" flag has been
set to the CLUTTER_DEBUG envvar or passed to the --clutter-debug
command line argument.
similar to CLUTTER_SHOW_FPS, there's also the --clutter-show-fps
command line switch; also, the --display and --screen command
line switches have been added: the first overrides the DISPLAY
envvar and the second controls the X screen used by Clutter to
get the root window on the display.
* clutter/clutter-main.h:
* clutter/clutter-main.c: Add extended support for GOption
in Clutter; use clutter_init_with_args() to let Clutter
parse your own command line arguments; use instead
clutter_get_option_group() to get the GOptionGroup used by
Clutter if you want to do the parsing yourself with
g_option_context_parse(). The init sequence has been verified,
updated and moved into common functions where possible.
* clutter/pango/pangoclutter-render.c:
* clutter/*.c: Include "clutter-debug.h" where needed; use
CLUTTER_NOTE() instead of CLUTTER_DBG().
* examples/super-oh.c: Use the new clutter_init_with_args()
function, and add a --num-hands command line switch to
the SuperOH example code controlling the number of hands at
runtime.
2006-11-21 16:27:53 -05:00
|
|
|
#include "clutter-private.h"
|
2008-04-25 09:37:36 -04:00
|
|
|
#include "clutter-scriptable.h"
|
2010-11-18 13:23:49 -05:00
|
|
|
#include "clutter-shader.h"
|
2010-10-21 06:29:09 -04:00
|
|
|
#include "clutter-stage-private.h"
|
2010-11-18 13:23:49 -05:00
|
|
|
#include "clutter-util.h"
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
static void clutter_scriptable_iface_init (ClutterScriptableIface *iface);
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
G_DEFINE_TYPE_WITH_CODE (ClutterTexture,
|
|
|
|
clutter_texture,
|
|
|
|
CLUTTER_TYPE_ACTOR,
|
|
|
|
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_SCRIPTABLE,
|
|
|
|
clutter_scriptable_iface_init));
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2007-07-24 13:38:35 -04:00
|
|
|
#define CLUTTER_TEXTURE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_TEXTURE, ClutterTexturePrivate))
|
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
typedef struct _ClutterTextureAsyncData ClutterTextureAsyncData;
|
|
|
|
|
2006-12-03 13:34:41 -05:00
|
|
|
struct _ClutterTexturePrivate
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
2010-04-26 07:58:17 -04:00
|
|
|
gint image_width;
|
|
|
|
gint image_height;
|
2009-06-22 07:07:08 -04:00
|
|
|
|
2010-04-26 07:58:17 -04:00
|
|
|
CoglHandle material;
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2010-04-26 07:58:17 -04:00
|
|
|
ClutterActor *fbo_source;
|
|
|
|
CoglHandle fbo_handle;
|
2008-04-25 09:37:36 -04:00
|
|
|
|
2009-09-25 14:14:40 -04:00
|
|
|
CoglHandle pick_material;
|
|
|
|
|
2010-08-05 10:29:54 -04:00
|
|
|
gchar *filename;
|
|
|
|
|
2010-04-26 07:58:17 -04:00
|
|
|
ClutterTextureAsyncData *async_data;
|
2009-02-25 12:10:54 -05:00
|
|
|
|
2010-04-26 07:58:17 -04:00
|
|
|
guint no_slice : 1;
|
|
|
|
guint sync_actor_size : 1;
|
|
|
|
guint repeat_x : 1;
|
|
|
|
guint repeat_y : 1;
|
|
|
|
guint keep_aspect_ratio : 1;
|
|
|
|
guint load_size_async : 1;
|
|
|
|
guint load_data_async : 1;
|
|
|
|
guint load_async_set : 1; /* used to make load_async possible */
|
2009-09-25 14:14:40 -04:00
|
|
|
guint pick_with_alpha : 1;
|
|
|
|
guint pick_with_alpha_supported : 1;
|
2010-05-28 12:11:31 -04:00
|
|
|
guint seen_create_pick_material_warning : 1;
|
2009-02-25 12:10:54 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _ClutterTextureAsyncData
|
|
|
|
{
|
|
|
|
/* Mutex used to synchronize setting the abort flag */
|
|
|
|
GMutex *mutex;
|
|
|
|
|
|
|
|
/* If set to true, the loaded data will be discarded */
|
|
|
|
gboolean abort;
|
|
|
|
|
|
|
|
/* The texture for which the data is being loaded */
|
|
|
|
ClutterTexture *texture;
|
|
|
|
|
|
|
|
/* Source ID of the idle handler for loading. If this is zero then
|
|
|
|
the data is being loaded in a thread from the thread pool. Once
|
|
|
|
the thread is finished it will be converted to idle load handler
|
2009-07-09 15:45:08 -04:00
|
|
|
and load_idle will be nonzero. If load_idle is nonzero, and
|
|
|
|
upload_queued is FALSE then the rest of the load can safely be
|
|
|
|
aborted by just removing the source, otherwise the abort flag
|
|
|
|
needs to be set and the data should be disowned */
|
2009-02-25 12:10:54 -05:00
|
|
|
guint load_idle;
|
|
|
|
|
2009-07-09 15:45:08 -04:00
|
|
|
/* Set when the texture is queued for GPU upload, used to determine
|
|
|
|
* what to do with the texture data when load_idle is zero.
|
|
|
|
*/
|
2009-09-25 14:14:40 -04:00
|
|
|
gboolean upload_queued;
|
2009-07-09 15:45:08 -04:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
gchar *load_filename;
|
2009-04-30 13:00:22 -04:00
|
|
|
CoglHandle load_bitmap;
|
2009-02-25 12:10:54 -05:00
|
|
|
GError *load_error;
|
2006-05-29 04:59:36 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PROP_0,
|
2008-04-25 09:37:36 -04:00
|
|
|
PROP_NO_SLICE,
|
2006-05-29 04:59:36 -04:00
|
|
|
PROP_MAX_TILE_WASTE,
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
PROP_PIXEL_FORMAT,
|
2006-05-29 04:59:36 -04:00
|
|
|
PROP_SYNC_SIZE,
|
|
|
|
PROP_REPEAT_Y,
|
2006-06-06 16:40:40 -04:00
|
|
|
PROP_REPEAT_X,
|
2008-04-25 09:37:36 -04:00
|
|
|
PROP_FILTER_QUALITY,
|
|
|
|
PROP_COGL_TEXTURE,
|
2008-12-23 11:39:11 -05:00
|
|
|
PROP_COGL_MATERIAL,
|
2008-06-23 11:31:12 -04:00
|
|
|
PROP_FILENAME,
|
2009-01-07 12:02:43 -05:00
|
|
|
PROP_KEEP_ASPECT_RATIO,
|
2009-03-11 14:26:30 -04:00
|
|
|
PROP_LOAD_ASYNC,
|
|
|
|
PROP_LOAD_DATA_ASYNC,
|
2010-06-21 05:20:32 -04:00
|
|
|
PROP_PICK_WITH_ALPHA,
|
|
|
|
|
|
|
|
PROP_LAST
|
2006-05-29 04:59:36 -04:00
|
|
|
};
|
|
|
|
|
2010-06-21 05:20:32 -04:00
|
|
|
static GParamSpec *obj_props[PROP_LAST];
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
enum
|
|
|
|
{
|
2006-12-13 13:12:09 -05:00
|
|
|
SIZE_CHANGE,
|
|
|
|
PIXBUF_CHANGE,
|
2009-01-07 12:02:43 -05:00
|
|
|
LOAD_SUCCESS,
|
|
|
|
LOAD_FINISHED,
|
2006-05-29 04:59:36 -04:00
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
|
|
|
static int texture_signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
static GThreadPool *async_thread_pool = NULL;
|
2009-07-09 15:45:08 -04:00
|
|
|
static guint repaint_upload_func = 0;
|
|
|
|
static GList *upload_list = NULL;
|
|
|
|
static GStaticMutex upload_list_mutex = G_STATIC_MUTEX_INIT;
|
2009-02-25 12:10:54 -05:00
|
|
|
|
2010-09-02 09:48:30 -04:00
|
|
|
static CoglMaterial *texture_template_material = NULL;
|
|
|
|
|
2008-02-03 18:25:12 -05:00
|
|
|
static void
|
|
|
|
texture_fbo_free_resources (ClutterTexture *texture);
|
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
GQuark
|
|
|
|
clutter_texture_error_quark (void)
|
|
|
|
{
|
|
|
|
return g_quark_from_static_string ("clutter-texture-error-quark");
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
2009-06-04 11:04:57 -04:00
|
|
|
static const struct
|
|
|
|
{
|
|
|
|
gint min_filter;
|
|
|
|
gint mag_filter;
|
|
|
|
}
|
|
|
|
clutter_texture_quality_filters[] =
|
|
|
|
{
|
|
|
|
/* CLUTTER_TEXTURE_QUALITY_LOW */
|
|
|
|
{ COGL_MATERIAL_FILTER_NEAREST, COGL_MATERIAL_FILTER_NEAREST },
|
|
|
|
|
|
|
|
/* CLUTTER_TEXTURE_QUALITY_MEDIUM */
|
|
|
|
{ COGL_MATERIAL_FILTER_LINEAR, COGL_MATERIAL_FILTER_LINEAR },
|
|
|
|
|
|
|
|
/* CLUTTER_TEXTURE_QUALITY_HIGH */
|
|
|
|
{ COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR, COGL_MATERIAL_FILTER_LINEAR }
|
|
|
|
};
|
|
|
|
|
2009-02-06 08:50:16 -05:00
|
|
|
static inline void
|
|
|
|
clutter_texture_quality_to_filters (ClutterTextureQuality quality,
|
|
|
|
gint *min_filter_p,
|
|
|
|
gint *mag_filter_p)
|
2008-06-07 11:08:05 -04:00
|
|
|
{
|
2009-06-04 11:04:57 -04:00
|
|
|
g_return_if_fail (quality < G_N_ELEMENTS (clutter_texture_quality_filters));
|
2009-02-06 08:50:16 -05:00
|
|
|
|
|
|
|
if (min_filter_p)
|
2009-06-04 11:04:57 -04:00
|
|
|
*min_filter_p = clutter_texture_quality_filters[quality].min_filter;
|
2009-02-06 08:50:16 -05:00
|
|
|
|
|
|
|
if (mag_filter_p)
|
2009-06-04 11:04:57 -04:00
|
|
|
*mag_filter_p = clutter_texture_quality_filters[quality].mag_filter;
|
2008-06-07 11:08:05 -04:00
|
|
|
}
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
static void
|
2006-09-19 15:27:16 -04:00
|
|
|
texture_free_gl_resources (ClutterTexture *texture)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
2009-02-06 08:50:16 -05:00
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
2006-05-29 04:59:36 -04:00
|
|
|
|
|
|
|
CLUTTER_MARK();
|
|
|
|
|
2009-02-11 12:52:50 -05:00
|
|
|
if (priv->material != COGL_INVALID_HANDLE)
|
2010-09-06 13:08:44 -04:00
|
|
|
{
|
|
|
|
/* We want to keep the layer so that the filter settings will
|
|
|
|
remain but we want to free its resources so we clear the
|
|
|
|
texture handle */
|
|
|
|
cogl_material_set_layer (priv->material, 0, COGL_INVALID_HANDLE);
|
|
|
|
}
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
2006-09-19 15:27:16 -04:00
|
|
|
static void
|
|
|
|
clutter_texture_unrealize (ClutterActor *actor)
|
|
|
|
{
|
|
|
|
ClutterTexture *texture;
|
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
|
|
|
|
texture = CLUTTER_TEXTURE(actor);
|
|
|
|
priv = texture->priv;
|
|
|
|
|
2008-12-23 11:39:11 -05:00
|
|
|
if (priv->material == COGL_INVALID_HANDLE)
|
2006-09-19 15:27:16 -04:00
|
|
|
return;
|
|
|
|
|
|
|
|
CLUTTER_MARK();
|
|
|
|
|
2009-11-01 09:36:05 -05:00
|
|
|
if (priv->fbo_source != NULL)
|
2008-02-08 05:37:38 -05:00
|
|
|
{
|
|
|
|
/* Free up our fbo handle and texture resources, realize will recreate */
|
2009-04-01 12:16:44 -04:00
|
|
|
cogl_handle_unref (priv->fbo_handle);
|
2008-04-25 09:37:36 -04:00
|
|
|
priv->fbo_handle = COGL_INVALID_HANDLE;
|
2008-02-08 05:37:38 -05:00
|
|
|
texture_free_gl_resources (texture);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-11-22 15:52:27 -05:00
|
|
|
CLUTTER_NOTE (TEXTURE, "Texture unrealized");
|
2006-09-19 15:27:16 -04:00
|
|
|
}
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
static void
|
2006-06-13 09:17:45 -04:00
|
|
|
clutter_texture_realize (ClutterActor *actor)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
2006-09-19 15:27:16 -04:00
|
|
|
ClutterTexture *texture;
|
|
|
|
ClutterTexturePrivate *priv;
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2006-06-13 09:17:45 -04:00
|
|
|
texture = CLUTTER_TEXTURE(actor);
|
2006-09-19 15:27:16 -04:00
|
|
|
priv = texture->priv;
|
2006-05-29 04:59:36 -04:00
|
|
|
|
|
|
|
CLUTTER_MARK();
|
|
|
|
|
2008-02-08 05:37:38 -05:00
|
|
|
if (priv->fbo_source)
|
|
|
|
{
|
2009-01-18 09:51:19 -05:00
|
|
|
CoglTextureFlags flags = COGL_TEXTURE_NONE;
|
2009-04-30 09:32:19 -04:00
|
|
|
CoglHandle tex;
|
2009-01-18 09:51:19 -05:00
|
|
|
|
2008-02-08 05:37:38 -05:00
|
|
|
/* Handle FBO's */
|
|
|
|
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
if (priv->no_slice)
|
|
|
|
flags |= COGL_TEXTURE_NO_SLICING;
|
2009-01-18 09:51:19 -05:00
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
tex = cogl_texture_new_with_size (priv->image_width,
|
|
|
|
priv->image_height,
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
flags,
|
2009-05-09 14:39:01 -04:00
|
|
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE);
|
2009-04-30 09:32:19 -04:00
|
|
|
|
|
|
|
cogl_material_set_layer (priv->material, 0, tex);
|
2008-02-08 05:37:38 -05:00
|
|
|
|
2009-04-30 09:32:19 -04:00
|
|
|
priv->fbo_handle = cogl_offscreen_new_to_texture (tex);
|
2008-02-08 05:37:38 -05:00
|
|
|
|
2009-04-30 09:32:19 -04:00
|
|
|
/* The material now has a reference to the texture so it will
|
|
|
|
stick around */
|
|
|
|
cogl_handle_unref (tex);
|
2008-02-08 05:37:38 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
if (priv->fbo_handle == COGL_INVALID_HANDLE)
|
2008-02-08 05:37:38 -05:00
|
|
|
{
|
|
|
|
g_warning ("%s: Offscreen texture creation failed", G_STRLOC);
|
|
|
|
CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
clutter_actor_set_size (actor, priv->image_width, priv->image_height);
|
|
|
|
|
2008-02-08 05:37:38 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-04-15 08:57:45 -04:00
|
|
|
/* If the texture is not a FBO, then realization is a no-op but we
|
|
|
|
* still want to be in REALIZED state to maintain invariants.
|
|
|
|
* ClutterTexture doesn't need to be realized to have a Cogl texture
|
|
|
|
* because Clutter assumes that a GL context is always current so
|
|
|
|
* there is no need to wait to realization time to create the
|
|
|
|
* texture. Although this is slightly odd it would be wasteful to
|
|
|
|
* redundantly store a copy of the texture data in local memory just
|
|
|
|
* so that we can make a texture during realize.
|
2009-11-02 12:08:55 -05:00
|
|
|
*/
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2006-11-22 15:52:27 -05:00
|
|
|
CLUTTER_NOTE (TEXTURE, "Texture realized");
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
Bug #815 - Split up request, allocation, and paint box
* clutter/clutter-actor.[ch]: Rework the size allocation,
request and paint area. Now ::request_coords() is called
::allocate(), and ::query_coords() has been split into
::get_preferred_width() and ::get_preferred_height(). See
the documentation and the layout test on how to implement
a container and layout manager with the new API. (#915,
based on a patch by Havoc Pennington, Lucas Rocha and Johan
Bilien)
* clutter/clutter-clone-texture.c: Port CloneTexture to
the new size negotiation API; it just means forwarding
the requests to the parent texture.
* clutter/clutter-deprecated.h: Add deprecated and replaced
API.
* clutter/clutter-entry.c: Port Entry to the new size
negotiation API.
* clutter/clutter-group.c: Port Group to the new size
negotiation API; the semantics of the Group actor do not
change.
* clutter/clutter-label.c: Port Label to the new size
negotiation API, and vastly simplify the code.
* clutter/clutter-main.[ch]: Add API for executing a
relayout when needed.
* clutter/clutter-private.h: Add new Stage private API.
* clutter/clutter-rectangle.c: Update the get_abs_opacity()
call to get_paint_opacity().
* clutter/clutter-stage.c:
(clutter_stage_get_preferred_width),
(clutter_stage_get_preferred_height),
(clutter_stage_allocate),
(clutter_stage_class_init): Port Stage to the new size
negotiation API.
* clutter/clutter-texture.c: Port Texture to the new size
negotiation API.
* clutter/clutter-types.h: Add ClutterRequestMode enumeration.
* clutter/x11/clutter-stage-x11.c: Port the X11 stage
implementation to the new size negotiation API.
* tests/Makefile.am: Add the layout manager test case.
* tests/test-opacity.c: Update.
* tests/test-project.c: Update.
* tests/test-layout.c: Test case for a layout manager implemented
using the new size negotiation API; the layout manager handles
both transformed and untransformed children.
2008-06-10 13:07:52 -04:00
|
|
|
static void
|
|
|
|
clutter_texture_get_preferred_width (ClutterActor *self,
|
Remove Units from the public API
With the recent change to internal floating point values, ClutterUnit
has become a redundant type, defined to be a float. All integer entry
points are being internally converted to floating point values to be
passed to the GL pipeline with the least amount of conversion.
ClutterUnit is thus exposed as just a "pixel with fractionary bits",
and not -- as users might think -- as generic, resolution and device
independent units. not that it was the case, but a definitive amount
of people was convinced it did provide this "feature", and was flummoxed
about the mere existence of this type.
So, having ClutterUnit exposed in the public API doubles the entry
points and has the following disadvantages:
- we have to maintain twice the amount of entry points in ClutterActor
- we still do an integer-to-float implicit conversion
- we introduce a weird impedance between pixels and "pixels with
fractionary bits"
- language bindings will have to choose what to bind, and resort
to manually overriding the API
+ *except* for language bindings based on GObject-Introspection, as
they cannot do manual overrides, thus will replicate the entire
set of entry points
For these reason, we should coalesces every Actor entry point for
pixels and for ClutterUnit into a single entry point taking a float,
like:
void clutter_actor_set_x (ClutterActor *self,
gfloat x);
void clutter_actor_get_size (ClutterActor *self,
gfloat *width,
gfloat *height);
gfloat clutter_actor_get_height (ClutterActor *self);
etc.
The issues I have identified are:
- we'll have a two cases of compiler warnings:
- printf() format of the return values from %d to %f
- clutter_actor_get_size() taking floats instead of unsigned ints
- we'll have a problem with varargs when passing an integer instead
of a floating point value, except on 64bit platforms where the
size of a float is the same as the size of an int
To be clear: the *intent* of the API should not change -- we still use
pixels everywhere -- but:
- we remove ambiguity in the API with regard to pixels and units
- we remove entry points we get to maintain for the whole 1.0
version of the API
- we make things simpler to bind for both manual language bindings
and automatic (gobject-introspection based) ones
- we have the simplest API possible while still exposing the
capabilities of the underlying GL implementation
2009-05-06 11:44:47 -04:00
|
|
|
gfloat for_height,
|
|
|
|
gfloat *min_width_p,
|
|
|
|
gfloat *natural_width_p)
|
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
Bug #815 - Split up request, allocation, and paint box
* clutter/clutter-actor.[ch]: Rework the size allocation,
request and paint area. Now ::request_coords() is called
::allocate(), and ::query_coords() has been split into
::get_preferred_width() and ::get_preferred_height(). See
the documentation and the layout test on how to implement
a container and layout manager with the new API. (#915,
based on a patch by Havoc Pennington, Lucas Rocha and Johan
Bilien)
* clutter/clutter-clone-texture.c: Port CloneTexture to
the new size negotiation API; it just means forwarding
the requests to the parent texture.
* clutter/clutter-deprecated.h: Add deprecated and replaced
API.
* clutter/clutter-entry.c: Port Entry to the new size
negotiation API.
* clutter/clutter-group.c: Port Group to the new size
negotiation API; the semantics of the Group actor do not
change.
* clutter/clutter-label.c: Port Label to the new size
negotiation API, and vastly simplify the code.
* clutter/clutter-main.[ch]: Add API for executing a
relayout when needed.
* clutter/clutter-private.h: Add new Stage private API.
* clutter/clutter-rectangle.c: Update the get_abs_opacity()
call to get_paint_opacity().
* clutter/clutter-stage.c:
(clutter_stage_get_preferred_width),
(clutter_stage_get_preferred_height),
(clutter_stage_allocate),
(clutter_stage_class_init): Port Stage to the new size
negotiation API.
* clutter/clutter-texture.c: Port Texture to the new size
negotiation API.
* clutter/clutter-types.h: Add ClutterRequestMode enumeration.
* clutter/x11/clutter-stage-x11.c: Port the X11 stage
implementation to the new size negotiation API.
* tests/Makefile.am: Add the layout manager test case.
* tests/test-opacity.c: Update.
* tests/test-project.c: Update.
* tests/test-layout.c: Test case for a layout manager implemented
using the new size negotiation API; the layout manager handles
both transformed and untransformed children.
2008-06-10 13:07:52 -04:00
|
|
|
{
|
|
|
|
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
|
|
|
|
|
|
|
/* Min request is always 0 since we can scale down or clip */
|
|
|
|
if (min_width_p)
|
|
|
|
*min_width_p = 0;
|
|
|
|
|
|
|
|
if (priv->sync_actor_size)
|
|
|
|
{
|
|
|
|
if (natural_width_p)
|
2008-06-17 10:45:33 -04:00
|
|
|
{
|
2008-06-23 11:31:12 -04:00
|
|
|
if (!priv->keep_aspect_ratio ||
|
|
|
|
for_height < 0 ||
|
2009-06-22 07:07:08 -04:00
|
|
|
priv->image_height <= 0)
|
2008-06-23 11:31:12 -04:00
|
|
|
{
|
2009-06-22 07:07:08 -04:00
|
|
|
*natural_width_p = priv->image_width;
|
2008-06-23 11:31:12 -04:00
|
|
|
}
|
2008-06-17 10:45:33 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Set the natural width so as to preserve the aspect ratio */
|
2009-06-22 07:07:08 -04:00
|
|
|
gfloat ratio = (gfloat) priv->image_width
|
|
|
|
/ (gfloat) priv->image_height;
|
2008-06-23 11:31:12 -04:00
|
|
|
|
Remove Units from the public API
With the recent change to internal floating point values, ClutterUnit
has become a redundant type, defined to be a float. All integer entry
points are being internally converted to floating point values to be
passed to the GL pipeline with the least amount of conversion.
ClutterUnit is thus exposed as just a "pixel with fractionary bits",
and not -- as users might think -- as generic, resolution and device
independent units. not that it was the case, but a definitive amount
of people was convinced it did provide this "feature", and was flummoxed
about the mere existence of this type.
So, having ClutterUnit exposed in the public API doubles the entry
points and has the following disadvantages:
- we have to maintain twice the amount of entry points in ClutterActor
- we still do an integer-to-float implicit conversion
- we introduce a weird impedance between pixels and "pixels with
fractionary bits"
- language bindings will have to choose what to bind, and resort
to manually overriding the API
+ *except* for language bindings based on GObject-Introspection, as
they cannot do manual overrides, thus will replicate the entire
set of entry points
For these reason, we should coalesces every Actor entry point for
pixels and for ClutterUnit into a single entry point taking a float,
like:
void clutter_actor_set_x (ClutterActor *self,
gfloat x);
void clutter_actor_get_size (ClutterActor *self,
gfloat *width,
gfloat *height);
gfloat clutter_actor_get_height (ClutterActor *self);
etc.
The issues I have identified are:
- we'll have a two cases of compiler warnings:
- printf() format of the return values from %d to %f
- clutter_actor_get_size() taking floats instead of unsigned ints
- we'll have a problem with varargs when passing an integer instead
of a floating point value, except on 64bit platforms where the
size of a float is the same as the size of an int
To be clear: the *intent* of the API should not change -- we still use
pixels everywhere -- but:
- we remove ambiguity in the API with regard to pixels and units
- we remove entry points we get to maintain for the whole 1.0
version of the API
- we make things simpler to bind for both manual language bindings
and automatic (gobject-introspection based) ones
- we have the simplest API possible while still exposing the
capabilities of the underlying GL implementation
2009-05-06 11:44:47 -04:00
|
|
|
*natural_width_p = ratio * for_height;
|
2008-06-17 10:45:33 -04:00
|
|
|
}
|
|
|
|
}
|
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
Bug #815 - Split up request, allocation, and paint box
* clutter/clutter-actor.[ch]: Rework the size allocation,
request and paint area. Now ::request_coords() is called
::allocate(), and ::query_coords() has been split into
::get_preferred_width() and ::get_preferred_height(). See
the documentation and the layout test on how to implement
a container and layout manager with the new API. (#915,
based on a patch by Havoc Pennington, Lucas Rocha and Johan
Bilien)
* clutter/clutter-clone-texture.c: Port CloneTexture to
the new size negotiation API; it just means forwarding
the requests to the parent texture.
* clutter/clutter-deprecated.h: Add deprecated and replaced
API.
* clutter/clutter-entry.c: Port Entry to the new size
negotiation API.
* clutter/clutter-group.c: Port Group to the new size
negotiation API; the semantics of the Group actor do not
change.
* clutter/clutter-label.c: Port Label to the new size
negotiation API, and vastly simplify the code.
* clutter/clutter-main.[ch]: Add API for executing a
relayout when needed.
* clutter/clutter-private.h: Add new Stage private API.
* clutter/clutter-rectangle.c: Update the get_abs_opacity()
call to get_paint_opacity().
* clutter/clutter-stage.c:
(clutter_stage_get_preferred_width),
(clutter_stage_get_preferred_height),
(clutter_stage_allocate),
(clutter_stage_class_init): Port Stage to the new size
negotiation API.
* clutter/clutter-texture.c: Port Texture to the new size
negotiation API.
* clutter/clutter-types.h: Add ClutterRequestMode enumeration.
* clutter/x11/clutter-stage-x11.c: Port the X11 stage
implementation to the new size negotiation API.
* tests/Makefile.am: Add the layout manager test case.
* tests/test-opacity.c: Update.
* tests/test-project.c: Update.
* tests/test-layout.c: Test case for a layout manager implemented
using the new size negotiation API; the layout manager handles
both transformed and untransformed children.
2008-06-10 13:07:52 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (natural_width_p)
|
|
|
|
*natural_width_p = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_texture_get_preferred_height (ClutterActor *self,
|
Remove Units from the public API
With the recent change to internal floating point values, ClutterUnit
has become a redundant type, defined to be a float. All integer entry
points are being internally converted to floating point values to be
passed to the GL pipeline with the least amount of conversion.
ClutterUnit is thus exposed as just a "pixel with fractionary bits",
and not -- as users might think -- as generic, resolution and device
independent units. not that it was the case, but a definitive amount
of people was convinced it did provide this "feature", and was flummoxed
about the mere existence of this type.
So, having ClutterUnit exposed in the public API doubles the entry
points and has the following disadvantages:
- we have to maintain twice the amount of entry points in ClutterActor
- we still do an integer-to-float implicit conversion
- we introduce a weird impedance between pixels and "pixels with
fractionary bits"
- language bindings will have to choose what to bind, and resort
to manually overriding the API
+ *except* for language bindings based on GObject-Introspection, as
they cannot do manual overrides, thus will replicate the entire
set of entry points
For these reason, we should coalesces every Actor entry point for
pixels and for ClutterUnit into a single entry point taking a float,
like:
void clutter_actor_set_x (ClutterActor *self,
gfloat x);
void clutter_actor_get_size (ClutterActor *self,
gfloat *width,
gfloat *height);
gfloat clutter_actor_get_height (ClutterActor *self);
etc.
The issues I have identified are:
- we'll have a two cases of compiler warnings:
- printf() format of the return values from %d to %f
- clutter_actor_get_size() taking floats instead of unsigned ints
- we'll have a problem with varargs when passing an integer instead
of a floating point value, except on 64bit platforms where the
size of a float is the same as the size of an int
To be clear: the *intent* of the API should not change -- we still use
pixels everywhere -- but:
- we remove ambiguity in the API with regard to pixels and units
- we remove entry points we get to maintain for the whole 1.0
version of the API
- we make things simpler to bind for both manual language bindings
and automatic (gobject-introspection based) ones
- we have the simplest API possible while still exposing the
capabilities of the underlying GL implementation
2009-05-06 11:44:47 -04:00
|
|
|
gfloat for_width,
|
|
|
|
gfloat *min_height_p,
|
|
|
|
gfloat *natural_height_p)
|
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
Bug #815 - Split up request, allocation, and paint box
* clutter/clutter-actor.[ch]: Rework the size allocation,
request and paint area. Now ::request_coords() is called
::allocate(), and ::query_coords() has been split into
::get_preferred_width() and ::get_preferred_height(). See
the documentation and the layout test on how to implement
a container and layout manager with the new API. (#915,
based on a patch by Havoc Pennington, Lucas Rocha and Johan
Bilien)
* clutter/clutter-clone-texture.c: Port CloneTexture to
the new size negotiation API; it just means forwarding
the requests to the parent texture.
* clutter/clutter-deprecated.h: Add deprecated and replaced
API.
* clutter/clutter-entry.c: Port Entry to the new size
negotiation API.
* clutter/clutter-group.c: Port Group to the new size
negotiation API; the semantics of the Group actor do not
change.
* clutter/clutter-label.c: Port Label to the new size
negotiation API, and vastly simplify the code.
* clutter/clutter-main.[ch]: Add API for executing a
relayout when needed.
* clutter/clutter-private.h: Add new Stage private API.
* clutter/clutter-rectangle.c: Update the get_abs_opacity()
call to get_paint_opacity().
* clutter/clutter-stage.c:
(clutter_stage_get_preferred_width),
(clutter_stage_get_preferred_height),
(clutter_stage_allocate),
(clutter_stage_class_init): Port Stage to the new size
negotiation API.
* clutter/clutter-texture.c: Port Texture to the new size
negotiation API.
* clutter/clutter-types.h: Add ClutterRequestMode enumeration.
* clutter/x11/clutter-stage-x11.c: Port the X11 stage
implementation to the new size negotiation API.
* tests/Makefile.am: Add the layout manager test case.
* tests/test-opacity.c: Update.
* tests/test-project.c: Update.
* tests/test-layout.c: Test case for a layout manager implemented
using the new size negotiation API; the layout manager handles
both transformed and untransformed children.
2008-06-10 13:07:52 -04:00
|
|
|
{
|
|
|
|
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
|
|
|
|
|
|
|
/* Min request is always 0 since we can scale down or clip */
|
|
|
|
if (min_height_p)
|
|
|
|
*min_height_p = 0;
|
|
|
|
|
|
|
|
if (priv->sync_actor_size)
|
|
|
|
{
|
|
|
|
if (natural_height_p)
|
2008-06-17 10:45:33 -04:00
|
|
|
{
|
2008-06-23 11:31:12 -04:00
|
|
|
if (!priv->keep_aspect_ratio ||
|
|
|
|
for_width < 0 ||
|
2009-06-22 07:07:08 -04:00
|
|
|
priv->image_width <= 0)
|
2008-06-23 11:31:12 -04:00
|
|
|
{
|
2009-06-22 07:07:08 -04:00
|
|
|
*natural_height_p = priv->image_height;
|
2008-06-23 11:31:12 -04:00
|
|
|
}
|
2008-06-17 10:45:33 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Set the natural height so as to preserve the aspect ratio */
|
2009-06-22 07:07:08 -04:00
|
|
|
gfloat ratio = (gfloat) priv->image_height
|
|
|
|
/ (gfloat) priv->image_width;
|
2008-06-23 11:31:12 -04:00
|
|
|
|
Remove Units from the public API
With the recent change to internal floating point values, ClutterUnit
has become a redundant type, defined to be a float. All integer entry
points are being internally converted to floating point values to be
passed to the GL pipeline with the least amount of conversion.
ClutterUnit is thus exposed as just a "pixel with fractionary bits",
and not -- as users might think -- as generic, resolution and device
independent units. not that it was the case, but a definitive amount
of people was convinced it did provide this "feature", and was flummoxed
about the mere existence of this type.
So, having ClutterUnit exposed in the public API doubles the entry
points and has the following disadvantages:
- we have to maintain twice the amount of entry points in ClutterActor
- we still do an integer-to-float implicit conversion
- we introduce a weird impedance between pixels and "pixels with
fractionary bits"
- language bindings will have to choose what to bind, and resort
to manually overriding the API
+ *except* for language bindings based on GObject-Introspection, as
they cannot do manual overrides, thus will replicate the entire
set of entry points
For these reason, we should coalesces every Actor entry point for
pixels and for ClutterUnit into a single entry point taking a float,
like:
void clutter_actor_set_x (ClutterActor *self,
gfloat x);
void clutter_actor_get_size (ClutterActor *self,
gfloat *width,
gfloat *height);
gfloat clutter_actor_get_height (ClutterActor *self);
etc.
The issues I have identified are:
- we'll have a two cases of compiler warnings:
- printf() format of the return values from %d to %f
- clutter_actor_get_size() taking floats instead of unsigned ints
- we'll have a problem with varargs when passing an integer instead
of a floating point value, except on 64bit platforms where the
size of a float is the same as the size of an int
To be clear: the *intent* of the API should not change -- we still use
pixels everywhere -- but:
- we remove ambiguity in the API with regard to pixels and units
- we remove entry points we get to maintain for the whole 1.0
version of the API
- we make things simpler to bind for both manual language bindings
and automatic (gobject-introspection based) ones
- we have the simplest API possible while still exposing the
capabilities of the underlying GL implementation
2009-05-06 11:44:47 -04:00
|
|
|
*natural_height_p = ratio * for_width;
|
2008-06-17 10:45:33 -04:00
|
|
|
}
|
|
|
|
}
|
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
Bug #815 - Split up request, allocation, and paint box
* clutter/clutter-actor.[ch]: Rework the size allocation,
request and paint area. Now ::request_coords() is called
::allocate(), and ::query_coords() has been split into
::get_preferred_width() and ::get_preferred_height(). See
the documentation and the layout test on how to implement
a container and layout manager with the new API. (#915,
based on a patch by Havoc Pennington, Lucas Rocha and Johan
Bilien)
* clutter/clutter-clone-texture.c: Port CloneTexture to
the new size negotiation API; it just means forwarding
the requests to the parent texture.
* clutter/clutter-deprecated.h: Add deprecated and replaced
API.
* clutter/clutter-entry.c: Port Entry to the new size
negotiation API.
* clutter/clutter-group.c: Port Group to the new size
negotiation API; the semantics of the Group actor do not
change.
* clutter/clutter-label.c: Port Label to the new size
negotiation API, and vastly simplify the code.
* clutter/clutter-main.[ch]: Add API for executing a
relayout when needed.
* clutter/clutter-private.h: Add new Stage private API.
* clutter/clutter-rectangle.c: Update the get_abs_opacity()
call to get_paint_opacity().
* clutter/clutter-stage.c:
(clutter_stage_get_preferred_width),
(clutter_stage_get_preferred_height),
(clutter_stage_allocate),
(clutter_stage_class_init): Port Stage to the new size
negotiation API.
* clutter/clutter-texture.c: Port Texture to the new size
negotiation API.
* clutter/clutter-types.h: Add ClutterRequestMode enumeration.
* clutter/x11/clutter-stage-x11.c: Port the X11 stage
implementation to the new size negotiation API.
* tests/Makefile.am: Add the layout manager test case.
* tests/test-opacity.c: Update.
* tests/test-project.c: Update.
* tests/test-layout.c: Test case for a layout manager implemented
using the new size negotiation API; the layout manager handles
both transformed and untransformed children.
2008-06-10 13:07:52 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (natural_height_p)
|
|
|
|
*natural_height_p = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-04 06:44:18 -04:00
|
|
|
static void
|
2009-06-03 09:02:06 -04:00
|
|
|
clutter_texture_allocate (ClutterActor *self,
|
|
|
|
const ClutterActorBox *box,
|
|
|
|
ClutterAllocationFlags flags)
|
2008-07-04 06:44:18 -04:00
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv = CLUTTER_TEXTURE (self)->priv;
|
|
|
|
|
|
|
|
/* chain up to set actor->allocation */
|
2009-06-03 09:02:06 -04:00
|
|
|
CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->allocate (self,
|
|
|
|
box,
|
|
|
|
flags);
|
2008-07-04 06:44:18 -04:00
|
|
|
|
|
|
|
/* If we adopted the source fbo then allocate that at its preferred
|
|
|
|
size */
|
|
|
|
if (priv->fbo_source && clutter_actor_get_parent (priv->fbo_source) == self)
|
2009-06-03 09:02:06 -04:00
|
|
|
clutter_actor_allocate_preferred_size (priv->fbo_source, flags);
|
2008-07-04 06:44:18 -04:00
|
|
|
}
|
|
|
|
|
2008-08-01 08:23:57 -04:00
|
|
|
static void
|
2009-11-01 20:14:50 -05:00
|
|
|
set_viewport_with_buffer_under_fbo_source (ClutterActor *fbo_source,
|
|
|
|
int viewport_width,
|
|
|
|
int viewport_height)
|
2008-08-01 08:23:57 -04:00
|
|
|
{
|
2010-08-19 10:26:19 -04:00
|
|
|
ClutterActorBox box = { 0, };
|
|
|
|
float x_offset, y_offset;
|
2008-08-01 08:23:57 -04:00
|
|
|
|
2010-09-07 13:04:19 -04:00
|
|
|
if (clutter_actor_get_paint_box (fbo_source, &box))
|
|
|
|
clutter_actor_box_get_origin (&box, &x_offset, &y_offset);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* As a fallback when the paint box can't be determined we use
|
|
|
|
* the transformed allocation to come up with an offset instead.
|
|
|
|
*
|
|
|
|
* FIXME: when we don't have a paint box we should instead be
|
|
|
|
* falling back to a stage sized fbo with an offset of (0,0)
|
|
|
|
*/
|
|
|
|
|
|
|
|
ClutterVertex verts[4];
|
|
|
|
float x_min = G_MAXFLOAT, y_min = G_MAXFLOAT;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Get the actors allocation transformed into screen coordinates.
|
|
|
|
*
|
|
|
|
* XXX: Note: this may not be a bounding box for the actor, since an
|
|
|
|
* actor with depth may escape the box due to its perspective
|
|
|
|
* projection. */
|
|
|
|
clutter_actor_get_abs_allocation_vertices (fbo_source, verts);
|
|
|
|
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (verts); ++i)
|
|
|
|
{
|
|
|
|
if (verts[i].x < x_min)
|
|
|
|
x_min = verts[i].x;
|
|
|
|
if (verts[i].y < y_min)
|
|
|
|
y_min = verts[i].y;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX: It's not good enough to round by simply truncating the fraction here
|
|
|
|
* via a cast, as it results in offscreen rendering being offset by 1 pixel
|
|
|
|
* in many cases... */
|
|
|
|
#define ROUND(x) ((x) >= 0 ? (long)((x) + 0.5) : (long)((x) - 0.5))
|
|
|
|
|
|
|
|
x_offset = ROUND (x_min);
|
|
|
|
y_offset = ROUND (y_min);
|
|
|
|
|
|
|
|
#undef ROUND
|
|
|
|
}
|
2009-11-01 18:56:03 -05:00
|
|
|
|
2009-11-01 20:14:50 -05:00
|
|
|
/* translate the viewport so that the source actor lands on the
|
2009-11-26 14:06:35 -05:00
|
|
|
* sub-region backed by the offscreen framebuffer... */
|
2010-08-19 10:26:19 -04:00
|
|
|
cogl_set_viewport (-x_offset, -y_offset, viewport_width, viewport_height);
|
2008-08-01 08:23:57 -04:00
|
|
|
}
|
|
|
|
|
2009-09-24 09:34:09 -04:00
|
|
|
static void
|
|
|
|
update_fbo (ClutterActor *self)
|
|
|
|
{
|
|
|
|
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
|
|
|
ClutterMainContext *context;
|
|
|
|
ClutterShader *shader = NULL;
|
|
|
|
ClutterActor *stage = NULL;
|
2010-09-07 13:04:19 -04:00
|
|
|
CoglMatrix projection;
|
2009-09-24 09:34:09 -04:00
|
|
|
CoglColor transparent_col;
|
|
|
|
|
|
|
|
context = _clutter_context_get_default ();
|
|
|
|
|
|
|
|
if (context->shaders)
|
|
|
|
shader = clutter_actor_get_shader (context->shaders->data);
|
|
|
|
|
2009-11-01 20:14:50 -05:00
|
|
|
/* Temporarily turn off the shader on the top of the context's shader stack,
|
|
|
|
* to restore the GL pipeline to it's natural state.
|
2009-09-24 09:34:09 -04:00
|
|
|
*/
|
|
|
|
if (shader)
|
|
|
|
clutter_shader_set_is_enabled (shader, FALSE);
|
|
|
|
|
|
|
|
/* Redirect drawing to the fbo */
|
2009-11-26 14:06:35 -05:00
|
|
|
cogl_push_framebuffer (priv->fbo_handle);
|
2009-09-24 09:34:09 -04:00
|
|
|
|
|
|
|
if ((stage = clutter_actor_get_stage (self)))
|
|
|
|
{
|
|
|
|
gfloat stage_width, stage_height;
|
|
|
|
ClutterActor *source_parent;
|
|
|
|
|
2009-11-01 20:14:50 -05:00
|
|
|
/* We copy the projection and modelview matrices from the stage to
|
2009-11-26 14:06:35 -05:00
|
|
|
* the offscreen framebuffer and create a viewport larger than the
|
|
|
|
* offscreen framebuffer - the same size as the stage.
|
2009-11-01 20:14:50 -05:00
|
|
|
*
|
|
|
|
* The fbo source actor gets rendered into this stage size viewport at the
|
|
|
|
* same position it normally would after applying all it's usual parent
|
|
|
|
* transforms and it's own scale and rotate transforms etc.
|
|
|
|
*
|
|
|
|
* The viewport is offset such that the offscreen buffer will be positioned
|
|
|
|
* under the actor.
|
|
|
|
*/
|
|
|
|
|
2010-09-07 13:04:19 -04:00
|
|
|
_clutter_stage_get_projection_matrix (CLUTTER_STAGE (stage), &projection);
|
|
|
|
|
|
|
|
/* Set the projection matrix modelview matrix as it is for the
|
|
|
|
* stage... */
|
|
|
|
cogl_set_projection_matrix (&projection);
|
2009-09-24 09:34:09 -04:00
|
|
|
|
2010-09-07 13:04:19 -04:00
|
|
|
clutter_actor_get_size (stage, &stage_width, &stage_height);
|
2009-09-24 09:34:09 -04:00
|
|
|
|
2010-09-07 13:04:19 -04:00
|
|
|
/* Set a negatively offset the viewport so that the offscreen
|
|
|
|
* framebuffer is position underneath the fbo_source actor... */
|
2009-11-01 20:14:50 -05:00
|
|
|
set_viewport_with_buffer_under_fbo_source (priv->fbo_source,
|
|
|
|
stage_width,
|
|
|
|
stage_height);
|
2009-09-24 09:34:09 -04:00
|
|
|
|
2010-09-07 13:04:19 -04:00
|
|
|
/* Apply the source's parent transformations to the modelview */
|
2009-09-24 09:34:09 -04:00
|
|
|
if ((source_parent = clutter_actor_get_parent (priv->fbo_source)))
|
2010-09-07 08:10:55 -04:00
|
|
|
{
|
|
|
|
CoglMatrix modelview;
|
|
|
|
|
|
|
|
/* NB: _clutter_actor_apply_modelview_transform_recursive
|
|
|
|
* will never include the transformation between stage
|
|
|
|
* coordinates and OpenGL window coordinates, we have to
|
|
|
|
* explicitly use the stage->apply_transform to get that...
|
|
|
|
*/
|
|
|
|
|
|
|
|
cogl_matrix_init_identity (&modelview);
|
|
|
|
_clutter_actor_apply_modelview_transform (stage, &modelview);
|
|
|
|
_clutter_actor_apply_modelview_transform_recursive (source_parent,
|
|
|
|
NULL,
|
|
|
|
&modelview);
|
|
|
|
cogl_set_modelview_matrix (&modelview);
|
|
|
|
}
|
2009-09-24 09:34:09 -04:00
|
|
|
}
|
|
|
|
|
2009-11-01 18:56:03 -05:00
|
|
|
|
2009-09-24 09:34:09 -04:00
|
|
|
/* cogl_clear is called to clear the buffers */
|
2010-09-03 11:55:12 -04:00
|
|
|
cogl_color_init_from_4ub (&transparent_col, 0, 0, 0, 0);
|
2009-09-24 09:34:09 -04:00
|
|
|
cogl_clear (&transparent_col,
|
|
|
|
COGL_BUFFER_BIT_COLOR |
|
|
|
|
COGL_BUFFER_BIT_DEPTH);
|
|
|
|
cogl_disable_fog ();
|
|
|
|
|
|
|
|
/* Render the actor to the fbo */
|
|
|
|
clutter_actor_paint (priv->fbo_source);
|
|
|
|
|
2009-11-26 14:06:35 -05:00
|
|
|
/* Restore drawing to the previous framebuffer */
|
|
|
|
cogl_pop_framebuffer ();
|
2009-09-24 09:34:09 -04:00
|
|
|
|
|
|
|
/* If there is a shader on top of the shader stack, turn it back on. */
|
|
|
|
if (shader)
|
|
|
|
clutter_shader_set_is_enabled (shader, TRUE);
|
|
|
|
}
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
static void
|
2009-09-25 14:14:40 -04:00
|
|
|
gen_texcoords_and_draw_cogl_rectangle (ClutterActor *self)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
2007-03-19 06:00:38 -04:00
|
|
|
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
2007-07-26 07:04:04 -04:00
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
2009-09-25 14:14:40 -04:00
|
|
|
ClutterActorBox box;
|
|
|
|
float t_w, t_h;
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2009-05-20 12:38:58 -04:00
|
|
|
clutter_actor_get_allocation_box (self, &box);
|
2007-04-27 17:13:06 -04:00
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
if (priv->repeat_x && priv->image_width > 0)
|
2009-09-25 14:14:40 -04:00
|
|
|
t_w = (box.x2 - box.x1) / (float) priv->image_width;
|
2008-04-25 09:37:36 -04:00
|
|
|
else
|
2009-01-20 11:20:54 -05:00
|
|
|
t_w = 1.0;
|
2008-10-30 12:37:55 -04:00
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
if (priv->repeat_y && priv->image_height > 0)
|
2009-09-25 14:14:40 -04:00
|
|
|
t_h = (box.y2 - box.y1) / (float) priv->image_height;
|
2008-04-25 09:37:36 -04:00
|
|
|
else
|
2009-01-20 11:20:54 -05:00
|
|
|
t_h = 1.0;
|
2008-04-25 09:37:36 -04:00
|
|
|
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 11:15:40 -05:00
|
|
|
cogl_rectangle_with_texture_coords (0, 0,
|
2009-05-20 12:38:58 -04:00
|
|
|
box.x2 - box.x1,
|
|
|
|
box.y2 - box.y1,
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 11:15:40 -05:00
|
|
|
0, 0, t_w, t_h);
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
2009-09-25 14:14:40 -04:00
|
|
|
static CoglHandle
|
|
|
|
create_pick_material (ClutterActor *self)
|
|
|
|
{
|
2010-05-28 12:11:31 -04:00
|
|
|
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
2010-09-02 09:48:30 -04:00
|
|
|
CoglHandle pick_material = cogl_material_copy (texture_template_material);
|
2009-09-25 14:14:40 -04:00
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
if (!cogl_material_set_layer_combine (pick_material, 0,
|
|
|
|
"RGBA = "
|
|
|
|
" MODULATE (CONSTANT, TEXTURE[A])",
|
|
|
|
&error))
|
|
|
|
{
|
2010-05-28 12:11:31 -04:00
|
|
|
if (!priv->seen_create_pick_material_warning)
|
2009-09-25 14:14:40 -04:00
|
|
|
g_warning ("Error setting up texture combine for shaped "
|
|
|
|
"texture picking: %s", error->message);
|
2010-05-28 12:11:31 -04:00
|
|
|
priv->seen_create_pick_material_warning = TRUE;
|
2009-09-25 14:14:40 -04:00
|
|
|
g_error_free (error);
|
|
|
|
cogl_handle_unref (pick_material);
|
|
|
|
return COGL_INVALID_HANDLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
cogl_material_set_blend (pick_material,
|
|
|
|
"RGBA = ADD (SRC_COLOR[RGBA], 0)",
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
cogl_material_set_alpha_test_function (pick_material,
|
|
|
|
COGL_MATERIAL_ALPHA_FUNC_EQUAL,
|
|
|
|
1.0);
|
|
|
|
|
|
|
|
return pick_material;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_texture_pick (ClutterActor *self,
|
|
|
|
const ClutterColor *color)
|
|
|
|
{
|
|
|
|
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
|
|
|
|
|
|
|
if (!clutter_actor_should_pick_paint (self))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (G_LIKELY (priv->pick_with_alpha_supported) && priv->pick_with_alpha)
|
|
|
|
{
|
|
|
|
CoglColor pick_color;
|
|
|
|
|
|
|
|
if (priv->pick_material == COGL_INVALID_HANDLE)
|
|
|
|
priv->pick_material = create_pick_material (self);
|
|
|
|
|
|
|
|
if (priv->pick_material == COGL_INVALID_HANDLE)
|
|
|
|
{
|
|
|
|
priv->pick_with_alpha_supported = FALSE;
|
|
|
|
CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->pick (self,
|
|
|
|
color);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (priv->fbo_handle != COGL_INVALID_HANDLE)
|
|
|
|
update_fbo (self);
|
|
|
|
|
2010-09-03 11:55:12 -04:00
|
|
|
cogl_color_init_from_4ub (&pick_color,
|
|
|
|
color->red,
|
|
|
|
color->green,
|
|
|
|
color->blue,
|
|
|
|
0xff);
|
2009-09-25 14:14:40 -04:00
|
|
|
cogl_material_set_layer_combine_constant (priv->pick_material,
|
|
|
|
0, &pick_color);
|
|
|
|
cogl_material_set_layer (priv->pick_material, 0,
|
|
|
|
clutter_texture_get_cogl_texture (texture));
|
|
|
|
cogl_set_source (priv->pick_material);
|
|
|
|
gen_texcoords_and_draw_cogl_rectangle (self);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->pick (self, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_texture_paint (ClutterActor *self)
|
|
|
|
{
|
|
|
|
ClutterTexture *texture = CLUTTER_TEXTURE (self);
|
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
|
|
|
guint8 paint_opacity = clutter_actor_get_paint_opacity (self);
|
|
|
|
|
|
|
|
CLUTTER_NOTE (PAINT,
|
|
|
|
"painting texture '%s'",
|
|
|
|
clutter_actor_get_name (self) ? clutter_actor_get_name (self)
|
|
|
|
: "unknown");
|
|
|
|
|
|
|
|
if (priv->fbo_handle != COGL_INVALID_HANDLE)
|
|
|
|
update_fbo (self);
|
|
|
|
|
|
|
|
cogl_material_set_color4ub (priv->material,
|
|
|
|
paint_opacity,
|
|
|
|
paint_opacity,
|
|
|
|
paint_opacity,
|
|
|
|
paint_opacity);
|
|
|
|
cogl_set_source (priv->material);
|
|
|
|
|
|
|
|
gen_texcoords_and_draw_cogl_rectangle (self);
|
|
|
|
}
|
|
|
|
|
2010-09-08 14:47:11 -04:00
|
|
|
static gboolean
|
2010-09-09 07:30:29 -04:00
|
|
|
clutter_texture_get_paint_volume (ClutterActor *self,
|
2010-09-08 14:47:11 -04:00
|
|
|
ClutterPaintVolume *volume)
|
|
|
|
{
|
2010-09-09 07:30:29 -04:00
|
|
|
return _clutter_actor_set_default_paint_volume (self,
|
|
|
|
CLUTTER_TYPE_TEXTURE,
|
|
|
|
volume);
|
2010-09-08 14:47:11 -04:00
|
|
|
}
|
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
static void
|
|
|
|
clutter_texture_async_data_free (ClutterTextureAsyncData *data)
|
|
|
|
{
|
|
|
|
/* This function should only be called either from the main thread
|
|
|
|
once it is known that the load thread has completed or from the
|
2009-07-09 15:45:08 -04:00
|
|
|
load thread/upload function itself if the abort flag is true (in
|
|
|
|
which case the main thread has disowned the data) */
|
2009-02-25 12:10:54 -05:00
|
|
|
|
|
|
|
if (data->load_filename)
|
|
|
|
g_free (data->load_filename);
|
|
|
|
|
|
|
|
if (data->load_bitmap)
|
2009-04-30 13:00:22 -04:00
|
|
|
cogl_handle_unref (data->load_bitmap);
|
2009-02-25 12:10:54 -05:00
|
|
|
|
|
|
|
if (data->load_error)
|
|
|
|
g_error_free (data->load_error);
|
|
|
|
|
|
|
|
if (data->mutex)
|
|
|
|
g_mutex_free (data->mutex);
|
|
|
|
|
|
|
|
g_slice_free (ClutterTextureAsyncData, data);
|
|
|
|
}
|
|
|
|
|
2009-01-12 11:54:30 -05:00
|
|
|
/*
|
|
|
|
* clutter_texture_async_load_cancel:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
*
|
|
|
|
* Cancels an asynchronous loading operation, whether done
|
|
|
|
* with threads enabled or just using the main loop
|
|
|
|
*/
|
2009-01-07 12:02:43 -05:00
|
|
|
static void
|
2009-01-12 11:54:30 -05:00
|
|
|
clutter_texture_async_load_cancel (ClutterTexture *texture)
|
2009-01-07 12:02:43 -05:00
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
if (priv->async_data)
|
2009-01-07 12:02:43 -05:00
|
|
|
{
|
2009-02-25 12:10:54 -05:00
|
|
|
GMutex *mutex = priv->async_data->mutex;
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
/* The mutex will only be NULL if the no thread was used for
|
|
|
|
this load, in which case there's no need for any
|
|
|
|
synchronization */
|
|
|
|
if (mutex)
|
|
|
|
g_mutex_lock (mutex);
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
/* If there is no thread behind this load then we can just abort
|
|
|
|
the idle handler and destroy the load data immediately */
|
|
|
|
if (priv->async_data->load_idle)
|
|
|
|
{
|
|
|
|
g_source_remove (priv->async_data->load_idle);
|
|
|
|
priv->async_data->load_idle = 0;
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
if (mutex)
|
|
|
|
g_mutex_unlock (mutex);
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
clutter_texture_async_data_free (priv->async_data);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise we need to tell the thread to abort and disown
|
2009-07-09 15:45:08 -04:00
|
|
|
the data, if the data has been loaded and decoded the data
|
|
|
|
is now waiting for a master clock iteration to be repainted */
|
2009-02-25 12:10:54 -05:00
|
|
|
priv->async_data->abort = TRUE;
|
|
|
|
|
|
|
|
if (mutex)
|
|
|
|
g_mutex_unlock (mutex);
|
|
|
|
}
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
priv->async_data = NULL;
|
|
|
|
}
|
2009-01-07 12:02:43 -05:00
|
|
|
}
|
|
|
|
|
2007-10-12 04:17:00 -04:00
|
|
|
static void
|
2006-05-29 04:59:36 -04:00
|
|
|
clutter_texture_dispose (GObject *object)
|
|
|
|
{
|
2007-07-26 07:04:04 -04:00
|
|
|
ClutterTexture *texture = CLUTTER_TEXTURE (object);
|
2010-09-06 13:08:44 -04:00
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2007-07-24 13:38:35 -04:00
|
|
|
texture_free_gl_resources (texture);
|
2008-02-03 18:25:12 -05:00
|
|
|
texture_fbo_free_resources (texture);
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2009-01-12 11:54:30 -05:00
|
|
|
clutter_texture_async_load_cancel (texture);
|
2009-02-05 13:27:04 -05:00
|
|
|
|
|
|
|
if (priv->material != COGL_INVALID_HANDLE)
|
|
|
|
{
|
2009-04-01 12:16:44 -04:00
|
|
|
cogl_handle_unref (priv->material);
|
2009-02-05 13:27:04 -05:00
|
|
|
priv->material = COGL_INVALID_HANDLE;
|
|
|
|
}
|
2009-02-05 15:24:18 -05:00
|
|
|
|
2009-09-25 14:14:40 -04:00
|
|
|
if (priv->pick_material != COGL_INVALID_HANDLE)
|
|
|
|
{
|
|
|
|
cogl_handle_unref (priv->pick_material);
|
|
|
|
priv->pick_material = COGL_INVALID_HANDLE;
|
|
|
|
}
|
|
|
|
|
2010-09-06 13:08:44 -04:00
|
|
|
G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_texture_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv = CLUTTER_TEXTURE (object)->priv;
|
|
|
|
|
2010-08-05 10:29:54 -04:00
|
|
|
g_free (priv->filename);
|
|
|
|
|
2009-02-05 15:24:18 -05:00
|
|
|
G_OBJECT_CLASS (clutter_texture_parent_class)->finalize (object);
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-10-12 04:17:00 -04:00
|
|
|
clutter_texture_set_property (GObject *object,
|
2006-05-29 04:59:36 -04:00
|
|
|
guint prop_id,
|
2007-10-12 04:17:00 -04:00
|
|
|
const GValue *value,
|
2006-05-29 04:59:36 -04:00
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
2009-05-19 07:51:29 -04:00
|
|
|
ClutterTexture *texture;
|
2006-05-29 04:59:36 -04:00
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
|
2009-05-19 07:51:29 -04:00
|
|
|
texture = CLUTTER_TEXTURE (object);
|
2006-05-29 04:59:36 -04:00
|
|
|
priv = texture->priv;
|
|
|
|
|
2007-10-12 04:17:00 -04:00
|
|
|
switch (prop_id)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
|
|
|
case PROP_SYNC_SIZE:
|
2009-05-19 07:51:29 -04:00
|
|
|
clutter_texture_set_sync_size (texture, g_value_get_boolean (value));
|
2006-05-29 04:59:36 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
case PROP_REPEAT_X:
|
2009-05-19 07:51:29 -04:00
|
|
|
clutter_texture_set_repeat (texture,
|
|
|
|
g_value_get_boolean (value),
|
|
|
|
priv->repeat_y);
|
2006-05-29 04:59:36 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
case PROP_REPEAT_Y:
|
2009-05-19 07:51:29 -04:00
|
|
|
clutter_texture_set_repeat (texture,
|
|
|
|
priv->repeat_x,
|
|
|
|
g_value_get_boolean (value));
|
2006-05-29 04:59:36 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2006-06-06 16:40:40 -04:00
|
|
|
case PROP_FILTER_QUALITY:
|
2008-04-25 09:37:36 -04:00
|
|
|
clutter_texture_set_filter_quality (texture,
|
2008-06-07 11:08:05 -04:00
|
|
|
g_value_get_enum (value));
|
2008-04-25 09:37:36 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
case PROP_COGL_TEXTURE:
|
2009-05-19 07:51:29 -04:00
|
|
|
{
|
|
|
|
CoglHandle hnd = g_value_get_boxed (value);
|
|
|
|
|
|
|
|
clutter_texture_set_cogl_texture (texture, hnd);
|
|
|
|
}
|
2008-04-25 09:37:36 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
Fully integrates CoglMaterial throughout the rest of Cogl
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
2009-01-23 11:15:40 -05:00
|
|
|
case PROP_COGL_MATERIAL:
|
2009-05-19 07:51:29 -04:00
|
|
|
{
|
|
|
|
CoglHandle hnd = g_value_get_boxed (value);
|
|
|
|
|
|
|
|
clutter_texture_set_cogl_material (texture, hnd);
|
|
|
|
}
|
2008-12-23 11:39:11 -05:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
case PROP_FILENAME:
|
|
|
|
clutter_texture_set_from_file (texture,
|
|
|
|
g_value_get_string (value),
|
|
|
|
NULL);
|
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
case PROP_NO_SLICE:
|
|
|
|
priv->no_slice = g_value_get_boolean (value);
|
2006-06-06 16:40:40 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2008-06-23 11:31:12 -04:00
|
|
|
case PROP_KEEP_ASPECT_RATIO:
|
2009-05-19 07:51:29 -04:00
|
|
|
clutter_texture_set_keep_aspect_ratio (texture,
|
|
|
|
g_value_get_boolean (value));
|
2008-06-23 11:31:12 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2009-03-11 14:26:30 -04:00
|
|
|
case PROP_LOAD_DATA_ASYNC:
|
2009-05-19 07:51:29 -04:00
|
|
|
clutter_texture_set_load_data_async (texture,
|
|
|
|
g_value_get_boolean (value));
|
2009-03-11 14:26:30 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2009-01-07 12:02:43 -05:00
|
|
|
case PROP_LOAD_ASYNC:
|
2009-05-19 07:51:29 -04:00
|
|
|
clutter_texture_set_load_async (texture, g_value_get_boolean (value));
|
2009-01-07 12:02:43 -05:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2009-09-25 14:14:40 -04:00
|
|
|
case PROP_PICK_WITH_ALPHA:
|
|
|
|
clutter_texture_set_pick_with_alpha (texture,
|
|
|
|
g_value_get_boolean (value));
|
|
|
|
break;
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
}
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-10-12 04:17:00 -04:00
|
|
|
clutter_texture_get_property (GObject *object,
|
2006-05-29 04:59:36 -04:00
|
|
|
guint prop_id,
|
2007-10-12 04:17:00 -04:00
|
|
|
GValue *value,
|
2006-05-29 04:59:36 -04:00
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
ClutterTexture *texture;
|
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
|
|
|
|
texture = CLUTTER_TEXTURE(object);
|
|
|
|
priv = texture->priv;
|
|
|
|
|
2007-10-12 04:17:00 -04:00
|
|
|
switch (prop_id)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
|
|
|
case PROP_PIXEL_FORMAT:
|
2009-05-19 07:51:29 -04:00
|
|
|
g_value_set_enum (value, clutter_texture_get_pixel_format (texture));
|
2006-05-29 04:59:36 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
case PROP_MAX_TILE_WASTE:
|
|
|
|
g_value_set_int (value, clutter_texture_get_max_tile_waste (texture));
|
|
|
|
break;
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
case PROP_SYNC_SIZE:
|
2006-06-13 09:17:45 -04:00
|
|
|
g_value_set_boolean (value, priv->sync_actor_size);
|
2006-05-29 04:59:36 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
case PROP_REPEAT_X:
|
|
|
|
g_value_set_boolean (value, priv->repeat_x);
|
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
case PROP_REPEAT_Y:
|
|
|
|
g_value_set_boolean (value, priv->repeat_y);
|
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2006-06-06 16:40:40 -04:00
|
|
|
case PROP_FILTER_QUALITY:
|
2008-06-07 11:08:05 -04:00
|
|
|
g_value_set_enum (value, clutter_texture_get_filter_quality (texture));
|
2008-04-25 09:37:36 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
case PROP_COGL_TEXTURE:
|
|
|
|
g_value_set_boxed (value, clutter_texture_get_cogl_texture (texture));
|
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2008-12-23 11:39:11 -05:00
|
|
|
case PROP_COGL_MATERIAL:
|
|
|
|
g_value_set_boxed (value, clutter_texture_get_cogl_material (texture));
|
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
case PROP_NO_SLICE:
|
|
|
|
g_value_set_boolean (value, priv->no_slice);
|
2006-06-06 16:40:40 -04:00
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2008-06-23 11:31:12 -04:00
|
|
|
case PROP_KEEP_ASPECT_RATIO:
|
|
|
|
g_value_set_boolean (value, priv->keep_aspect_ratio);
|
|
|
|
break;
|
2009-05-19 07:51:29 -04:00
|
|
|
|
2009-09-25 14:14:40 -04:00
|
|
|
case PROP_PICK_WITH_ALPHA:
|
|
|
|
g_value_set_boolean (value, priv->pick_with_alpha);
|
|
|
|
break;
|
|
|
|
|
2010-08-05 10:29:54 -04:00
|
|
|
case PROP_FILENAME:
|
|
|
|
g_value_set_string (value, priv->filename);
|
|
|
|
break;
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
2007-10-12 04:17:00 -04:00
|
|
|
}
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_texture_class_init (ClutterTextureClass *klass)
|
|
|
|
{
|
2009-05-19 07:51:29 -04:00
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
2010-06-03 07:57:50 -04:00
|
|
|
GParamSpec *pspec;
|
2007-07-24 13:38:35 -04:00
|
|
|
|
|
|
|
g_type_class_add_private (klass, sizeof (ClutterTexturePrivate));
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2010-09-08 14:47:11 -04:00
|
|
|
actor_class->paint = clutter_texture_paint;
|
|
|
|
actor_class->pick = clutter_texture_pick;
|
|
|
|
actor_class->get_paint_volume = clutter_texture_get_paint_volume;
|
|
|
|
actor_class->realize = clutter_texture_realize;
|
|
|
|
actor_class->unrealize = clutter_texture_unrealize;
|
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
Bug #815 - Split up request, allocation, and paint box
* clutter/clutter-actor.[ch]: Rework the size allocation,
request and paint area. Now ::request_coords() is called
::allocate(), and ::query_coords() has been split into
::get_preferred_width() and ::get_preferred_height(). See
the documentation and the layout test on how to implement
a container and layout manager with the new API. (#915,
based on a patch by Havoc Pennington, Lucas Rocha and Johan
Bilien)
* clutter/clutter-clone-texture.c: Port CloneTexture to
the new size negotiation API; it just means forwarding
the requests to the parent texture.
* clutter/clutter-deprecated.h: Add deprecated and replaced
API.
* clutter/clutter-entry.c: Port Entry to the new size
negotiation API.
* clutter/clutter-group.c: Port Group to the new size
negotiation API; the semantics of the Group actor do not
change.
* clutter/clutter-label.c: Port Label to the new size
negotiation API, and vastly simplify the code.
* clutter/clutter-main.[ch]: Add API for executing a
relayout when needed.
* clutter/clutter-private.h: Add new Stage private API.
* clutter/clutter-rectangle.c: Update the get_abs_opacity()
call to get_paint_opacity().
* clutter/clutter-stage.c:
(clutter_stage_get_preferred_width),
(clutter_stage_get_preferred_height),
(clutter_stage_allocate),
(clutter_stage_class_init): Port Stage to the new size
negotiation API.
* clutter/clutter-texture.c: Port Texture to the new size
negotiation API.
* clutter/clutter-types.h: Add ClutterRequestMode enumeration.
* clutter/x11/clutter-stage-x11.c: Port the X11 stage
implementation to the new size negotiation API.
* tests/Makefile.am: Add the layout manager test case.
* tests/test-opacity.c: Update.
* tests/test-project.c: Update.
* tests/test-layout.c: Test case for a layout manager implemented
using the new size negotiation API; the layout manager handles
both transformed and untransformed children.
2008-06-10 13:07:52 -04:00
|
|
|
|
2008-07-04 06:44:18 -04:00
|
|
|
actor_class->get_preferred_width = clutter_texture_get_preferred_width;
|
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
Bug #815 - Split up request, allocation, and paint box
* clutter/clutter-actor.[ch]: Rework the size allocation,
request and paint area. Now ::request_coords() is called
::allocate(), and ::query_coords() has been split into
::get_preferred_width() and ::get_preferred_height(). See
the documentation and the layout test on how to implement
a container and layout manager with the new API. (#915,
based on a patch by Havoc Pennington, Lucas Rocha and Johan
Bilien)
* clutter/clutter-clone-texture.c: Port CloneTexture to
the new size negotiation API; it just means forwarding
the requests to the parent texture.
* clutter/clutter-deprecated.h: Add deprecated and replaced
API.
* clutter/clutter-entry.c: Port Entry to the new size
negotiation API.
* clutter/clutter-group.c: Port Group to the new size
negotiation API; the semantics of the Group actor do not
change.
* clutter/clutter-label.c: Port Label to the new size
negotiation API, and vastly simplify the code.
* clutter/clutter-main.[ch]: Add API for executing a
relayout when needed.
* clutter/clutter-private.h: Add new Stage private API.
* clutter/clutter-rectangle.c: Update the get_abs_opacity()
call to get_paint_opacity().
* clutter/clutter-stage.c:
(clutter_stage_get_preferred_width),
(clutter_stage_get_preferred_height),
(clutter_stage_allocate),
(clutter_stage_class_init): Port Stage to the new size
negotiation API.
* clutter/clutter-texture.c: Port Texture to the new size
negotiation API.
* clutter/clutter-types.h: Add ClutterRequestMode enumeration.
* clutter/x11/clutter-stage-x11.c: Port the X11 stage
implementation to the new size negotiation API.
* tests/Makefile.am: Add the layout manager test case.
* tests/test-opacity.c: Update.
* tests/test-project.c: Update.
* tests/test-layout.c: Test case for a layout manager implemented
using the new size negotiation API; the layout manager handles
both transformed and untransformed children.
2008-06-10 13:07:52 -04:00
|
|
|
actor_class->get_preferred_height = clutter_texture_get_preferred_height;
|
2008-07-04 06:44:18 -04:00
|
|
|
actor_class->allocate = clutter_texture_allocate;
|
2006-05-29 04:59:36 -04:00
|
|
|
|
|
|
|
gobject_class->dispose = clutter_texture_dispose;
|
2009-02-05 15:24:18 -05:00
|
|
|
gobject_class->finalize = clutter_texture_finalize;
|
2006-05-29 04:59:36 -04:00
|
|
|
gobject_class->set_property = clutter_texture_set_property;
|
|
|
|
gobject_class->get_property = clutter_texture_get_property;
|
|
|
|
|
2010-06-03 07:57:50 -04:00
|
|
|
pspec = g_param_spec_boolean ("sync-size",
|
|
|
|
P_("Sync size of actor"),
|
|
|
|
P_("Auto sync size of actor to underlying pixbuf dimensions"),
|
|
|
|
TRUE,
|
|
|
|
CLUTTER_PARAM_READWRITE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_SYNC_SIZE] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_SYNC_SIZE, pspec);
|
|
|
|
|
|
|
|
pspec = g_param_spec_boolean ("disable-slicing",
|
|
|
|
P_("Disable Slicing"),
|
2010-10-05 03:35:19 -04:00
|
|
|
P_("Forces the underlying texture to be singular and not made of smaller space saving "
|
|
|
|
"individual textures"),
|
2010-06-03 07:57:50 -04:00
|
|
|
FALSE,
|
|
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
CLUTTER_PARAM_READWRITE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_NO_SLICE] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_NO_SLICE, pspec);
|
|
|
|
|
|
|
|
pspec = g_param_spec_int ("tile-waste",
|
|
|
|
P_("Tile Waste"),
|
|
|
|
P_("Maximum waste area of a sliced texture"),
|
|
|
|
-1, G_MAXINT,
|
|
|
|
COGL_TEXTURE_MAX_WASTE,
|
|
|
|
CLUTTER_PARAM_READABLE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_MAX_TILE_WASTE] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_MAX_TILE_WASTE, pspec);
|
|
|
|
|
|
|
|
pspec = g_param_spec_boolean ("repeat-x",
|
|
|
|
P_("Horizontal repeat"),
|
2010-10-05 03:35:19 -04:00
|
|
|
P_("Repeat the contents rather than scaling them horizontally"),
|
2010-06-03 07:57:50 -04:00
|
|
|
FALSE,
|
|
|
|
CLUTTER_PARAM_READWRITE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_REPEAT_X] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_REPEAT_X, pspec);
|
|
|
|
|
|
|
|
pspec = g_param_spec_boolean ("repeat-y",
|
|
|
|
P_("Vertical repeat"),
|
2010-10-05 03:35:19 -04:00
|
|
|
P_("Repeat the contents rather than scaling them vertically"),
|
2010-06-03 07:57:50 -04:00
|
|
|
FALSE,
|
|
|
|
CLUTTER_PARAM_READWRITE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_REPEAT_Y] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_REPEAT_Y, pspec);
|
|
|
|
|
|
|
|
pspec = g_param_spec_enum ("filter-quality",
|
|
|
|
P_("Filter Quality"),
|
2010-10-05 03:35:19 -04:00
|
|
|
P_("Rendering quality used when drawing the texture"),
|
2010-06-03 07:57:50 -04:00
|
|
|
CLUTTER_TYPE_TEXTURE_QUALITY,
|
|
|
|
CLUTTER_TEXTURE_QUALITY_MEDIUM,
|
|
|
|
G_PARAM_CONSTRUCT | CLUTTER_PARAM_READWRITE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_FILTER_QUALITY] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_FILTER_QUALITY, pspec);
|
|
|
|
|
|
|
|
pspec = g_param_spec_enum ("pixel-format",
|
|
|
|
P_("Pixel Format"),
|
2010-10-05 03:35:19 -04:00
|
|
|
P_("The Cogl pixel format to use"),
|
2010-06-03 07:57:50 -04:00
|
|
|
COGL_TYPE_PIXEL_FORMAT,
|
|
|
|
COGL_PIXEL_FORMAT_RGBA_8888,
|
|
|
|
CLUTTER_PARAM_READABLE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_PIXEL_FORMAT] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_PIXEL_FORMAT, pspec);
|
|
|
|
|
|
|
|
pspec = g_param_spec_boxed ("cogl-texture",
|
2010-10-05 03:03:19 -04:00
|
|
|
P_("Cogl Texture"),
|
|
|
|
P_("The underlying Cogl texture handle used to draw this actor"),
|
2010-06-03 07:57:50 -04:00
|
|
|
COGL_TYPE_HANDLE,
|
2010-08-05 10:29:54 -04:00
|
|
|
CLUTTER_PARAM_READWRITE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_COGL_TEXTURE] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_COGL_TEXTURE, pspec);
|
|
|
|
|
|
|
|
pspec = g_param_spec_boxed ("cogl-material",
|
2010-10-05 03:03:19 -04:00
|
|
|
P_("Cogl Material"),
|
|
|
|
P_("The underlying Cogl material handle used to draw this actor"),
|
2010-06-03 07:57:50 -04:00
|
|
|
COGL_TYPE_HANDLE,
|
2010-08-05 10:29:54 -04:00
|
|
|
CLUTTER_PARAM_READWRITE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_COGL_MATERIAL] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_COGL_MATERIAL, pspec);
|
|
|
|
|
2010-08-05 10:29:54 -04:00
|
|
|
/**
|
|
|
|
* ClutterTexture:filename:
|
|
|
|
*
|
|
|
|
* The path of the file containing the image data to be displayed by
|
|
|
|
* the texture.
|
|
|
|
*
|
|
|
|
* This property is unset when using the clutter_texture_set_from_*_data()
|
|
|
|
* family of functions.
|
|
|
|
*/
|
2010-06-03 07:57:50 -04:00
|
|
|
pspec = g_param_spec_string ("filename",
|
|
|
|
P_("Filename"),
|
2010-08-05 10:29:54 -04:00
|
|
|
P_("The path of the file containing the image data"),
|
2010-06-03 07:57:50 -04:00
|
|
|
NULL,
|
2010-08-05 10:29:54 -04:00
|
|
|
CLUTTER_PARAM_READWRITE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_FILENAME] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_FILENAME, pspec);
|
|
|
|
|
|
|
|
pspec = g_param_spec_boolean ("keep-aspect-ratio",
|
|
|
|
P_("Keep Aspect Ratio"),
|
|
|
|
P_("Keep the aspect ratio of the texture when requesting the preferred width or height"),
|
|
|
|
FALSE,
|
|
|
|
CLUTTER_PARAM_READWRITE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_KEEP_ASPECT_RATIO] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_KEEP_ASPECT_RATIO, pspec);
|
2009-03-12 06:14:40 -04:00
|
|
|
|
2009-01-12 11:54:30 -05:00
|
|
|
/**
|
2009-03-12 07:48:44 -04:00
|
|
|
* ClutterTexture:load-async:
|
2009-01-12 11:54:30 -05:00
|
|
|
*
|
2009-03-12 07:48:44 -04:00
|
|
|
* Tries to load a texture from a filename by using a local thread to perform
|
|
|
|
* the read operations. The initially created texture has dimensions 0x0 when
|
2009-03-12 07:48:44 -04:00
|
|
|
* the true size becomes available the #ClutterTexture::size-change signal is
|
2009-03-12 07:48:44 -04:00
|
|
|
* emitted and when the image has completed loading the
|
2009-03-12 07:48:44 -04:00
|
|
|
* #ClutterTexture::load-finished signal is emitted.
|
2009-01-12 11:54:30 -05:00
|
|
|
*
|
2009-03-12 07:48:44 -04:00
|
|
|
* Threading is only enabled if g_thread_init() has been called prior to
|
|
|
|
* clutter_init(), otherwise #ClutterTexture will use the main loop to load
|
|
|
|
* the image.
|
|
|
|
*
|
|
|
|
* The upload of the texture data on the GL pipeline is not asynchronous, as
|
|
|
|
* it must be performed from within the same thread that called
|
|
|
|
* clutter_main().
|
2009-01-12 11:54:30 -05:00
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
2010-06-03 07:57:50 -04:00
|
|
|
pspec = g_param_spec_boolean ("load-async",
|
|
|
|
P_("Load asynchronously"),
|
2010-10-05 03:35:19 -04:00
|
|
|
P_("Load files inside a thread to avoid blocking when loading images from disk"),
|
2010-06-03 07:57:50 -04:00
|
|
|
FALSE,
|
|
|
|
CLUTTER_PARAM_WRITABLE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_LOAD_ASYNC] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_LOAD_ASYNC, pspec);
|
2009-03-11 14:26:30 -04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2009-03-12 07:48:44 -04:00
|
|
|
* ClutterTexture:load-data-async:
|
2009-03-11 14:26:30 -04:00
|
|
|
*
|
2009-03-12 07:48:44 -04:00
|
|
|
* Like #ClutterTexture:load-async but loads the width and height
|
2009-03-12 07:48:44 -04:00
|
|
|
* synchronously causing some blocking.
|
2009-03-11 14:26:30 -04:00
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
2010-06-03 07:57:50 -04:00
|
|
|
pspec = g_param_spec_boolean ("load-data-async",
|
|
|
|
P_("Load data asynchronously"),
|
2010-10-05 03:35:19 -04:00
|
|
|
P_("Decode image data files inside a thread to reduce blocking when loading images from disk"),
|
2010-06-03 07:57:50 -04:00
|
|
|
FALSE,
|
|
|
|
CLUTTER_PARAM_WRITABLE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_LOAD_DATA_ASYNC] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_LOAD_DATA_ASYNC, pspec);
|
2009-01-07 12:02:43 -05:00
|
|
|
|
2009-09-25 14:14:40 -04:00
|
|
|
/**
|
|
|
|
* ClutterTexture::pick-with-alpha:
|
|
|
|
*
|
|
|
|
* Determines whether a #ClutterTexture should have it's shape defined
|
|
|
|
* by its alpha channel when picking.
|
|
|
|
*
|
|
|
|
* Be aware that this is a bit more costly than the default picking
|
|
|
|
* due to the texture lookup, extra test against the alpha value and
|
|
|
|
* the fact that it will also interrupt the batching of geometry
|
|
|
|
* done internally.
|
|
|
|
*
|
|
|
|
* Also there is currently no control over the threshold used to
|
|
|
|
* determine what value of alpha is considered pickable, and so
|
|
|
|
* only fully opaque parts of the texture will react to picking.
|
|
|
|
*
|
|
|
|
* Since: 1.4
|
|
|
|
*/
|
2010-06-03 07:57:50 -04:00
|
|
|
pspec = g_param_spec_boolean ("pick-with-alpha",
|
|
|
|
P_("Pick With Alpha"),
|
|
|
|
P_("Shape actor with alpha channel when picking"),
|
|
|
|
FALSE,
|
|
|
|
CLUTTER_PARAM_READWRITE);
|
2010-06-21 05:20:32 -04:00
|
|
|
obj_props[PROP_PICK_WITH_ALPHA] = pspec;
|
2010-06-03 07:57:50 -04:00
|
|
|
g_object_class_install_property (gobject_class, PROP_PICK_WITH_ALPHA, pspec);
|
2009-03-12 07:48:44 -04:00
|
|
|
|
2006-12-13 13:12:09 -05:00
|
|
|
/**
|
|
|
|
* ClutterTexture::size-change:
|
|
|
|
* @texture: the texture which received the signal
|
|
|
|
* @width: the width of the new texture
|
|
|
|
* @height: the height of the new texture
|
|
|
|
*
|
|
|
|
* The ::size-change signal is emitted each time the size of the
|
|
|
|
* pixbuf used by @texture changes. The new size is given as
|
|
|
|
* argument to the callback.
|
|
|
|
*/
|
|
|
|
texture_signals[SIZE_CHANGE] =
|
2006-05-29 04:59:36 -04:00
|
|
|
g_signal_new ("size-change",
|
|
|
|
G_TYPE_FROM_CLASS (gobject_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
G_STRUCT_OFFSET (ClutterTextureClass, size_change),
|
|
|
|
NULL, NULL,
|
2010-06-11 10:49:46 -04:00
|
|
|
_clutter_marshal_VOID__INT_INT,
|
2009-06-22 07:07:08 -04:00
|
|
|
G_TYPE_NONE, 2,
|
|
|
|
G_TYPE_INT,
|
|
|
|
G_TYPE_INT);
|
2006-12-13 13:12:09 -05:00
|
|
|
/**
|
|
|
|
* ClutterTexture::pixbuf-change:
|
|
|
|
* @texture: the texture which received the signal
|
2007-10-12 04:17:00 -04:00
|
|
|
*
|
2006-12-13 13:12:09 -05:00
|
|
|
* The ::pixbuf-change signal is emitted each time the pixbuf
|
|
|
|
* used by @texture changes.
|
|
|
|
*/
|
|
|
|
texture_signals[PIXBUF_CHANGE] =
|
2006-05-29 04:59:36 -04:00
|
|
|
g_signal_new ("pixbuf-change",
|
|
|
|
G_TYPE_FROM_CLASS (gobject_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
G_STRUCT_OFFSET (ClutterTextureClass, pixbuf_change),
|
|
|
|
NULL, NULL,
|
2010-06-11 10:49:46 -04:00
|
|
|
_clutter_marshal_VOID__VOID,
|
2007-10-12 04:17:00 -04:00
|
|
|
G_TYPE_NONE,
|
|
|
|
0);
|
2009-01-07 12:02:43 -05:00
|
|
|
/**
|
|
|
|
* ClutterTexture::load-finished:
|
|
|
|
* @texture: the texture which received the signal
|
|
|
|
* @error: A set error, or %NULL
|
|
|
|
*
|
2009-01-12 11:54:30 -05:00
|
|
|
* The ::load-finished signal is emitted when a texture load has
|
|
|
|
* completed. If there was an error during loading, @error will
|
|
|
|
* be set, otherwise it will be %NULL
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
2009-01-07 12:02:43 -05:00
|
|
|
*/
|
|
|
|
texture_signals[LOAD_FINISHED] =
|
2009-01-12 11:54:30 -05:00
|
|
|
g_signal_new (I_("load-finished"),
|
2009-01-07 12:02:43 -05:00
|
|
|
G_TYPE_FROM_CLASS (gobject_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
G_STRUCT_OFFSET (ClutterTextureClass, load_finished),
|
|
|
|
NULL, NULL,
|
2010-06-11 10:49:46 -04:00
|
|
|
_clutter_marshal_VOID__POINTER,
|
2009-01-07 12:02:43 -05:00
|
|
|
G_TYPE_NONE,
|
|
|
|
1,
|
|
|
|
G_TYPE_POINTER);
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
static ClutterScriptableIface *parent_scriptable_iface = NULL;
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_texture_set_custom_property (ClutterScriptable *scriptable,
|
|
|
|
ClutterScript *script,
|
|
|
|
const gchar *name,
|
|
|
|
const GValue *value)
|
|
|
|
{
|
|
|
|
ClutterTexture *texture = CLUTTER_TEXTURE (scriptable);
|
|
|
|
|
|
|
|
if (strcmp ("filename", name) == 0)
|
|
|
|
{
|
|
|
|
const gchar *str = g_value_get_string (value);
|
|
|
|
gchar *path;
|
|
|
|
GError *error;
|
|
|
|
|
2008-06-24 12:47:43 -04:00
|
|
|
path = clutter_script_lookup_filename (script, str);
|
|
|
|
if (G_UNLIKELY (!path))
|
2010-10-31 12:49:40 -04:00
|
|
|
{
|
|
|
|
g_warning ("Unable to find image %s", str);
|
|
|
|
return;
|
|
|
|
}
|
2008-04-25 09:37:36 -04:00
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
clutter_texture_set_from_file (texture, path, &error);
|
|
|
|
if (error)
|
|
|
|
{
|
2009-03-17 10:12:01 -04:00
|
|
|
g_warning ("Unable to open image path at '%s': %s",
|
2008-04-25 09:37:36 -04:00
|
|
|
path,
|
|
|
|
error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (path);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* chain up */
|
|
|
|
if (parent_scriptable_iface->set_custom_property)
|
|
|
|
parent_scriptable_iface->set_custom_property (scriptable, script,
|
|
|
|
name,
|
|
|
|
value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_scriptable_iface_init (ClutterScriptableIface *iface)
|
|
|
|
{
|
|
|
|
parent_scriptable_iface = g_type_interface_peek_parent (iface);
|
|
|
|
|
|
|
|
if (!parent_scriptable_iface)
|
2008-12-23 11:29:29 -05:00
|
|
|
parent_scriptable_iface = g_type_default_interface_peek
|
2008-06-10 06:49:21 -04:00
|
|
|
(CLUTTER_TYPE_SCRIPTABLE);
|
2008-04-25 09:37:36 -04:00
|
|
|
|
|
|
|
iface->set_custom_property = clutter_texture_set_custom_property;
|
|
|
|
}
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
static void
|
|
|
|
clutter_texture_init (ClutterTexture *self)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
|
2007-10-12 04:17:00 -04:00
|
|
|
self->priv = priv = CLUTTER_TEXTURE_GET_PRIVATE (self);
|
2006-06-08 17:28:05 -04:00
|
|
|
|
2008-06-23 11:31:12 -04:00
|
|
|
priv->repeat_x = FALSE;
|
|
|
|
priv->repeat_y = FALSE;
|
|
|
|
priv->sync_actor_size = TRUE;
|
|
|
|
priv->fbo_handle = COGL_INVALID_HANDLE;
|
2009-09-25 14:14:40 -04:00
|
|
|
priv->pick_material = COGL_INVALID_HANDLE;
|
2008-06-23 11:31:12 -04:00
|
|
|
priv->keep_aspect_ratio = FALSE;
|
2009-09-25 14:14:40 -04:00
|
|
|
priv->pick_with_alpha = FALSE;
|
|
|
|
priv->pick_with_alpha_supported = TRUE;
|
2010-05-28 12:11:31 -04:00
|
|
|
priv->seen_create_pick_material_warning = FALSE;
|
2010-09-02 09:48:30 -04:00
|
|
|
|
|
|
|
if (G_UNLIKELY (texture_template_material == NULL))
|
|
|
|
{
|
|
|
|
CoglHandle dummy_tex;
|
|
|
|
|
|
|
|
dummy_tex = cogl_texture_new_with_size (1, 1, COGL_TEXTURE_NO_SLICING,
|
|
|
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE);
|
|
|
|
|
|
|
|
texture_template_material = cogl_material_new ();
|
|
|
|
cogl_material_set_layer (texture_template_material, 0, dummy_tex);
|
|
|
|
cogl_handle_unref (dummy_tex);
|
|
|
|
}
|
|
|
|
|
2010-09-18 03:41:52 -04:00
|
|
|
g_assert (texture_template_material != NULL);
|
2010-09-02 09:48:30 -04:00
|
|
|
priv->material = cogl_material_copy (texture_template_material);
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
2008-12-23 11:39:11 -05:00
|
|
|
/**
|
|
|
|
* clutter_texture_get_cogl_material:
|
|
|
|
* @texture: A #ClutterTexture
|
|
|
|
*
|
|
|
|
* Returns a handle to the underlying COGL material used for drawing
|
2010-09-03 07:14:50 -04:00
|
|
|
* the actor.
|
2008-12-23 11:39:11 -05:00
|
|
|
*
|
2010-09-03 07:14:50 -04:00
|
|
|
* Return value: (transfer none): a handle for a #CoglMaterial. The
|
|
|
|
* material is owned by the #ClutterTexture and it should not be
|
|
|
|
* unreferenced
|
2008-12-23 11:39:11 -05:00
|
|
|
*
|
2010-09-03 07:14:50 -04:00
|
|
|
* Since: 1.0
|
2008-12-23 11:39:11 -05:00
|
|
|
*/
|
|
|
|
CoglHandle
|
|
|
|
clutter_texture_get_cogl_material (ClutterTexture *texture)
|
|
|
|
{
|
2009-02-19 07:05:20 -05:00
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), COGL_INVALID_HANDLE);
|
|
|
|
|
2008-12-23 11:39:11 -05:00
|
|
|
return texture->priv->material;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_set_cogl_material:
|
|
|
|
* @texture: A #ClutterTexture
|
|
|
|
* @cogl_material: A CoglHandle for a material
|
|
|
|
*
|
2009-08-26 13:24:48 -04:00
|
|
|
* Replaces the underlying Cogl material drawn by this actor with
|
|
|
|
* @cogl_material. A reference to the material is taken so if the
|
|
|
|
* handle is no longer needed it should be deref'd with
|
|
|
|
* cogl_handle_unref. Texture data is attached to the material so
|
|
|
|
* calling this function also replaces the Cogl
|
|
|
|
* texture. #ClutterTexture requires that the material have a texture
|
|
|
|
* layer so you should set one on the material before calling this
|
|
|
|
* function.
|
2008-12-23 11:39:11 -05:00
|
|
|
*
|
|
|
|
* Since: 0.8
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
clutter_texture_set_cogl_material (ClutterTexture *texture,
|
|
|
|
CoglHandle cogl_material)
|
|
|
|
{
|
|
|
|
CoglHandle cogl_texture;
|
|
|
|
|
2009-02-19 07:05:20 -05:00
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
|
|
|
|
2009-08-26 13:28:35 -04:00
|
|
|
cogl_handle_ref (cogl_material);
|
|
|
|
|
2008-12-23 11:39:11 -05:00
|
|
|
if (texture->priv->material)
|
2009-04-01 12:16:44 -04:00
|
|
|
cogl_handle_unref (texture->priv->material);
|
2008-12-23 11:39:11 -05:00
|
|
|
|
|
|
|
texture->priv->material = cogl_material;
|
|
|
|
|
|
|
|
/* XXX: We are re-asserting the first layer of the new material to ensure the
|
|
|
|
* priv state is in sync with the contents of the material. */
|
|
|
|
cogl_texture = clutter_texture_get_cogl_texture (texture);
|
|
|
|
clutter_texture_set_cogl_texture (texture, cogl_texture);
|
|
|
|
/* XXX: If we add support for more material layers, this will need
|
|
|
|
* extending */
|
|
|
|
}
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
/**
|
2010-09-03 07:14:50 -04:00
|
|
|
* clutter_texture_get_cogl_texture:
|
2006-06-22 05:14:35 -04:00
|
|
|
* @texture: A #ClutterTexture
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2009-02-19 08:44:29 -05:00
|
|
|
* Retrieves the handle to the underlying COGL texture used for drawing
|
2008-04-25 09:37:36 -04:00
|
|
|
* the actor. No extra reference is taken so if you need to keep the
|
2009-04-01 12:16:44 -04:00
|
|
|
* handle then you should call cogl_handle_ref() on it.
|
2009-02-19 08:44:29 -05:00
|
|
|
*
|
|
|
|
* The texture handle returned is the first layer of the material
|
|
|
|
* handle used by the #ClutterTexture. If you need to access the other
|
|
|
|
* layers you should use clutter_texture_get_cogl_material() instead
|
|
|
|
* and use the #CoglMaterial API.
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2010-09-03 07:14:50 -04:00
|
|
|
* Return value: (transfer none): a #CoglHandle for the texture. The returned
|
|
|
|
* handle is owned by the #ClutterTexture and it should not be unreferenced
|
2008-01-21 06:39:23 -05:00
|
|
|
*
|
2010-09-03 07:14:50 -04:00
|
|
|
* Since: 0.8
|
2009-02-19 08:44:29 -05:00
|
|
|
*/
|
2008-04-25 09:37:36 -04:00
|
|
|
CoglHandle
|
|
|
|
clutter_texture_get_cogl_texture (ClutterTexture *texture)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
2010-09-18 03:41:52 -04:00
|
|
|
ClutterTexturePrivate *priv;
|
2010-09-06 12:50:57 -04:00
|
|
|
CoglMaterialLayerType layer_type;
|
2008-12-23 11:39:11 -05:00
|
|
|
const GList *layers;
|
|
|
|
int n_layers;
|
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), COGL_INVALID_HANDLE);
|
2008-02-05 09:49:29 -05:00
|
|
|
|
2010-09-18 03:41:52 -04:00
|
|
|
priv = texture->priv;
|
|
|
|
|
|
|
|
layers = cogl_material_get_layers (priv->material);
|
2010-09-06 12:50:57 -04:00
|
|
|
if (layers == NULL)
|
|
|
|
return COGL_INVALID_HANDLE;
|
|
|
|
|
2008-12-23 11:39:11 -05:00
|
|
|
n_layers = g_list_length ((GList *)layers);
|
|
|
|
if (n_layers == 0)
|
|
|
|
return COGL_INVALID_HANDLE;
|
2009-01-26 10:25:55 -05:00
|
|
|
|
2010-09-06 12:50:57 -04:00
|
|
|
layer_type = cogl_material_layer_get_type (layers->data);
|
|
|
|
if (layer_type != COGL_MATERIAL_LAYER_TYPE_TEXTURE)
|
|
|
|
return COGL_INVALID_HANDLE;
|
|
|
|
|
2008-12-23 11:39:11 -05:00
|
|
|
return cogl_material_layer_get_texture (layers->data);
|
2008-04-25 09:37:36 -04:00
|
|
|
}
|
2006-09-19 15:27:16 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
/**
|
|
|
|
* clutter_texture_set_cogl_texture
|
|
|
|
* @texture: A #ClutterTexture
|
|
|
|
* @cogl_tex: A CoglHandle for a texture
|
|
|
|
*
|
|
|
|
* Replaces the underlying COGL texture drawn by this actor with
|
|
|
|
* @cogl_tex. A reference to the texture is taken so if the handle is
|
2009-04-01 12:16:44 -04:00
|
|
|
* no longer needed it should be deref'd with cogl_handle_unref.
|
2008-04-25 09:37:36 -04:00
|
|
|
*
|
|
|
|
* Since: 0.8
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
clutter_texture_set_cogl_texture (ClutterTexture *texture,
|
|
|
|
CoglHandle cogl_tex)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv;
|
2009-06-22 07:07:08 -04:00
|
|
|
gboolean size_changed;
|
|
|
|
guint width, height;
|
2006-09-19 15:27:16 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
|
|
|
g_return_if_fail (cogl_is_texture (cogl_tex));
|
2008-02-05 09:49:29 -05:00
|
|
|
|
2010-04-15 08:57:45 -04:00
|
|
|
/* This function can set the texture without the actor being
|
|
|
|
realized. This is ok because Clutter requires that the GL context
|
|
|
|
always be current so there is no point in waiting to realization
|
|
|
|
to set the texture. */
|
Enforce invariants on mapped, realized, visibility states
Bug 1138 - No trackable "mapped" state
* Add a VISIBLE flag tracking application programmer's
expected showing-state for the actor, allowing us to
always ensure we keep what the app wants while tracking
internal implementation state separately.
* Make MAPPED reflect whether the actor will be painted;
add notification on a ClutterActor::mapped property.
Keep MAPPED state updated as the actor is shown,
ancestors are shown, actor is reparented, etc.
* Require a stage and realized parents to realize; this means
at realization time the correct window system and GL resources
are known. But unparented actors can no longer be realized.
* Allow children to be unrealized even if parent is realized.
Otherwise in effect either all actors or no actors are realized,
i.e. it becomes a stage-global flag.
* Allow clutter_actor_realize() to "fail" if not inside a toplevel
* Rework clutter_actor_unrealize() so internally we have
a flavor that does not mess with visibility flag
* Add _clutter_actor_rerealize() to encapsulate a somewhat
tricky operation we were doing in a couple of places
* Do not realize/unrealize children in ClutterGroup,
ClutterActor already does it
* Do not realize impl by hand in clutter_stage_show(),
since showing impl already does that
* Do not unrealize in various dispose() methods, since
ClutterActor dispose implementation already does it
and chaining up is mandatory
* ClutterTexture uses COGL while unrealizable (before it's
added to a stage). Previously this breakage was affecting
ClutterActor because we had to allow realize outside
a stage. Move the breakage to ClutterTexture, by making
ClutterTexture just use COGL while not realized.
* Unrealize before we set parent to NULL in clutter_actor_unparent().
This means unrealize() implementations can get to the stage.
Because actors need the stage in order to detach from stage.
* Update clutter-actor-invariants.txt to reflect latest changes
* Remove explicit hide/unrealize from ClutterActor::dispose since
unparent already forces those
Instead just assert that unparent() occurred and did the right thing.
* Check whether parent implements unrealize before chaining up
Needed because ClutterGroup no longer has to implement unrealize.
* Perform unrealize in the default handler for the signal.
This allows non-containers that have children to work properly,
and allows containers to override how it's done.
* Add map/unmap virtual methods and set MAPPED flag on self and
children in there. This allows subclasses to hook map/unmap.
These are not signals, because notify::mapped is better for
anything it's legitimate for a non-subclass to do.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
2009-04-02 09:16:43 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
priv = texture->priv;
|
2008-02-05 09:49:29 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
width = cogl_texture_get_width (cogl_tex);
|
|
|
|
height = cogl_texture_get_height (cogl_tex);
|
2008-02-05 09:49:29 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
/* Reference the new texture now in case it is the same one we are
|
|
|
|
already using */
|
2009-04-01 12:16:44 -04:00
|
|
|
cogl_handle_ref (cogl_tex);
|
2007-07-29 18:55:04 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
/* Remove FBO if exisiting */
|
|
|
|
if (priv->fbo_source)
|
|
|
|
texture_fbo_free_resources (texture);
|
2009-02-06 08:50:16 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
/* Remove old texture */
|
|
|
|
texture_free_gl_resources (texture);
|
Enforce invariants on mapped, realized, visibility states
Bug 1138 - No trackable "mapped" state
* Add a VISIBLE flag tracking application programmer's
expected showing-state for the actor, allowing us to
always ensure we keep what the app wants while tracking
internal implementation state separately.
* Make MAPPED reflect whether the actor will be painted;
add notification on a ClutterActor::mapped property.
Keep MAPPED state updated as the actor is shown,
ancestors are shown, actor is reparented, etc.
* Require a stage and realized parents to realize; this means
at realization time the correct window system and GL resources
are known. But unparented actors can no longer be realized.
* Allow children to be unrealized even if parent is realized.
Otherwise in effect either all actors or no actors are realized,
i.e. it becomes a stage-global flag.
* Allow clutter_actor_realize() to "fail" if not inside a toplevel
* Rework clutter_actor_unrealize() so internally we have
a flavor that does not mess with visibility flag
* Add _clutter_actor_rerealize() to encapsulate a somewhat
tricky operation we were doing in a couple of places
* Do not realize/unrealize children in ClutterGroup,
ClutterActor already does it
* Do not realize impl by hand in clutter_stage_show(),
since showing impl already does that
* Do not unrealize in various dispose() methods, since
ClutterActor dispose implementation already does it
and chaining up is mandatory
* ClutterTexture uses COGL while unrealizable (before it's
added to a stage). Previously this breakage was affecting
ClutterActor because we had to allow realize outside
a stage. Move the breakage to ClutterTexture, by making
ClutterTexture just use COGL while not realized.
* Unrealize before we set parent to NULL in clutter_actor_unparent().
This means unrealize() implementations can get to the stage.
Because actors need the stage in order to detach from stage.
* Update clutter-actor-invariants.txt to reflect latest changes
* Remove explicit hide/unrealize from ClutterActor::dispose since
unparent already forces those
Instead just assert that unparent() occurred and did the right thing.
* Check whether parent implements unrealize before chaining up
Needed because ClutterGroup no longer has to implement unrealize.
* Perform unrealize in the default handler for the signal.
This allows non-containers that have children to work properly,
and allows containers to override how it's done.
* Add map/unmap virtual methods and set MAPPED flag on self and
children in there. This allows subclasses to hook map/unmap.
These are not signals, because notify::mapped is better for
anything it's legitimate for a non-subclass to do.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
2009-04-02 09:16:43 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
/* Use the new texture */
|
2010-09-18 03:41:52 -04:00
|
|
|
if (priv->material == NULL)
|
|
|
|
priv->material = cogl_material_copy (texture_template_material);
|
|
|
|
|
|
|
|
g_assert (priv->material != NULL);
|
2008-12-23 11:39:11 -05:00
|
|
|
cogl_material_set_layer (priv->material, 0, cogl_tex);
|
2007-07-29 18:55:04 -04:00
|
|
|
|
2009-02-05 13:26:08 -05:00
|
|
|
/* The material now holds a reference to the texture so we can
|
|
|
|
safely release the reference we claimed above */
|
2009-04-01 12:16:44 -04:00
|
|
|
cogl_handle_unref (cogl_tex);
|
2009-02-05 13:26:08 -05:00
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
size_changed = (width != priv->image_width || height != priv->image_height);
|
|
|
|
priv->image_width = width;
|
|
|
|
priv->image_height = height;
|
2007-10-12 04:17:00 -04:00
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
CLUTTER_NOTE (TEXTURE, "set size (w:%d, h:%d)",
|
|
|
|
priv->image_width,
|
|
|
|
priv->image_height);
|
2006-09-19 15:27:16 -04:00
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
if (size_changed)
|
2008-04-25 09:37:36 -04:00
|
|
|
{
|
2008-06-10 Emmanuele Bassi <ebassi@openedhand.com>
Bug #815 - Split up request, allocation, and paint box
* clutter/clutter-actor.[ch]: Rework the size allocation,
request and paint area. Now ::request_coords() is called
::allocate(), and ::query_coords() has been split into
::get_preferred_width() and ::get_preferred_height(). See
the documentation and the layout test on how to implement
a container and layout manager with the new API. (#915,
based on a patch by Havoc Pennington, Lucas Rocha and Johan
Bilien)
* clutter/clutter-clone-texture.c: Port CloneTexture to
the new size negotiation API; it just means forwarding
the requests to the parent texture.
* clutter/clutter-deprecated.h: Add deprecated and replaced
API.
* clutter/clutter-entry.c: Port Entry to the new size
negotiation API.
* clutter/clutter-group.c: Port Group to the new size
negotiation API; the semantics of the Group actor do not
change.
* clutter/clutter-label.c: Port Label to the new size
negotiation API, and vastly simplify the code.
* clutter/clutter-main.[ch]: Add API for executing a
relayout when needed.
* clutter/clutter-private.h: Add new Stage private API.
* clutter/clutter-rectangle.c: Update the get_abs_opacity()
call to get_paint_opacity().
* clutter/clutter-stage.c:
(clutter_stage_get_preferred_width),
(clutter_stage_get_preferred_height),
(clutter_stage_allocate),
(clutter_stage_class_init): Port Stage to the new size
negotiation API.
* clutter/clutter-texture.c: Port Texture to the new size
negotiation API.
* clutter/clutter-types.h: Add ClutterRequestMode enumeration.
* clutter/x11/clutter-stage-x11.c: Port the X11 stage
implementation to the new size negotiation API.
* tests/Makefile.am: Add the layout manager test case.
* tests/test-opacity.c: Update.
* tests/test-project.c: Update.
* tests/test-layout.c: Test case for a layout manager implemented
using the new size negotiation API; the layout manager handles
both transformed and untransformed children.
2008-06-10 13:07:52 -04:00
|
|
|
g_signal_emit (texture, texture_signals[SIZE_CHANGE], 0,
|
2009-06-22 07:07:08 -04:00
|
|
|
priv->image_width,
|
|
|
|
priv->image_height);
|
2007-06-22 11:16:40 -04:00
|
|
|
|
2009-01-26 11:24:17 -05:00
|
|
|
if (priv->sync_actor_size)
|
2010-08-05 11:19:51 -04:00
|
|
|
{
|
|
|
|
ClutterActor *actor = CLUTTER_ACTOR (texture);
|
|
|
|
|
|
|
|
/* we have been requested to keep the actor size in
|
|
|
|
* sync with the texture data; if we also want to
|
|
|
|
* maintain the aspect ratio we want to change the
|
|
|
|
* requisition mode depending on the orientation of
|
|
|
|
* the texture, so that the parent container can do
|
|
|
|
* the right thing
|
|
|
|
*/
|
|
|
|
if (priv->keep_aspect_ratio)
|
|
|
|
{
|
|
|
|
ClutterRequestMode request;
|
|
|
|
|
2010-08-16 10:56:49 -04:00
|
|
|
if (priv->image_width >= priv->image_height)
|
2010-08-05 11:19:51 -04:00
|
|
|
request = CLUTTER_REQUEST_HEIGHT_FOR_WIDTH;
|
|
|
|
else
|
|
|
|
request = CLUTTER_REQUEST_WIDTH_FOR_HEIGHT;
|
|
|
|
|
|
|
|
clutter_actor_set_request_mode (actor, request);
|
|
|
|
}
|
|
|
|
|
|
|
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (texture));
|
|
|
|
}
|
2006-09-19 15:27:16 -04:00
|
|
|
}
|
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
/* rename signal */
|
|
|
|
g_signal_emit (texture, texture_signals[PIXBUF_CHANGE], 0);
|
|
|
|
|
|
|
|
/* If resized actor may need resizing but paint() will do this */
|
2010-02-09 14:34:32 -05:00
|
|
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (texture));
|
2010-08-05 10:29:54 -04:00
|
|
|
|
2010-06-21 05:20:32 -04:00
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_COGL_TEXTURE]);
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
static gboolean
|
|
|
|
clutter_texture_set_from_data (ClutterTexture *texture,
|
|
|
|
const guchar *data,
|
|
|
|
CoglPixelFormat source_format,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
gint rowstride,
|
|
|
|
gint bpp,
|
|
|
|
GError **error)
|
2007-12-20 09:26:07 -05:00
|
|
|
{
|
2009-01-18 09:51:19 -05:00
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
|
|
|
CoglHandle new_texture = COGL_INVALID_HANDLE;
|
|
|
|
CoglTextureFlags flags = COGL_TEXTURE_NONE;
|
2007-12-20 09:26:07 -05:00
|
|
|
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
if (priv->no_slice)
|
|
|
|
flags |= COGL_TEXTURE_NO_SLICING;
|
2009-01-18 09:51:19 -05:00
|
|
|
|
Enforce invariants on mapped, realized, visibility states
Bug 1138 - No trackable "mapped" state
* Add a VISIBLE flag tracking application programmer's
expected showing-state for the actor, allowing us to
always ensure we keep what the app wants while tracking
internal implementation state separately.
* Make MAPPED reflect whether the actor will be painted;
add notification on a ClutterActor::mapped property.
Keep MAPPED state updated as the actor is shown,
ancestors are shown, actor is reparented, etc.
* Require a stage and realized parents to realize; this means
at realization time the correct window system and GL resources
are known. But unparented actors can no longer be realized.
* Allow children to be unrealized even if parent is realized.
Otherwise in effect either all actors or no actors are realized,
i.e. it becomes a stage-global flag.
* Allow clutter_actor_realize() to "fail" if not inside a toplevel
* Rework clutter_actor_unrealize() so internally we have
a flavor that does not mess with visibility flag
* Add _clutter_actor_rerealize() to encapsulate a somewhat
tricky operation we were doing in a couple of places
* Do not realize/unrealize children in ClutterGroup,
ClutterActor already does it
* Do not realize impl by hand in clutter_stage_show(),
since showing impl already does that
* Do not unrealize in various dispose() methods, since
ClutterActor dispose implementation already does it
and chaining up is mandatory
* ClutterTexture uses COGL while unrealizable (before it's
added to a stage). Previously this breakage was affecting
ClutterActor because we had to allow realize outside
a stage. Move the breakage to ClutterTexture, by making
ClutterTexture just use COGL while not realized.
* Unrealize before we set parent to NULL in clutter_actor_unparent().
This means unrealize() implementations can get to the stage.
Because actors need the stage in order to detach from stage.
* Update clutter-actor-invariants.txt to reflect latest changes
* Remove explicit hide/unrealize from ClutterActor::dispose since
unparent already forces those
Instead just assert that unparent() occurred and did the right thing.
* Check whether parent implements unrealize before chaining up
Needed because ClutterGroup no longer has to implement unrealize.
* Perform unrealize in the default handler for the signal.
This allows non-containers that have children to work properly,
and allows containers to override how it's done.
* Add map/unmap virtual methods and set MAPPED flag on self and
children in there. This allows subclasses to hook map/unmap.
These are not signals, because notify::mapped is better for
anything it's legitimate for a non-subclass to do.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
2009-04-02 09:16:43 -04:00
|
|
|
/* FIXME if we are not realized, we should store the data
|
|
|
|
* for future use, instead of creating the texture.
|
|
|
|
*/
|
2009-01-18 09:51:19 -05:00
|
|
|
new_texture = cogl_texture_new_from_data (width, height,
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
flags,
|
2009-01-18 09:51:19 -05:00
|
|
|
source_format,
|
|
|
|
COGL_PIXEL_FORMAT_ANY,
|
|
|
|
rowstride,
|
|
|
|
data);
|
2007-12-20 09:26:07 -05:00
|
|
|
|
2009-01-18 09:51:19 -05:00
|
|
|
if (G_UNLIKELY (new_texture == COGL_INVALID_HANDLE))
|
2007-12-20 09:26:07 -05:00
|
|
|
{
|
2009-10-26 07:51:30 -04:00
|
|
|
GError *inner_error = NULL;
|
|
|
|
|
|
|
|
g_set_error (&inner_error, CLUTTER_TEXTURE_ERROR,
|
2008-04-25 09:37:36 -04:00
|
|
|
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
2010-10-05 03:03:19 -04:00
|
|
|
"Failed to create Cogl texture");
|
2007-12-20 09:26:07 -05:00
|
|
|
|
2009-10-26 07:51:30 -04:00
|
|
|
g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, inner_error);
|
|
|
|
|
|
|
|
if (error != NULL)
|
|
|
|
g_propagate_error (error, inner_error);
|
|
|
|
else
|
|
|
|
g_error_free (inner_error);
|
2009-06-06 10:57:29 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
return FALSE;
|
2007-12-20 09:26:07 -05:00
|
|
|
}
|
|
|
|
|
2010-08-05 10:29:54 -04:00
|
|
|
g_free (priv->filename);
|
|
|
|
priv->filename = NULL;
|
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
clutter_texture_set_cogl_texture (texture, new_texture);
|
2007-12-20 09:26:07 -05:00
|
|
|
|
2009-04-01 12:16:44 -04:00
|
|
|
cogl_handle_unref (new_texture);
|
2007-12-20 09:26:07 -05:00
|
|
|
|
2009-06-06 10:57:29 -04:00
|
|
|
g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, NULL);
|
2009-01-14 10:30:10 -05:00
|
|
|
|
2007-12-20 09:26:07 -05:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
/**
|
2007-05-25 06:56:09 -04:00
|
|
|
* clutter_texture_set_from_rgb_data:
|
2006-06-22 05:14:35 -04:00
|
|
|
* @texture: A #ClutterTexture
|
2008-02-15 12:11:50 -05:00
|
|
|
* @data: Image data in RGBA type colorspace.
|
2008-02-15 10:49:44 -05:00
|
|
|
* @has_alpha: Set to TRUE if image data has an alpha channel.
|
2006-09-19 15:27:16 -04:00
|
|
|
* @width: Width in pixels of image data.
|
|
|
|
* @height: Height in pixels of image data
|
|
|
|
* @rowstride: Distance in bytes between row starts.
|
2008-12-23 11:29:29 -05:00
|
|
|
* @bpp: bytes per pixel (Currently only 3 and 4 supported,
|
2008-07-01 06:11:39 -04:00
|
|
|
* depending on @has_alpha)
|
2007-05-25 06:56:09 -04:00
|
|
|
* @flags: #ClutterTextureFlags
|
2007-12-24 11:24:26 -05:00
|
|
|
* @error: return location for a #GError, or %NULL.
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2006-09-19 15:27:16 -04:00
|
|
|
* Sets #ClutterTexture image data.
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2007-12-24 11:24:26 -05:00
|
|
|
* Return value: %TRUE on success, %FALSE on failure.
|
|
|
|
*
|
|
|
|
* Since: 0.4.
|
2009-05-31 10:06:16 -04:00
|
|
|
*/
|
2007-10-12 04:17:00 -04:00
|
|
|
gboolean
|
2009-05-31 10:06:16 -04:00
|
|
|
clutter_texture_set_from_rgb_data (ClutterTexture *texture,
|
|
|
|
const guchar *data,
|
|
|
|
gboolean has_alpha,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
gint rowstride,
|
|
|
|
gint bpp,
|
|
|
|
ClutterTextureFlags flags,
|
|
|
|
GError **error)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
2009-05-31 10:06:16 -04:00
|
|
|
CoglPixelFormat source_format;
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE);
|
2007-05-25 06:56:09 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
/* Convert the flags to a CoglPixelFormat */
|
|
|
|
if (has_alpha)
|
2006-07-24 17:15:19 -04:00
|
|
|
{
|
2008-04-25 09:37:36 -04:00
|
|
|
if (bpp != 4)
|
2006-07-24 17:15:19 -04:00
|
|
|
{
|
2008-04-25 09:37:36 -04:00
|
|
|
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
|
|
|
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
2009-05-31 10:07:58 -04:00
|
|
|
"Unsupported bits per pixel value '%d': "
|
|
|
|
"Clutter supports only a BPP value of 4 "
|
|
|
|
"for RGBA data",
|
|
|
|
bpp);
|
2008-04-25 09:37:36 -04:00
|
|
|
return FALSE;
|
2006-07-24 17:15:19 -04:00
|
|
|
}
|
2009-05-31 10:07:58 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
source_format = COGL_PIXEL_FORMAT_RGBA_8888;
|
2006-09-19 15:27:16 -04:00
|
|
|
}
|
2008-04-25 09:37:36 -04:00
|
|
|
else
|
2006-09-19 15:27:16 -04:00
|
|
|
{
|
2008-04-25 09:37:36 -04:00
|
|
|
if (bpp != 3)
|
|
|
|
{
|
|
|
|
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
|
|
|
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
2009-05-31 10:07:58 -04:00
|
|
|
"Unsupported bits per pixel value '%d': "
|
|
|
|
"Clutter supports only a BPP value of 3 "
|
|
|
|
"for RGB data",
|
|
|
|
bpp);
|
2008-04-25 09:37:36 -04:00
|
|
|
return FALSE;
|
|
|
|
}
|
2009-05-31 10:07:58 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
source_format = COGL_PIXEL_FORMAT_RGB_888;
|
2006-09-19 15:27:16 -04:00
|
|
|
}
|
2009-05-31 10:07:58 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
if ((flags & CLUTTER_TEXTURE_RGB_FLAG_BGR))
|
|
|
|
source_format |= COGL_BGR_BIT;
|
|
|
|
if ((flags & CLUTTER_TEXTURE_RGB_FLAG_PREMULT))
|
|
|
|
source_format |= COGL_PREMULT_BIT;
|
|
|
|
|
|
|
|
return clutter_texture_set_from_data (texture, data,
|
|
|
|
source_format,
|
|
|
|
width, height,
|
|
|
|
rowstride, bpp,
|
|
|
|
error);
|
2007-05-25 06:56:09 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_set_from_yuv_data:
|
|
|
|
* @texture: A #ClutterTexture
|
2008-02-15 10:18:02 -05:00
|
|
|
* @data: Image data in YUV type colorspace.
|
2007-05-25 06:56:09 -04:00
|
|
|
* @width: Width in pixels of image data.
|
|
|
|
* @height: Height in pixels of image data
|
|
|
|
* @flags: #ClutterTextureFlags
|
2007-07-24 13:38:35 -04:00
|
|
|
* @error: Return location for a #GError, or %NULL.
|
2007-05-25 06:56:09 -04:00
|
|
|
*
|
2007-07-24 13:38:35 -04:00
|
|
|
* Sets a #ClutterTexture from YUV image data. If an error occurred,
|
|
|
|
* %FALSE is returned and @error is set.
|
2007-05-25 06:56:09 -04:00
|
|
|
*
|
2007-07-24 13:38:35 -04:00
|
|
|
* Return value: %TRUE if the texture was successfully updated
|
|
|
|
*
|
2008-12-05 09:08:06 -05:00
|
|
|
* Since: 0.4
|
2009-01-12 11:54:30 -05:00
|
|
|
*/
|
2007-10-12 04:17:00 -04:00
|
|
|
gboolean
|
2009-01-12 11:54:30 -05:00
|
|
|
clutter_texture_set_from_yuv_data (ClutterTexture *texture,
|
|
|
|
const guchar *data,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
ClutterTextureFlags flags,
|
|
|
|
GError **error)
|
2007-05-25 06:56:09 -04:00
|
|
|
{
|
2007-07-24 13:38:35 -04:00
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE);
|
|
|
|
|
|
|
|
if (!clutter_feature_available (CLUTTER_FEATURE_TEXTURE_YUV))
|
|
|
|
{
|
|
|
|
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
|
|
|
CLUTTER_TEXTURE_ERROR_NO_YUV,
|
|
|
|
"YUV textures are not supported");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2007-05-25 06:56:09 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
/* Convert the flags to a CoglPixelFormat */
|
|
|
|
if ((flags & CLUTTER_TEXTURE_YUV_FLAG_YUV2))
|
2007-05-25 06:56:09 -04:00
|
|
|
{
|
2008-04-25 09:37:36 -04:00
|
|
|
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
|
|
|
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
2009-05-31 10:07:58 -04:00
|
|
|
"YUV2 textues are not supported");
|
2008-04-25 09:37:36 -04:00
|
|
|
return FALSE;
|
2007-05-25 06:56:09 -04:00
|
|
|
}
|
2007-06-07 19:51:53 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
return clutter_texture_set_from_data (texture, data,
|
|
|
|
COGL_PIXEL_FORMAT_YUV,
|
|
|
|
width, height,
|
|
|
|
width * 3, 3,
|
|
|
|
error);
|
2006-09-19 15:27:16 -04:00
|
|
|
}
|
|
|
|
|
2009-01-12 11:54:30 -05:00
|
|
|
/*
|
|
|
|
* clutter_texture_async_load_complete:
|
|
|
|
* @self: a #ClutterTexture
|
2009-04-30 13:00:22 -04:00
|
|
|
* @bitmap: a handle to a CoglBitmap
|
2009-01-12 11:54:30 -05:00
|
|
|
* @error: load error
|
|
|
|
*
|
2009-02-25 12:10:54 -05:00
|
|
|
* If @error is %NULL, loads @bitmap into a #CoglTexture.
|
2009-01-12 11:54:30 -05:00
|
|
|
*
|
|
|
|
* This function emits the ::load-finished signal on @self.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
clutter_texture_async_load_complete (ClutterTexture *self,
|
2009-04-30 13:00:22 -04:00
|
|
|
CoglHandle bitmap,
|
2009-01-12 11:54:30 -05:00
|
|
|
const GError *error)
|
2009-01-07 12:02:43 -05:00
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv = self->priv;
|
2009-01-12 11:54:30 -05:00
|
|
|
CoglHandle handle;
|
2009-01-18 09:51:19 -05:00
|
|
|
CoglTextureFlags flags = COGL_TEXTURE_NONE;
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
priv->async_data = NULL;
|
|
|
|
|
2009-01-12 11:54:30 -05:00
|
|
|
if (error == NULL)
|
2009-01-07 12:02:43 -05:00
|
|
|
{
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
if (priv->no_slice)
|
|
|
|
flags |= COGL_TEXTURE_NO_SLICING;
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
handle = cogl_texture_new_from_bitmap (bitmap,
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
flags,
|
2009-01-18 09:51:19 -05:00
|
|
|
COGL_PIXEL_FORMAT_ANY);
|
2009-01-07 12:02:43 -05:00
|
|
|
clutter_texture_set_cogl_texture (self, handle);
|
2009-06-22 07:07:08 -04:00
|
|
|
|
2009-03-12 06:14:40 -04:00
|
|
|
if (priv->load_size_async)
|
|
|
|
{
|
2009-03-12 06:38:39 -04:00
|
|
|
g_signal_emit (self, texture_signals[SIZE_CHANGE], 0,
|
2009-06-22 07:07:08 -04:00
|
|
|
cogl_texture_get_width (handle),
|
2009-03-12 06:38:39 -04:00
|
|
|
cogl_texture_get_height (handle));
|
2009-03-12 06:14:40 -04:00
|
|
|
}
|
2009-06-06 10:57:29 -04:00
|
|
|
|
2009-04-01 12:16:44 -04:00
|
|
|
cogl_handle_unref (handle);
|
2009-01-07 12:02:43 -05:00
|
|
|
}
|
2009-01-12 11:54:30 -05:00
|
|
|
|
|
|
|
g_signal_emit (self, texture_signals[LOAD_FINISHED], 0, error);
|
2009-01-12 12:09:47 -05:00
|
|
|
|
|
|
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
2009-01-12 11:54:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2009-02-25 12:10:54 -05:00
|
|
|
clutter_texture_thread_idle_func (gpointer user_data)
|
2009-01-12 11:54:30 -05:00
|
|
|
{
|
2009-02-25 12:10:54 -05:00
|
|
|
ClutterTextureAsyncData *data = user_data;
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
/* Grab the mutex so we can be sure the thread has unlocked it
|
|
|
|
before we destroy it */
|
|
|
|
g_mutex_lock (data->mutex);
|
2009-07-09 15:45:08 -04:00
|
|
|
if (data->abort)
|
|
|
|
{
|
|
|
|
g_mutex_unlock (data->mutex);
|
|
|
|
clutter_texture_async_data_free (data);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-02-25 12:10:54 -05:00
|
|
|
g_mutex_unlock (data->mutex);
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
clutter_texture_async_load_complete (data->texture, data->load_bitmap,
|
|
|
|
data->load_error);
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
clutter_texture_async_data_free (data);
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-01-07 12:02:43 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-07-09 15:45:08 -04:00
|
|
|
static gboolean
|
2009-07-11 20:27:31 -04:00
|
|
|
texture_repaint_upload_func (gpointer user_data)
|
2009-07-09 15:45:08 -04:00
|
|
|
{
|
|
|
|
gulong start_time;
|
|
|
|
|
|
|
|
g_static_mutex_lock (&upload_list_mutex);
|
|
|
|
|
|
|
|
if (upload_list)
|
|
|
|
{
|
|
|
|
start_time = clutter_get_timestamp ();
|
2009-07-11 20:27:31 -04:00
|
|
|
|
|
|
|
/* continue uploading textures as long as we havent spent more
|
|
|
|
* then 5ms doing so this stage redraw cycle.
|
|
|
|
*/
|
2009-07-09 15:45:08 -04:00
|
|
|
do
|
|
|
|
{
|
|
|
|
ClutterTextureAsyncData *data = upload_list->data;
|
2009-07-11 20:27:31 -04:00
|
|
|
|
2009-07-09 15:45:08 -04:00
|
|
|
clutter_texture_thread_idle_func (data);
|
2009-07-11 20:27:31 -04:00
|
|
|
|
2009-07-09 15:45:08 -04:00
|
|
|
upload_list = g_list_remove (upload_list, data);
|
|
|
|
}
|
|
|
|
while (upload_list && clutter_get_timestamp () < start_time + 5 * 1000);
|
|
|
|
}
|
2009-07-11 20:27:31 -04:00
|
|
|
|
2009-07-09 15:45:08 -04:00
|
|
|
if (upload_list)
|
|
|
|
{
|
2009-07-11 20:27:31 -04:00
|
|
|
ClutterMasterClock *master_clock;
|
|
|
|
|
|
|
|
master_clock = _clutter_master_clock_get_default ();
|
|
|
|
_clutter_master_clock_ensure_next_iteration (master_clock);
|
2009-07-09 15:45:08 -04:00
|
|
|
}
|
2009-07-11 20:27:31 -04:00
|
|
|
|
2009-07-09 15:45:08 -04:00
|
|
|
g_static_mutex_unlock (&upload_list_mutex);
|
2009-07-11 20:27:31 -04:00
|
|
|
|
2009-07-09 15:45:08 -04:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
static void
|
|
|
|
clutter_texture_thread_func (gpointer user_data, gpointer pool_data)
|
2009-01-07 12:02:43 -05:00
|
|
|
{
|
2009-02-25 12:10:54 -05:00
|
|
|
ClutterTextureAsyncData *data = user_data;
|
|
|
|
gboolean should_abort;
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
/* Make sure we haven't been told to abort before the thread had a
|
|
|
|
chance to run */
|
|
|
|
g_mutex_lock (data->mutex);
|
|
|
|
should_abort = data->abort;
|
|
|
|
g_mutex_unlock (data->mutex);
|
|
|
|
|
|
|
|
if (should_abort)
|
2009-02-17 07:00:08 -05:00
|
|
|
{
|
2009-02-25 12:10:54 -05:00
|
|
|
/* If we've been told to abort then main thread has disowned the
|
|
|
|
async data and we need to free it */
|
|
|
|
clutter_texture_async_data_free (data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
data->load_bitmap = cogl_bitmap_new_from_file (data->load_filename,
|
|
|
|
&data->load_error);
|
|
|
|
|
|
|
|
/* Check again if we've been told to abort */
|
|
|
|
g_mutex_lock (data->mutex);
|
|
|
|
|
|
|
|
if (data->abort)
|
|
|
|
{
|
|
|
|
g_mutex_unlock (data->mutex);
|
|
|
|
|
|
|
|
clutter_texture_async_data_free (data);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-07-11 20:27:31 -04:00
|
|
|
ClutterMasterClock *master_clock = _clutter_master_clock_get_default ();
|
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
/* Make sure we give the image to GL in the main thread, where we
|
|
|
|
* hold the main Clutter lock. Once load_idle is non-NULL then the
|
|
|
|
* main thread is guaranteed not to set the abort flag. It can't
|
|
|
|
* set it while we're holding the mutex so we can safely start the
|
|
|
|
* idle handler now without the possibility of calling the
|
|
|
|
* callback after it is aborted */
|
2009-07-09 15:45:08 -04:00
|
|
|
g_static_mutex_lock (&upload_list_mutex);
|
2009-07-11 20:27:31 -04:00
|
|
|
|
2009-07-09 15:45:08 -04:00
|
|
|
if (repaint_upload_func == 0)
|
|
|
|
{
|
2009-07-11 20:27:31 -04:00
|
|
|
repaint_upload_func =
|
|
|
|
clutter_threads_add_repaint_func (texture_repaint_upload_func,
|
|
|
|
NULL, NULL);
|
2009-07-09 15:45:08 -04:00
|
|
|
}
|
2009-07-11 20:27:31 -04:00
|
|
|
|
2009-07-09 15:45:08 -04:00
|
|
|
upload_list = g_list_append (upload_list, data);
|
|
|
|
data->upload_queued = TRUE;
|
2009-07-11 20:27:31 -04:00
|
|
|
|
2009-07-09 15:45:08 -04:00
|
|
|
g_static_mutex_unlock (&upload_list_mutex);
|
2009-02-25 12:10:54 -05:00
|
|
|
|
|
|
|
g_mutex_unlock (data->mutex);
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-07-11 20:27:31 -04:00
|
|
|
_clutter_master_clock_ensure_next_iteration (master_clock);
|
|
|
|
}
|
2009-01-07 12:02:43 -05:00
|
|
|
}
|
|
|
|
|
2009-01-12 11:54:30 -05:00
|
|
|
static gboolean
|
2009-02-25 12:10:54 -05:00
|
|
|
clutter_texture_idle_func (gpointer user_data)
|
2009-01-12 11:54:30 -05:00
|
|
|
{
|
2009-02-25 12:10:54 -05:00
|
|
|
ClutterTextureAsyncData *data = user_data;
|
|
|
|
GError *internal_error = NULL;
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
data->load_bitmap = cogl_bitmap_new_from_file (data->load_filename,
|
2009-01-12 11:54:30 -05:00
|
|
|
&internal_error);
|
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
clutter_texture_async_load_complete (data->texture, data->load_bitmap,
|
|
|
|
internal_error);
|
2009-01-12 11:54:30 -05:00
|
|
|
|
|
|
|
if (internal_error)
|
|
|
|
g_error_free (internal_error);
|
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
clutter_texture_async_data_free (data);
|
|
|
|
|
2009-01-12 11:54:30 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* clutter_texture_async_load:
|
2009-02-25 12:10:54 -05:00
|
|
|
* @self: a #ClutterTExture
|
|
|
|
* @filename: name of the file to load
|
2009-01-12 11:54:30 -05:00
|
|
|
* @error: return location for a #GError
|
|
|
|
*
|
|
|
|
* Starts an asynchronous load of the file name stored inside
|
2009-02-25 12:10:54 -05:00
|
|
|
* the load_filename member of @data.
|
2009-01-12 11:54:30 -05:00
|
|
|
*
|
|
|
|
* If threading is enabled we use a GThread to perform the actual
|
|
|
|
* I/O; if threading is not enabled, we use an idle GSource.
|
|
|
|
*
|
|
|
|
* The I/O is the only bit done in a thread -- uploading the
|
|
|
|
* texture data to the GL pipeline must be done from within the
|
|
|
|
* same thread that called clutter_main(). Threaded upload should
|
|
|
|
* be part of the GL implementation.
|
|
|
|
*
|
|
|
|
* This function will block until we get a size from the file
|
|
|
|
* so that we can effectively get the size the texture actor after
|
|
|
|
* clutter_texture_set_from_file().
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the asynchronous loading was successfully
|
|
|
|
* initiated, %FALSE otherwise
|
|
|
|
*/
|
|
|
|
static gboolean
|
2009-02-25 12:10:54 -05:00
|
|
|
clutter_texture_async_load (ClutterTexture *self,
|
|
|
|
const gchar *filename,
|
|
|
|
GError **error)
|
2009-01-12 11:54:30 -05:00
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv = self->priv;
|
2009-02-25 12:10:54 -05:00
|
|
|
ClutterTextureAsyncData *data;
|
2009-01-12 11:54:30 -05:00
|
|
|
gint width, height;
|
|
|
|
gboolean res;
|
|
|
|
|
|
|
|
/* ask the file for a size; if we cannot get the size then
|
|
|
|
* there's no point in even continuing the asynchronous
|
|
|
|
* loading, so we just stop there
|
|
|
|
*/
|
2009-03-11 14:26:30 -04:00
|
|
|
|
|
|
|
if (priv->load_size_async)
|
|
|
|
{
|
|
|
|
res = TRUE;
|
2009-03-12 06:14:40 -04:00
|
|
|
width = 0;
|
|
|
|
height = 0;
|
2009-03-11 14:26:30 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
res = cogl_bitmap_get_size_from_file (filename, &width, &height);
|
|
|
|
}
|
|
|
|
|
2009-01-12 11:54:30 -05:00
|
|
|
if (!res)
|
|
|
|
{
|
|
|
|
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
|
|
|
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
2010-10-05 03:03:19 -04:00
|
|
|
"Failed to create Cogl texture");
|
2009-01-12 11:54:30 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
2009-01-12 12:09:47 -05:00
|
|
|
{
|
2009-06-22 07:07:08 -04:00
|
|
|
priv->image_width = width;
|
|
|
|
priv->image_height = height;
|
2009-01-12 12:09:47 -05:00
|
|
|
}
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
clutter_texture_async_load_cancel (self);
|
|
|
|
|
|
|
|
data = g_slice_new (ClutterTextureAsyncData);
|
|
|
|
|
|
|
|
data->abort = FALSE;
|
|
|
|
data->texture = self;
|
|
|
|
data->load_idle = 0;
|
|
|
|
data->load_filename = g_strdup (filename);
|
|
|
|
data->load_bitmap = NULL;
|
|
|
|
data->load_error = NULL;
|
|
|
|
|
|
|
|
priv->async_data = data;
|
|
|
|
|
2009-01-12 11:54:30 -05:00
|
|
|
if (g_thread_supported ())
|
|
|
|
{
|
2009-02-25 12:10:54 -05:00
|
|
|
data->mutex = g_mutex_new ();
|
|
|
|
|
|
|
|
if (async_thread_pool == NULL)
|
|
|
|
/* This apparently can't fail if exclusive == FALSE */
|
|
|
|
async_thread_pool
|
|
|
|
= g_thread_pool_new (clutter_texture_thread_func,
|
2009-03-10 09:00:57 -04:00
|
|
|
NULL, 1, FALSE, NULL);
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
g_thread_pool_push (async_thread_pool, data, NULL);
|
2009-01-12 11:54:30 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-25 12:10:54 -05:00
|
|
|
data->mutex = NULL;
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-02-25 12:10:54 -05:00
|
|
|
data->load_idle
|
|
|
|
= clutter_threads_add_idle (clutter_texture_idle_func, data);
|
2009-01-12 11:54:30 -05:00
|
|
|
}
|
2009-02-25 12:10:54 -05:00
|
|
|
|
|
|
|
return TRUE;
|
2009-01-12 11:54:30 -05:00
|
|
|
}
|
|
|
|
|
2006-09-19 15:27:16 -04:00
|
|
|
/**
|
2008-04-25 09:37:36 -04:00
|
|
|
* clutter_texture_set_from_file:
|
2006-09-19 15:27:16 -04:00
|
|
|
* @texture: A #ClutterTexture
|
2008-04-25 09:37:36 -04:00
|
|
|
* @filename: The filename of the image in GLib file name encoding
|
2007-07-24 13:38:35 -04:00
|
|
|
* @error: Return location for a #GError, or %NULL
|
2006-09-19 15:27:16 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Sets the #ClutterTexture image data from an image file. In case of
|
2007-07-24 13:38:35 -04:00
|
|
|
* failure, %FALSE is returned and @error is set.
|
2006-09-19 15:27:16 -04:00
|
|
|
*
|
2009-01-12 12:09:47 -05:00
|
|
|
* If #ClutterTexture:load-async is set to %TRUE, this function
|
|
|
|
* will return as soon as possible, and the actual image loading
|
2009-03-12 07:48:44 -04:00
|
|
|
* from disk will be performed asynchronously. #ClutterTexture::size-change
|
2009-05-12 09:15:18 -04:00
|
|
|
* will be emitten when the size of the texture is available and
|
2009-03-12 07:48:44 -04:00
|
|
|
* #ClutterTexture::load-finished will be emitted when the image has been
|
|
|
|
* loaded or if an error occurred.
|
2009-01-12 12:09:47 -05:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Return value: %TRUE if the image was successfully loaded and set
|
2007-07-24 13:38:35 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Since: 0.8
|
2007-07-24 13:38:35 -04:00
|
|
|
*/
|
2007-05-25 06:56:09 -04:00
|
|
|
gboolean
|
2008-04-25 09:37:36 -04:00
|
|
|
clutter_texture_set_from_file (ClutterTexture *texture,
|
|
|
|
const gchar *filename,
|
|
|
|
GError **error)
|
2006-09-19 15:27:16 -04:00
|
|
|
{
|
2009-01-12 11:54:30 -05:00
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
CoglHandle new_texture = COGL_INVALID_HANDLE;
|
|
|
|
GError *internal_error = NULL;
|
2009-01-18 09:51:19 -05:00
|
|
|
CoglTextureFlags flags = COGL_TEXTURE_NONE;
|
2007-05-25 06:56:09 -04:00
|
|
|
|
2008-03-18 13:56:50 -04:00
|
|
|
priv = texture->priv;
|
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2009-03-12 06:14:40 -04:00
|
|
|
if (priv->load_data_async)
|
2009-02-25 12:10:54 -05:00
|
|
|
return clutter_texture_async_load (texture, filename, error);
|
2009-01-07 12:02:43 -05:00
|
|
|
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
if (priv->no_slice)
|
|
|
|
flags |= COGL_TEXTURE_NO_SLICING;
|
2009-01-12 11:54:30 -05:00
|
|
|
|
|
|
|
new_texture = cogl_texture_new_from_file (filename,
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
flags,
|
2009-01-12 11:54:30 -05:00
|
|
|
COGL_PIXEL_FORMAT_ANY,
|
|
|
|
&internal_error);
|
2009-06-06 10:57:29 -04:00
|
|
|
|
|
|
|
/* If COGL didn't give an error then make one up */
|
|
|
|
if (internal_error == NULL && new_texture == COGL_INVALID_HANDLE)
|
2008-04-25 09:37:36 -04:00
|
|
|
{
|
2009-06-06 10:57:29 -04:00
|
|
|
g_set_error (&internal_error, CLUTTER_TEXTURE_ERROR,
|
|
|
|
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
2010-10-05 03:03:19 -04:00
|
|
|
"Failed to create Cogl texture");
|
2009-06-06 10:57:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (internal_error != NULL)
|
|
|
|
{
|
|
|
|
g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0,
|
|
|
|
internal_error);
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2009-06-06 10:57:29 -04:00
|
|
|
g_propagate_error (error, internal_error);
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
return FALSE;
|
|
|
|
}
|
2008-03-18 13:56:50 -04:00
|
|
|
|
2010-08-05 10:29:54 -04:00
|
|
|
g_free (priv->filename);
|
|
|
|
priv->filename = g_strdup (filename);
|
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
clutter_texture_set_cogl_texture (texture, new_texture);
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2009-04-01 12:16:44 -04:00
|
|
|
cogl_handle_unref (new_texture);
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2009-06-06 10:57:29 -04:00
|
|
|
g_signal_emit (texture, texture_signals[LOAD_FINISHED], 0, NULL);
|
2009-01-12 11:54:30 -05:00
|
|
|
|
2010-06-21 05:20:32 -04:00
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_FILENAME]);
|
2010-08-05 10:29:54 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
return TRUE;
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-06-12 07:43:25 -04:00
|
|
|
* clutter_texture_set_filter_quality:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
* @filter_quality: new filter quality value
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-06-10 07:18:19 -04:00
|
|
|
* Sets the filter quality when scaling a texture. The quality is an
|
|
|
|
* enumeration currently the following values are supported:
|
2008-06-12 07:43:25 -04:00
|
|
|
* %CLUTTER_TEXTURE_QUALITY_LOW which is fast but only uses nearest neighbour
|
|
|
|
* interpolation. %CLUTTER_TEXTURE_QUALITY_MEDIUM which is computationally a
|
|
|
|
* bit more expensive (bilinear interpolation), and
|
|
|
|
* %CLUTTER_TEXTURE_QUALITY_HIGH which uses extra texture memory resources to
|
|
|
|
* improve scaled down rendering as well (by using mipmaps). The default value
|
|
|
|
* is %CLUTTER_TEXTURE_QUALITY_MEDIUM.
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Since: 0.8
|
|
|
|
*/
|
2006-05-29 04:59:36 -04:00
|
|
|
void
|
2008-06-07 11:08:05 -04:00
|
|
|
clutter_texture_set_filter_quality (ClutterTexture *texture,
|
|
|
|
ClutterTextureQuality filter_quality)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv;
|
2008-06-07 11:08:05 -04:00
|
|
|
ClutterTextureQuality old_quality;
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2007-07-26 07:04:04 -04:00
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
|
|
|
|
2006-05-29 04:59:36 -04:00
|
|
|
priv = texture->priv;
|
2007-07-26 07:04:04 -04:00
|
|
|
|
2008-06-07 11:08:05 -04:00
|
|
|
old_quality = clutter_texture_get_filter_quality (texture);
|
2008-10-31 12:59:51 -04:00
|
|
|
|
2008-06-07 11:08:05 -04:00
|
|
|
if (filter_quality != old_quality)
|
2008-04-25 09:37:36 -04:00
|
|
|
{
|
2009-02-06 08:50:16 -05:00
|
|
|
gint min_filter, mag_filter;
|
|
|
|
|
2009-06-06 09:37:41 -04:00
|
|
|
min_filter = mag_filter = COGL_MATERIAL_FILTER_LINEAR;
|
2009-06-04 11:04:57 -04:00
|
|
|
clutter_texture_quality_to_filters (filter_quality,
|
2009-02-06 08:50:16 -05:00
|
|
|
&min_filter,
|
|
|
|
&mag_filter);
|
|
|
|
|
2009-06-04 11:04:57 -04:00
|
|
|
cogl_material_set_layer_filters (priv->material, 0,
|
|
|
|
min_filter, mag_filter);
|
2008-10-31 12:59:51 -04:00
|
|
|
|
2010-02-09 14:34:32 -05:00
|
|
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (texture));
|
2010-08-05 10:29:54 -04:00
|
|
|
|
2010-06-21 05:20:32 -04:00
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_FILTER_QUALITY]);
|
2008-04-25 09:37:36 -04:00
|
|
|
}
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-04-25 09:37:36 -04:00
|
|
|
* clutter_texture_get_filter_quality
|
2006-06-22 05:14:35 -04:00
|
|
|
* @texture: A #ClutterTexture
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Gets the filter quality used when scaling a texture.
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Return value: The filter quality value.
|
|
|
|
*
|
|
|
|
* Since: 0.8
|
|
|
|
*/
|
2008-06-07 11:08:05 -04:00
|
|
|
ClutterTextureQuality
|
2008-04-25 09:37:36 -04:00
|
|
|
clutter_texture_get_filter_quality (ClutterTexture *texture)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
2008-04-25 09:37:36 -04:00
|
|
|
ClutterTexturePrivate *priv;
|
2009-06-04 11:04:57 -04:00
|
|
|
const GList *layers;
|
|
|
|
CoglMaterialFilter min_filter, mag_filter;
|
|
|
|
int i;
|
2008-03-18 13:56:50 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), 0);
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
priv = texture->priv;
|
2006-05-29 04:59:36 -04:00
|
|
|
|
2009-06-04 11:04:57 -04:00
|
|
|
layers = cogl_material_get_layers (priv->material);
|
|
|
|
if (layers == NULL)
|
|
|
|
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++)
|
|
|
|
if (clutter_texture_quality_filters[i].min_filter == min_filter
|
|
|
|
&& clutter_texture_quality_filters[i].mag_filter == mag_filter)
|
|
|
|
return i;
|
|
|
|
|
|
|
|
/* Unknown filter combination */
|
|
|
|
return CLUTTER_TEXTURE_QUALITY_LOW;
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-04-25 09:37:36 -04:00
|
|
|
* clutter_texture_get_max_tile_waste
|
2006-06-22 05:14:35 -04:00
|
|
|
* @texture: A #ClutterTexture
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Gets the maximum waste that will be used when creating a texture or
|
|
|
|
* -1 if slicing is disabled.
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Return value: The maximum waste or -1 if the texture waste is
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
* unlimited.
|
2008-04-25 09:37:36 -04:00
|
|
|
*
|
|
|
|
* Since: 0.8
|
|
|
|
*/
|
|
|
|
gint
|
|
|
|
clutter_texture_get_max_tile_waste (ClutterTexture *texture)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
2007-03-19 06:00:38 -04:00
|
|
|
ClutterTexturePrivate *priv;
|
2008-12-23 11:39:11 -05:00
|
|
|
CoglHandle cogl_texture;
|
2007-03-19 06:00:38 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), 0);
|
2007-10-12 04:17:00 -04:00
|
|
|
|
2007-03-19 06:00:38 -04:00
|
|
|
priv = texture->priv;
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
|
2008-12-23 11:39:11 -05:00
|
|
|
cogl_texture = clutter_texture_get_cogl_texture (texture);
|
2007-03-19 06:00:38 -04:00
|
|
|
|
2008-12-23 11:39:11 -05:00
|
|
|
if (cogl_texture == COGL_INVALID_HANDLE)
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
return priv->no_slice ? -1 : COGL_TEXTURE_MAX_WASTE;
|
2008-04-25 09:37:36 -04:00
|
|
|
else
|
2008-12-23 11:39:11 -05:00
|
|
|
return cogl_texture_get_max_waste (cogl_texture);
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-04-25 09:37:36 -04:00
|
|
|
* clutter_texture_new_from_file:
|
|
|
|
* @filename: The name of an image file to load.
|
|
|
|
* @error: Return locatoin for an error.
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Creates a new ClutterTexture actor to display the image contained a
|
|
|
|
* file. If the image failed to load then NULL is returned and @error
|
|
|
|
* is set.
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Return value: A newly created #ClutterTexture object or NULL on
|
|
|
|
* error.
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Since: 0.8
|
2006-05-29 04:59:36 -04:00
|
|
|
**/
|
2008-04-25 09:37:36 -04:00
|
|
|
ClutterActor*
|
|
|
|
clutter_texture_new_from_file (const gchar *filename,
|
|
|
|
GError **error)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
2008-04-25 09:37:36 -04:00
|
|
|
ClutterActor *texture = clutter_texture_new ();
|
2007-03-19 06:00:38 -04:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
if (!clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
|
|
|
|
filename, error))
|
|
|
|
{
|
|
|
|
g_object_ref_sink (texture);
|
|
|
|
g_object_unref (texture);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return texture;
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-04-25 09:37:36 -04:00
|
|
|
* clutter_texture_new:
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Creates a new empty #ClutterTexture object.
|
2006-05-29 04:59:36 -04:00
|
|
|
*
|
2008-04-25 09:37:36 -04:00
|
|
|
* Return value: A newly created #ClutterTexture object.
|
2006-05-29 04:59:36 -04:00
|
|
|
**/
|
2008-04-25 09:37:36 -04:00
|
|
|
ClutterActor *
|
|
|
|
clutter_texture_new (void)
|
2006-05-29 04:59:36 -04:00
|
|
|
{
|
2008-04-25 09:37:36 -04:00
|
|
|
return g_object_new (CLUTTER_TYPE_TEXTURE, NULL);
|
2006-05-29 04:59:36 -04:00
|
|
|
}
|
2007-12-20 09:26:07 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
/**
|
|
|
|
* clutter_texture_get_base_size:
|
2009-05-19 07:51:29 -04:00
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
* @width: (out): return location for the width, or %NULL
|
|
|
|
* @height: (out): return location for the height, or %NULL
|
2008-02-12 08:41:44 -05:00
|
|
|
*
|
2009-05-19 07:51:29 -04:00
|
|
|
* Gets the size in pixels of the untransformed underlying image
|
|
|
|
*/
|
|
|
|
void
|
2008-04-25 09:37:36 -04:00
|
|
|
clutter_texture_get_base_size (ClutterTexture *texture,
|
|
|
|
gint *width,
|
|
|
|
gint *height)
|
|
|
|
{
|
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
2007-12-20 09:26:07 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
if (width)
|
2009-06-22 07:07:08 -04:00
|
|
|
*width = texture->priv->image_width;
|
2007-12-20 09:26:07 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
if (height)
|
2009-06-22 07:07:08 -04:00
|
|
|
*height = texture->priv->image_height;
|
2007-12-20 09:26:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_set_area_from_rgb_data:
|
|
|
|
* @texture: A #ClutterTexture
|
|
|
|
* @data: Image data in RGB type colorspace.
|
2008-02-15 10:49:44 -05:00
|
|
|
* @has_alpha: Set to TRUE if image data has an alpha channel.
|
2007-12-20 09:26:07 -05:00
|
|
|
* @x: X coordinate of upper left corner of region to update.
|
|
|
|
* @y: Y coordinate of upper left corner of region to update.
|
|
|
|
* @width: Width in pixels of region to update.
|
|
|
|
* @height: Height in pixels of region to update.
|
2008-02-07 07:55:51 -05:00
|
|
|
* @rowstride: Distance in bytes between row starts on source buffer.
|
2008-12-23 11:29:29 -05:00
|
|
|
* @bpp: bytes per pixel (Currently only 3 and 4 supported,
|
2008-07-01 06:11:39 -04:00
|
|
|
* depending on @has_alpha)
|
2007-12-20 09:26:07 -05:00
|
|
|
* @flags: #ClutterTextureFlags
|
2007-12-24 11:24:26 -05:00
|
|
|
* @error: return location for a #GError, or %NULL
|
2007-12-20 09:26:07 -05:00
|
|
|
*
|
2008-02-15 10:49:44 -05:00
|
|
|
* Updates a sub-region of the pixel data in a #ClutterTexture.
|
2007-12-20 09:26:07 -05:00
|
|
|
*
|
2007-12-24 11:24:26 -05:00
|
|
|
* Return value: %TRUE on success, %FALSE on failure.
|
2007-12-20 09:26:07 -05:00
|
|
|
*
|
2008-12-05 09:08:06 -05:00
|
|
|
* Since: 0.6
|
2007-12-24 11:24:26 -05:00
|
|
|
*/
|
2007-12-20 09:26:07 -05:00
|
|
|
gboolean
|
|
|
|
clutter_texture_set_area_from_rgb_data (ClutterTexture *texture,
|
|
|
|
const guchar *data,
|
|
|
|
gboolean has_alpha,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
gint rowstride,
|
|
|
|
gint bpp,
|
|
|
|
ClutterTextureFlags flags,
|
|
|
|
GError **error)
|
|
|
|
{
|
2010-02-11 10:19:46 -05:00
|
|
|
CoglPixelFormat source_format;
|
|
|
|
CoglHandle cogl_texture;
|
2007-12-20 09:26:07 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
if (has_alpha)
|
2007-12-20 09:26:07 -05:00
|
|
|
{
|
2008-04-25 09:37:36 -04:00
|
|
|
if (bpp != 4)
|
|
|
|
{
|
|
|
|
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
|
|
|
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
|
|
|
"Unsupported BPP");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-02-11 10:19:46 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
source_format = COGL_PIXEL_FORMAT_RGBA_8888;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (bpp != 3)
|
|
|
|
{
|
|
|
|
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
|
|
|
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
|
|
|
"Unsupported BPP");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-02-11 10:19:46 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
source_format = COGL_PIXEL_FORMAT_RGB_888;
|
2007-12-20 09:26:07 -05:00
|
|
|
}
|
2010-02-11 10:19:46 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
if ((flags & CLUTTER_TEXTURE_RGB_FLAG_BGR))
|
|
|
|
source_format |= COGL_BGR_BIT;
|
2010-02-11 10:19:46 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
if ((flags & CLUTTER_TEXTURE_RGB_FLAG_PREMULT))
|
|
|
|
source_format |= COGL_PREMULT_BIT;
|
2007-12-20 09:26:07 -05:00
|
|
|
|
Enforce invariants on mapped, realized, visibility states
Bug 1138 - No trackable "mapped" state
* Add a VISIBLE flag tracking application programmer's
expected showing-state for the actor, allowing us to
always ensure we keep what the app wants while tracking
internal implementation state separately.
* Make MAPPED reflect whether the actor will be painted;
add notification on a ClutterActor::mapped property.
Keep MAPPED state updated as the actor is shown,
ancestors are shown, actor is reparented, etc.
* Require a stage and realized parents to realize; this means
at realization time the correct window system and GL resources
are known. But unparented actors can no longer be realized.
* Allow children to be unrealized even if parent is realized.
Otherwise in effect either all actors or no actors are realized,
i.e. it becomes a stage-global flag.
* Allow clutter_actor_realize() to "fail" if not inside a toplevel
* Rework clutter_actor_unrealize() so internally we have
a flavor that does not mess with visibility flag
* Add _clutter_actor_rerealize() to encapsulate a somewhat
tricky operation we were doing in a couple of places
* Do not realize/unrealize children in ClutterGroup,
ClutterActor already does it
* Do not realize impl by hand in clutter_stage_show(),
since showing impl already does that
* Do not unrealize in various dispose() methods, since
ClutterActor dispose implementation already does it
and chaining up is mandatory
* ClutterTexture uses COGL while unrealizable (before it's
added to a stage). Previously this breakage was affecting
ClutterActor because we had to allow realize outside
a stage. Move the breakage to ClutterTexture, by making
ClutterTexture just use COGL while not realized.
* Unrealize before we set parent to NULL in clutter_actor_unparent().
This means unrealize() implementations can get to the stage.
Because actors need the stage in order to detach from stage.
* Update clutter-actor-invariants.txt to reflect latest changes
* Remove explicit hide/unrealize from ClutterActor::dispose since
unparent already forces those
Instead just assert that unparent() occurred and did the right thing.
* Check whether parent implements unrealize before chaining up
Needed because ClutterGroup no longer has to implement unrealize.
* Perform unrealize in the default handler for the signal.
This allows non-containers that have children to work properly,
and allows containers to override how it's done.
* Add map/unmap virtual methods and set MAPPED flag on self and
children in there. This allows subclasses to hook map/unmap.
These are not signals, because notify::mapped is better for
anything it's legitimate for a non-subclass to do.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
2009-04-02 09:16:43 -04:00
|
|
|
/* attempt to realize ... */
|
|
|
|
if (!CLUTTER_ACTOR_IS_REALIZED (texture) &&
|
|
|
|
clutter_actor_get_stage (CLUTTER_ACTOR (texture)) != NULL)
|
2010-02-11 10:19:46 -05:00
|
|
|
{
|
|
|
|
clutter_actor_realize (CLUTTER_ACTOR (texture));
|
|
|
|
}
|
2007-12-20 09:26:07 -05:00
|
|
|
|
Enforce invariants on mapped, realized, visibility states
Bug 1138 - No trackable "mapped" state
* Add a VISIBLE flag tracking application programmer's
expected showing-state for the actor, allowing us to
always ensure we keep what the app wants while tracking
internal implementation state separately.
* Make MAPPED reflect whether the actor will be painted;
add notification on a ClutterActor::mapped property.
Keep MAPPED state updated as the actor is shown,
ancestors are shown, actor is reparented, etc.
* Require a stage and realized parents to realize; this means
at realization time the correct window system and GL resources
are known. But unparented actors can no longer be realized.
* Allow children to be unrealized even if parent is realized.
Otherwise in effect either all actors or no actors are realized,
i.e. it becomes a stage-global flag.
* Allow clutter_actor_realize() to "fail" if not inside a toplevel
* Rework clutter_actor_unrealize() so internally we have
a flavor that does not mess with visibility flag
* Add _clutter_actor_rerealize() to encapsulate a somewhat
tricky operation we were doing in a couple of places
* Do not realize/unrealize children in ClutterGroup,
ClutterActor already does it
* Do not realize impl by hand in clutter_stage_show(),
since showing impl already does that
* Do not unrealize in various dispose() methods, since
ClutterActor dispose implementation already does it
and chaining up is mandatory
* ClutterTexture uses COGL while unrealizable (before it's
added to a stage). Previously this breakage was affecting
ClutterActor because we had to allow realize outside
a stage. Move the breakage to ClutterTexture, by making
ClutterTexture just use COGL while not realized.
* Unrealize before we set parent to NULL in clutter_actor_unparent().
This means unrealize() implementations can get to the stage.
Because actors need the stage in order to detach from stage.
* Update clutter-actor-invariants.txt to reflect latest changes
* Remove explicit hide/unrealize from ClutterActor::dispose since
unparent already forces those
Instead just assert that unparent() occurred and did the right thing.
* Check whether parent implements unrealize before chaining up
Needed because ClutterGroup no longer has to implement unrealize.
* Perform unrealize in the default handler for the signal.
This allows non-containers that have children to work properly,
and allows containers to override how it's done.
* Add map/unmap virtual methods and set MAPPED flag on self and
children in there. This allows subclasses to hook map/unmap.
These are not signals, because notify::mapped is better for
anything it's legitimate for a non-subclass to do.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
2009-04-02 09:16:43 -04:00
|
|
|
/* due to the fudging of clutter_texture_set_cogl_texture()
|
|
|
|
* which allows setting a texture pre-realize, we may end
|
|
|
|
* up having a texture even if we couldn't realize yet.
|
|
|
|
*/
|
2008-12-23 11:39:11 -05:00
|
|
|
cogl_texture = clutter_texture_get_cogl_texture (texture);
|
|
|
|
if (cogl_texture == COGL_INVALID_HANDLE)
|
2008-04-25 09:37:36 -04:00
|
|
|
{
|
|
|
|
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
|
|
|
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
|
|
|
"Failed to realize actor");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2008-12-23 11:39:11 -05:00
|
|
|
if (!cogl_texture_set_region (cogl_texture,
|
2008-04-25 09:37:36 -04:00
|
|
|
0, 0,
|
|
|
|
x, y, width, height,
|
|
|
|
width, height,
|
|
|
|
source_format,
|
|
|
|
rowstride,
|
|
|
|
data))
|
|
|
|
{
|
|
|
|
g_set_error (error, CLUTTER_TEXTURE_ERROR,
|
|
|
|
CLUTTER_TEXTURE_ERROR_BAD_FORMAT,
|
2010-10-05 03:03:19 -04:00
|
|
|
"Failed to upload Cogl texture data");
|
2008-04-25 09:37:36 -04:00
|
|
|
return FALSE;
|
|
|
|
}
|
2007-12-20 09:26:07 -05:00
|
|
|
|
2010-08-05 10:29:54 -04:00
|
|
|
g_free (texture->priv->filename);
|
|
|
|
texture->priv->filename = NULL;
|
|
|
|
|
2007-12-20 09:26:07 -05:00
|
|
|
/* rename signal */
|
|
|
|
g_signal_emit (texture, texture_signals[PIXBUF_CHANGE], 0);
|
|
|
|
|
2010-02-09 14:34:32 -05:00
|
|
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (texture));
|
2007-12-20 09:26:07 -05:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2008-02-06 09:39:04 -05:00
|
|
|
static void
|
|
|
|
on_fbo_source_size_change (GObject *object,
|
|
|
|
GParamSpec *param_spec,
|
|
|
|
ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv = texture->priv;
|
Remove Units from the public API
With the recent change to internal floating point values, ClutterUnit
has become a redundant type, defined to be a float. All integer entry
points are being internally converted to floating point values to be
passed to the GL pipeline with the least amount of conversion.
ClutterUnit is thus exposed as just a "pixel with fractionary bits",
and not -- as users might think -- as generic, resolution and device
independent units. not that it was the case, but a definitive amount
of people was convinced it did provide this "feature", and was flummoxed
about the mere existence of this type.
So, having ClutterUnit exposed in the public API doubles the entry
points and has the following disadvantages:
- we have to maintain twice the amount of entry points in ClutterActor
- we still do an integer-to-float implicit conversion
- we introduce a weird impedance between pixels and "pixels with
fractionary bits"
- language bindings will have to choose what to bind, and resort
to manually overriding the API
+ *except* for language bindings based on GObject-Introspection, as
they cannot do manual overrides, thus will replicate the entire
set of entry points
For these reason, we should coalesces every Actor entry point for
pixels and for ClutterUnit into a single entry point taking a float,
like:
void clutter_actor_set_x (ClutterActor *self,
gfloat x);
void clutter_actor_get_size (ClutterActor *self,
gfloat *width,
gfloat *height);
gfloat clutter_actor_get_height (ClutterActor *self);
etc.
The issues I have identified are:
- we'll have a two cases of compiler warnings:
- printf() format of the return values from %d to %f
- clutter_actor_get_size() taking floats instead of unsigned ints
- we'll have a problem with varargs when passing an integer instead
of a floating point value, except on 64bit platforms where the
size of a float is the same as the size of an int
To be clear: the *intent* of the API should not change -- we still use
pixels everywhere -- but:
- we remove ambiguity in the API with regard to pixels and units
- we remove entry points we get to maintain for the whole 1.0
version of the API
- we make things simpler to bind for both manual language bindings
and automatic (gobject-introspection based) ones
- we have the simplest API possible while still exposing the
capabilities of the underlying GL implementation
2009-05-06 11:44:47 -04:00
|
|
|
gfloat w, h;
|
2010-08-19 10:26:19 -04:00
|
|
|
ClutterActorBox box;
|
2010-09-07 13:04:19 -04:00
|
|
|
gboolean status;
|
|
|
|
|
|
|
|
status = clutter_actor_get_paint_box (priv->fbo_source, &box);
|
|
|
|
if (status)
|
|
|
|
clutter_actor_box_get_size (&box, &w, &h);
|
|
|
|
|
|
|
|
/* In the end we will size the framebuffer according to the paint
|
|
|
|
* box, but for code that does:
|
|
|
|
* tex = clutter_texture_new_from_actor (src);
|
|
|
|
* clutter_actor_get_size (tex, &width, &height);
|
|
|
|
* it seems more helpfull to return the src actor size if it has a
|
|
|
|
* degenerate paint box. The most likely reason it will have a
|
|
|
|
* degenerate paint box is simply that the src currently has no
|
|
|
|
* parent. */
|
|
|
|
if (status == FALSE || w == 0 || h == 0)
|
|
|
|
clutter_actor_get_size (priv->fbo_source, &w, &h);
|
|
|
|
|
|
|
|
/* We can't create a texture with a width or height of 0... */
|
|
|
|
w = MAX (1, w);
|
|
|
|
h = MAX (1, h);
|
2008-02-12 08:41:44 -05:00
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
if (w != priv->image_width || h != priv->image_height)
|
2008-02-06 09:39:04 -05:00
|
|
|
{
|
2009-01-18 09:51:19 -05:00
|
|
|
CoglTextureFlags flags = COGL_TEXTURE_NONE;
|
2009-04-30 09:32:19 -04:00
|
|
|
CoglHandle tex;
|
2009-01-18 09:51:19 -05:00
|
|
|
|
2008-02-08 05:37:38 -05:00
|
|
|
/* tear down the FBO */
|
2009-04-30 10:00:01 -04:00
|
|
|
if (priv->fbo_handle != COGL_INVALID_HANDLE)
|
|
|
|
cogl_handle_unref (priv->fbo_handle);
|
2008-02-06 09:39:04 -05:00
|
|
|
|
|
|
|
texture_free_gl_resources (texture);
|
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
priv->image_width = w;
|
|
|
|
priv->image_height = h;
|
2009-01-18 09:51:19 -05:00
|
|
|
|
[cogl] Remove max_waste argument from Texture ctors
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
2009-05-23 14:18:18 -04:00
|
|
|
flags |= COGL_TEXTURE_NO_SLICING;
|
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
tex = cogl_texture_new_with_size (MAX (priv->image_width, 1),
|
|
|
|
MAX (priv->image_height, 1),
|
2009-04-30 09:32:19 -04:00
|
|
|
flags,
|
2009-05-09 14:39:01 -04:00
|
|
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE);
|
2009-04-30 09:32:19 -04:00
|
|
|
|
|
|
|
cogl_material_set_layer (priv->material, 0, tex);
|
2008-02-06 09:39:04 -05:00
|
|
|
|
2009-04-30 09:32:19 -04:00
|
|
|
priv->fbo_handle = cogl_offscreen_new_to_texture (tex);
|
2008-02-06 09:39:04 -05:00
|
|
|
|
2009-04-30 09:32:19 -04:00
|
|
|
/* The material now has a reference to the texture so it will
|
|
|
|
stick around */
|
|
|
|
cogl_handle_unref (tex);
|
2008-02-12 08:41:44 -05:00
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
if (priv->fbo_handle == COGL_INVALID_HANDLE)
|
|
|
|
{
|
|
|
|
g_warning ("%s: Offscreen texture creation failed", G_STRLOC);
|
|
|
|
return;
|
|
|
|
}
|
2008-02-06 09:39:04 -05:00
|
|
|
|
2009-01-12 12:12:24 -05:00
|
|
|
clutter_actor_set_size (CLUTTER_ACTOR (texture), w, h);
|
2008-02-06 09:39:04 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_fbo_parent_change (ClutterActor *actor,
|
|
|
|
ClutterActor *old_parent,
|
|
|
|
ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
ClutterActor *parent = CLUTTER_ACTOR(texture);
|
|
|
|
|
|
|
|
while ((parent = clutter_actor_get_parent (parent)) != NULL)
|
|
|
|
if (parent == actor)
|
2008-02-08 05:37:38 -05:00
|
|
|
{
|
|
|
|
g_warning ("Offscreen texture is ancestor of source!");
|
|
|
|
/* Desperate but will avoid infinite loops */
|
|
|
|
clutter_actor_unparent (actor);
|
|
|
|
}
|
2008-02-06 09:39:04 -05:00
|
|
|
}
|
|
|
|
|
2010-09-07 14:40:28 -04:00
|
|
|
static void
|
|
|
|
fbo_source_queue_redraw_cb (ClutterActor *source,
|
|
|
|
ClutterActor *origin,
|
|
|
|
ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (texture));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
fbo_source_queue_relayout_cb (ClutterActor *source,
|
|
|
|
ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (texture));
|
|
|
|
}
|
|
|
|
|
2008-02-01 10:29:00 -05:00
|
|
|
/**
|
|
|
|
* clutter_texture_new_from_actor:
|
2008-02-12 08:41:44 -05:00
|
|
|
* @actor: A source #ClutterActor
|
2008-02-01 10:29:00 -05:00
|
|
|
*
|
2008-02-12 08:41:44 -05:00
|
|
|
* Creates a new #ClutterTexture object with its source a prexisting
|
2008-02-08 05:37:38 -05:00
|
|
|
* actor (and associated children). The textures content will contain
|
2008-02-12 08:41:44 -05:00
|
|
|
* 'live' redirected output of the actors scene.
|
2008-02-01 10:29:00 -05:00
|
|
|
*
|
|
|
|
* Note this function is intented as a utility call for uniformly applying
|
2008-02-15 10:18:02 -05:00
|
|
|
* shaders to groups and other potential visual effects. It requires that
|
2008-12-23 11:29:29 -05:00
|
|
|
* the %CLUTTER_FEATURE_OFFSCREEN feature is supported by the current backend
|
2008-06-06 09:44:22 -04:00
|
|
|
* and the target system.
|
2008-02-08 05:37:38 -05:00
|
|
|
*
|
|
|
|
* Some tips on usage:
|
|
|
|
*
|
|
|
|
* <itemizedlist>
|
|
|
|
* <listitem>
|
2008-02-12 08:41:44 -05:00
|
|
|
* <para>The source actor must be made visible (i.e by calling
|
2008-07-04 06:44:18 -04:00
|
|
|
* #clutter_actor_show).</para>
|
|
|
|
* </listitem>
|
|
|
|
* <listitem>
|
|
|
|
* <para>The source actor must have a parent in order for it to be
|
|
|
|
* allocated a size from the layouting mechanism. If the source
|
|
|
|
* actor does not have a parent when this function is called then
|
|
|
|
* the ClutterTexture will adopt it and allocate it at its
|
|
|
|
* preferred size. Using this you can clone an actor that is
|
|
|
|
* otherwise not displayed. Because of this feature if you do
|
|
|
|
* intend to display the source actor then you must make sure that
|
|
|
|
* the actor is parented before calling
|
|
|
|
* clutter_texture_new_from_actor() or that you unparent it before
|
|
|
|
* adding it to a container.</para>
|
2008-08-01 08:23:57 -04:00
|
|
|
* </listitem>
|
|
|
|
* <listitem>
|
|
|
|
* <para>When getting the image for the clone texture, Clutter
|
|
|
|
* will attempt to render the source actor exactly as it would
|
|
|
|
* appear if it was rendered on screen. The source actor's parent
|
|
|
|
* transformations are taken into account. Therefore if your
|
|
|
|
* source actor is rotated along the X or Y axes so that it has
|
|
|
|
* some depth, the texture will appear differently depending on
|
|
|
|
* the on-screen location of the source actor. While painting the
|
|
|
|
* source actor, Clutter will set up a temporary asymmetric
|
|
|
|
* perspective matrix as the projection matrix so that the source
|
|
|
|
* actor will be projected as if a small section of the screen was
|
|
|
|
* being viewed. Before version 0.8.2, an orthogonal identity
|
|
|
|
* projection was used which meant that the source actor would be
|
|
|
|
* clipped if any part of it was not on the zero Z-plane.</para>
|
2008-02-08 08:52:11 -05:00
|
|
|
* </listitem>
|
2008-02-08 05:37:38 -05:00
|
|
|
* <listitem>
|
|
|
|
* <para>Avoid reparenting the source with the created texture.</para>
|
|
|
|
* </listitem>
|
|
|
|
* <listitem>
|
2008-02-12 08:41:44 -05:00
|
|
|
* <para>A group can be padded with a transparent rectangle as to
|
2008-02-08 05:37:38 -05:00
|
|
|
* provide a border to contents for shader output (blurring text
|
|
|
|
* for example).</para>
|
|
|
|
* </listitem>
|
|
|
|
* <listitem>
|
2008-02-12 08:41:44 -05:00
|
|
|
* <para>The texture will automatically resize to contain a further
|
2008-02-15 10:18:02 -05:00
|
|
|
* transformed source. However, this involves overhead and can be
|
2008-02-08 05:37:38 -05:00
|
|
|
* avoided by placing the source actor in a bounding group
|
|
|
|
* sized large enough to contain any child tranformations.</para>
|
|
|
|
* </listitem>
|
|
|
|
* <listitem>
|
2008-03-18 13:56:50 -04:00
|
|
|
* <para>Uploading pixel data to the texture (e.g by using
|
2010-11-18 09:14:37 -05:00
|
|
|
* clutter_texture_set_from_file()) will destroy the offscreen texture
|
|
|
|
* data and end redirection.</para>
|
2008-02-08 05:37:38 -05:00
|
|
|
* </listitem>
|
|
|
|
* <listitem>
|
2008-04-25 09:37:36 -04:00
|
|
|
* <para>cogl_texture_get_data() with the handle returned by
|
|
|
|
* clutter_texture_get_cogl_texture() can be used to read the
|
|
|
|
* offscreen texture pixels into a pixbuf.</para>
|
2008-02-08 05:37:38 -05:00
|
|
|
* </listitem>
|
|
|
|
* </itemizedlist>
|
2008-02-01 10:29:00 -05:00
|
|
|
*
|
2008-02-15 10:18:02 -05:00
|
|
|
* Return value: A newly created #ClutterTexture object, or %NULL on failure.
|
2008-02-08 08:52:11 -05:00
|
|
|
*
|
|
|
|
* Since: 0.6
|
|
|
|
*/
|
2008-02-01 10:29:00 -05:00
|
|
|
ClutterActor *
|
|
|
|
clutter_texture_new_from_actor (ClutterActor *actor)
|
|
|
|
{
|
|
|
|
ClutterTexture *texture;
|
|
|
|
ClutterTexturePrivate *priv;
|
Remove Units from the public API
With the recent change to internal floating point values, ClutterUnit
has become a redundant type, defined to be a float. All integer entry
points are being internally converted to floating point values to be
passed to the GL pipeline with the least amount of conversion.
ClutterUnit is thus exposed as just a "pixel with fractionary bits",
and not -- as users might think -- as generic, resolution and device
independent units. not that it was the case, but a definitive amount
of people was convinced it did provide this "feature", and was flummoxed
about the mere existence of this type.
So, having ClutterUnit exposed in the public API doubles the entry
points and has the following disadvantages:
- we have to maintain twice the amount of entry points in ClutterActor
- we still do an integer-to-float implicit conversion
- we introduce a weird impedance between pixels and "pixels with
fractionary bits"
- language bindings will have to choose what to bind, and resort
to manually overriding the API
+ *except* for language bindings based on GObject-Introspection, as
they cannot do manual overrides, thus will replicate the entire
set of entry points
For these reason, we should coalesces every Actor entry point for
pixels and for ClutterUnit into a single entry point taking a float,
like:
void clutter_actor_set_x (ClutterActor *self,
gfloat x);
void clutter_actor_get_size (ClutterActor *self,
gfloat *width,
gfloat *height);
gfloat clutter_actor_get_height (ClutterActor *self);
etc.
The issues I have identified are:
- we'll have a two cases of compiler warnings:
- printf() format of the return values from %d to %f
- clutter_actor_get_size() taking floats instead of unsigned ints
- we'll have a problem with varargs when passing an integer instead
of a floating point value, except on 64bit platforms where the
size of a float is the same as the size of an int
To be clear: the *intent* of the API should not change -- we still use
pixels everywhere -- but:
- we remove ambiguity in the API with regard to pixels and units
- we remove entry points we get to maintain for the whole 1.0
version of the API
- we make things simpler to bind for both manual language bindings
and automatic (gobject-introspection based) ones
- we have the simplest API possible while still exposing the
capabilities of the underlying GL implementation
2009-05-06 11:44:47 -04:00
|
|
|
gfloat w, h;
|
2010-08-19 10:26:19 -04:00
|
|
|
ClutterActorBox box;
|
2010-09-07 13:04:19 -04:00
|
|
|
gboolean status;
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2008-02-02 20:53:10 -05:00
|
|
|
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL);
|
|
|
|
|
2008-02-01 10:29:00 -05:00
|
|
|
if (clutter_feature_available (CLUTTER_FEATURE_OFFSCREEN) == FALSE)
|
|
|
|
return NULL;
|
|
|
|
|
2008-02-02 20:53:10 -05:00
|
|
|
if (!CLUTTER_ACTOR_IS_REALIZED (actor))
|
|
|
|
{
|
|
|
|
clutter_actor_realize (actor);
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2008-02-02 20:53:10 -05:00
|
|
|
if (!CLUTTER_ACTOR_IS_REALIZED (actor))
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-09-07 13:04:19 -04:00
|
|
|
status = clutter_actor_get_paint_box (actor, &box);
|
|
|
|
if (status)
|
|
|
|
clutter_actor_box_get_size (&box, &w, &h);
|
|
|
|
|
|
|
|
/* In the end we will size the framebuffer according to the paint
|
|
|
|
* box, but for code that does:
|
|
|
|
* tex = clutter_texture_new_from_actor (src);
|
|
|
|
* clutter_actor_get_size (tex, &width, &height);
|
|
|
|
* it seems more helpfull to return the src actor size if it has a
|
|
|
|
* degenerate paint box. The most likely reason it will have a
|
|
|
|
* degenerate paint box is simply that the src currently has no
|
|
|
|
* parent. */
|
|
|
|
if (status == FALSE || w == 0 || h == 0)
|
|
|
|
clutter_actor_get_size (actor, &w, &h);
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2010-08-19 10:26:19 -04:00
|
|
|
/* We can't create a 0x0 fbo so always bump the size up to at least
|
|
|
|
* 1 */
|
2010-09-07 13:04:19 -04:00
|
|
|
w = MAX (1, w);
|
|
|
|
h = MAX (1, h);
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2008-02-08 05:37:38 -05:00
|
|
|
/* Hopefully now were good.. */
|
2008-12-23 11:29:29 -05:00
|
|
|
texture = g_object_new (CLUTTER_TYPE_TEXTURE,
|
2008-06-06 09:44:22 -04:00
|
|
|
"disable-slicing", TRUE,
|
|
|
|
NULL);
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2008-02-02 20:53:10 -05:00
|
|
|
priv = texture->priv;
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2008-07-04 06:44:18 -04:00
|
|
|
priv->fbo_source = g_object_ref_sink (actor);
|
|
|
|
|
|
|
|
/* If the actor doesn't have a parent then claim it so that it will
|
|
|
|
get a size allocation during layout */
|
|
|
|
if (clutter_actor_get_parent (actor) == NULL)
|
|
|
|
clutter_actor_set_parent (actor, CLUTTER_ACTOR (texture));
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2008-02-06 09:39:04 -05:00
|
|
|
/* Connect up any signals which could change our underlying size */
|
|
|
|
g_signal_connect (actor,
|
|
|
|
"notify::width",
|
|
|
|
G_CALLBACK(on_fbo_source_size_change),
|
|
|
|
texture);
|
|
|
|
g_signal_connect (actor,
|
|
|
|
"notify::height",
|
|
|
|
G_CALLBACK(on_fbo_source_size_change),
|
|
|
|
texture);
|
|
|
|
g_signal_connect (actor,
|
|
|
|
"notify::scale-x",
|
|
|
|
G_CALLBACK(on_fbo_source_size_change),
|
|
|
|
texture);
|
|
|
|
g_signal_connect (actor,
|
|
|
|
"notify::scale-y",
|
|
|
|
G_CALLBACK(on_fbo_source_size_change),
|
|
|
|
texture);
|
|
|
|
g_signal_connect (actor,
|
|
|
|
"notify::rotation-angle-x",
|
|
|
|
G_CALLBACK(on_fbo_source_size_change),
|
|
|
|
texture);
|
|
|
|
g_signal_connect (actor,
|
|
|
|
"notify::rotation-angle-y",
|
|
|
|
G_CALLBACK(on_fbo_source_size_change),
|
|
|
|
texture);
|
|
|
|
g_signal_connect (actor,
|
|
|
|
"notify::rotation-angle-z",
|
|
|
|
G_CALLBACK(on_fbo_source_size_change),
|
|
|
|
texture);
|
|
|
|
|
2010-09-07 14:40:28 -04:00
|
|
|
g_signal_connect (actor, "queue-relayout",
|
|
|
|
G_CALLBACK (fbo_source_queue_relayout_cb), texture);
|
|
|
|
g_signal_connect (actor, "queue-redraw",
|
|
|
|
G_CALLBACK (fbo_source_queue_redraw_cb), texture);
|
|
|
|
|
2008-02-06 09:39:04 -05:00
|
|
|
/* And a warning if the source becomes a child of the texture */
|
|
|
|
g_signal_connect (actor,
|
|
|
|
"parent-set",
|
|
|
|
G_CALLBACK(on_fbo_parent_change),
|
|
|
|
texture);
|
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
priv->image_width = w;
|
|
|
|
priv->image_height = h;
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2009-06-22 07:07:08 -04:00
|
|
|
clutter_actor_set_size (CLUTTER_ACTOR (texture),
|
|
|
|
priv->image_width,
|
|
|
|
priv->image_height);
|
2008-02-01 10:29:00 -05:00
|
|
|
|
2009-01-12 12:12:24 -05:00
|
|
|
return CLUTTER_ACTOR (texture);
|
2008-02-01 10:29:00 -05:00
|
|
|
}
|
2008-02-03 18:25:12 -05:00
|
|
|
|
|
|
|
static void
|
|
|
|
texture_fbo_free_resources (ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
|
|
|
|
priv = texture->priv;
|
|
|
|
|
|
|
|
CLUTTER_MARK();
|
|
|
|
|
|
|
|
if (priv->fbo_source != NULL)
|
|
|
|
{
|
2008-07-04 06:44:18 -04:00
|
|
|
/* If we parented the texture then unparent it again so that it
|
|
|
|
will lose the reference */
|
|
|
|
if (clutter_actor_get_parent (priv->fbo_source)
|
|
|
|
== CLUTTER_ACTOR (texture))
|
|
|
|
clutter_actor_unparent (priv->fbo_source);
|
|
|
|
|
2008-02-12 08:41:44 -05:00
|
|
|
g_signal_handlers_disconnect_by_func
|
|
|
|
(priv->fbo_source,
|
|
|
|
G_CALLBACK(on_fbo_parent_change),
|
2008-02-08 05:37:38 -05:00
|
|
|
texture);
|
2008-02-12 08:41:44 -05:00
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_func
|
|
|
|
(priv->fbo_source,
|
|
|
|
G_CALLBACK(on_fbo_source_size_change),
|
2008-02-08 05:37:38 -05:00
|
|
|
texture);
|
|
|
|
|
2010-09-07 14:40:28 -04:00
|
|
|
g_signal_handlers_disconnect_by_func
|
|
|
|
(priv->fbo_source,
|
|
|
|
G_CALLBACK(fbo_source_queue_relayout_cb),
|
|
|
|
texture);
|
|
|
|
|
|
|
|
g_signal_handlers_disconnect_by_func
|
|
|
|
(priv->fbo_source,
|
|
|
|
G_CALLBACK(fbo_source_queue_redraw_cb),
|
|
|
|
texture);
|
|
|
|
|
2008-02-03 18:25:12 -05:00
|
|
|
g_object_unref (priv->fbo_source);
|
2008-02-08 05:37:38 -05:00
|
|
|
|
2008-02-03 18:25:12 -05:00
|
|
|
priv->fbo_source = NULL;
|
|
|
|
}
|
|
|
|
|
2008-04-25 09:37:36 -04:00
|
|
|
if (priv->fbo_handle != COGL_INVALID_HANDLE)
|
2008-02-03 18:25:12 -05:00
|
|
|
{
|
2009-04-01 12:16:44 -04:00
|
|
|
cogl_handle_unref (priv->fbo_handle);
|
2008-04-25 09:37:36 -04:00
|
|
|
priv->fbo_handle = COGL_INVALID_HANDLE;
|
2008-02-03 18:25:12 -05:00
|
|
|
}
|
|
|
|
}
|
2009-05-19 07:51:29 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_set_sync_size:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
* @sync_size: %TRUE if the texture should have the same size of the
|
|
|
|
* underlying image data
|
|
|
|
*
|
|
|
|
* Sets whether @texture should have the same preferred size as the
|
|
|
|
* underlying image data.
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
clutter_texture_set_sync_size (ClutterTexture *texture,
|
|
|
|
gboolean sync_size)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
|
|
|
|
|
|
|
priv = texture->priv;
|
|
|
|
|
|
|
|
if (priv->sync_actor_size != sync_size)
|
|
|
|
{
|
|
|
|
priv->sync_actor_size = sync_size;
|
|
|
|
|
|
|
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (texture));
|
|
|
|
|
2010-06-21 05:20:32 -04:00
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_SYNC_SIZE]);
|
2009-05-19 07:51:29 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_get_sync_size:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
*
|
2010-07-22 05:04:06 -04:00
|
|
|
* Retrieves the value set with clutter_texture_set_sync_size()
|
2009-05-19 07:51:29 -04:00
|
|
|
*
|
|
|
|
* Return value: %TRUE if the #ClutterTexture should have the same
|
|
|
|
* preferred size of the underlying image data
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
clutter_texture_get_sync_size (ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE);
|
|
|
|
|
|
|
|
return texture->priv->sync_actor_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_set_repeat:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
* @repeat_x: %TRUE if the texture should repeat horizontally
|
|
|
|
* @repeat_y: %TRUE if the texture should repeat vertically
|
|
|
|
*
|
|
|
|
* Sets whether the @texture should repeat horizontally or
|
|
|
|
* vertically when the actor size is bigger than the image size
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
clutter_texture_set_repeat (ClutterTexture *texture,
|
|
|
|
gboolean repeat_x,
|
|
|
|
gboolean repeat_y)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
gboolean changed = FALSE;
|
|
|
|
|
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
|
|
|
|
|
|
|
priv = texture->priv;
|
|
|
|
|
|
|
|
g_object_freeze_notify (G_OBJECT (texture));
|
|
|
|
|
|
|
|
if (priv->repeat_x != repeat_x)
|
|
|
|
{
|
|
|
|
priv->repeat_x = repeat_x;
|
|
|
|
|
2010-06-21 05:20:32 -04:00
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_REPEAT_X]);
|
2009-05-19 07:51:29 -04:00
|
|
|
|
|
|
|
changed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (priv->repeat_y != repeat_y)
|
|
|
|
{
|
|
|
|
priv->repeat_y = repeat_y;
|
|
|
|
|
2010-06-21 05:20:32 -04:00
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_REPEAT_Y]);
|
2009-05-19 07:51:29 -04:00
|
|
|
|
|
|
|
changed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (changed)
|
|
|
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (texture));
|
|
|
|
|
|
|
|
g_object_thaw_notify (G_OBJECT (texture));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_get_repeat:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
* @repeat_x: (out): return location for the horizontal repeat
|
|
|
|
* @repeat_y: (out): return location for the vertical repeat
|
|
|
|
*
|
|
|
|
* Retrieves the horizontal and vertical repeat values set
|
|
|
|
* using clutter_texture_set_repeat()
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
clutter_texture_get_repeat (ClutterTexture *texture,
|
|
|
|
gboolean *repeat_x,
|
|
|
|
gboolean *repeat_y)
|
|
|
|
{
|
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
|
|
|
|
|
|
|
if (repeat_x != NULL)
|
|
|
|
*repeat_x = texture->priv->repeat_x;
|
|
|
|
|
|
|
|
if (repeat_y != NULL)
|
|
|
|
*repeat_y = texture->priv->repeat_y;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_get_pixel_format:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
*
|
|
|
|
* Retrieves the pixel format used by @texture. This is
|
|
|
|
* equivalent to:
|
|
|
|
*
|
|
|
|
* |[
|
|
|
|
* handle = clutter_texture_get_pixel_format (texture);
|
|
|
|
*
|
|
|
|
* if (handle != COGL_INVALID_HANDLE)
|
|
|
|
* format = cogl_texture_get_format (handle);
|
|
|
|
* ]|
|
|
|
|
*
|
|
|
|
* Return value: a #CoglPixelFormat value
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
CoglPixelFormat
|
|
|
|
clutter_texture_get_pixel_format (ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
CoglHandle cogl_texture;
|
|
|
|
|
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), COGL_PIXEL_FORMAT_ANY);
|
|
|
|
|
|
|
|
cogl_texture = clutter_texture_get_cogl_texture (texture);
|
|
|
|
if (cogl_texture == COGL_INVALID_HANDLE)
|
|
|
|
return COGL_PIXEL_FORMAT_ANY;
|
|
|
|
|
|
|
|
return cogl_texture_get_format (cogl_texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_set_keep_aspect_ratio:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
* @keep_aspect: %TRUE to maintain aspect ratio
|
|
|
|
*
|
|
|
|
* Sets whether @texture should have a preferred size maintaining
|
|
|
|
* the aspect ratio of the underlying image
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
clutter_texture_set_keep_aspect_ratio (ClutterTexture *texture,
|
|
|
|
gboolean keep_aspect)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
|
|
|
|
|
|
|
priv = texture->priv;
|
|
|
|
|
|
|
|
if (priv->keep_aspect_ratio != keep_aspect)
|
|
|
|
{
|
|
|
|
priv->keep_aspect_ratio = keep_aspect;
|
|
|
|
|
|
|
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (texture));
|
|
|
|
|
2010-06-21 05:20:32 -04:00
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_KEEP_ASPECT_RATIO]);
|
2009-05-19 07:51:29 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_get_keep_aspect_ratio:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
*
|
2010-07-22 05:21:21 -04:00
|
|
|
* Retrieves the value set using clutter_texture_set_keep_aspect_ratio()
|
2009-05-19 07:51:29 -04:00
|
|
|
*
|
|
|
|
* Return value: %TRUE if the #ClutterTexture should maintain the
|
|
|
|
* aspect ratio of the underlying image
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
clutter_texture_get_keep_aspect_ratio (ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE);
|
|
|
|
|
|
|
|
return texture->priv->keep_aspect_ratio;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_set_load_async:
|
|
|
|
* @texture: a #ClutterTexture
|
2009-05-28 12:18:13 -04:00
|
|
|
* @load_async: %TRUE if the texture should asynchronously load data
|
2009-05-19 07:51:29 -04:00
|
|
|
* from a filename
|
|
|
|
*
|
|
|
|
* Sets whether @texture should use a worker thread to load the data
|
|
|
|
* from disk asynchronously. Setting @load_async to %TRUE will make
|
|
|
|
* clutter_texture_set_from_file() return immediately.
|
|
|
|
*
|
|
|
|
* See the #ClutterTexture:load-async property documentation, and
|
|
|
|
* clutter_texture_set_load_data_async().
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
clutter_texture_set_load_async (ClutterTexture *texture,
|
|
|
|
gboolean load_async)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
|
|
|
|
|
|
|
priv = texture->priv;
|
|
|
|
|
|
|
|
if (priv->load_async_set != load_async)
|
|
|
|
{
|
|
|
|
priv->load_data_async = load_async;
|
|
|
|
priv->load_size_async = load_async;
|
|
|
|
|
|
|
|
priv->load_async_set = load_async;
|
|
|
|
|
2010-06-21 05:20:32 -04:00
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_LOAD_ASYNC]);
|
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_LOAD_DATA_ASYNC]);
|
2009-05-19 07:51:29 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_get_load_async:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
*
|
2010-07-22 05:21:21 -04:00
|
|
|
* Retrieves the value set using clutter_texture_set_load_async()
|
2009-05-19 07:51:29 -04:00
|
|
|
*
|
|
|
|
* Return value: %TRUE if the #ClutterTexture should load the data from
|
|
|
|
* disk asynchronously
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
clutter_texture_get_load_async (ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE);
|
|
|
|
|
|
|
|
return texture->priv->load_async_set;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_set_load_data_async:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
* @load_async: %TRUE if the texture should asynchronously load data
|
|
|
|
* from a filename
|
|
|
|
*
|
|
|
|
* Sets whether @texture should use a worker thread to load the data
|
|
|
|
* from disk asynchronously. Setting @load_async to %TRUE will make
|
|
|
|
* clutter_texture_set_from_file() block until the #ClutterTexture has
|
|
|
|
* determined the width and height of the image data.
|
|
|
|
*
|
|
|
|
* See the #ClutterTexture:load-async property documentation, and
|
|
|
|
* clutter_texture_set_load_async().
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
clutter_texture_set_load_data_async (ClutterTexture *texture,
|
|
|
|
gboolean load_async)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
|
|
|
|
|
|
|
priv = texture->priv;
|
|
|
|
|
|
|
|
if (priv->load_data_async != load_async)
|
|
|
|
{
|
|
|
|
/* load-data-async always unsets load-size-async */
|
|
|
|
priv->load_data_async = load_async;
|
|
|
|
priv->load_size_async = FALSE;
|
|
|
|
|
|
|
|
priv->load_async_set = load_async;
|
|
|
|
|
2010-06-21 05:20:32 -04:00
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_LOAD_ASYNC]);
|
|
|
|
_clutter_notify_by_pspec (G_OBJECT (texture), obj_props[PROP_LOAD_DATA_ASYNC]);
|
2009-05-19 07:51:29 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_get_load_data_async:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
*
|
|
|
|
* Retrieves the value set by clutter_texture_set_load_data_async()
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the #ClutterTexture should load the image
|
|
|
|
* data from a file asynchronously
|
|
|
|
*
|
|
|
|
* Since: 1.0
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
clutter_texture_get_load_data_async (ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE);
|
|
|
|
|
|
|
|
return texture->priv->load_async_set &&
|
|
|
|
texture->priv->load_data_async;
|
|
|
|
}
|
2009-09-25 14:14:40 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_set_pick_with_alpha:
|
|
|
|
* @texture: a #ClutterTexture
|
2010-06-01 09:14:41 -04:00
|
|
|
* @pick_with_alpha: %TRUE if the alpha channel should affect the
|
|
|
|
* picking shape
|
2009-09-25 14:14:40 -04:00
|
|
|
*
|
|
|
|
* Sets whether @texture should have it's shape defined by the alpha
|
|
|
|
* channel when picking.
|
|
|
|
*
|
|
|
|
* Be aware that this is a bit more costly than the default picking
|
|
|
|
* due to the texture lookup, extra test against the alpha value and
|
|
|
|
* the fact that it will also interrupt the batching of geometry done
|
|
|
|
* internally.
|
|
|
|
*
|
|
|
|
* Also there is currently no control over the threshold used to
|
|
|
|
* determine what value of alpha is considered pickable, and so only
|
|
|
|
* fully opaque parts of the texture will react to picking.
|
|
|
|
*
|
|
|
|
* Since: 1.4
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
clutter_texture_set_pick_with_alpha (ClutterTexture *texture,
|
|
|
|
gboolean pick_with_alpha)
|
|
|
|
{
|
|
|
|
ClutterTexturePrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (CLUTTER_IS_TEXTURE (texture));
|
|
|
|
|
|
|
|
priv = texture->priv;
|
|
|
|
|
|
|
|
if (priv->pick_with_alpha == pick_with_alpha)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!pick_with_alpha && priv->pick_material != COGL_INVALID_HANDLE)
|
|
|
|
{
|
|
|
|
cogl_handle_unref (priv->pick_material);
|
|
|
|
priv->pick_material = COGL_INVALID_HANDLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* NB: the pick material is created lazily when we first pick */
|
|
|
|
priv->pick_with_alpha = pick_with_alpha;
|
2010-08-18 13:05:15 -04:00
|
|
|
|
|
|
|
/* NB: actors are expected to call clutter_actor_queue_redraw when
|
|
|
|
* ever some state changes that will affect painting *or picking...
|
|
|
|
*/
|
|
|
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (texture));
|
2009-09-25 14:14:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_texture_get_pick_with_alpha:
|
|
|
|
* @texture: a #ClutterTexture
|
|
|
|
*
|
|
|
|
* Retrieves the value set by clutter_texture_set_load_data_async()
|
|
|
|
*
|
|
|
|
* Return value: %TRUE if the #ClutterTexture should define its shape
|
|
|
|
* using the alpha channel when picking.
|
|
|
|
*
|
|
|
|
* Since: 1.4
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
clutter_texture_get_pick_with_alpha (ClutterTexture *texture)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (CLUTTER_IS_TEXTURE (texture), FALSE);
|
|
|
|
|
|
|
|
return texture->priv->pick_with_alpha ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
|