#include <string.h> for memset

Thu Sep 24 12:39:27 BST 1998  Adam D. Moss <adam@gimp.org>

	* app/brush_edit.c: #include <string.h> for memset

	* app/layers_dialog.c:

	Display re-rendering is now handled in an interruptible
	asynchronous idle-threaded, uh, paradigm shift.

	The upshot of this is that fiddling about with layers
	in the layers dialog is now a shipload faster for some
	common operations.

	Still needs to be ratified w.r.t. multiple gimages, but
	it's there.
This commit is contained in:
BST 1998 Adam D. Moss 1998-09-24 12:05:49 +00:00 committed by Adam D. Moss
parent 0fb97ecb8e
commit 0bcb1a1dda
6 changed files with 350 additions and 28 deletions

View File

@ -1,3 +1,19 @@
Thu Sep 24 12:39:27 BST 1998 Adam D. Moss <adam@gimp.org>
* app/brush_edit.c: #include <string.h> for memset
* app/layers_dialog.c:
Display re-rendering is now handled in an interruptible
asynchronous idle-threaded, uh, paradigm shift.
The upshot of this is that fiddling about with layers
in the layers dialog is now a shipload faster for some
common operations.
Still needs to be ratified w.r.t. multiple gimages, but
it's there.
Wed Sep 23 18:07:54 1998 Jay Cox (jaycox@earthlink.net)
* app/channel.[ch]

View File

@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <string.h>
#include "appenv.h"
#include "gimpbrushgenerated.h"
#include "brush_edit.h"

View File

@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <string.h>
#include "appenv.h"
#include "gimpbrushgenerated.h"
#include "brush_edit.h"

View File

