app: add "Swap compression" option to the preferences

Add a new "Swap compression" option to the preferences, allowing
explicit control over the tile-swap compression algorithm.
Previously, control over swap compression was only possible through
GEGL command-line options/environment variables.  Since the GEGL
API to list all available compression algorithms is still private
for now, we currently only list the three predefined compression
levels -- "best performance" (the default), "balanced", and "best
compression" -- and a "none" option, to disable compression
altogether.  Selecting a custom compression algorithm is possible
by entering its name manually.
This commit is contained in:
Ell 2019-09-22 16:44:23 +03:00
parent e30a24273d
commit 1664ecbf1d
14 changed files with 471 additions and 33 deletions

View File

@ -38,7 +38,9 @@
#include "gimp-intl.h"
#define GIMP_MAX_MEM_PROCESS (MIN (G_MAXSIZE, GIMP_MAX_MEMSIZE))
#define GIMP_DEFAULT_SWAP_COMPRESSION "fast"
#define GIMP_MAX_MEM_PROCESS (MIN (G_MAXSIZE, GIMP_MAX_MEMSIZE))
enum
@ -46,6 +48,7 @@ enum
PROP_0,
PROP_TEMP_PATH,
PROP_SWAP_PATH,
PROP_SWAP_COMPRESSION,
PROP_NUM_PROCESSORS,
PROP_TILE_CACHE_SIZE,
PROP_USE_OPENCL,
@ -105,6 +108,13 @@ gimp_gegl_config_class_init (GimpGeglConfigClass *klass)
GIMP_PARAM_STATIC_STRINGS |
GIMP_CONFIG_PARAM_RESTART);
GIMP_CONFIG_PROP_STRING (object_class, PROP_SWAP_COMPRESSION,
"swap-compression",
"Swap compression",
SWAP_COMPRESSION_BLURB,
GIMP_DEFAULT_SWAP_COMPRESSION,
GIMP_PARAM_STATIC_STRINGS);
n_threads = g_get_num_processors ();
max_n_threads =
@ -174,6 +184,7 @@ gimp_gegl_config_finalize (GObject *object)
g_free (gegl_config->temp_path);
g_free (gegl_config->swap_path);
g_free (gegl_config->swap_compression);
gimp_debug_remove_instance (object);
@ -198,6 +209,10 @@ gimp_gegl_config_set_property (GObject *object,
g_free (gegl_config->swap_path);
gegl_config->swap_path = g_value_dup_string (value);
break;
case PROP_SWAP_COMPRESSION:
g_free (gegl_config->swap_compression);
gegl_config->swap_compression = g_value_dup_string (value);
break;
case PROP_NUM_PROCESSORS:
gegl_config->num_processors = g_value_get_int (value);
break;
@ -234,6 +249,9 @@ gimp_gegl_config_get_property (GObject *object,
case PROP_SWAP_PATH:
g_value_set_string (value, gegl_config->swap_path);
break;
case PROP_SWAP_COMPRESSION:
g_value_set_string (value, gegl_config->swap_compression);
break;
case PROP_NUM_PROCESSORS:
g_value_set_int (value, gegl_config->num_processors);
break;

View File

@ -37,6 +37,7 @@ struct _GimpGeglConfig
gchar *temp_path;
gchar *swap_path;
gchar *swap_compression;
gint num_processors;
guint64 tile_cache_size;
gboolean use_opencl;

View File

@ -456,6 +456,9 @@ _("Enable the Seamless Clone tool.")
#define SPACE_BAR_ACTION_BLURB \
_("What to do when the space bar is pressed in the image window.")
#define SWAP_COMPRESSION_BLURB \
_("The compression method used for tile data stored in the swap file.")
#define SWAP_PATH_BLURB \
_("Sets the swap file location. GIMP uses a tile based memory allocation " \
"scheme. The swap file is used to quickly and easily swap tiles out to " \

View File

@ -390,3 +390,20 @@ prefs_profile_combo_box_add (GObject *config,
return combo;
}
GtkWidget *
prefs_compression_combo_box_add (GObject *config,
const gchar *property_name,
const gchar *label,
GtkGrid *grid,
gint grid_top,
GtkSizeGroup *group)
{
GtkWidget *combo = gimp_prop_compression_combo_box_new (config,
property_name);
if (combo)
prefs_widget_add_aligned (combo, label, grid, grid_top, FALSE, group);
return combo;
}

View File

@ -122,6 +122,12 @@ GtkWidget * prefs_profile_combo_box_add (GObject *config,
GtkSizeGroup *group,
GObject *profile_path_config,
const gchar *profile_path_property_name);
GtkWidget * prefs_compression_combo_box_add (GObject *config,
const gchar *property_name,
const gchar *label,
GtkGrid *grid,
gint grid_top,
GtkSizeGroup *group);
#endif /* __PREFERENCES_DIALOG_H__ */

View File

@ -1185,10 +1185,14 @@ prefs_dialog_new (Gimp *gimp,
_("Maximum _new image size:"),
GTK_GRID (grid), 3, size_group);
prefs_compression_combo_box_add (object, "swap-compression",
_("S_wap compression:"),
GTK_GRID (grid), 4, size_group);
#ifdef ENABLE_MP
prefs_spin_button_add (object, "num-processors", 1.0, 4.0, 0,
_("Number of _threads to use:"),
GTK_GRID (grid), 4, size_group);
GTK_GRID (grid), 5, size_group);
#endif /* ENABLE_MP */
/* Hardware Acceleration */

View File

@ -40,11 +40,12 @@
#include <operation/gegl-operation.h>
static void gimp_gegl_notify_swap_path (GimpGeglConfig *config);
static void gimp_gegl_notify_temp_path (GimpGeglConfig *config);
static void gimp_gegl_notify_tile_cache_size (GimpGeglConfig *config);
static void gimp_gegl_notify_num_processors (GimpGeglConfig *config);
static void gimp_gegl_notify_use_opencl (GimpGeglConfig *config);
static void gimp_gegl_notify_temp_path (GimpGeglConfig *config);
static void gimp_gegl_notify_swap_path (GimpGeglConfig *config);
static void gimp_gegl_notify_swap_compression (GimpGeglConfig *config);
static void gimp_gegl_notify_tile_cache_size (GimpGeglConfig *config);
static void gimp_gegl_notify_num_processors (GimpGeglConfig *config);
static void gimp_gegl_notify_use_opencl (GimpGeglConfig *config);
/* public functions */
@ -58,23 +59,27 @@ gimp_gegl_init (Gimp *gimp)
config = GIMP_GEGL_CONFIG (gimp->config);
/* make sure swap and temp directories exist */
gimp_gegl_notify_swap_path (config);
/* make sure temp and swap directories exist */
gimp_gegl_notify_temp_path (config);
gimp_gegl_notify_swap_path (config);
g_object_set (gegl_config (),
"tile-cache-size", (guint64) config->tile_cache_size,
"threads", config->num_processors,
"use-opencl", config->use_opencl,
"swap-compression", config->swap_compression,
"tile-cache-size", (guint64) config->tile_cache_size,
"threads", config->num_processors,
"use-opencl", config->use_opencl,
NULL);
gimp_parallel_init (gimp);
g_signal_connect (config, "notify::temp-path",
G_CALLBACK (gimp_gegl_notify_temp_path),
NULL);
g_signal_connect (config, "notify::swap-path",
G_CALLBACK (gimp_gegl_notify_swap_path),
NULL);
g_signal_connect (config, "notify::temp-path",
G_CALLBACK (gimp_gegl_notify_temp_path),
g_signal_connect (config, "notify::swap-compression",
G_CALLBACK (gimp_gegl_notify_swap_compression),
NULL);
g_signal_connect (config, "notify::num-processors",
G_CALLBACK (gimp_gegl_notify_num_processors),
@ -105,6 +110,17 @@ gimp_gegl_exit (Gimp *gimp)
/* private functions */
static void
gimp_gegl_notify_temp_path (GimpGeglConfig *config)
{
GFile *file = gimp_file_new_for_config_path (config->temp_path, NULL);
if (! g_file_query_exists (file, NULL))
g_file_make_directory_with_parents (file, NULL, NULL);
g_object_unref (file);
}
static void
gimp_gegl_notify_swap_path (GimpGeglConfig *config)
{
@ -123,14 +139,11 @@ gimp_gegl_notify_swap_path (GimpGeglConfig *config)
}
static void
gimp_gegl_notify_temp_path (GimpGeglConfig *config)
gimp_gegl_notify_swap_compression (GimpGeglConfig *config)
{
GFile *file = gimp_file_new_for_config_path (config->temp_path, NULL);
if (! g_file_query_exists (file, NULL))
g_file_make_directory_with_parents (file, NULL, NULL);
g_object_unref (file);
g_object_set (gegl_config (),
"swap-compression", config->swap_compression,
NULL);
}
static void

View File

@ -96,6 +96,8 @@ libappwidgets_a_sources = \
gimpcombotagentry.h \
gimpcomponenteditor.c \
gimpcomponenteditor.h \
gimpcompressioncombobox.c \
gimpcompressioncombobox.h \
gimpcontainerbox.c \
gimpcontainerbox.h \
gimpcontainercombobox.c \

View File

@ -0,0 +1,212 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpcompressioncombobox.c
* Copyright (C) 2004, 2008 Sven Neumann <sven@gimp.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "stdlib.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
#include "gimpcompressioncombobox.h"
#include "gimp-intl.h"
enum
{
COLUMN_ID,
COLUMN_LABEL,
N_COLUMNS
};
/* local function prototypes */
static void gimp_compression_combo_box_constructed (GObject *object);
static gboolean gimp_compression_combo_box_separator_func (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data);
G_DEFINE_TYPE (GimpCompressionComboBox, gimp_compression_combo_box,
GIMP_TYPE_STRING_COMBO_BOX)
#define parent_class gimp_compression_combo_box_parent_class
/* private functions */
static void
gimp_compression_combo_box_class_init (GimpCompressionComboBoxClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gimp_compression_combo_box_constructed;
}
static void
gimp_compression_combo_box_init (GimpCompressionComboBox *combo_box)
{
}
static void
gimp_compression_combo_box_constructed (GObject *object)
{
GimpCompressionComboBox *combo_box = GIMP_COMPRESSION_COMBO_BOX (object);
GtkCellLayout *layout;
GtkCellRenderer *cell;
GtkListStore *store;
GtkTreeIter iter;
G_OBJECT_CLASS (parent_class)->constructed (object);
store = gtk_list_store_new (N_COLUMNS,
G_TYPE_STRING, /* ID */
G_TYPE_STRING); /* LABEL */
gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store));
g_object_unref (store);
gtk_combo_box_set_row_separator_func (
GTK_COMBO_BOX (combo_box),
gimp_compression_combo_box_separator_func,
NULL,
NULL);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COLUMN_ID, "none",
COLUMN_LABEL, C_("compression", "None"),
-1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COLUMN_ID, NULL,
COLUMN_LABEL, NULL,
-1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COLUMN_ID, "fast",
COLUMN_LABEL, C_("compression", "Best performance"),
-1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COLUMN_ID, "balanced",
COLUMN_LABEL, C_("compression", "Balanced"),
-1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COLUMN_ID, "best",
COLUMN_LABEL, C_("compression", "Best compression"),
-1);
gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (combo_box),
COLUMN_LABEL);
layout = GTK_CELL_LAYOUT (combo_box);
cell = gtk_cell_renderer_text_new ();
gtk_cell_layout_clear (layout);
gtk_cell_layout_pack_start (layout, cell, TRUE);
gtk_cell_layout_set_attributes (layout, cell,
"text", COLUMN_LABEL,
NULL);
}
static gboolean
gimp_compression_combo_box_separator_func (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
gchar *value;
gboolean result;
gtk_tree_model_get (model, iter, COLUMN_ID, &value, -1);
result = ! value;
g_free (value);
return result;
}
/* public functions */
GtkWidget *
gimp_compression_combo_box_new (void)
{
return g_object_new (GIMP_TYPE_COMPRESSION_COMBO_BOX,
"has-entry", TRUE,
"id-column", COLUMN_ID,
"label-column", COLUMN_LABEL,
NULL);
}
void
gimp_compression_combo_box_set_compression (GimpCompressionComboBox *combo_box,
const gchar *compression)
{
g_return_if_fail (GIMP_IS_COMPRESSION_COMBO_BOX (combo_box));
g_return_if_fail (compression != NULL);
if (! gimp_string_combo_box_set_active (GIMP_STRING_COMBO_BOX (combo_box),
compression))
{
GtkWidget *entry;
entry = gtk_bin_get_child (GTK_BIN (combo_box));
gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), -1);
gtk_entry_set_text (GTK_ENTRY (entry), compression);
}
}
gchar *
gimp_compression_combo_box_get_compression (GimpCompressionComboBox *combo_box)
{
gchar *result;
g_return_val_if_fail (GIMP_IS_COMPRESSION_COMBO_BOX (combo_box), NULL);
result = gimp_string_combo_box_get_active (GIMP_STRING_COMBO_BOX (combo_box));
if (! result)
{
GtkWidget *entry;
entry = gtk_bin_get_child (GTK_BIN (combo_box));
result = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
}
return result;
}

