Mon Dec 13 19:25:39 GMT 1999 Adam D. Moss <adam@gimp.org

* app/tile.c
	* app/tile.h
	* app/tile_manager.c
	* app/tile_swap.c:

	Allocate Tile's array of TileRowHints dynamically.  Make type
	of TileRowHint explicit since it's fairly space-critical.
	Can save several hundred K of memory with this and struct
	changes.

	Added warnings for old basically-untested-or-insane
	paths through the tile referencing code.

	* app/tile_pvt.h: Shrink down and rearrange fields of Tile
	struct to save some space with gcc's padding for most people.

	* app/paint_funcs.c: Use tile_sanitize_rowhints() to ensure
          that rowhints have been allocated before use.

	* app/channel_ops.c
	* app/gdisplay.c
	* app/pixel_region.c: Cosmetic, sanity or unfinished debug
          changes (the latter commented out) for fun and reference.
This commit is contained in:
Adam D. Moss 1999-12-13 19:48:24 +00:00
parent 23f7ad6bd2
commit 22b8c94feb
23 changed files with 521 additions and 142 deletions

View File

@ -1,3 +1,29 @@
Mon Dec 13 19:25:39 GMT 1999 Adam D. Moss <adam@gimp.org
* app/tile.c
* app/tile.h
* app/tile_manager.c
* app/tile_swap.c:
Allocate Tile's array of TileRowHints dynamically. Make type
of TileRowHint explicit since it's fairly space-critical.
Can save several hundred K of memory with this and struct
changes.
Added warnings for old basically-untested-or-insane
paths through the tile referencing code.
* app/tile_pvt.h: Shrink down and rearrange fields of Tile
struct to save some space with gcc's padding for most people.
* app/paint_funcs.c: Use tile_sanitize_rowhints() to ensure
that rowhints have been allocated before use.
* app/channel_ops.c
* app/gdisplay.c
* app/pixel_region.c: Cosmetic, sanity or unfinished debug
changes (the latter commented out) for fun and reference.
1999-12-13 Shirasaki Yasuhiro <yasuhiro@gnome.gr.jp>
* po/POTFILES.in: Added missing app/path_tool.c.

View File

@ -363,7 +363,7 @@ pixel_regions_process (void *PRI_ptr)
{
/* only set the dirty flag if PRH->dirty_tiles = true */
tile_release (PRH->PR->curtile,
PRH->PR->dirty * PRI->dirty_tiles);
PRH->PR->dirty && PRI->dirty_tiles);
PRH->PR->curtile = NULL;
}

View File