@ -197,6 +197,10 @@ static void layers_dialog_scale_layer_query (Layer *);
static void layers_dialog_resize_layer_query (Layer *);
void layers_dialog_layer_merge_query (GImage *, int);
/* Idle rerendering of altered areas. */
static void reinit_layer_idlerender (GimpImage *, Layer *);
static void idlerender_gimage_destroy_handler (GimpImage *);
/*
* Shared data
@ -219,6 +223,17 @@ static GdkPixmap *mask_pixmap[3] = {NULL, NULL, NULL};
static int suspend_gimage_notify = 0;
GimpImage* idlerender_gimage;
int idlerender_width;
int idlerender_height;
int idlerender_x;
int idlerender_y;
int idlerender_basex;
int idlerender_basey;
guint idlerender_idleid = 0;
guint idlerender_handlerid = 0;
gboolean idle_active = 0;
static MenuItem layers_ops[] =
{
{ "New Layer", 'N', GDK_CONTROL_MASK,
@ -702,7 +717,8 @@ layers_dialog_create ()
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
layersD->opacity_data = GTK_ADJUSTMENT (gtk_adjustment_new (100.0, 0.0, 100.0, 1.0, 1.0, 0.0));
slider = gtk_hscale_new (layersD->opacity_data);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_range_set_update_policy (GTK_RANGE (slider),
GTK_UPDATE_CONTINUOUS);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_RIGHT);
gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (layersD->opacity_data), "value_changed",
@ -1446,8 +1462,7 @@ paint_mode_menu_callback (GtkWidget *w,
{
layer->mode = mode;
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
gdisplays_flush ();
reinit_layer_idlerender(gimage, layer);
}
}
}
@ -1485,8 +1500,7 @@ opacity_scale_update (GtkAdjustment *adjustment,
{
layer->opacity = opacity;
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
gdisplays_flush ();
reinit_layer_idlerender (gimage, layer);
}
}
@ -2135,6 +2149,146 @@ layer_widget_select_update (GtkWidget *w,
}
/* FIXME: idlerender stuff only knows about one gimage at
a time... shouldn't be hard to fix... get rid of those stupid
globals for one. [Adam] */
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 int
idlerender_callback (void* unused)
{
const int CHUNK_WIDTH = 128;
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);
}
/* ADAM: 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)
{
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);
}
}
static void
reinit_layer_idlerender (GimpImage* gimage, Layer *layer)
{
int ibasex, ibasey;
gimp_drawable_offsets (GIMP_DRAWABLE(layer),
&ibasex, &ibasey);
unify_and_start_idlerender (gimage, ibasex, ibasey,
GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height);
}
static void reinit_gimage_idlerender (GimpImage* gimage)
{
unify_and_start_idlerender (gimage, 0, 0, gimage->width, gimage->height);
}
static gint
layer_widget_button_events (GtkWidget *widget,
GdkEvent *event)
@ -2211,19 +2365,15 @@ layer_widget_button_events (GtkWidget *widget,
{
if (exclusive)
{
printf("Case 1, kick-ass!\n");fflush(stdout);
gimage_invalidate_preview (layer_widget->gimage);
gdisplays_update_area (layer_widget->gimage, 0, 0,
layer_widget->gimage->width,
layer_widget->gimage->height);
gdisplays_flush ();
reinit_gimage_idlerender (layer_widget->gimage);
}
else if (old_state != GIMP_DRAWABLE(layer_widget->layer)->visible)
{
/* Invalidate the gimage preview */
drawable_update (GIMP_DRAWABLE(layer_widget->layer), 0, 0,
GIMP_DRAWABLE(layer_widget->layer)->width,
GIMP_DRAWABLE(layer_widget->layer)->height);
gdisplays_flush ();
printf("Case 2, what incredible irony!\n");fflush(stdout);
reinit_layer_idlerender (layer_widget->gimage,
layer_widget->layer);
}
}
else if ((widget == layer_widget->linked_widget) &&

View File

@ -197,6 +197,10 @@ static void layers_dialog_scale_layer_query (Layer *);
static void layers_dialog_resize_layer_query (Layer *);
void layers_dialog_layer_merge_query (GImage *, int);
/* Idle rerendering of altered areas. */
static void reinit_layer_idlerender (GimpImage *, Layer *);
static void idlerender_gimage_destroy_handler (GimpImage *);
/*
* Shared data
@ -219,6 +223,17 @@ static GdkPixmap *mask_pixmap[3] = {NULL, NULL, NULL};
static int suspend_gimage_notify = 0;
GimpImage* idlerender_gimage;
int idlerender_width;
int idlerender_height;
int idlerender_x;
int idlerender_y;
int idlerender_basex;
int idlerender_basey;
guint idlerender_idleid = 0;
guint idlerender_handlerid = 0;
gboolean idle_active = 0;
static MenuItem layers_ops[] =
{
{ "New Layer", 'N', GDK_CONTROL_MASK,
@ -702,7 +717,8 @@ layers_dialog_create ()
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
layersD->opacity_data = GTK_ADJUSTMENT (gtk_adjustment_new (100.0, 0.0, 100.0, 1.0, 1.0, 0.0));
slider = gtk_hscale_new (layersD->opacity_data);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_range_set_update_policy (GTK_RANGE (slider),
GTK_UPDATE_CONTINUOUS);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_RIGHT);
gtk_box_pack_start (GTK_BOX (util_box), slider, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (layersD->opacity_data), "value_changed",
@ -1446,8 +1462,7 @@ paint_mode_menu_callback (GtkWidget *w,
{
layer->mode = mode;
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
gdisplays_flush ();
reinit_layer_idlerender(gimage, layer);
}
}
}
@ -1485,8 +1500,7 @@ opacity_scale_update (GtkAdjustment *adjustment,
{
layer->opacity = opacity;
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
gdisplays_flush ();
reinit_layer_idlerender (gimage, layer);
}
}
@ -2135,6 +2149,146 @@ layer_widget_select_update (GtkWidget *w,
}
/* FIXME: idlerender stuff only knows about one gimage at
a time... shouldn't be hard to fix... get rid of those stupid
globals for one. [Adam] */
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 int
idlerender_callback (void* unused)
{
const int CHUNK_WIDTH = 128;
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);
}
/* ADAM: 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)
{
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);
}
}
static void
reinit_layer_idlerender (GimpImage* gimage, Layer *layer)
{
int ibasex, ibasey;
gimp_drawable_offsets (GIMP_DRAWABLE(layer),
&ibasex, &ibasey);
unify_and_start_idlerender (gimage, ibasex, ibasey,
GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height);
}
static void reinit_gimage_idlerender (GimpImage* gimage)
{
unify_and_start_idlerender (gimage, 0, 0, gimage->width, gimage->height);
}
static gint
layer_widget_button_events (GtkWidget *widget,
GdkEvent *event)
@ -2211,19 +2365,15 @@ layer_widget_button_events (GtkWidget *widget,
{
if (exclusive)
{
printf("Case 1, kick-ass!\n");fflush(stdout);
gimage_invalidate_preview (layer_widget->gimage);
gdisplays_update_area (layer_widget->gimage, 0, 0,
layer_widget->gimage->width,
layer_widget->gimage->height);
gdisplays_flush ();
reinit_gimage_idlerender (layer_widget->gimage);
}
else if (old_state != GIMP_DRAWABLE(layer_widget->layer)->visible)
{
/* Invalidate the gimage preview */
drawable_update (GIMP_DRAWABLE(layer_widget->layer), 0, 0,
GIMP_DRAWABLE(layer_widget->layer)->width,
GIMP_DRAWABLE(layer_widget->layer)->height);
gdisplays_flush ();
printf("Case 2, what incredible irony!\n");fflush(stdout);
reinit_layer_idlerender (layer_widget->gimage,
layer_widget->layer);
}
}
else if ((widget == layer_widget->linked_widget) &&

View File

@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <string.h>
#include "appenv.h"
#include "gimpbrushgenerated.h"
#include "brush_edit.h"