Commit d1d3697c authored by BST 1998  Adam D. Moss's avatar BST 1998 Adam D. Moss Committed by Adam D. Moss
Browse files

Moved the idlerender stuff into gdisplay.c. Implemented idlerender when

Sat Sep 26 20:46:18 BST 1998  Adam D. Moss <adam@gimp.org>

	* app/channel.c app/channel_ops.c app/drawable.c
	app/floating_sel.c app/gdisplay.c app/gdisplay.h
	app/gimpimage.c app/layers_dialog.c app/undo.c:

	Moved the idlerender stuff into gdisplay.c.  Implemented
	idlerender when doing floating_sel->layer, and undoing/redoing
	layer deletion.

	idlerender would be useful in many other places for improving
	interactivity, if it weren't for the following problems:

		* By definition, idlerender doesn't wait for a
		gdisplays_update() call	before starting work - it just
		runs in idle time, which due to CPU contention with
		plugins may not	be genuinely available idle time when
		things are 'noninteractive'.

		* Most GIMP functions don't know whether they're
		being run interactively or not.  idlerender only
		makes sense for interactive work.  This is why
		it is currently only applied to those functions which
		would normally only be activated manually.

		* Mixing idlerender and drawable_update() /
		gdisplays_update_area() calls can lead to a region
		being rerendered twice.

	Hence, some slogwork is needed before idlerender can be
	applied in the more general case.