View File

@ -0,0 +1,55 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpcompressioncombobox.h
* Copyright (C) 2019 Ell
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef __GIMP_COMPRESSION_COMBO_BOX_H__
#define __GIMP_COMPRESSION_COMBO_BOX_H__
#define GIMP_TYPE_COMPRESSION_COMBO_BOX (gimp_compression_combo_box_get_type ())
#define GIMP_COMPRESSION_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_COMPRESSION_COMBO_BOX, GimpCompressionComboBox))
#define GIMP_COMPRESSION_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_COMPRESSION_COMBO_BOX, GimpCompressionComboBoxClass))
#define GIMP_IS_COMPRESSION_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_COMPRESSION_COMBO_BOX))
#define GIMP_IS_COMPRESSION_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_COMPRESSION_COMBO_BOX))
#define GIMP_COMPRESSION_COMBO_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_COMPRESSION_COMBO_BOX, GimpCompressionComboBoxClass))
typedef struct _GimpCompressionComboBoxClass GimpCompressionComboBoxClass;
struct _GimpCompressionComboBox
{
GimpStringComboBox parent_instance;
};
struct _GimpCompressionComboBoxClass
{
GimpStringComboBoxClass parent_instance;
};
GType gimp_compression_combo_box_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_compression_combo_box_new (void);
void gimp_compression_combo_box_set_compression (GimpCompressionComboBox *combo_box,
const gchar *compression);
gchar * gimp_compression_combo_box_get_compression (GimpCompressionComboBox *combo_box);
#endif /* __GIMP_COMPRESSION_COMBO_BOX_H__ */