@ -157,9 +157,17 @@ tile_manager_get (TileManager *tm,
if (wantwrite && !wantread)
{
g_warning("WRITE-ONLY TILE... OUCHIE");
g_warning("WRITE-ONLY TILE... UNTESTED!");
}
/*
if ((*tile_ptr)->share_count &&
(*tile_ptr)->write_count)
fprintf(stderr," >> MEEPITY %d,%d << ",
(*tile_ptr)->share_count,
(*tile_ptr)->write_count
); */
if (wantread)
{
TILE_MUTEX_LOCK (*tile_ptr);
@ -169,17 +177,25 @@ tile_manager_get (TileManager *tm,
{
/* Copy-on-write required */
Tile *newtile = g_new (Tile, 1);
tile_init (newtile, (*tile_ptr)->bpp);
newtile->ewidth = (*tile_ptr)->ewidth;
newtile->eheight = (*tile_ptr)->eheight;
newtile->valid = (*tile_ptr)->valid;
newtile->data = g_new (guchar, tile_size (newtile));
i = newtile->eheight;
while (i--)
{
newtile->rowhint[i] = (*tile_ptr)->rowhint[i];
}
if (!newtile->valid)
g_warning ("Oh boy, r/w tile is invalid... we suck. Please report.");
if ((*tile_ptr)->rowhint)
{
tile_sanitize_rowhints (newtile);
i = newtile->eheight;
while (i--)
{
newtile->rowhint[i] = (*tile_ptr)->rowhint[i];
}
}
if ((*tile_ptr)->data != NULL)
{
@ -199,8 +215,13 @@ tile_manager_get (TileManager *tm,
}
(*tile_ptr)->write_count++;
(*tile_ptr)->dirty = 1;
(*tile_ptr)->dirty = TRUE;
}
/* else
{
if ((*tile_ptr)->write_count)
fprintf(stderr,"STINK! r/o on r/w tile /%d\007 ",(*tile_ptr)->write_count);
} */
TILE_MUTEX_UNLOCK (*tile_ptr);
tile_lock (*tile_ptr);
}
@ -233,6 +254,17 @@ tile_manager_validate (TileManager *tm,
if (tm->validate_proc)
(* tm->validate_proc) (tm, tile);
/* DEBUG STUFF -> if (tm->user_data)
{
// fprintf(stderr,"V%p ",tm->user_data);
fprintf(stderr,"V");
}
else
{
fprintf(stderr,"v");
} */
}
void
@ -286,6 +318,7 @@ tile_invalidate (Tile **tile_ptr, TileManager *tm, int tile_num)
{
/* This tile is shared. Replace it with a new, invalid tile. */
Tile *newtile = g_new (Tile, 1);
tile_init (newtile, tile->bpp);
newtile->ewidth = tile->ewidth;
newtile->eheight = tile->eheight;
@ -400,6 +433,9 @@ tile_manager_map (TileManager *tm,
/* printf(")");fflush(stdout);*/
if (!srctile->valid)
g_warning("tile_manager_map: srctile not validated yet! please report.");
TILE_MUTEX_LOCK (*tile_ptr);
if ((*tile_ptr)->ewidth != srctile->ewidth ||
(*tile_ptr)->eheight != srctile->eheight ||

View File

@ -40,23 +40,23 @@ struct _Tile
guint dirty : 1; /* is the tile dirty? has it been modified? */
guint valid : 1; /* is the tile valid? */
/* An array of hints for rendering purposes */
TileRowHint rowhint[TILE_HEIGHT];
unsigned char bpp; /* the bytes per pixel (1, 2, 3 or 4) */
unsigned short ewidth; /* the effective width of the tile */
unsigned short eheight; /* the effective height of the tile */
/* a tile's effective width and height may be smaller
* (but not larger) than TILE_WIDTH and TILE_HEIGHT.
* this is to handle edge tiles of a drawable.
*/
TileRowHint *rowhint; /* An array of hints for rendering purposes */
guchar *data; /* the data for the tile. this may be NULL in which
* case the tile data is on disk.
*/
int ewidth; /* the effective width of the tile */
int eheight; /* the effective height of the tile */
/* a tile's effective width and height may be smaller
* (but not larger) than TILE_WIDTH and TILE_HEIGHT.
* this is to handle edge tiles of a drawable.
*/
int bpp; /* the bytes per pixel (1, 2, 3 or 4) */
int swap_num; /* the index into the file table of the file to be used
* for swapping. swap_num 1 is always the global swap file.
*/
int swap_num; /* the index into the file table of the file to be used
* for swapping. swap_num 1 is always the global swap file.
*/
off_t swap_offset; /* the offset within the swap file of the tile data.
* if the tile data is in memory this will be set to -1.
*/

View File

@ -30,8 +30,8 @@
#define MAX_OPEN_SWAP_FILES 16
#include "tile.h"
#include "tile_swap.h"
#include "tile_pvt.h" /* ick. */
typedef struct _SwapFile SwapFile;
@ -180,6 +180,13 @@ tile_swap_exit1 (gpointer key,
void
tile_swap_exit ()
{
#ifdef HINTS_SANITY
extern int tile_exist_peak;
fprintf(stderr,"Tile exist peak was %d Tile structs (%d bytes)",
tile_exist_peak, tile_exist_peak * sizeof(Tile));
#endif
if (swap_files)
g_hash_table_foreach (swap_files, tile_swap_exit1, NULL);
}

View File

@ -13,6 +13,25 @@ static void tile_destroy (Tile *tile);
int tile_count = 0;
void
tile_sanitize_rowhints (Tile *tile)
{
int height, y;
/* If tile has rowhints array already, do nothing. */
if (tile->rowhint)
return;
height = tile->eheight;
tile->rowhint = g_new (TileRowHint, height);
for (y=0; y<height; y++)
{
tile->rowhint[y] = TILEROWHINT_UNKNOWN;
}
}
TileRowHint
tile_get_rowhint (Tile *tile, int yoff)
{
@ -23,7 +42,7 @@ tile_get_rowhint (Tile *tile, int yoff)
}
else
g_error("GET_ROWHINT OUT OF RANGE");
/* return TILEROWHINT_OUTOFRANGE; */
return TILEROWHINT_OUTOFRANGE;
#else
return tile->rowhint[yoff];
#endif
@ -48,8 +67,6 @@ void
tile_init (Tile *tile,
int bpp)
{
int y;
tile->ref_count = 0;
tile->write_count = 0;
tile->share_count = 0;
@ -64,11 +81,7 @@ tile_init (Tile *tile,
tile->tlink = NULL;
tile->next = tile->prev = NULL;
tile->listhead = NULL;
for (y=0; y<TILE_HEIGHT; y++)
{
tile->rowhint[y] = TILEROWHINT_UNKNOWN;
}
tile->rowhint = NULL;
#ifdef USE_PTHREADS
{
@ -82,6 +95,11 @@ int tile_ref_count = 0;
int tile_share_count = 0;
int tile_active_count = 0;
#ifdef HINTS_SANITY
int tile_exist_peak = 0;
int tile_exist_count = 0;
#endif
void
tile_lock (Tile *tile)
{
@ -144,10 +162,13 @@ tile_release (Tile *tile, int dirty)
int y;
tile->write_count -= 1;
for (y = 0; y < tile->eheight; y++)
if (tile->rowhint)
{
tile->rowhint[y] = TILEROWHINT_UNKNOWN;
for (y = 0; y < tile->eheight; y++)
{
tile->rowhint[y] = TILEROWHINT_UNKNOWN;
}
}
}
@ -156,7 +177,7 @@ tile_release (Tile *tile, int dirty)
tile_active_count--;
if (tile->share_count == 0)
{
/* tile is dead */
/* tile is truly dead */
tile_destroy (tile);
return; /* skip terminal unlock */
}
@ -180,6 +201,12 @@ tile_alloc (Tile *tile)
/* Allocate the data for the tile.
*/
tile->data = g_new (guchar, tile_size (tile));
#ifdef HINTS_SANITY
tile_exist_count++;
if (tile_exist_count > tile_exist_peak)
tile_exist_peak = tile_exist_count;
#endif
}
static void
@ -200,6 +227,11 @@ tile_destroy (Tile *tile)
g_free (tile->data);
tile->data = NULL;
}
if (tile->rowhint)
{
g_free (tile->rowhint);
tile->rowhint = NULL;
}
if (tile->swap_offset != -1)
{
/* If the tile is on disk, then delete its
@ -213,6 +245,10 @@ tile_destroy (Tile *tile)
TILE_MUTEX_UNLOCK (tile);
g_free (tile);
tile_count --;
#ifdef HINTS_SANITY
tile_exist_count--;
#endif
}
@ -270,7 +306,7 @@ tile_attach (Tile *tile, void *tm, int tile_num)
{
TileLink *tmp;
if (tile->share_count > 0 && !tile->valid)
if ((tile->share_count > 0) && (!tile->valid))
{
/* trying to share invalid tiles is problematic, not to mention silly */
tile_manager_validate ((TileManager*) tile->tlink->tm, tile);
@ -300,15 +336,17 @@ tile_detach (Tile *tile, void *tm, int tile_num)
tile->ref_count, tile->share_count);
#endif
for (link = &tile->tlink; *link; link = &(*link)->next)
for (link = &tile->tlink;
*link != NULL;
link = &(*link)->next)
{
if ((*link)->tm == tm && (*link)->tile_num == tile_num)
if (((*link)->tm == tm) && ((*link)->tile_num == tile_num))
break;
}
if (*link == NULL)
{
g_warning ("Tried to detach a nonattached tile");
g_warning ("Tried to detach a nonattached tile -- TILE BUG!");
return;
}

View File

@ -19,16 +19,18 @@
typedef struct _Tile Tile;
typedef enum
{
TILEROWHINT_BROKEN = 0,
TILEROWHINT_OPAQUE,
TILEROWHINT_TRANSPARENT,
TILEROWHINT_MIXED,
TILEROWHINT_OUTOFRANGE,
TILEROWHINT_UNDEFINED,
TILEROWHINT_UNKNOWN
} TileRowHint;
/* explicit guchar type rather than enum since gcc chooses an int
* representation but arrays of TileRowHints are quite space-critical
* in GIMP.
*/
typedef guchar TileRowHint;
#define TILEROWHINT_BROKEN 0
#define TILEROWHINT_OPAQUE 1
#define TILEROWHINT_TRANSPARENT 2
#define TILEROWHINT_MIXED 3
#define TILEROWHINT_OUTOFRANGE 4
#define TILEROWHINT_UNDEFINED 5
#define TILEROWHINT_UNKNOWN 6
/* Initializes the fields of a tile to "good" values.
@ -68,6 +70,7 @@ void tile_mark_valid (Tile *tile);
/* DOCUMENT ME -- adm */
TileRowHint tile_get_rowhint (Tile *tile, int yoff);
void tile_set_rowhint (Tile *tile, int yoff, TileRowHint rowhint);
void tile_sanitize_rowhints (Tile *tile);
void *tile_data_pointer (Tile *tile, int xoff, int yoff);

View File

@ -741,10 +741,8 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
if (newgimage->construct_flag)
#endif
{
/* We don't want to copy a half-redrawn projection, so force a flush. */
gdisplays_finish_draw();
gdisplays_flush_now();
tile_manager_set_user_data(gimp_image_projection (newgimage),
(void *) newgimage);
/*
newgimage->proj_type = oldgimage->proj_type;
@ -752,13 +750,15 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
newgimage->proj_level = oldgimage->proj_level;
gimage_projection_realloc (new_gimage);*/
/*
pixel_region_init (&srcPR, gimp_image_projection (oldgimage), 0, 0,
oldgimage->width, oldgimage->height, FALSE);
pixel_region_init (&destPR, gimp_image_projection (newgimage), 0, 0,
newgimage->width, newgimage->height, TRUE);
copy_region(&srcPR, &destPR);*/
copy_region(&srcPR, &destPR);
/*
pixel_region_init (&srcPR, gimp_image_projection (oldgimage),
newgdisplay->disp_xoffset, newgdisplay->disp_yoffset,
newgdisplay->disp_width, newgdisplay->disp_height,
@ -768,6 +768,37 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
newgdisplay->disp_width, newgdisplay->disp_height,
TRUE);
copy_region(&srcPR, &destPR);
*/
if (1)
{
GDisplay* gdisp;
int x,y,w,h;
int x1, y1, x2, y2;
gdisp = newgdisplay;
fprintf (stderr, " [pointers: %p, %p ] ", oldgimage, gdisp->gimage);
gdisplay_untransform_coords (gdisp, 0, 0, &x1, &y1, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height,
&x2, &y2, FALSE, FALSE);
fprintf(stderr," <%dx%d %dx%d %d,%d->%d,%d> ",
oldgimage->width, oldgimage->height,
newgimage->width, newgimage->height,
x1,y1, x2,y2);
gimage_invalidate_without_render (gdisp->gimage, 0,0,
gdisp->gimage->width,
gdisp->gimage->height,
// 64,64,128,128);
// newgdisplay->disp_width,newgdisplay->disp_height,
// newgdisplay->disp_width+newgdisplay->disp_xoffset,newgdisplay->disp_height+newgdisplay->disp_yoffset
x1, y1, x2, y2
);
}
}
}
#endif
@ -781,7 +812,11 @@ channel_ops_duplicate (GimpImage *gimage)
new_gimage = duplicate (gimage);
/* We don't want to copy a half-redrawn projection, so force a flush. */
/* gdisplays_finish_draw();
gdisplays_flush_now(); */
new_gdisp = gdisplay_new (new_gimage, 0x0101);
/* duplicate_projection(gimage, new_gimage, new_gdisp); */
/* duplicate_projection(gimage, new_gimage, new_gdisp);*/
}

View File

@ -741,10 +741,8 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
if (newgimage->construct_flag)
#endif
{
/* We don't want to copy a half-redrawn projection, so force a flush. */
gdisplays_finish_draw();
gdisplays_flush_now();
tile_manager_set_user_data(gimp_image_projection (newgimage),
(void *) newgimage);
/*
newgimage->proj_type = oldgimage->proj_type;
@ -752,13 +750,15 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
newgimage->proj_level = oldgimage->proj_level;
gimage_projection_realloc (new_gimage);*/
/*
pixel_region_init (&srcPR, gimp_image_projection (oldgimage), 0, 0,
oldgimage->width, oldgimage->height, FALSE);
pixel_region_init (&destPR, gimp_image_projection (newgimage), 0, 0,
newgimage->width, newgimage->height, TRUE);
copy_region(&srcPR, &destPR);*/
copy_region(&srcPR, &destPR);
/*
pixel_region_init (&srcPR, gimp_image_projection (oldgimage),
newgdisplay->disp_xoffset, newgdisplay->disp_yoffset,
newgdisplay->disp_width, newgdisplay->disp_height,
@ -768,6 +768,37 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
newgdisplay->disp_width, newgdisplay->disp_height,
TRUE);
copy_region(&srcPR, &destPR);
*/
if (1)
{
GDisplay* gdisp;
int x,y,w,h;
int x1, y1, x2, y2;
gdisp = newgdisplay;
fprintf (stderr, " [pointers: %p, %p ] ", oldgimage, gdisp->gimage);
gdisplay_untransform_coords (gdisp, 0, 0, &x1, &y1, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height,
&x2, &y2, FALSE, FALSE);
fprintf(stderr," <%dx%d %dx%d %d,%d->%d,%d> ",
oldgimage->width, oldgimage->height,
newgimage->width, newgimage->height,
x1,y1, x2,y2);
gimage_invalidate_without_render (gdisp->gimage, 0,0,
gdisp->gimage->width,
gdisp->gimage->height,
// 64,64,128,128);
// newgdisplay->disp_width,newgdisplay->disp_height,
// newgdisplay->disp_width+newgdisplay->disp_xoffset,newgdisplay->disp_height+newgdisplay->disp_yoffset
x1, y1, x2, y2
);
}
}
}
#endif
@ -781,7 +812,11 @@ channel_ops_duplicate (GimpImage *gimage)
new_gimage = duplicate (gimage);
/* We don't want to copy a half-redrawn projection, so force a flush. */
/* gdisplays_finish_draw();
gdisplays_flush_now(); */
new_gdisp = gdisplay_new (new_gimage, 0x0101);
/* duplicate_projection(gimage, new_gimage, new_gdisp); */
/* duplicate_projection(gimage, new_gimage, new_gdisp);*/
}

View File

@ -741,10 +741,8 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
if (newgimage->construct_flag)
#endif
{
/* We don't want to copy a half-redrawn projection, so force a flush. */
gdisplays_finish_draw();
gdisplays_flush_now();
tile_manager_set_user_data(gimp_image_projection (newgimage),
(void *) newgimage);
/*
newgimage->proj_type = oldgimage->proj_type;
@ -752,13 +750,15 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
newgimage->proj_level = oldgimage->proj_level;
gimage_projection_realloc (new_gimage);*/
/*
pixel_region_init (&srcPR, gimp_image_projection (oldgimage), 0, 0,
oldgimage->width, oldgimage->height, FALSE);
pixel_region_init (&destPR, gimp_image_projection (newgimage), 0, 0,
newgimage->width, newgimage->height, TRUE);
copy_region(&srcPR, &destPR);*/
copy_region(&srcPR, &destPR);
/*
pixel_region_init (&srcPR, gimp_image_projection (oldgimage),
newgdisplay->disp_xoffset, newgdisplay->disp_yoffset,
newgdisplay->disp_width, newgdisplay->disp_height,
@ -768,6 +768,37 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
newgdisplay->disp_width, newgdisplay->disp_height,
TRUE);
copy_region(&srcPR, &destPR);
*/
if (1)
{
GDisplay* gdisp;
int x,y,w,h;
int x1, y1, x2, y2;
gdisp = newgdisplay;
fprintf (stderr, " [pointers: %p, %p ] ", oldgimage, gdisp->gimage);
gdisplay_untransform_coords (gdisp, 0, 0, &x1, &y1, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height,
&x2, &y2, FALSE, FALSE);
fprintf(stderr," <%dx%d %dx%d %d,%d->%d,%d> ",
oldgimage->width, oldgimage->height,
newgimage->width, newgimage->height,
x1,y1, x2,y2);
gimage_invalidate_without_render (gdisp->gimage, 0,0,
gdisp->gimage->width,
gdisp->gimage->height,
// 64,64,128,128);
// newgdisplay->disp_width,newgdisplay->disp_height,
// newgdisplay->disp_width+newgdisplay->disp_xoffset,newgdisplay->disp_height+newgdisplay->disp_yoffset
x1, y1, x2, y2
);
}
}
}
#endif
@ -781,7 +812,11 @@ channel_ops_duplicate (GimpImage *gimage)
new_gimage = duplicate (gimage);
/* We don't want to copy a half-redrawn projection, so force a flush. */
/* gdisplays_finish_draw();
gdisplays_flush_now(); */
new_gdisp = gdisplay_new (new_gimage, 0x0101);
/* duplicate_projection(gimage, new_gimage, new_gdisp); */
/* duplicate_projection(gimage, new_gimage, new_gdisp);*/
}

View File

@ -1222,13 +1222,15 @@ gdisplay_paint_area (GDisplay *gdisp,
/* calculate the extents of the update as limited by what's visible */
gdisplay_untransform_coords (gdisp, 0, 0, &x1, &y1, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height, &x2, &y2, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height,
&x2, &y2, FALSE, FALSE);
gimage_invalidate (gdisp->gimage, x, y, w, h, x1, y1, x2, y2);
/* display the area */
gdisplay_transform_coords (gdisp, x, y, &x1, &y1, FALSE);
gdisplay_transform_coords (gdisp, x + w, y + h, &x2, &y2, FALSE);
gdisplay_expose_area (gdisp, x1, y1, (x2 - x1), (y2 - y1));
}

View File

@ -1222,13 +1222,15 @@ gdisplay_paint_area (GDisplay *gdisp,
/* calculate the extents of the update as limited by what's visible */
gdisplay_untransform_coords (gdisp, 0, 0, &x1, &y1, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height, &x2, &y2, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height,
&x2, &y2, FALSE, FALSE);
gimage_invalidate (gdisp->gimage, x, y, w, h, x1, y1, x2, y2);
/* display the area */
gdisplay_transform_coords (gdisp, x, y, &x1, &y1, FALSE);
gdisplay_transform_coords (gdisp, x + w, y + h, &x2, &y2, FALSE);
gdisplay_expose_area (gdisp, x1, y1, (x2 - x1), (y2 - y1));
}

View File

@ -1222,13 +1222,15 @@ gdisplay_paint_area (GDisplay *gdisp,
/* calculate the extents of the update as limited by what's visible */
gdisplay_untransform_coords (gdisp, 0, 0, &x1, &y1, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height, &x2, &y2, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height,
&x2, &y2, FALSE, FALSE);
gimage_invalidate (gdisp->gimage, x, y, w, h, x1, y1, x2, y2);
/* display the area */
gdisplay_transform_coords (gdisp, x, y, &x1, &y1, FALSE);
gdisplay_transform_coords (gdisp, x + w, y + h, &x2, &y2, FALSE);
gdisplay_expose_area (gdisp, x1, y1, (x2 - x1), (y2 - y1));
}

View File

@ -741,10 +741,8 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
if (newgimage->construct_flag)
#endif
{
/* We don't want to copy a half-redrawn projection, so force a flush. */
gdisplays_finish_draw();
gdisplays_flush_now();
tile_manager_set_user_data(gimp_image_projection (newgimage),
(void *) newgimage);
/*
newgimage->proj_type = oldgimage->proj_type;
@ -752,13 +750,15 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
newgimage->proj_level = oldgimage->proj_level;
gimage_projection_realloc (new_gimage);*/
/*
pixel_region_init (&srcPR, gimp_image_projection (oldgimage), 0, 0,
oldgimage->width, oldgimage->height, FALSE);
pixel_region_init (&destPR, gimp_image_projection (newgimage), 0, 0,
newgimage->width, newgimage->height, TRUE);
copy_region(&srcPR, &destPR);*/
copy_region(&srcPR, &destPR);
/*
pixel_region_init (&srcPR, gimp_image_projection (oldgimage),
newgdisplay->disp_xoffset, newgdisplay->disp_yoffset,
newgdisplay->disp_width, newgdisplay->disp_height,
@ -768,6 +768,37 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
newgdisplay->disp_width, newgdisplay->disp_height,
TRUE);
copy_region(&srcPR, &destPR);
*/
if (1)
{
GDisplay* gdisp;
int x,y,w,h;
int x1, y1, x2, y2;
gdisp = newgdisplay;
fprintf (stderr, " [pointers: %p, %p ] ", oldgimage, gdisp->gimage);
gdisplay_untransform_coords (gdisp, 0, 0, &x1, &y1, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height,
&x2, &y2, FALSE, FALSE);
fprintf(stderr," <%dx%d %dx%d %d,%d->%d,%d> ",
oldgimage->width, oldgimage->height,
newgimage->width, newgimage->height,
x1,y1, x2,y2);
gimage_invalidate_without_render (gdisp->gimage, 0,0,
gdisp->gimage->width,
gdisp->gimage->height,
// 64,64,128,128);
// newgdisplay->disp_width,newgdisplay->disp_height,
// newgdisplay->disp_width+newgdisplay->disp_xoffset,newgdisplay->disp_height+newgdisplay->disp_yoffset
x1, y1, x2, y2
);
}
}
}
#endif
@ -781,7 +812,11 @@ channel_ops_duplicate (GimpImage *gimage)
new_gimage = duplicate (gimage);
/* We don't want to copy a half-redrawn projection, so force a flush. */
/* gdisplays_finish_draw();
gdisplays_flush_now(); */
new_gdisp = gdisplay_new (new_gimage, 0x0101);
/* duplicate_projection(gimage, new_gimage, new_gdisp); */
/* duplicate_projection(gimage, new_gimage, new_gdisp);*/
}

