static void dispose (GObject *gobject) { GeglCache *self = GEGL_CACHE (gobject); while (g_idle_remove_by_data (gobject)) ; /* Check with GEGL_IS_NODE since sometimes the node is destroyed * before we get here */ if (GEGL_IS_NODE (self->node)) { gint handler = g_signal_handler_find (self->node, G_SIGNAL_MATCH_DATA, g_signal_lookup ("invalidated", GEGL_TYPE_NODE), 0, NULL, NULL, self); if (handler) { g_signal_handler_disconnect (self->node, handler); } self->node = NULL; } G_OBJECT_CLASS (gegl_cache_parent_class)->dispose (gobject); }
static void finalize (GObject *gobject) { GeglCache *self = GEGL_CACHE (gobject); g_mutex_free (self->mutex); if (self->valid_region) gegl_region_destroy (self->valid_region); G_OBJECT_CLASS (gegl_cache_parent_class)->finalize (gobject); }
static void set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec) { GeglCache *self = GEGL_CACHE (gobject); switch (property_id) { case PROP_NODE: g_mutex_lock (self->mutex); if (self->node) { gulong handler; handler = g_signal_handler_find (self->node, G_SIGNAL_MATCH_DATA, g_signal_lookup ("invalidated", GEGL_TYPE_NODE), 0, NULL, NULL, self); if (handler) { g_signal_handler_disconnect (self->node, handler); } } /* just getting the node, the cache holds no reference on the node, * it is the node that holds reference on the cache */ self->node = GEGL_NODE (g_value_get_object (value)); g_signal_connect (G_OBJECT (self->node), "invalidated", G_CALLBACK (node_invalidated), self); g_mutex_unlock (self->mutex); break; case PROP_X: g_object_set_property (gobject, "GeglBuffer::x", value); break; case PROP_Y: g_object_set_property (gobject, "GeglBuffer::y", value); break; case PROP_WIDTH: g_object_set_property (gobject, "GeglBuffer::width", value); break; case PROP_HEIGHT: g_object_set_property (gobject, "GeglBuffer::height", value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec); break; } }
static void gegl_cache_constructed (GObject *object) { GeglCache *self = GEGL_CACHE (object); gint i; G_OBJECT_CLASS (gegl_cache_parent_class)->constructed (object); for (i = 0; i < GEGL_CACHE_VALID_MIPMAPS; i++) self->valid_region[i] = gegl_region_new (); }
static void finalize (GObject *gobject) { GeglCache *self = GEGL_CACHE (gobject); gint i; g_mutex_clear (&self->mutex); for (i = 0; i < GEGL_CACHE_VALID_MIPMAPS; i++) if (self->valid_region[i]) gegl_region_destroy (self->valid_region[i]); G_OBJECT_CLASS (gegl_cache_parent_class)->finalize (gobject); }
static GObject * gegl_cache_constructor (GType type, guint n_params, GObjectConstructParam *params) { GObject *object; GeglCache *self; object = G_OBJECT_CLASS (gegl_cache_parent_class)->constructor (type, n_params, params); self = GEGL_CACHE (object); self->valid_region = gegl_region_new (); self->format = GEGL_BUFFER (self)->format; return object; }
static void node_invalidated (GeglNode *source, const GeglRectangle *rect, gpointer data) { GeglCache *cache = GEGL_CACHE (data); GeglRectangle expanded = gegl_rectangle_expand (rect); { GeglRegion *region; region = gegl_region_rectangle (&expanded); gegl_region_subtract (cache->valid_region, region); gegl_region_destroy (region); } g_mutex_lock (cache->mutex); g_signal_emit_by_name (cache, "invalidated", &expanded, NULL); g_mutex_unlock (cache->mutex); }
gboolean gegl_buffer_list_valid_rectangles (GeglBuffer *buffer, GeglRectangle **rectangles, gint *n_rectangles) { GeglCache *cache; gint level = 0; /* should be an argument */ g_return_val_if_fail (GEGL_IS_CACHE (buffer), FALSE); cache = GEGL_CACHE (buffer); if (level < 0) level = 0; if (level >= GEGL_CACHE_VALID_MIPMAPS) level = GEGL_CACHE_VALID_MIPMAPS-1; gegl_region_get_rectangles (cache->valid_region[level], rectangles, n_rectangles); return TRUE; }
static void get_property (GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec) { GeglCache *self = GEGL_CACHE (gobject); switch (property_id) { case PROP_NODE: g_value_set_object (value, self->node); break; /* For the rest, upchaining to the property implementation in GeglBuffer */ case PROP_X: g_object_get_property (gobject, "GeglBuffer::x", value); break; case PROP_Y: g_object_get_property (gobject, "GeglBuffer::y", value); break; case PROP_WIDTH: g_object_get_property (gobject, "GeglBuffer::width", value); break; case PROP_HEIGHT: g_object_get_property (gobject, "GeglBuffer::height", value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec); break; } }