[gegl] buffer: clear hot tile when removing a tile from the cache
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: clear hot tile when removing a tile from the cache
- Date: Tue, 31 May 2016 20:11:52 +0000 (UTC)
commit cd98e944f5c30a8549f9cc22d5eb7f50a9dca334
Author: Ell <ell_se yahoo com>
Date: Tue May 31 18:03:00 2016 +0000
buffer: clear hot tile when removing a tile from the cache
When removing a tile from the cache in gegl_tile_handler_cache_void()
and gegl_tile_handler_cache_invalidate(), check if it's the
associated tile storage's hot tile, and clear the hot tile if it is.
Failing to do so keeps the hot tile pointing to an outdated tile,
which can cause the 1x1 buffer access functions (_get_pixel(),
_set_pixel(), NN sampling) to return wrong results.
See the next commit for a test case.
gegl/buffer/gegl-tile-handler-cache.c | 32 ++++++++++++++++++++++++--------
1 files changed, 24 insertions(+), 8 deletions(-)
---
diff --git a/gegl/buffer/gegl-tile-handler-cache.c b/gegl/buffer/gegl-tile-handler-cache.c
index 12bb60d..d49f7d4 100644
--- a/gegl/buffer/gegl-tile-handler-cache.c
+++ b/gegl/buffer/gegl-tile-handler-cache.c
@@ -372,6 +372,27 @@ gegl_tile_handler_cache_has_tile (GeglTileHandlerCache *cache,
return FALSE;
}
+static void
+drop_hot_tile (GeglTile *tile)
+{
+ GeglTileStorage *storage = tile->tile_storage;
+
+ if (storage)
+ {
+ if (gegl_config_threads()>1)
+ g_rec_mutex_lock (&storage->mutex);
+
+ if (storage->hot_tile == tile)
+ {
+ gegl_tile_unref (storage->hot_tile);
+ storage->hot_tile = NULL;
+ }
+
+ if (gegl_config_threads()>1)
+ g_rec_mutex_unlock (&storage->mutex);
+ }
+}
+
static gboolean
gegl_tile_handler_cache_trim (GeglTileHandlerCache *cache)
{
@@ -383,18 +404,11 @@ gegl_tile_handler_cache_trim (GeglTileHandlerCache *cache)
{
CacheItem *last_writable = LINK_GET_ITEM (link);
GeglTile *tile = last_writable->tile;
- GeglTileStorage *storage = tile->tile_storage;
last_writable->handler->items = g_slist_remove (last_writable->handler->items, last_writable);
g_hash_table_remove (cache_ht, last_writable);
cache_total -= tile->size;
-
- if (storage && storage->hot_tile == tile)
- {
- storage->hot_tile = NULL;
- gegl_tile_unref (tile);
- }
-
+ drop_hot_tile (tile);
gegl_tile_unref (tile);
g_slice_free (CacheItem, last_writable);
return TRUE;
@@ -416,6 +430,7 @@ gegl_tile_handler_cache_invalidate (GeglTileHandlerCache *cache,
if (item)
{
cache_total -= item->tile->size;
+ drop_hot_tile (item->tile);
item->tile->tile_storage = NULL;
gegl_tile_mark_as_stored (item->tile); /* to cheat it out of being stored */
gegl_tile_unref (item->tile);
@@ -452,6 +467,7 @@ gegl_tile_handler_cache_void (GeglTileHandlerCache *cache,
if (item)
{
+ drop_hot_tile (item->tile);
gegl_tile_void (item->tile);
gegl_tile_unref (item->tile);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]