[gnome-photos/wip/baedert/gtkimageview: 8/10] geglimage; Pre-render to surface
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-photos/wip/baedert/gtkimageview: 8/10] geglimage; Pre-render to surface
- Date: Fri, 15 Apr 2016 19:04:23 +0000 (UTC)
commit dea6a365799c92f18793b4fc4bdbd7319a44e47d
Author: Timm Bäder <mail baedert org>
Date: Fri Apr 15 17:07:31 2016 +0200
geglimage; Pre-render to surface
src/photos-gegl-image.c | 162 ++++++++++++++++++++++++++------------
src/photos-gegl-image.h | 5 +-
src/photos-preview-nav-buttons.c | 2 +-
src/photos-tool-crop.c | 4 +-
4 files changed, 120 insertions(+), 53 deletions(-)
---
diff --git a/src/photos-gegl-image.c b/src/photos-gegl-image.c
index cb3cab1..8c9e875 100644
--- a/src/photos-gegl-image.c
+++ b/src/photos-gegl-image.c
@@ -23,70 +23,108 @@ photos_gegl_image_get_scale_factor (GtkAbstractImage *_image)
}
static void
-photos_gegl_image_render_surface (PhotosGeglImage *image)
+photos_gegl_image_update_bbox (PhotosGeglImage *image)
{
GeglRectangle roi = image->roi;
+ GeglRectangle box = gegl_node_get_bounding_box (image->node);
+ gboolean bbox_changed = !gegl_rectangle_equal (&roi, &box);
- roi.x *= image->view_scale;
- roi.y *= image->view_scale;
+ image->width = box.width;
+ image->height = box.height;
- gegl_node_blit (image->node,
- image->view_scale,
- &roi,
- image->format,
- image->buf,
- GEGL_AUTO_ROWSTRIDE,
- GEGL_BLIT_CACHE | GEGL_BLIT_DIRTY);
-
- /*if (!image->surface)*/
- /*{*/
- image->surface = cairo_image_surface_create_for_data (image->buf,
- CAIRO_FORMAT_ARGB32,
- image->width * image->view_scale,
- image->height * image->view_scale,
- image->stride);
- /*}*/
+ image->roi = box;
+ g_message ("%s: New roi: %d, %d, %d, %d", __FUNCTION__, box.x, box.y, box.width, box.height);
- g_signal_emit_by_name (G_OBJECT (image), "changed", 0);
+ if (bbox_changed)
+ g_signal_emit_by_name (G_OBJECT (image), "changed", 0);
}
+
static void
-photos_gegl_image_update_bbox (PhotosGeglImage *image)
+photos_gegl_image_render_surface (PhotosGeglImage *image)
{
+ int w, h;
+ GeglRectangle roi = image->roi;
GeglRectangle box;
+ gboolean bbox_changed;
+ gboolean bbox_size_changed;
+ gboolean height_changed;
+ gboolean stride_changed = FALSE;
+ gboolean scale_changed = (image->view_scale != image->rendered_scale);
- if (!image->node)
- return;
+ g_assert (image->node);
box = gegl_node_get_bounding_box (image->node);
-#if 0
- g_message ("old size: %d, %d; new size: %d, %d", image->width, image->height,
- box.width, box.height);
- g_message ("bbox: %d, %d, %d, %d", box.x, box.y, box.width, box.height);
-#endif
+ bbox_changed = !gegl_rectangle_equal (&box, &image->roi);
+ bbox_size_changed = (box.width != image->width || box.height != image->height);
+ height_changed = (box.height != image->height);
- /*if (image->width != box.width || image->height != box.height ||*/
- /*image->roi.x != box.x || image->roi.y != box.y)*/
- /*{*/
+ if (bbox_size_changed || scale_changed)
+ {
+ int new_stride;
image->width = box.width;
image->height = box.height;
- image->roi.x = box.x;
- image->roi.y = box.y;
- image->roi.width = box.width /* image->scale_factor */* image->view_scale;
- image->roi.height = box.height /* image->scale_factor */* image->view_scale;
-
+ image->roi = box;
+ g_message ("%s: New roi: %d, %d, %d, %d", __FUNCTION__, box.x, box.y, box.width, box.height);
+ new_stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
+ box.width * image->view_scale);
+ stride_changed = (image->stride != new_stride);
+ image->stride = new_stride;
+ }
+ roi = image->roi;
- image->stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
- box.width * image->view_scale);
+ roi.x *= image->view_scale;
+ roi.y *= image->view_scale;
+ roi.width *= image->view_scale;
+ roi.height *= image->view_scale;
+ if (stride_changed || height_changed)
+ {
g_clear_pointer (&image->buf, g_free);
- g_clear_pointer (&image->buf, cairo_surface_destroy);
+ image->buf = g_malloc (image->stride * image->height); /* stride is already scaled */
+ }
+
+ if (scale_changed || bbox_changed)
+ {
+ g_message ("Blit");
+ gegl_node_blit (image->node,
+ image->view_scale,
+ &roi,
+ image->format,
+ image->buf,
+ GEGL_AUTO_ROWSTRIDE,
+ GEGL_BLIT_CACHE | GEGL_BLIT_DIRTY);
+ }
+
+ if (image->surface)
+ {
+ w = cairo_image_surface_get_width (image->surface);
+ h = cairo_image_surface_get_height (image->surface);
+ }
+ else
+ {
+ w = 0;
+ h = 0;
+ }
- image->buf = g_malloc (image->stride * box.height); /* stride is already scaled */
- /*}*/
+ if (!image->surface ||
+ w != (image->width * image->view_scale) ||
+ h != (image->height * image->view_scale))
+ {
+ g_message ("New surface");
+ g_clear_pointer (&image->surface, cairo_surface_destroy);
+ image->surface = cairo_image_surface_create_for_data (image->buf,
+ CAIRO_FORMAT_ARGB32,
+ image->width * image->view_scale,
+ image->height * image->view_scale,
+ image->stride);
+ }
+
+ image->rendered_scale = image->view_scale;
+ g_signal_emit_by_name (G_OBJECT (image), "changed", 0);
}
static void
@@ -96,7 +134,8 @@ photos_gegl_image_draw (GtkAbstractImage *_image, cairo_t *ct)
if (image->surface)
{
- cairo_scale (ct, 1.0 / image->view_scale, 1.0 / image->view_scale);
+ cairo_scale (ct, 1.0 / image->rendered_scale, 1.0 / image->rendered_scale);
+ /*cairo_scale (ct, 1.0 / image->view_scale, 1.0 / image->view_scale);*/
cairo_set_source_surface (ct, image->surface, 0, 0);
}
}
@@ -104,7 +143,9 @@ photos_gegl_image_draw (GtkAbstractImage *_image, cairo_t *ct)
static void
photos_gegl_image_computed (PhotosGeglImage *image)
{
- photos_gegl_image_update_bbox (image);
+ static int i = -1;
+
+ g_message ("%s: %d", __FUNCTION__, ++i);
photos_gegl_image_render_surface (image);
}
@@ -119,7 +160,6 @@ photos_gegl_image_new (GeglNode *node, int scale_factor)
image->scale_factor = scale_factor;
image->format = babl_format ("cairo-ARGB32");
- photos_gegl_image_update_bbox (image);
photos_gegl_image_render_surface (image);
return image;
@@ -130,6 +170,7 @@ photos_gegl_image_init (PhotosGeglImage *image)
{
image->surface = NULL;
image->view_scale = 1.0;
+ image->rendered_scale = 1.0;
}
static void
@@ -137,11 +178,8 @@ photos_gegl_image_finalize (GObject *_image)
{
PhotosGeglImage *image = PHOTOS_GEGL_IMAGE (_image);
- if (image->surface)
- cairo_surface_destroy (image->surface);
-
- if (image->buf)
- g_free (image->buf);
+ g_clear_pointer (&image->surface, cairo_surface_destroy);
+ g_clear_pointer (&image->buf, g_free);
G_OBJECT_CLASS (photos_gegl_image_parent_class)->finalize (_image);
}
@@ -160,6 +198,19 @@ photos_gegl_image_class_init (PhotosGeglImageClass *klass)
image_class->get_scale_factor = photos_gegl_image_get_scale_factor;
}
+static gboolean
+redraw_cb (gpointer data)
+{
+ PhotosGeglImage *image = data;
+
+
+ if (G_LIKELY (image->node))
+ photos_gegl_image_render_surface (image);
+
+ image->redraw_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
void
photos_gegl_image_set_view_scale (PhotosGeglImage *image, double view_scale)
{
@@ -168,5 +219,16 @@ photos_gegl_image_set_view_scale (PhotosGeglImage *image, double view_scale)
image->view_scale = view_scale;
- photos_gegl_image_render_surface (image);
+ if (!image->node)
+ return;
+
+ photos_gegl_image_update_bbox (image);
+
+ if (image->redraw_id != 0)
+ {
+ g_source_remove (image->redraw_id);
+ image->redraw_id = 0;
+ }
+
+ image->redraw_id = g_timeout_add (200, redraw_cb, image);
}
diff --git a/src/photos-gegl-image.h b/src/photos-gegl-image.h
index 57c8e05..aafde0e 100644
--- a/src/photos-gegl-image.h
+++ b/src/photos-gegl-image.h
@@ -19,13 +19,16 @@ struct _PhotosGeglImage
GeglNode *node;
int width;
int height;
- double view_scale;
cairo_surface_t *surface;
guchar *buf;
const Babl *format;
GeglRectangle roi;
int stride;
int scale_factor;
+
+ double view_scale;
+ double rendered_scale;
+ guint redraw_id;
};
struct _PhotosGeglImageClass
diff --git a/src/photos-preview-nav-buttons.c b/src/photos-preview-nav-buttons.c
index 166e8d8..410175d 100644
--- a/src/photos-preview-nav-buttons.c
+++ b/src/photos-preview-nav-buttons.c
@@ -114,7 +114,7 @@ photos_preview_nav_buttons_fade_in_button (PhotosPreviewNavButtons *self, GtkWid
return;
gtk_widget_show_all (widget);
- gtk_revealer_set_reveal_child (GTK_REVEALER (widget), TRUE);
+ gtk_revealer_set_reveal_child (GTK_REVEALER (widget), FALSE);
}
diff --git a/src/photos-tool-crop.c b/src/photos-tool-crop.c
index 7120e77..8fc7c18 100644
--- a/src/photos-tool-crop.c
+++ b/src/photos-tool-crop.c
@@ -233,8 +233,10 @@ photos_tool_crop_surface_create (PhotosToolCrop *self)
window = gtk_widget_get_window (self->view);
zoom = photos_image_view_get_zoom (PHOTOS_IMAGE_VIEW (self->view));
- self->bbox_zoomed.height = (gint) (zoom * self->bbox_source.height + 0.5);
+ g_message ("bbox_source: %d, %d (zoom: %f)", self->bbox_source.width, self->bbox_source.height, zoom);
+ /*zoom = 1.0;*/
self->bbox_zoomed.width = (gint) (zoom * self->bbox_source.width + 0.5);
+ self->bbox_zoomed.height = (gint) (zoom * self->bbox_source.height + 0.5);
self->surface = gdk_window_create_similar_surface (window,
CAIRO_CONTENT_COLOR_ALPHA,
self->bbox_zoomed.width,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]