View File

@ -741,10 +741,8 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
if (newgimage->construct_flag)
#endif
{
/* We don't want to copy a half-redrawn projection, so force a flush. */
gdisplays_finish_draw();
gdisplays_flush_now();
tile_manager_set_user_data(gimp_image_projection (newgimage),
(void *) newgimage);
/*
newgimage->proj_type = oldgimage->proj_type;
@ -752,13 +750,15 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
newgimage->proj_level = oldgimage->proj_level;
gimage_projection_realloc (new_gimage);*/
/*
pixel_region_init (&srcPR, gimp_image_projection (oldgimage), 0, 0,
oldgimage->width, oldgimage->height, FALSE);
pixel_region_init (&destPR, gimp_image_projection (newgimage), 0, 0,
newgimage->width, newgimage->height, TRUE);
copy_region(&srcPR, &destPR);*/
copy_region(&srcPR, &destPR);
/*
pixel_region_init (&srcPR, gimp_image_projection (oldgimage),
newgdisplay->disp_xoffset, newgdisplay->disp_yoffset,
newgdisplay->disp_width, newgdisplay->disp_height,
@ -768,6 +768,37 @@ duplicate_projection (GimpImage *oldgimage, GimpImage *newgimage,
newgdisplay->disp_width, newgdisplay->disp_height,
TRUE);
copy_region(&srcPR, &destPR);
*/
if (1)
{
GDisplay* gdisp;
int x,y,w,h;
int x1, y1, x2, y2;
gdisp = newgdisplay;
fprintf (stderr, " [pointers: %p, %p ] ", oldgimage, gdisp->gimage);
gdisplay_untransform_coords (gdisp, 0, 0, &x1, &y1, FALSE, FALSE);
gdisplay_untransform_coords (gdisp, gdisp->disp_width, gdisp->disp_height,
&x2, &y2, FALSE, FALSE);
fprintf(stderr," <%dx%d %dx%d %d,%d->%d,%d> ",
oldgimage->width, oldgimage->height,
newgimage->width, newgimage->height,
x1,y1, x2,y2);
gimage_invalidate_without_render (gdisp->gimage, 0,0,
gdisp->gimage->width,
gdisp->gimage->height,
// 64,64,128,128);
// newgdisplay->disp_width,newgdisplay->disp_height,
// newgdisplay->disp_width+newgdisplay->disp_xoffset,newgdisplay->disp_height+newgdisplay->disp_yoffset
x1, y1, x2, y2
);
}
}
}
#endif
@ -781,7 +812,11 @@ channel_ops_duplicate (GimpImage *gimage)
new_gimage = duplicate (gimage);
/* We don't want to copy a half-redrawn projection, so force a flush. */
/* gdisplays_finish_draw();
gdisplays_flush_now(); */
new_gdisp = gdisplay_new (new_gimage, 0x0101);
/* duplicate_projection(gimage, new_gimage, new_gdisp); */
/* duplicate_projection(gimage, new_gimage, new_gdisp);*/
}

