Commit 0ffabfe9 authored by scott's avatar scott

Bunch of tile-related stuff.

parent 5343ba58
Tue Aug 11 12:24:14 1998 Scott Goehring <scott@poverty.bloomington.in.us>
* tile.c tile.h: exported some accessor functions, made Tile
opaque.
* tile_manager.c tile_manager.h: added a public call to invalidate
a tile
* blend.c boundary.c by_color_select.c channel.c color_picker.c
drawable_cmds.c fuzzy_select.c gimpimage.c image_render.c ink.c
layer.c paint_core.c paint_funcs.c pixel_region.c plug_in.c undo.c
xcf.c: eliminated references to tile private data
* ink.c (ink_set_undo_tiles), paint_core.c (set_undo_tiles): used
tile sharing to replace tile copies for undo tiles
* undo.c (undo_pop_image): swap tiles instead of pixels when
possible
Mon Aug 10 14:48:20 PDT 1998 Manish Singh <yosh@gimp.org>
* app/gdisplay.c: corrected 2 annoyances: that stupid hash table
......
......@@ -47,7 +47,7 @@
#include "menus.h"
#include "plug_in.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h" /* ick. */
#define SEPARATE_PROGRESS_BAR
......@@ -1367,9 +1367,9 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
}
if (tile_data.use_shm)
memcpy (tile->data, shm_addr, tile_size (tile));
memcpy (tile_data_pointer (tile, 0, 0), shm_addr, tile_size (tile));
else
memcpy (tile->data, tile_info->data, tile_size (tile));
memcpy (tile_data_pointer (tile, 0, 0), tile_info->data, tile_size (tile));
tile_release (tile, TRUE);
......@@ -1406,15 +1406,15 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_data.drawable_ID = tile_req->drawable_ID;
tile_data.tile_num = tile_req->tile_num;
tile_data.shadow = tile_req->shadow;
tile_data.bpp = tile->bpp;
tile_data.width = tile->ewidth;
tile_data.height = tile->eheight;
tile_data.bpp = tile_bpp(tile);
tile_data.width = tile_ewidth(tile);
tile_data.height = tile_eheight(tile);
tile_data.use_shm = (shm_ID == -1) ? FALSE : TRUE;
if (tile_data.use_shm)
memcpy (shm_addr, tile->data, tile_size (tile));
memcpy (shm_addr, tile_data_pointer (tile, 0, 0), tile_size (tile));
else
tile_data.data = tile->data;
tile_data.data = tile_data_pointer (tile, 0, 0);
if (!gp_tile_data_write (current_writefd, &tile_data))
{
......
......@@ -21,7 +21,7 @@
#include "errors.h"
#include "boundary.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h"
/* half intensity for mask */
#define HALF_WAY 127
......@@ -126,8 +126,8 @@ find_empty_segs (PixelRegion *maskPR,
if (tile)
tile_release (tile, FALSE);
tile = tile_manager_get_tile (maskPR->tiles, x, scanline, 0, TRUE, FALSE);
data = tile->data + tile->bpp *
((scanline % TILE_HEIGHT) * tile->ewidth + (x % TILE_WIDTH)) + (tile->bpp - 1);
data = tile_data_pointer (tile, x % TILE_WIDTH, scanline % TILE_HEIGHT) + (tile_bpp(tile) - 1);
tilex = x / TILE_WIDTH;
}
......@@ -143,7 +143,7 @@ find_empty_segs (PixelRegion *maskPR,
(*num_empty)++;
last = val;
data += tile->bpp;
data += tile_bpp(tile);
}
if (last > 0)
......
......@@ -23,7 +23,7 @@
#include "pixel_region.h"
#include "tile_manager_pvt.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h" /* ick. */
typedef struct _PixelRegionHolder PixelRegionHolder;
......@@ -144,25 +144,25 @@ pixel_region_get_row (PR, x, y, w, data, subsample)
while (x < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, FALSE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
npixels = tile->ewidth - (x % TILE_WIDTH);
tile_data = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
npixels = tile_ewidth (tile) - (x % TILE_WIDTH);
if ((x + npixels) > end) /* make sure we don't write past the end */
npixels = end - x;
if (subsample == 1) /* optimize for the common case */
{
memcpy(data, tile_data, tile->bpp*npixels);
data += tile->bpp*npixels;
memcpy(data, tile_data, tile_bpp(tile)*npixels);
data += tile_bpp(tile)*npixels;
x += npixels;
}
else
{
boundary = x + npixels;
inc = subsample * tile->bpp;
inc = subsample * tile_bpp(tile);
for ( ; x < boundary; x += subsample)
{
for (b = 0; b < tile->bpp; b++)
for (b = 0; b < tile_bpp(tile); b++)
*data++ = tile_data[b];
tile_data += inc;
}
......@@ -191,16 +191,16 @@ pixel_region_set_row (PR, x, y, w, data)
while (x < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, TRUE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
tile_data = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
npixels = tile->ewidth - (x % TILE_WIDTH);
npixels = tile_ewidth(tile) - (x % TILE_WIDTH);
if ((x + npixels) > end) /* make sure we don't write past the end */
npixels = end - x;
memcpy(tile_data, data, tile->bpp*npixels);
memcpy(tile_data, data, tile_bpp(tile)*npixels);
data += tile->bpp*npixels;
data += tile_bpp(tile)*npixels;
x += npixels;
tile_release (tile, TRUE);
......@@ -230,16 +230,16 @@ pixel_region_get_col (PR, x, y, h, data, subsample)
while (y < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, FALSE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = y + (tile->eheight - (y % TILE_HEIGHT));
tile_data = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
boundary = y + (tile_eheight(tile) - (y % TILE_HEIGHT));
if (boundary > end) /* make sure we don't write past the end */
boundary = end;
inc = subsample * tile->bpp * tile->ewidth;
inc = subsample * tile_bpp(tile) * tile_ewidth(tile);
for ( ; y < boundary; y += subsample)
{
for (b = 0; b < tile->bpp; b++)
for (b = 0; b < tile_bpp(tile); b++)
*data++ = tile_data[b];
tile_data += inc;
}
......@@ -270,16 +270,16 @@ pixel_region_set_col (PR, x, y, h, data)
while (y < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, 0, TRUE, TRUE);
tile_data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
boundary = y + (tile->eheight - (y % TILE_HEIGHT));
inc = tile->bpp * tile->ewidth;
tile_data = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
boundary = y + (tile_eheight(tile) - (y % TILE_HEIGHT));
inc = tile_bpp(tile) * tile_ewidth(tile);
if (boundary > end) /* make sure we don't write past the end */
boundary = end;
for ( ; y < boundary; y++)
{
for (b = 0; b < tile->bpp; b++)
for (b = 0; b < tile_bpp(tile); b++)
tile_data[b] = *data++;
tile_data += inc;
}
......@@ -596,8 +596,8 @@ pixel_region_configure (PRH, PRI)
offx = PRH->PR->x % TILE_WIDTH;
offy = PRH->PR->y % TILE_HEIGHT;
PRH->PR->rowstride = tile->ewidth * PRH->PR->bytes;
PRH->PR->data = tile->data + offy * PRH->PR->rowstride + offx * PRH->PR->bytes;
PRH->PR->rowstride = tile_ewidth(tile) * PRH->PR->bytes;
PRH->PR->data = tile_data_pointer(tile, offx, offy);
}
else
{
......
......@@ -25,7 +25,6 @@
static void tile_manager_destroy_level (TileManager *tm,
TileLevel *level);
static void tile_invalidate (Tile **tile_ptr, TileManager *tm, int tile_num);
static int tile_manager_get_tile_num (TileManager *tm,
int xpixel,
int ypixel,
......@@ -444,7 +443,20 @@ tile_manager_destroy_level (TileManager *tm, TileLevel *level)
}
static void
void
tile_invalidate_tile (Tile **tile_ptr, TileManager *tm,
int xpixel, int ypixel, int level)
{
int tile_num;
tile_num = tile_manager_get_tile_num (tm, xpixel, ypixel, level);
if (tile_num < 0) return;
tile_invalidate (tile_ptr, tm, tile_num);
}
void
tile_invalidate (Tile **tile_ptr, TileManager *tm, int tile_num)
{
Tile *tile = *tile_ptr;
......
......@@ -119,6 +119,10 @@ void tile_manager_map (TileManager *tm,
void tile_manager_validate (TileManager *tm,
Tile *tile);
void tile_invalidate (Tile **tile_ptr, TileManager *tm, int tile_num);
void tile_invalidate_tile (Tile **tile_ptr, TileManager *tm,
int xpixel, int ypixel, int level);
/* Given a toplevel tile, this procedure will invalidate
* (set the dirty bit) for all tiles in lower levels which
* contain this toplevel tile.
......
......@@ -204,6 +204,43 @@ tile_size (Tile *tile)
}
int
tile_ewidth (Tile *tile)
{
return tile->ewidth;
}
int
tile_eheight (Tile *tile)
{
return tile->eheight;
}
int
tile_bpp (Tile *tile)
{
return tile->bpp;
}
int
tile_is_valid (Tile *tile)
{
return tile->valid;
}
void
tile_mark_valid (Tile *tile)
{
TILE_MUTEX_LOCK (tile);
tile->valid = TRUE;
TILE_MUTEX_UNLOCK (tile);
}
void
tile_attach (Tile *tile, void *tm, int tile_num)
{
......@@ -264,3 +301,9 @@ tile_detach (Tile *tile, void *tm, int tile_num)
}
void *
tile_data_pointer (Tile *tile, int xoff, int yoff)
{
int offset = yoff * tile->ewidth + xoff;
return (void *)(tile->data + offset * tile->bpp);
}
......@@ -45,6 +45,16 @@ void tile_alloc (Tile *tile);
*/
int tile_size (Tile *tile);
int tile_ewidth (Tile *tile);
int tile_eheight (Tile *tile);
int tile_bpp (Tile *tile);
int tile_is_valid (Tile *tile);
void tile_mark_valid (Tile *tile);
void *tile_data_pointer (Tile *tile, int xoff, int yoff);
/* tile_attach attaches a tile to a tile manager: this function
* increments the tile's share count and inserts a tilelink into the
* tile's link list. tile_detach reverses the process.
......
......@@ -37,7 +37,7 @@
#include "tools.h"
#include "undo.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h"
/* target size */
#define TARGET_HEIGHT 15
......@@ -1034,7 +1034,7 @@ gradient_calc_shapeburst_angular_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = 1.0 - *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = 1.0 - *((float *) tile_data_pointer (tile, ix % TILE_WIDTH, iy % TILE_HEIGHT));
tile_release (tile, FALSE);
return value;
......@@ -1052,7 +1052,7 @@ gradient_calc_shapeburst_spherical_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = *((float *) tile_data_pointer (tile, ix % TILE_WIDTH, iy % TILE_HEIGHT));
value = 1.0 - sin (0.5 * M_PI * value);
tile_release (tile, FALSE);
......@@ -1071,7 +1071,7 @@ gradient_calc_shapeburst_dimpled_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = *((float *) tile_data_pointer (tile, ix % TILE_WIDTH, iy % TILE_HEIGHT));
value = cos (0.5 * M_PI * value);
tile_release (tile, FALSE);
......
......@@ -21,7 +21,7 @@
#include "errors.h"
#include "boundary.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h"
/* half intensity for mask */
#define HALF_WAY 127
......@@ -126,8 +126,8 @@ find_empty_segs (PixelRegion *maskPR,
if (tile)
tile_release (tile, FALSE);
tile = tile_manager_get_tile (maskPR->tiles, x, scanline, 0, TRUE, FALSE);
data = tile->data + tile->bpp *
((scanline % TILE_HEIGHT) * tile->ewidth + (x % TILE_WIDTH)) + (tile->bpp - 1);
data = tile_data_pointer (tile, x % TILE_WIDTH, scanline % TILE_HEIGHT) + (tile_bpp(tile) - 1);
tilex = x / TILE_WIDTH;
}
......@@ -143,7 +143,7 @@ find_empty_segs (PixelRegion *maskPR,
(*num_empty)++;
last = val;
data += tile->bpp;
data += tile_bpp(tile);
}
if (last > 0)
......
......@@ -30,7 +30,7 @@
#include "gdisplay.h"
#include "rect_select.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h" /* ick. */
#define DEFAULT_FUZZINESS 15
#define PREVIEW_WIDTH 256
......@@ -361,7 +361,7 @@ by_color_select_button_release (Tool *tool,
if (x < 0 || y < 0 || x >= gdisp->gimage->width || y >= gdisp->gimage->height)
return;
tile = tile_manager_get_tile (gimage_composite (gdisp->gimage), x, y, 0, TRUE, FALSE);
data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
data = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
gimage_get_color (gdisp->gimage, gimage_composite_type(gdisp->gimage), col, data);
tile_release (tile, FALSE);
}
......@@ -370,7 +370,7 @@ by_color_select_button_release (Tool *tool,
if (x < 0 || y < 0 || x >= drawable_width (drawable) || y >= drawable_height (drawable))
return;
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0, TRUE, FALSE);
data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
data = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
gimage_get_color (gdisp->gimage, drawable_type(drawable), col, data);
tile_release (tile, FALSE);
}
......@@ -932,7 +932,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
if (x < 0 || y < 0 || x >= bcd->gimage->width || y >= bcd->gimage->height)
return;
tile = tile_manager_get_tile (gimage_composite (bcd->gimage), x, y, 0, TRUE, FALSE);
col = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
col = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
}
else
{
......@@ -944,7 +944,7 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
if (x < 0 || y < 0 || x >= drawable_width (drawable) || y >= drawable_height (drawable))
return;
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0, TRUE, FALSE);
col = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
col = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
}
by_color_select (bcd->gimage, drawable, col,
......
......@@ -31,7 +31,7 @@
#include "undo.h"
#include "channel_pvt.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h"
/*
enum {
......@@ -111,7 +111,8 @@ static void
channel_validate (TileManager *tm, Tile *tile, int level)
{
/* Set the contents of the tile to empty */
memset (tile->data, TRANSPARENT_OPACITY, tile->ewidth * tile->eheight);
memset (tile_data_pointer (tile, 0, 0),
TRANSPARENT_OPACITY, tile_size(tile));
}
......@@ -549,7 +550,7 @@ channel_value (Channel *mask, int x, int y)
}
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
val = *(unsigned char *)(tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT));
tile_release (tile, FALSE);
return val;
......
......@@ -26,7 +26,7 @@
#include "palette.h"
#include "tools.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h" /* ick. */
/* maximum information buffer size */
......@@ -328,8 +328,7 @@ get_color (GImage *gimage,
if (x >= 0 && y >= 0 && x < width && y < height)
{
tile = tile_manager_get_tile (tiles, x, y, 0, TRUE, FALSE);
src = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
src = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
}
else
return FALSE;
......
......@@ -31,7 +31,7 @@
#include "undo.h"
#include "channel_pvt.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h"
/*
enum {
......@@ -111,7 +111,8 @@ static void
channel_validate (TileManager *tm, Tile *tile, int level)
{
/* Set the contents of the tile to empty */
memset (tile->data, TRANSPARENT_OPACITY, tile->ewidth * tile->eheight);
memset (tile_data_pointer (tile, 0, 0),
TRANSPARENT_OPACITY, tile_size(tile));
}
......@@ -549,7 +550,7 @@ channel_value (Channel *mask, int x, int y)
}
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
val = *(unsigned char *)(tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT));
tile_release (tile, FALSE);
return val;
......
......@@ -31,7 +31,7 @@
#include "undo.h"
#include "channel_pvt.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h"
/*
enum {
......@@ -111,7 +111,8 @@ static void
channel_validate (TileManager *tm, Tile *tile, int level)
{
/* Set the contents of the tile to empty */
memset (tile->data, TRANSPARENT_OPACITY, tile->ewidth * tile->eheight);
memset (tile_data_pointer (tile, 0, 0),
TRANSPARENT_OPACITY, tile_size(tile));
}
......@@ -549,7 +550,7 @@ channel_value (Channel *mask, int x, int y)
}
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0, TRUE, FALSE);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
val = *(unsigned char *)(tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT));
tile_release (tile, FALSE);
return val;
......
......@@ -37,7 +37,7 @@
#include "tools.h"
#include "undo.h"
#include "tile_pvt.h" /* ick. */
#include "tile.h"
/* target size */
#define TARGET_HEIGHT 15
......@@ -1034,7 +1034,7 @@ gradient_calc_shapeburst_angular_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = 1.0 - *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = 1.0 - *((float *) tile_data_pointer (tile, ix % TILE_WIDTH, iy % TILE_HEIGHT));
tile_release (tile, FALSE);
return value;
......@@ -1052,7 +1052,7 @@ gradient_calc_shapeburst_spherical_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = *((float *) tile_data_pointer (tile, ix % TILE_WIDTH, iy % TILE_HEIGHT));
value = 1.0 - sin (0.5 * M_PI * value);
tile_release (tile, FALSE);
......@@ -1071,7 +1071,7 @@ gradient_calc_shapeburst_dimpled_factor (double x,
ix = (int) BOUNDS (x, 0, distR.w);
iy = (int) BOUNDS (y, 0, distR.h);
tile = tile_manager_get_tile (distR.tiles, ix, iy, 0, TRUE, FALSE);
value = *(((float *) tile->data) + ((iy % TILE_HEIGHT) * tile->ewidth + (ix % TILE_WIDTH)));
value = *((float *) tile_data_pointer (tile, ix % TILE_WIDTH, iy % TILE_HEIGHT));
value = cos (0.5 * M_PI * value);
tile_release (tile, FALSE);
......
......@@ -26,8 +26,8 @@
#include "undo.h"
#include "gimpsignal.h"
#include "tile_manager.h" /* ick. */
#include "tile_pvt.h"
#include "tile_manager.h"
#include "tile.h"
#include "layer_pvt.h"
#include "drawable_pvt.h" /* ick ick. */
......@@ -1234,19 +1234,19 @@ gimp_image_invalidate (GimpImage *gimage, int x, int y, int w, int h, int x1, in
if (! flat)
{
/* check if the tile is outside the bounds */
if ((MIN ((j + tile->ewidth), x2) - MAX (j, x1)) <= 0)
if ((MIN ((j + tile_ewidth(tile)), x2) - MAX (j, x1)) <= 0)
{
tile->valid = FALSE;
tile_invalidate_tile (&tile, tm, j, i, 0);
if (j < x1)
startx = MAX (startx, (j + tile->ewidth));
startx = MAX (startx, (j + tile_ewidth(tile)));