static gpointer gegl_tile_backend_swap_set_tile (GeglTileSource *self, GeglTile *tile, gint x, gint y, gint z) { GeglTileBackend *backend; GeglTileBackendSwap *tile_backend_swap; SwapEntry *entry; backend = GEGL_TILE_BACKEND (self); tile_backend_swap = GEGL_TILE_BACKEND_SWAP (backend); entry = gegl_tile_backend_swap_lookup_entry (tile_backend_swap, x, y, z); gegl_tile_backend_swap_ensure_exist (); if (entry == NULL) { entry = gegl_tile_backend_swap_entry_create (x, y, z); entry->offset = gegl_tile_backend_swap_find_offset (gegl_tile_backend_get_tile_size (backend)); g_hash_table_insert (tile_backend_swap->index, entry, entry); } gegl_tile_backend_swap_entry_write (tile_backend_swap, entry, tile); gegl_tile_mark_as_stored (tile); return NULL; }
static void gegl_tile_backend_swap_entry_write (GeglTileBackendSwap *self, SwapEntry *entry, guchar *source) { ThreadParams *params; gint length = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self)); guchar *new_source; gegl_tile_backend_swap_ensure_exist (); if (entry->link) { g_mutex_lock (&mutex); if (entry->link) { params = entry->link->data; memcpy (params->source, source, length); g_mutex_unlock (&mutex); GEGL_NOTE(GEGL_DEBUG_TILE_BACKEND, "overwrote queue entry %i, %i, %i at %i", entry->x, entry->y, entry->z, (gint)entry->offset); return; } g_mutex_unlock (&mutex); } new_source = g_malloc (length); memcpy (new_source, source, length); params = g_slice_new0 (ThreadParams); params->operation = OP_WRITE; params->length = length; params->source = new_source; params->entry = entry; gegl_tile_backend_swap_push_queue (params); GEGL_NOTE(GEGL_DEBUG_TILE_BACKEND, "pushed write of entry %i, %i, %i at %i", entry->x, entry->y, entry->z, (gint)entry->offset); }
static void gegl_tile_backend_swap_entry_write (GeglTileBackendSwap *self, SwapEntry *entry, GeglTile *tile) { ThreadParams *params; gint length = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self)); gegl_tile_backend_swap_ensure_exist (); if (entry->link) { g_mutex_lock (&mutex); if (entry->link) { params = entry->link->data; gegl_tile_unref (params->tile); params->tile = gegl_tile_dup (tile); g_mutex_unlock (&mutex); GEGL_NOTE(GEGL_DEBUG_TILE_BACKEND, "tile %i, %i, %i at %i is already enqueued, changed data", entry->x, entry->y, entry->z, (gint)entry->offset); return; } g_mutex_unlock (&mutex); } params = g_slice_new0 (ThreadParams); params->operation = OP_WRITE; params->length = length; params->tile = gegl_tile_dup (tile); params->entry = entry; gegl_tile_backend_swap_push_queue (params); GEGL_NOTE(GEGL_DEBUG_TILE_BACKEND, "pushed write of entry %i, %i, %i at %i", entry->x, entry->y, entry->z, (gint)entry->offset); }
static void gegl_tile_backend_swap_entry_read (GeglTileBackendSwap *self, SwapEntry *entry, guchar *dest) { gint tile_size = gegl_tile_backend_get_tile_size (GEGL_TILE_BACKEND (self)); gint to_be_read = tile_size; guint64 offset = entry->offset; gegl_tile_backend_swap_ensure_exist (); if (entry->link || in_progress) { ThreadParams *queued_op = NULL; g_mutex_lock (&mutex); if (entry->link) queued_op = entry->link->data; else if (in_progress && in_progress->entry == entry) queued_op = in_progress; if (queued_op) { memcpy (dest, gegl_tile_get_data (queued_op->tile), to_be_read); g_mutex_unlock (&mutex); GEGL_NOTE(GEGL_DEBUG_TILE_BACKEND, "read entry %i, %i, %i from queue", entry->x, entry->y, entry->z); return; } g_mutex_unlock (&mutex); } if (in_offset != offset) { if (lseek (in_fd, offset, SEEK_SET) < 0) { g_warning ("unable to seek to tile in buffer: %s", g_strerror (errno)); return; } in_offset = offset; } while (to_be_read > 0) { GError *error = NULL; gint byte_read; byte_read = read (in_fd, dest + tile_size - to_be_read, to_be_read); if (byte_read <= 0) { g_message ("unable to read tile data from swap: " "%s (%d/%d bytes read) %s", g_strerror (errno), byte_read, to_be_read, error?error->message:"--"); return; } to_be_read -= byte_read; in_offset += byte_read; } GEGL_NOTE(GEGL_DEBUG_TILE_BACKEND, "read entry %i, %i, %i from %i", entry->x, entry->y, entry->z, (gint)offset); }