parent d1d516c2
Sat Sep 26 20:46:18 BST 1998 Adam D. Moss <adam@gimp.org>
* app/channel.c app/channel_ops.c app/drawable.c
app/floating_sel.c app/gdisplay.c app/gdisplay.h
app/gimpimage.c app/layers_dialog.c app/undo.c:
Moved the idlerender stuff into gdisplay.c. Implemented
idlerender when doing floating_sel->layer, and undoing/redoing
layer deletion.
idlerender would be useful in many other places for improving
interactivity, if it weren't for the following problems:
* By definition, idlerender doesn't wait for a
gdisplays_update() call before starting work - it just
runs in idle time, which due to CPU contention with
plugins may not be genuinely available idle time when
things are 'noninteractive'.
* Most GIMP functions don't know whether they're
being run interactively or not. idlerender only
makes sense for interactive work. This is why
it is currently only applied to those functions which
would normally only be activated manually.
* Mixing idlerender and drawable_update() /
gdisplays_update_area() calls can lead to a region
being rerendered twice.
Hence, some slogwork is needed before idlerender can be
applied in the more general case.
Sat Sep 26 00:54:14 EDT 1998 Adrian Likins <adrian@gimp.org>
*gimptool.1: minor update to add info about -strip
......
......@@ -271,6 +271,8 @@ channel_scale (Channel *channel, int new_width, int new_height)
if (new_width == 0 || new_height == 0)
return;
printf(" channel_scale ");fflush(stdout);
/* Update the old channel position */
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
......@@ -314,6 +316,8 @@ channel_resize (Channel *channel, int new_width, int new_height,
if (!new_width || !new_height)
return;
printf(" channel_resize ");fflush(stdout);
x1 = BOUNDS (offx, 0, new_width);
y1 = BOUNDS (offy, 0, new_height);
x2 = BOUNDS ((offx + GIMP_DRAWABLE(channel)->width), 0, new_width);
......
......@@ -437,6 +437,9 @@ offset (GImage *gimage,
/* swap the tiles */
drawable->tiles = new_tiles;
printf(" offset ");fflush(stdout);
/* update the drawable */
drawable_update (drawable, 0, 0, drawable_width (drawable), drawable_height (drawable));
}
......
......@@ -271,6 +271,8 @@ channel_scale (Channel *channel, int new_width, int new_height)
if (new_width == 0 || new_height == 0)
return;
printf(" channel_scale ");fflush(stdout);
/* Update the old channel position */
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
......@@ -314,6 +316,8 @@ channel_resize (Channel *channel, int new_width, int new_height,
if (!new_width || !new_height)
return;
printf(" channel_resize ");fflush(stdout);
x1 = BOUNDS (offx, 0, new_width);
y1 = BOUNDS (offy, 0, new_height);
x2 = BOUNDS ((offx + GIMP_DRAWABLE(channel)->width), 0, new_width);
......
......@@ -271,6 +271,8 @@ channel_scale (Channel *channel, int new_width, int new_height)
if (new_width == 0 || new_height == 0)
return;
printf(" channel_scale ");fflush(stdout);
/* Update the old channel position */
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
......@@ -314,6 +316,8 @@ channel_resize (Channel *channel, int new_width, int new_height,
if (!new_width || !new_height)
return;
printf(" channel_resize ");fflush(stdout);
x1 = BOUNDS (offx, 0, new_width);
y1 = BOUNDS (offy, 0, new_height);
x2 = BOUNDS ((offx + GIMP_DRAWABLE(channel)->width), 0, new_width);
......
......@@ -437,6 +437,9 @@ offset (GImage *gimage,
/* swap the tiles */
drawable->tiles = new_tiles;
printf(" offset ");fflush(stdout);
/* update the drawable */
drawable_update (drawable, 0, 0, drawable_width (drawable), drawable_height (drawable));
}
......
......@@ -437,6 +437,9 @@ offset (GImage *gimage,
/* swap the tiles */
drawable->tiles = new_tiles;
printf(" offset ");fflush(stdout);
/* update the drawable */
drawable_update (drawable, 0, 0, drawable_width (drawable), drawable_height (drawable));
}
......
......@@ -20,6 +20,7 @@
#include "drawable.h"
#include "floating_sel.h"
#include "gdisplay.h"
#include "general.h"
#include "gimage_mask.h"
#include "paint_funcs.h"
......@@ -2032,9 +2033,13 @@ gimp_image_merge_layers (GimpImage *gimage, GSList *merge_list, MergeType merge_
GIMP_DRAWABLE(merge_layer)->visible = TRUE;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[RESTRUCTURE]);
printf(" gimp_image_merge_layers ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(merge_layer), 0, 0, drawable_width (GIMP_DRAWABLE(merge_layer)), drawable_height (GIMP_DRAWABLE(merge_layer)));
/*reinit_layer_idlerender (gimage, merge_layer);*/
return merge_layer;
}
......@@ -2099,6 +2104,7 @@ gimp_image_add_layer (GimpImage *gimage, Layer *float_layer, int position)
gimp_image_set_active_layer (gimage, float_layer);
/* update the new layer's area */
printf(" gimp_image_add_layer ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(float_layer), 0, 0, drawable_width (GIMP_DRAWABLE(float_layer)), drawable_height (GIMP_DRAWABLE(float_layer)));
/* invalidate the composite preview */
......
......@@ -20,6 +20,7 @@
#include "drawable.h"
#include "floating_sel.h"
#include "gdisplay.h"
#include "general.h"
#include "gimage_mask.h"
#include "paint_funcs.h"
......@@ -2032,9 +2033,13 @@ gimp_image_merge_layers (GimpImage *gimage, GSList *merge_list, MergeType merge_
GIMP_DRAWABLE(merge_layer)->visible = TRUE;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[RESTRUCTURE]);
printf(" gimp_image_merge_layers ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(merge_layer), 0, 0, drawable_width (GIMP_DRAWABLE(merge_layer)), drawable_height (GIMP_DRAWABLE(merge_layer)));
/*reinit_layer_idlerender (gimage, merge_layer);*/
return merge_layer;
}
......@@ -2099,6 +2104,7 @@ gimp_image_add_layer (GimpImage *gimage, Layer *float_layer, int position)
gimp_image_set_active_layer (gimage, float_layer);
/* update the new layer's area */
printf(" gimp_image_add_layer ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(float_layer), 0, 0, drawable_width (GIMP_DRAWABLE(float_layer)), drawable_height (GIMP_DRAWABLE(float_layer)));
/* invalidate the composite preview */
......
......@@ -20,6 +20,7 @@
#include "drawable.h"
#include "floating_sel.h"
#include "gdisplay.h"
#include "general.h"
#include "gimage_mask.h"
#include "paint_funcs.h"
......@@ -2032,9 +2033,13 @@ gimp_image_merge_layers (GimpImage *gimage, GSList *merge_list, MergeType merge_
GIMP_DRAWABLE(merge_layer)->visible = TRUE;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[RESTRUCTURE]);
printf(" gimp_image_merge_layers ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(merge_layer), 0, 0, drawable_width (GIMP_DRAWABLE(merge_layer)), drawable_height (GIMP_DRAWABLE(merge_layer)));
/*reinit_layer_idlerender (gimage, merge_layer);*/
return merge_layer;
}
......@@ -2099,6 +2104,7 @@ gimp_image_add_layer (GimpImage *gimage, Layer *float_layer, int position)
gimp_image_set_active_layer (gimage, float_layer);
/* update the new layer's area */
printf(" gimp_image_add_layer ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(float_layer), 0, 0, drawable_width (GIMP_DRAWABLE(float_layer)), drawable_height (GIMP_DRAWABLE(float_layer)));
/* invalidate the composite preview */
......
......@@ -20,6 +20,7 @@
#include "drawable.h"
#include "floating_sel.h"
#include "gdisplay.h"
#include "general.h"
#include "gimage_mask.h"
#include "paint_funcs.h"
......@@ -2032,9 +2033,13 @@ gimp_image_merge_layers (GimpImage *gimage, GSList *merge_list, MergeType merge_
GIMP_DRAWABLE(merge_layer)->visible = TRUE;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[RESTRUCTURE]);
printf(" gimp_image_merge_layers ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(merge_layer), 0, 0, drawable_width (GIMP_DRAWABLE(merge_layer)), drawable_height (GIMP_DRAWABLE(merge_layer)));
/*reinit_layer_idlerender (gimage, merge_layer);*/
return merge_layer;
}
......@@ -2099,6 +2104,7 @@ gimp_image_add_layer (GimpImage *gimage, Layer *float_layer, int position)
gimp_image_set_active_layer (gimage, float_layer);
/* update the new layer's area */
printf(" gimp_image_add_layer ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(float_layer), 0, 0, drawable_width (GIMP_DRAWABLE(float_layer)), drawable_height (GIMP_DRAWABLE(float_layer)));
/* invalidate the composite preview */
......
......@@ -20,6 +20,7 @@
#include "drawable.h"
#include "floating_sel.h"
#include "gdisplay.h"
#include "general.h"
#include "gimage_mask.h"
#include "paint_funcs.h"
......@@ -2032,9 +2033,13 @@ gimp_image_merge_layers (GimpImage *gimage, GSList *merge_list, MergeType merge_
GIMP_DRAWABLE(merge_layer)->visible = TRUE;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[RESTRUCTURE]);
printf(" gimp_image_merge_layers ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(merge_layer), 0, 0, drawable_width (GIMP_DRAWABLE(merge_layer)), drawable_height (GIMP_DRAWABLE(merge_layer)));
/*reinit_layer_idlerender (gimage, merge_layer);*/
return merge_layer;
}
......@@ -2099,6 +2104,7 @@ gimp_image_add_layer (GimpImage *gimage, Layer *float_layer, int position)
gimp_image_set_active_layer (gimage, float_layer);
/* update the new layer's area */
printf(" gimp_image_add_layer ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(float_layer), 0, 0, drawable_width (GIMP_DRAWABLE(float_layer)), drawable_height (GIMP_DRAWABLE(float_layer)));
/* invalidate the composite preview */
......
......@@ -1089,7 +1089,8 @@ undo_push_layer (GImage *gimage,
}
}
#include <stdio.h>
#warning AIE
int
undo_pop_layer (GImage *gimage,
int state,
......@@ -1133,7 +1134,9 @@ undo_pop_layer (GImage *gimage,
floating_sel_reset (lu->layer);
}
drawable_update (GIMP_DRAWABLE(lu->layer), 0, 0, GIMP_DRAWABLE(lu->layer)->width, GIMP_DRAWABLE(lu->layer)->height);
printf (" undo_pop1 ");fflush(stdout);
/* drawable_update (GIMP_DRAWABLE(lu->layer), 0, 0, GIMP_DRAWABLE(lu->layer)->width, GIMP_DRAWABLE(lu->layer)->height);*/
reinit_layer_idlerender (gimage, lu->layer);
}
/* restore layer */
else
......@@ -1153,7 +1156,10 @@ undo_pop_layer (GImage *gimage,
gimage->layers = g_slist_insert (gimage->layers, lu->layer, lu->prev_position);
gimage->layer_stack = g_slist_prepend (gimage->layer_stack, lu->layer);
gimage->active_layer = lu->layer;
drawable_update (GIMP_DRAWABLE(lu->layer), 0, 0, GIMP_DRAWABLE(lu->layer)->width, GIMP_DRAWABLE(lu->layer)->height);
printf (" undo_pop2 ");fflush(stdout);
/*drawable_update (GIMP_DRAWABLE(lu->layer), 0, 0, GIMP_DRAWABLE(lu->layer)->width, GIMP_DRAWABLE(lu->layer)->height);*/
reinit_layer_idlerender (gimage, lu->layer);
}
return TRUE;
......
......@@ -20,6 +20,7 @@
#include "drawable.h"
#include "floating_sel.h"
#include "gdisplay.h"
#include "general.h"
#include "gimage_mask.h"
#include "paint_funcs.h"
......@@ -2032,9 +2033,13 @@ gimp_image_merge_layers (GimpImage *gimage, GSList *merge_list, MergeType merge_
GIMP_DRAWABLE(merge_layer)->visible = TRUE;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[RESTRUCTURE]);
printf(" gimp_image_merge_layers ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(merge_layer), 0, 0, drawable_width (GIMP_DRAWABLE(merge_layer)), drawable_height (GIMP_DRAWABLE(merge_layer)));
/*reinit_layer_idlerender (gimage, merge_layer);*/
return merge_layer;
}
......@@ -2099,6 +2104,7 @@ gimp_image_add_layer (GimpImage *gimage, Layer *float_layer, int position)
gimp_image_set_active_layer (gimage, float_layer);
/* update the new layer's area */
printf(" gimp_image_add_layer ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(float_layer), 0, 0, drawable_width (GIMP_DRAWABLE(float_layer)), drawable_height (GIMP_DRAWABLE(float_layer)));
/* invalidate the composite preview */
......
......@@ -24,6 +24,7 @@
#include "layer.h"
#include "errors.h"
#include "floating_sel.h"
#include "gdisplay.h"
#include "gimage.h"
#include "gimage_mask.h"
#include "interface.h"
......@@ -210,8 +211,13 @@ floating_sel_to_layer (Layer *layer)
msw@gimp.org
*/
printf(" floating_sel_to_layer ");fflush(stdout);
/*
drawable_update (GIMP_DRAWABLE(layer), 0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
*/
/* This may be undesirable when invoked non-interactively... we'll see. */
reinit_layer_idlerender (gimage, layer);
}
void
......
......@@ -20,6 +20,7 @@
#include "drawable.h"
#include "floating_sel.h"
#include "gdisplay.h"
#include "general.h"
#include "gimage_mask.h"
#include "paint_funcs.h"
......@@ -2032,9 +2033,13 @@ gimp_image_merge_layers (GimpImage *gimage, GSList *merge_list, MergeType merge_
GIMP_DRAWABLE(merge_layer)->visible = TRUE;
gtk_signal_emit(GTK_OBJECT(gimage), gimp_image_signals[RESTRUCTURE]);
printf(" gimp_image_merge_layers ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(merge_layer), 0, 0, drawable_width (GIMP_DRAWABLE(merge_layer)), drawable_height (GIMP_DRAWABLE(merge_layer)));
/*reinit_layer_idlerender (gimage, merge_layer);*/
return merge_layer;
}
......@@ -2099,6 +2104,7 @@ gimp_image_add_layer (GimpImage *gimage, Layer *float_layer, int position)
gimp_image_set_active_layer (gimage, float_layer);
/* update the new layer's area */
printf(" gimp_image_add_layer ");fflush(stdout);
drawable_update (GIMP_DRAWABLE(float_layer), 0, 0, drawable_width (GIMP_DRAWABLE(float_layer)), drawable_height (GIMP_DRAWABLE(float_layer)));
/* invalidate the composite preview */
......
......@@ -54,6 +54,16 @@
GSList * display_list = NULL;
static int display_num = 1;
static GdkCursorType default_gdisplay_cursor = GDK_TOP_LEFT_ARROW;
static GimpImage* idlerender_gimage;
static int idlerender_width;
static int idlerender_height;
static int idlerender_x;
static int idlerender_y;
static int idlerender_basex;
static int idlerender_basey;
static guint idlerender_idleid = 0;
static guint idlerender_handlerid = 0;
static gboolean idle_active = 0;
/* Local functions */
static void gdisplay_format_title (GimpImage *, char *);
......@@ -1283,6 +1293,8 @@ gdisplays_update_area (GimpImage* gimage,
/* int x1, y1, x2, y2; */
/* int count = 0; */
/* printf("GDUA%p:%d,%d:%dx%d ", gimage,x,y,w,h);fflush(stdout);*/
/* traverse the linked list of displays */
while (list)
{
......@@ -1546,3 +1558,200 @@ gdisplay_hash (GDisplay *display)
{
return (gulong) display;
}
static void
idlerender_gimage_destroy_handler (GimpImage *gimage)
{
printf("Destroyed gimage at %p which idlerender was interested in...\n",
gimage); fflush(stdout);
if (idle_active)
{
printf("Idlerender stops now!\n"); fflush(stdout);
gtk_idle_remove (idlerender_idleid);
}
printf("Destroy handler finished.\n"); fflush(stdout);
}
static void
idlerender_abort (GimpImage *gimage)
{
}
static int
idlerender_callback (void* unused)
{
const int CHUNK_WIDTH = 256;
const int CHUNK_HEIGHT = 128;
int workx, worky, workw, workh;
workw = CHUNK_WIDTH;
workh = CHUNK_HEIGHT;
workx = idlerender_x;
worky = idlerender_y;
if (workx+workw > idlerender_basex+idlerender_width)
{
workw = idlerender_basex+idlerender_width-workx;
}
if (worky+workh > idlerender_basey+idlerender_height)
{
workh = idlerender_basey+idlerender_height-worky;
}
gdisplays_update_area (idlerender_gimage,
workx, worky, workw, workh);
gdisplays_flush ();
idlerender_x += CHUNK_WIDTH;
if (idlerender_x >= idlerender_basex+idlerender_width)
{
idlerender_x = idlerender_basex;
idlerender_y += CHUNK_HEIGHT;
if (idlerender_y >= idlerender_basey+idlerender_height)
{
idle_active = 0;
/* Disconnect signal handler which cared about whether
a gimage was destroyed in mid-render */
gtk_signal_disconnect (GTK_OBJECT (idlerender_gimage),
idlerender_handlerid);
return (0); /* FINISHED! */
}
}
return (1);
}
/* Force any outstanding unrendered area in the gimage to be
rendered before we return... this is necessary e.g. if we
are restarting the idlerender thread for a different gimage. */
static void
idlerender_force_completion (void)
{
gtk_idle_remove (idlerender_idleid);
while (idle_active)
idlerender_callback (NULL);
}
/* Unify the desired and current (if any) bounding rectangles
of areas being idle-redrawn, and restart the idle thread if needed. */
static void
unify_and_start_idlerender (GimpImage* gimage, int basex, int basey,
int width, int height)
{
/* If another gimage is already employing the idlerender thread,
force it to finish before starting with this one... */
if (idle_active && (idlerender_gimage != gimage) )
{
printf ("Okay, switched gimage... poke Adam if this does anything "
"funny.\n");
fflush(stdout);
idlerender_force_completion();
}
idlerender_gimage = gimage;
if (idle_active)
{
int left, right, top, bottom;
/*printf("(%d,%d) @ Region (%d,%d %dx%d) | (%d,%d %dx%d)\n",
idlerender_x, idlerender_y,
idlerender_basex, idlerender_basey,
idlerender_width, idlerender_height,
basex, basey,
width, height);*/
top = (basey < idlerender_y) ? basey : idlerender_y;
left = (basex < idlerender_basex) ? basex : idlerender_basex;
bottom = (basey+height > idlerender_basey+idlerender_height) ?
basey+height : idlerender_basey+idlerender_height;
right = (basex+width > idlerender_basex+idlerender_width) ?
basex+width : idlerender_basex+idlerender_width;
idlerender_x = idlerender_basex = left;
idlerender_y = idlerender_basey = top;
idlerender_width = right-left;
idlerender_height = bottom-top;
/*printf(" --> (%d,%d) @ (%d,%d %dx%d)\n",
idlerender_x, idlerender_y,
idlerender_basex, idlerender_basey,
idlerender_width, idlerender_height);*/
}
else
{
idlerender_x = idlerender_basex = basex;
idlerender_y = idlerender_basey = basey;
idlerender_width = width;
idlerender_height = height;
idle_active = 1;
/* Catch a signal to stop the idlerender thread if the corresponding
gimage is destroyed in mid-render */
idlerender_handlerid =
gtk_signal_connect (GTK_OBJECT (gimage), "destroy",
GTK_SIGNAL_FUNC(idlerender_gimage_destroy_handler),
NULL);
idlerender_idleid =
gtk_idle_add_priority (GTK_PRIORITY_LOW, idlerender_callback, NULL);
}
}
void
reinit_layer_idlerender (GimpImage* gimage, Layer* layer)
{
int ibasex, ibasey;
if (! layer)
return;
if (! (gimage = gimp_drawable_gimage (GIMP_DRAWABLE(layer))))
return;
gimp_drawable_offsets (GIMP_DRAWABLE(layer),
&ibasex, &ibasey);
unify_and_start_idlerender (gimage, ibasex, ibasey,
GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height);
}
void
reinit_drawable_idlerender (GimpImage* gimage, GimpDrawable *drawable)
{
int ibasex, ibasey;
if (! drawable)
return;
if (! (gimage = gimp_drawable_gimage (GIMP_DRAWABLE(drawable))))
return;
gimp_drawable_offsets (GIMP_DRAWABLE(drawable),
&ibasex, &ibasey);
unify_and_start_idlerender (gimage, ibasex, ibasey,
GIMP_DRAWABLE(drawable)->width,