Commit 373a4e74 authored by Michael Natterer's avatar Michael Natterer 😴

app: completely remove TileManager and friends (base/ and paint-funcs/)

And along with it a lot of stuff like the drawable preview cache, the
gegl tile manager backend, temporary gimp_gegl_buffer_foo() stuff, and
the remaining bits of performance.

The projection is in an evil semi-ported state which makes it work
ok-ish for stuff like layer moving, but absolutely unbearable for
painting, there is also an off-by-one rendering glitch at some zoom
levels.
parent 5835a730
......@@ -12,8 +12,6 @@ libgimpthumb = $(top_builddir)/libgimpthumb/libgimpthumb-$(GIMP_API_VERSION).la
# so that when e.g. changing a header-file the subdirs are built in
# the right order
SUBDIRS = \
base \
paint-funcs \
config \
core \
operations \
......@@ -164,8 +162,6 @@ gimpconsoleldadd = \
operations/libappoperations.a \
gegl/libappgegl.a \
config/libappconfig.a \
paint-funcs/libapppaint-funcs.a \
base/libappbase.a \
$(libgimpconfig) \
$(libgimpmath) \
$(libgimpthumb) \
......
......@@ -44,9 +44,6 @@
#include "config/gimprc.h"
#include "base/base.h"
#include "base/tile-swap.h"
#include "gegl/gimp-gegl.h"
#include "core/gimp.h"
......@@ -147,9 +144,7 @@ app_run (const gchar *full_prog_name,
{
GimpInitStatusFunc update_status_func = NULL;
Gimp *gimp;
GimpGeglConfig *config;
GMainLoop *loop;
gboolean swap_is_ok;
/* Create an instance of the "Gimp" object which is the root of the
* core object system
......@@ -189,14 +184,10 @@ app_run (const gchar *full_prog_name,
gimp_load_config (gimp, alternate_system_gimprc, alternate_gimprc);
config = GIMP_GEGL_CONFIG (gimp->config);
/* change the locale if a language if specified */
language_init (gimp->config->language);
/* initialize lowlevel stuff */
swap_is_ok = base_init (config, be_verbose, use_cpu_accel);
gimp_gegl_init (gimp);
#ifndef GIMP_CONSOLE_COMPILATION
......@@ -216,19 +207,6 @@ app_run (const gchar *full_prog_name,
*/
gimp_restore (gimp, update_status_func);
/* display a warning when no test swap file could be generated */
if (! swap_is_ok)
{
gchar *path = gimp_config_path_expand (config->swap_path, FALSE, NULL);
g_message (_("Unable to open a test swap file.\n\n"
"To avoid data loss, please check the location "
"and permissions of the swap directory defined in "
"your Preferences (currently \"%s\")."), path);
g_free (path);
}
/* enable autosave late so we don't autosave when the
* monitor resolution is set in gui_init()
*/
......@@ -264,7 +242,6 @@ app_run (const gchar *full_prog_name,
errors_exit ();
gegl_exit ();
base_exit ();
}
......
/Makefile
/Makefile.in
/.deps
/.libs
/*.lo
/libappbase.a
/libappbase.la
## Process this file with automake to produce Makefile.in
AM_CPPFLAGS = \
-DG_LOG_DOMAIN=\"Gimp-Base\"
INCLUDES = \
-I$(top_builddir) \
-I$(top_srcdir) \
-I$(top_builddir)/app \
-I$(top_srcdir)/app \
$(BABL_CFLAGS) \
$(CAIRO_CFLAGS) \
$(GEGL_CFLAGS) \
$(GDK_PIXBUF_CFLAGS) \
-I$(includedir)
noinst_LIBRARIES = libappbase.a
libappbase_a_SOURCES = \
base.c \
base.h \
base-types.h \
pixel-region.c \
pixel-region.h \
tile.c \
tile.h \
tile-private.h \
tile-cache.c \
tile-cache.h \
tile-manager.c \
tile-manager.h \
tile-manager-preview.c \
tile-manager-preview.h \
tile-manager-private.h \
tile-pyramid.c \
tile-pyramid.h \
tile-rowhints.c \
tile-rowhints.h \
tile-swap.c \
tile-swap.h
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BASE_TYPES_H__
#define __BASE_TYPES_H__
#include "core/core-types.h" /* screw include policy in base/ */
/* types */
typedef struct _PixelRegion PixelRegion;
typedef struct _Tile Tile;
typedef struct _TileManager TileManager;
typedef struct _TilePyramid TilePyramid;
#endif /* __BASE_TYPES_H__ */
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <glib-object.h>
#include <glib/gstdio.h>
#ifdef G_OS_WIN32
#include "libgimpbase/gimpwin32-io.h"
#endif
#include "libgimpconfig/gimpconfig.h"
#include "base-types.h"
#include "config/gimpgeglconfig.h"
#include "base.h"
#include "tile-cache.h"
#include "tile-manager.h"
#include "tile-swap.h"
static void base_toast_old_swap_files (const gchar *swap_path);
static void base_tile_cache_size_notify (GObject *config,
GParamSpec *param_spec,
gpointer data);
static GimpGeglConfig *base_config = NULL;
/* public functions */
gboolean
base_init (GimpGeglConfig *config,
gboolean be_verbose,
gboolean use_cpu_accel)
{
gboolean swap_is_ok;
gchar *temp_dir;
g_return_val_if_fail (GIMP_IS_GEGL_CONFIG (config), FALSE);
g_return_val_if_fail (base_config == NULL, FALSE);
base_config = g_object_ref (config);
tile_cache_init (config->tile_cache_size);
g_signal_connect (config, "notify::tile-cache-size",
G_CALLBACK (base_tile_cache_size_notify),
NULL);
if (! config->swap_path || ! *config->swap_path)
gimp_config_reset_property (G_OBJECT (config), "swap-path");
base_toast_old_swap_files (config->swap_path);
tile_swap_init (config->swap_path);
swap_is_ok = tile_swap_test ();
/* create the temp directory if it doesn't exist */
if (! config->temp_path || ! *config->temp_path)
gimp_config_reset_property (G_OBJECT (config), "temp-path");
temp_dir = gimp_config_path_expand (config->temp_path, TRUE, NULL);
if (! g_file_test (temp_dir, G_FILE_TEST_EXISTS))
g_mkdir_with_parents (temp_dir,
S_IRUSR | S_IXUSR | S_IWUSR |
S_IRGRP | S_IXGRP |
S_IROTH | S_IXOTH);
g_free (temp_dir);
return swap_is_ok;
}
void
base_exit (void)
{
g_return_if_fail (base_config != NULL);
#ifdef GIMP_UNSTABLE
tile_manager_exit ();
#endif
tile_cache_exit ();
tile_swap_exit ();
g_signal_handlers_disconnect_by_func (base_config,
base_tile_cache_size_notify,
NULL);
g_object_unref (base_config);
base_config = NULL;
}
/* private functions */
static void
base_toast_old_swap_files (const gchar *swap_path)
{
GDir *dir = NULL;
gchar *dirname;
const char *entry;
if (! swap_path)
return;
dirname = gimp_config_path_expand (swap_path, TRUE, NULL);
if (!dirname)
return;
dir = g_dir_open (dirname, 0, NULL);
if (!dir)
{
g_free (dirname);
return;
}
while ((entry = g_dir_read_name (dir)) != NULL)
if (g_str_has_prefix (entry, "gimpswap."))
{
/* don't try to kill swap files of running processes
* yes, I know they might not all be gimp processes, and when you
* unlink, it's refcounted, but lets not confuse the user by
* "where did my disk space go?" cause the filename is gone
* if the kill succeeds, and there running process isn't gimp
* we'll probably get it the next time around
*/
gint pid = atoi (entry + 9);
/* On Windows, you can't remove open files anyhow,
* so no harm trying.
*/
#ifndef G_OS_WIN32
if (kill (pid, 0))
#endif
{
gchar *filename = g_build_filename (dirname, entry, NULL);
g_unlink (filename);
g_free (filename);
}
}
g_dir_close (dir);
g_free (dirname);
}
static void
base_tile_cache_size_notify (GObject *config,
GParamSpec *param_spec,
gpointer data)
{
tile_cache_set_size (GIMP_GEGL_CONFIG (config)->tile_cache_size);
}
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BASE_H__
#define __BASE_H__
gboolean base_init (GimpGeglConfig *config,
gboolean be_verbose,
gboolean use_cpu_accel);
void base_exit (void);
#endif /* __BASE_H__ */
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <stdarg.h>
#include <string.h>
#include <gegl.h>
#include "core/core-types.h" /* eek, but this file will die anyway */
#include "core/gimptempbuf.h"
#include "pixel-region.h"
#include "tile-manager.h"
#include "tile.h"
/*********************/
/* Local Functions */
static gint get_portion_width (PixelRegionIterator *PRI);
static gint get_portion_height (PixelRegionIterator *PRI);
static void pixel_regions_free (PixelRegionIterator *PRI);
static PixelRegionIterator * pixel_regions_configure (PixelRegionIterator *PRI);
static void pixel_region_configure (PixelRegionHolder *PRH,
PixelRegionIterator *PRI);
/**************************/
/* Function definitions */
/**
* pixel_region_init:
* @PR: Pointer to PixelRegion struct, typically allocated on the
* stack
* @tiles: Tiles
* @x: X of region
* @y: Y of region
* @w: Width of region
* @h: Height of region
* @dirty: %TRUE if there will be changes to the pixel region that
* shall be written back to the tiles, %FALSE otherwise
*
* Initializes a pixel region over a set of tiles.
**/
void
pixel_region_init (PixelRegion *PR,
TileManager *tiles,
gint x,
gint y,
gint w,
gint h,
gboolean dirty)
{
PR->data = NULL;
PR->tiles = tiles;
PR->curtile = NULL;
PR->offx = 0;
PR->offy = 0;
PR->bytes = tile_manager_bpp (tiles);
PR->rowstride = PR->bytes * TILE_WIDTH;
PR->x = x;
PR->y = y;
PR->w = w;
PR->h = h;
PR->dirty = dirty;
PR->process_count = 0;
}
void
pixel_region_init_temp_buf (PixelRegion *PR,
GimpTempBuf *temp_buf,
gint x,
gint y,
gint w,
gint h)
{
PR->data = gimp_temp_buf_get_data (temp_buf);
PR->tiles = NULL;
PR->curtile = NULL;
PR->offx = 0;
PR->offy = 0;
PR->bytes = babl_format_get_bytes_per_pixel (gimp_temp_buf_get_format (temp_buf));
PR->rowstride = gimp_temp_buf_get_width (temp_buf) * PR->bytes;
PR->x = x;
PR->y = y;
PR->w = w;
PR->h = h;
PR->dirty = FALSE;
PR->process_count = 0;
}
void
pixel_region_init_data (PixelRegion *PR,
guchar *data,
gint bytes,
gint rowstride,
gint x,
gint y,
gint w,
gint h)
{
PR->data = data;
PR->tiles = NULL;
PR->curtile = NULL;
PR->offx = 0;
PR->offy = 0;
PR->bytes = bytes;
PR->rowstride = rowstride;
PR->x = x;
PR->y = y;
PR->w = w;
PR->h = h;
PR->dirty = FALSE;
PR->process_count = 0;
}
void
pixel_region_resize (PixelRegion *PR,
gint x,
gint y,
gint w,
gint h)
{
PR->x = x;
PR->y = y;
PR->w = w;
PR->h = h;
}
void
pixel_region_get_row (PixelRegion *PR,
gint x,
gint y,
gint w,
guchar *data,
gint subsample)
{
Tile *tile;
guchar *tile_data;
gint inc;
gint end;
gint boundary;
gint b;
gint npixels;
gint bpp;
end = x + w;
bpp = PR->bytes;
inc = subsample * bpp;
if (subsample == 1)
{
if (PR->tiles)
tile_manager_read_pixel_data (PR->tiles, x, y, end - 1, y, data,
PR->bytes);
else
memcpy (data, PR->data + x * bpp + y * PR->rowstride, w * bpp);
}
else
{
while (x < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, TRUE, FALSE);
tile_data = tile_data_pointer (tile, x, y);
npixels = tile_ewidth (tile) - (x % TILE_WIDTH);
if ((x + npixels) > end) /* make sure we don't write past the end */
npixels = end - x;
boundary = x + npixels;
for ( ; x < boundary; x += subsample)
{
for (b = 0; b < bpp; b++)
*data++ = tile_data[b];
tile_data += inc;
}
tile_release (tile, FALSE);
}
}
}
void
pixel_region_set_row (PixelRegion *PR,
gint x,
gint y,
gint w,
const guchar *data)
{
if (PR->tiles)
{
gint end = x + w;
tile_manager_write_pixel_data (PR->tiles, x, y, end - 1, y, data,
PR->bytes);
}
else
{
memcpy (PR->data + x * PR->bytes + y * PR->rowstride, data, w * PR->bytes);
}
}
void
pixel_region_get_col (PixelRegion *PR,
gint x,
gint y,
gint h,
guchar *data,
gint subsample)
{
Tile *tile;
guchar *tile_data;
gint bpp;
gint inc;
gint end;
gint boundary;
gint b;
end = y + h;
bpp = PR->bytes;
while (y < end)
{
tile = tile_manager_get_tile (PR->tiles, x, y, TRUE, FALSE);
tile_data = tile_data_pointer (tile, x, y);
boundary = y + (tile_eheight(tile) - (y % TILE_HEIGHT));
if (boundary > end) /* make sure we don't write past the end */
boundary = end;
inc = subsample * bpp * tile_ewidth (tile);
for ( ; y < boundary; y += subsample)
{
for (b = 0; b < bpp; b++)
*data++ = tile_data[b];
tile_data += inc;
}
tile_release (tile, FALSE);
}
}
void
pixel_region_set_col (PixelRegion *PR,
gint x,
gint y,
gint h,
const guchar *data)
{
gint end = y + h;
gint bpp = PR->bytes;
tile_manager_write_pixel_data (PR->tiles, x, y, x, end-1, data, bpp);
}
gboolean
pixel_region_has_alpha (PixelRegion *PR)
{
if (PR->bytes == 2 || PR->bytes == 4)
return TRUE;
else
return FALSE;
}
PixelRegionIterator *
pixel_regions_register (gint num_regions,
...)
{
PixelRegionIterator *PRI;
gboolean found;
va_list ap;
if (num_regions < 1)
return NULL;
PRI = g_slice_new0 (PixelRegionIterator);
va_start (ap, num_regions);
found = FALSE;
while (num_regions --)
{
PixelRegionHolder *PRH;
PixelRegion *PR;
PR = va_arg (ap, PixelRegion *);
PRH = g_slice_new0 (PixelRegionHolder);
PRH->PR = PR;
if (PR != NULL)
{
/* If there is a defined value for data, make sure tiles is NULL */
if (PR->data)
PR->tiles = NULL;
PRH->original_data = PR->data;
PRH->startx = PR->x;
PRH->starty = PR->y;
PRH->PR->process_count = 0;
if (! found)
{
found = TRUE;
PRI->region_width = PR->w;
PRI->region_height = PR->h;
}
}
/* Add the pixel region holder to the list */
PRI->pixel_regions = g_slist_prepend (PRI->pixel_regions, PRH);
}
va_end (ap);
return pixel_regions_configure (PRI);
}
PixelRegionIterator *
pixel_regions_process (PixelRegionIterator *PRI)
{
GSList *list;
PRI->process_count++;
/* Unref all referenced tiles and increment the offsets */
for (list = PRI->pixel_regions; list; list = g_slist_next (list))
{
PixelRegionHolder *PRH = list->data;
if ((PRH->PR != NULL) && (PRH->PR->process_count != PRI->process_count))
{
/* This eliminates the possibility of incrementing the