View File

@ -147,6 +147,8 @@ update_tile_rowhints (Tile* tile, int ymin, int ymax)
g_assert(tile!=NULL);
#endif
tile_sanitize_rowhints (tile);
bpp = tile_bpp (tile);
ewidth = tile_ewidth (tile);
eheight = tile_eheight (tile);

View File

@ -147,6 +147,8 @@ update_tile_rowhints (Tile* tile, int ymin, int ymax)
g_assert(tile!=NULL);
#endif
tile_sanitize_rowhints (tile);
bpp = tile_bpp (tile);
ewidth = tile_ewidth (tile);
eheight = tile_eheight (tile);

View File

@ -363,7 +363,7 @@ pixel_regions_process (void *PRI_ptr)
{
/* only set the dirty flag if PRH->dirty_tiles = true */
tile_release (PRH->PR->curtile,
PRH->PR->dirty * PRI->dirty_tiles);
PRH->PR->dirty && PRI->dirty_tiles);
PRH->PR->curtile = NULL;
}

View File

@ -13,6 +13,25 @@ static void tile_destroy (Tile *tile);
int tile_count = 0;
void
tile_sanitize_rowhints (Tile *tile)
{
int height, y;
/* If tile has rowhints array already, do nothing. */
if (tile->rowhint)
return;
height = tile->eheight;
tile->rowhint = g_new (TileRowHint, height);
for (y=0; y<height; y++)
{
tile->rowhint[y] = TILEROWHINT_UNKNOWN;
}
}
TileRowHint
tile_get_rowhint (Tile *tile, int yoff)
{
@ -23,7 +42,7 @@ tile_get_rowhint (Tile *tile, int yoff)
}
else
g_error("GET_ROWHINT OUT OF RANGE");
/* return TILEROWHINT_OUTOFRANGE; */
return TILEROWHINT_OUTOFRANGE;
#else
return tile->rowhint[yoff];
#endif
@ -48,8 +67,6 @@ void
tile_init (Tile *tile,
int bpp)
{
int y;
tile->ref_count = 0;
tile->write_count = 0;
tile->share_count = 0;
@ -64,11 +81,7 @@ tile_init (Tile *tile,
tile->tlink = NULL;
tile->next = tile->prev = NULL;
tile->listhead = NULL;
for (y=0; y<TILE_HEIGHT; y++)
{
tile->rowhint[y] = TILEROWHINT_UNKNOWN;
}
tile->rowhint = NULL;
#ifdef USE_PTHREADS
{
@ -82,6 +95,11 @@ int tile_ref_count = 0;
int tile_share_count = 0;
int tile_active_count = 0;
#ifdef HINTS_SANITY
int tile_exist_peak = 0;
int tile_exist_count = 0;
#endif
void
tile_lock (Tile *tile)
{
@ -144,10 +162,13 @@ tile_release (Tile *tile, int dirty)
int y;
tile->write_count -= 1;
for (y = 0; y < tile->eheight; y++)
if (tile->rowhint)
{
tile->rowhint[y] = TILEROWHINT_UNKNOWN;
for (y = 0; y < tile->eheight; y++)
{
tile->rowhint[y] = TILEROWHINT_UNKNOWN;
}
}
}
@ -156,7 +177,7 @@ tile_release (Tile *tile, int dirty)
tile_active_count--;
if (tile->share_count == 0)
{
/* tile is dead */
/* tile is truly dead */
tile_destroy (tile);
return; /* skip terminal unlock */
}
@ -180,6 +201,12 @@ tile_alloc (Tile *tile)
/* Allocate the data for the tile.
*/
tile->data = g_new (guchar, tile_size (tile));
#ifdef HINTS_SANITY
tile_exist_count++;
if (tile_exist_count > tile_exist_peak)
tile_exist_peak = tile_exist_count;
#endif
}
static void
@ -200,6 +227,11 @@ tile_destroy (Tile *tile)
g_free (tile->data);
tile->data = NULL;
}
if (tile->rowhint)
{
g_free (tile->rowhint);
tile->rowhint = NULL;
}
if (tile->swap_offset != -1)
{
/* If the tile is on disk, then delete its
@ -213,6 +245,10 @@ tile_destroy (Tile *tile)
TILE_MUTEX_UNLOCK (tile);
g_free (tile);
tile_count --;
#ifdef HINTS_SANITY
tile_exist_count--;
#endif
}
@ -270,7 +306,7 @@ tile_attach (Tile *tile, void *tm, int tile_num)
{
TileLink *tmp;
if (tile->share_count > 0 && !tile->valid)
if ((tile->share_count > 0) && (!tile->valid))
{
/* trying to share invalid tiles is problematic, not to mention silly */
tile_manager_validate ((TileManager*) tile->tlink->tm, tile);
@ -300,15 +336,17 @@ tile_detach (Tile *tile, void *tm, int tile_num)
tile->ref_count, tile->share_count);
#endif
for (link = &tile->tlink; *link; link = &(*link)->next)
for (link = &tile->tlink;
*link != NULL;
link = &(*link)->next)
{
if ((*link)->tm == tm && (*link)->tile_num == tile_num)
if (((*link)->tm == tm) && ((*link)->tile_num == tile_num))
break;
}
if (*link == NULL)
{
g_warning ("Tried to detach a nonattached tile");
g_warning ("Tried to detach a nonattached tile -- TILE BUG!");
return;
}

View File

@ -19,16 +19,18 @@
typedef struct _Tile Tile;
typedef enum
{
TILEROWHINT_BROKEN = 0,
TILEROWHINT_OPAQUE,
TILEROWHINT_TRANSPARENT,
TILEROWHINT_MIXED,
TILEROWHINT_OUTOFRANGE,
TILEROWHINT_UNDEFINED,
TILEROWHINT_UNKNOWN
} TileRowHint;
/* explicit guchar type rather than enum since gcc chooses an int
* representation but arrays of TileRowHints are quite space-critical
* in GIMP.
*/
typedef guchar TileRowHint;
#define TILEROWHINT_BROKEN 0
#define TILEROWHINT_OPAQUE 1
#define TILEROWHINT_TRANSPARENT 2
#define TILEROWHINT_MIXED 3
#define TILEROWHINT_OUTOFRANGE 4
#define TILEROWHINT_UNDEFINED 5
#define TILEROWHINT_UNKNOWN 6
/* Initializes the fields of a tile to "good" values.
@ -68,6 +70,7 @@ void tile_mark_valid (Tile *tile);
/* DOCUMENT ME -- adm */
TileRowHint tile_get_rowhint (Tile *tile, int yoff);
void tile_set_rowhint (Tile *tile, int yoff, TileRowHint rowhint);
void tile_sanitize_rowhints (Tile *tile);
void *tile_data_pointer (Tile *tile, int xoff, int yoff);

View File

@ -157,9 +157,17 @@ tile_manager_get (TileManager *tm,
if (wantwrite && !wantread)
{
g_warning("WRITE-ONLY TILE... OUCHIE");
g_warning("WRITE-ONLY TILE... UNTESTED!");
}
/*
if ((*tile_ptr)->share_count &&
(*tile_ptr)->write_count)
fprintf(stderr," >> MEEPITY %d,%d << ",
(*tile_ptr)->share_count,
(*tile_ptr)->write_count
); */
if (wantread)
{
TILE_MUTEX_LOCK (*tile_ptr);
@ -169,17 +177,25 @@ tile_manager_get (TileManager *tm,
{
/* Copy-on-write required */
Tile *newtile = g_new (Tile, 1);
tile_init (newtile, (*tile_ptr)->bpp);
newtile->ewidth = (*tile_ptr)->ewidth;
newtile->eheight = (*tile_ptr)->eheight;
newtile->valid = (*tile_ptr)->valid;
newtile->data = g_new (guchar, tile_size (newtile));
i = newtile->eheight;
while (i--)
{
newtile->rowhint[i] = (*tile_ptr)->rowhint[i];
}
if (!newtile->valid)
g_warning ("Oh boy, r/w tile is invalid... we suck. Please report.");
if ((*tile_ptr)->rowhint)
{
tile_sanitize_rowhints (newtile);
i = newtile->eheight;
while (i--)
{
newtile->rowhint[i] = (*tile_ptr)->rowhint[i];
}
}
if ((*tile_ptr)->data != NULL)
{
@ -199,8 +215,13 @@ tile_manager_get (TileManager *tm,
}
(*tile_ptr)->write_count++;
(*tile_ptr)->dirty = 1;
(*tile_ptr)->dirty = TRUE;
}
/* else
{
if ((*tile_ptr)->write_count)
fprintf(stderr,"STINK! r/o on r/w tile /%d\007 ",(*tile_ptr)->write_count);
} */
TILE_MUTEX_UNLOCK (*tile_ptr);
tile_lock (*tile_ptr);
}
@ -233,6 +254,17 @@ tile_manager_validate (TileManager *tm,
if (tm->validate_proc)
(* tm->validate_proc) (tm, tile);
/* DEBUG STUFF -> if (tm->user_data)
{
// fprintf(stderr,"V%p ",tm->user_data);
fprintf(stderr,"V");
}
else
{
fprintf(stderr,"v");
} */
}
void
@ -286,6 +318,7 @@ tile_invalidate (Tile **tile_ptr, TileManager *tm, int tile_num)
{
/* This tile is shared. Replace it with a new, invalid tile. */
Tile *newtile = g_new (Tile, 1);
tile_init (newtile, tile->bpp);
newtile->ewidth = tile->ewidth;
newtile->eheight = tile->eheight;
@ -400,6 +433,9 @@ tile_manager_map (TileManager *tm,
/* printf(")");fflush(stdout);*/
if (!srctile->valid)
g_warning("tile_manager_map: srctile not validated yet! please report.");
TILE_MUTEX_LOCK (*tile_ptr);
if ((*tile_ptr)->ewidth != srctile->ewidth ||
(*tile_ptr)->eheight != srctile->eheight ||

View File

@ -40,23 +40,23 @@ struct _Tile
guint dirty : 1; /* is the tile dirty? has it been modified? */
guint valid : 1; /* is the tile valid? */
/* An array of hints for rendering purposes */
TileRowHint rowhint[TILE_HEIGHT];
unsigned char bpp; /* the bytes per pixel (1, 2, 3 or 4) */
unsigned short ewidth; /* the effective width of the tile */
unsigned short eheight; /* the effective height of the tile */
/* a tile's effective width and height may be smaller
* (but not larger) than TILE_WIDTH and TILE_HEIGHT.
* this is to handle edge tiles of a drawable.
*/
TileRowHint *rowhint; /* An array of hints for rendering purposes */
guchar *data; /* the data for the tile. this may be NULL in which
* case the tile data is on disk.
*/
int ewidth; /* the effective width of the tile */
int eheight; /* the effective height of the tile */
/* a tile's effective width and height may be smaller
* (but not larger) than TILE_WIDTH and TILE_HEIGHT.
* this is to handle edge tiles of a drawable.
*/
int bpp; /* the bytes per pixel (1, 2, 3 or 4) */
int swap_num; /* the index into the file table of the file to be used
* for swapping. swap_num 1 is always the global swap file.
*/
int swap_num; /* the index into the file table of the file to be used
* for swapping. swap_num 1 is always the global swap file.
*/
off_t swap_offset; /* the offset within the swap file of the tile data.
* if the tile data is in memory this will be set to -1.
*/

View File

@ -30,8 +30,8 @@
#define MAX_OPEN_SWAP_FILES 16
#include "tile.h"
#include "tile_swap.h"
#include "tile_pvt.h" /* ick. */
typedef struct _SwapFile SwapFile;
@ -180,6 +180,13 @@ tile_swap_exit1 (gpointer key,
void
tile_swap_exit ()
{
#ifdef HINTS_SANITY
extern int tile_exist_peak;
fprintf(stderr,"Tile exist peak was %d Tile structs (%d bytes)",
tile_exist_peak, tile_exist_peak * sizeof(Tile));
#endif
if (swap_files)
g_hash_table_foreach (swap_files, tile_swap_exit1, NULL);
}