View File

@ -40,6 +40,7 @@
#include "core/gimpviewable.h"
#include "gimpcolorpanel.h"
#include "gimpcompressioncombobox.h"
#include "gimpdial.h"
#include "gimpdnd.h"
#include "gimpiconpicker.h"
@ -1745,6 +1746,107 @@ gimp_prop_profile_combo_notify (GObject *config,
}
/***************************/
/* compression combo box */
/***************************/
static void gimp_prop_compression_combo_box_callback (GtkWidget *combo,
GObject *config);
static void gimp_prop_compression_combo_box_notify (GObject *config,
GParamSpec *param_spec,
GtkWidget *combo);
GtkWidget *
gimp_prop_compression_combo_box_new (GObject *config,
const gchar *property_name)
{
GParamSpec *param_spec;
GtkWidget *combo;
gchar *value;
param_spec = check_param_spec_w (config, property_name,
G_TYPE_PARAM_STRING, G_STRFUNC);
if (! param_spec)
return NULL;
combo = gimp_compression_combo_box_new ();
g_object_get (config,
property_name, &value,
NULL);
gimp_compression_combo_box_set_compression (
GIMP_COMPRESSION_COMBO_BOX (combo), value);
g_free (value);
set_param_spec (G_OBJECT (combo), combo, param_spec);
g_signal_connect (combo, "changed",
G_CALLBACK (gimp_prop_compression_combo_box_callback),
config);
connect_notify (config, property_name,
G_CALLBACK (gimp_prop_compression_combo_box_notify),
combo);
return combo;
}
static void
gimp_prop_compression_combo_box_callback (GtkWidget *combo,
GObject *config)
{
GParamSpec *param_spec;
gchar *compression;
param_spec = get_param_spec (G_OBJECT (combo));
if (! param_spec)
return;
compression = gimp_compression_combo_box_get_compression (
GIMP_COMPRESSION_COMBO_BOX (combo));
g_signal_handlers_block_by_func (config,
gimp_prop_compression_combo_box_notify,
combo);
g_object_set (config,
param_spec->name, compression,
NULL);
g_signal_handlers_unblock_by_func (config,
gimp_prop_compression_combo_box_notify,
combo);
g_free (compression);
}
static void
gimp_prop_compression_combo_box_notify (GObject *config,
GParamSpec *param_spec,
GtkWidget *combo)
{
gchar *value;
g_object_get (config,
param_spec->name, &value,
NULL);
g_signal_handlers_block_by_func (combo,
gimp_prop_compression_combo_box_callback,
config);
gimp_compression_combo_box_set_compression (
GIMP_COMPRESSION_COMBO_BOX (combo), value);
g_signal_handlers_unblock_by_func (combo,
gimp_prop_compression_combo_box_callback,
config);
g_free (value);
}
/*****************/
/* icon picker */
/*****************/

