void gegl_buffer_iterator_stop (GeglBufferIterator *iterator) { GeglBufferIterators *i = (gpointer)iterator; gint no; for (no=0; no<i->iterators;no++) { gint j; gboolean found = FALSE; for (j=0; j<no; j++) if (i->buffer[no]==i->buffer[j]) { found = TRUE; break; } if (!found) gegl_buffer_unlock (i->buffer[no]); } for (no=0; no<i->iterators; no++) { if (i->buf[no]) iterator_buf_pool_release (i->buf[no]); i->buf[no]=NULL; g_object_unref (i->buffer[no]); } #if DEBUG_DIRECT g_print ("%f %f\n", (100.0*direct_read/(in_direct_read+direct_read)), 100.0*direct_write/(in_direct_write+direct_write)); #endif i->is_finished = TRUE; g_slice_free (GeglBufferIterators, i); }
gboolean gegl_buffer_iterator_next (GeglBufferIterator *iterator) { GeglBufferIterators *i = (gpointer)iterator; gboolean result = FALSE; gint no; if (i->is_finished) g_error ("%s called on finished buffer iterator", G_STRFUNC); if (i->iteration_no == 0) { for (no=0; no<i->iterators;no++) { gint j; gboolean found = FALSE; for (j=0; j<no; j++) if (i->buffer[no]==i->buffer[j]) { found = TRUE; break; } if (!found) gegl_buffer_lock (i->buffer[no]); } } else { /* complete pending write work */ for (no=0; no<i->iterators;no++) { if (i->flags[no] & GEGL_BUFFER_WRITE) { if (i->flags[no] & GEGL_BUFFER_SCAN_COMPATIBLE && i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE && i->roi[no].width == i->i[no].buffer->tile_storage->tile_width && (i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE)) { /* direct access */ #if DEBUG_DIRECT direct_write += i->roi[no].width * i->roi[no].height; #endif } else { #if DEBUG_DIRECT in_direct_write += i->roi[no].width * i->roi[no].height; #endif ensure_buf (i, no); /* XXX: should perhaps use _set_unlocked, and keep the lock in the * iterator. */ gegl_buffer_set (i->buffer[no], &(i->roi[no]), i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE); } } } } g_assert (i->iterators > 0); /* then we iterate all */ for (no=0; no<i->iterators;no++) { if (i->flags[no] & GEGL_BUFFER_SCAN_COMPATIBLE) { gboolean res; res = gegl_buffer_tile_iterator_next (&i->i[no]); if (no == 0) { result = res; } i->roi[no] = i->i[no].roi2; /* since they were scan compatible this should be true */ if (res != result) { g_print ("%i==%i != 0==%i\n", no, res, result); } g_assert (res == result); if ((i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE) && i->roi[no].width == i->i[no].buffer->tile_storage->tile_width ) { /* direct access */ i->data[no]=i->i[no].sub_data; #if DEBUG_DIRECT direct_read += i->roi[no].width * i->roi[no].height; #endif } else { ensure_buf (i, no); if (i->flags[no] & GEGL_BUFFER_READ) { gegl_buffer_get_unlocked (i->buffer[no], 1.0, &(i->roi[no]), i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE); } i->data[no]=i->buf[no]; #if DEBUG_DIRECT in_direct_read += i->roi[no].width * i->roi[no].height; #endif } } else { /* we copy the roi from iterator 0 */ i->roi[no] = i->roi[0]; i->roi[no].x += (i->rect[no].x-i->rect[0].x); i->roi[no].y += (i->rect[no].y-i->rect[0].y); ensure_buf (i, no); if (i->flags[no] & GEGL_BUFFER_READ) { gegl_buffer_get_unlocked (i->buffer[no], 1.0, &(i->roi[no]), i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE); } i->data[no]=i->buf[no]; #if DEBUG_DIRECT in_direct_read += i->roi[no].width * i->roi[no].height; #endif } i->length = i->roi[no].width * i->roi[no].height; } i->iteration_no++; if (result == FALSE) { for (no=0; no<i->iterators;no++) { gint j; gboolean found = FALSE; for (j=0; j<no; j++) if (i->buffer[no]==i->buffer[j]) { found = TRUE; break; } if (!found) gegl_buffer_unlock (i->buffer[no]); } for (no=0; no<i->iterators;no++) { if (i->buf[no]) iterator_buf_pool_release (i->buf[no]); i->buf[no]=NULL; g_object_unref (i->buffer[no]); } #if DEBUG_DIRECT g_print ("%f %f\n", (100.0*direct_read/(in_direct_read+direct_read)), 100.0*direct_write/(in_direct_write+direct_write)); #endif i->is_finished = TRUE; g_slice_free (GeglBufferIterators, i); } return result; }