View File

@ -108,20 +108,23 @@ GtkWidget * gimp_prop_number_pair_entry_new (GObject *config,
/* GParamString */
GtkWidget * gimp_prop_language_combo_box_new (GObject *config,
const gchar *property_name);
GtkWidget * gimp_prop_language_entry_new (GObject *config,
const gchar *property_name);
GtkWidget * gimp_prop_language_combo_box_new (GObject *config,
const gchar *property_name);
GtkWidget * gimp_prop_language_entry_new (GObject *config,
const gchar *property_name);
GtkWidget * gimp_prop_profile_combo_box_new (GObject *config,
const gchar *property_name,
GtkListStore *profile_store,
const gchar *dialog_title,
GObject *profile_path_config,
const gchar *profile_path_property_name);
GtkWidget * gimp_prop_profile_combo_box_new (GObject *config,
const gchar *property_name,
GtkListStore *profile_store,
const gchar *dialog_title,
GObject *profile_path_config,
const gchar *profile_path_property_name);
GtkWidget * gimp_prop_icon_picker_new (GimpViewable *viewable,
Gimp *gimp);
GtkWidget * gimp_prop_compression_combo_box_new (GObject *config,
const gchar *property_name);
GtkWidget * gimp_prop_icon_picker_new (GimpViewable *viewable,
Gimp *gimp);
/* Utility functions */

View File

@ -40,6 +40,7 @@ libappwidgets_sources = [
'gimpcolorselectorpalette.c',
'gimpcombotagentry.c',
'gimpcomponenteditor.c',
'gimpcompressioncombobox.c',
'gimpcontainerbox.c',
'gimpcontainercombobox.c',
'gimpcontainereditor.c',

View File

@ -178,6 +178,7 @@ typedef struct _GimpColorHistory GimpColorHistory;
typedef struct _GimpColormapSelection GimpColormapSelection;
typedef struct _GimpColorPanel GimpColorPanel;
typedef struct _GimpComboTagEntry GimpComboTagEntry;
typedef struct _GimpCompressionComboBox GimpCompressionComboBox;
typedef struct _GimpControllerEditor GimpControllerEditor;
typedef struct _GimpControllerList GimpControllerList;
typedef struct _GimpCurveView GimpCurveView;