libs: sync ctx with upstream
[gegl.git] / gegl / gegl-config.c
blobac7b9c242e9a491b1a1aaa9aa603186825479baa
1 /* This file is part of GEGL.
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 3 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
16 * Copyright 2006, 2007 Øyvind Kolås <pippin@gimp.org>
19 #include "config.h"
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <string.h>
25 #include <glib-object.h>
26 #include <glib/gprintf.h>
28 #include "gegl.h"
29 #include "gegl-types-internal.h"
30 #include "gegl-config.h"
31 #include "gegl-buffer-config.h"
33 #include "opencl/gegl-cl.h"
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
39 #ifdef G_OS_WIN32
40 #include <windows.h>
41 #endif
43 #ifdef __APPLE__
44 #include <mach/mach.h>
45 #endif
47 #if defined(__APPLE__) || defined(__FreeBSD__)
48 #include <sys/types.h>
49 #include <sys/sysctl.h>
50 #endif
52 G_DEFINE_TYPE (GeglConfig, gegl_config, G_TYPE_OBJECT)
54 static GObjectClass * parent_class = NULL;
56 enum
58 PROP_0,
59 PROP_QUALITY,
60 PROP_TILE_CACHE_SIZE,
61 PROP_CHUNK_SIZE,
62 PROP_SWAP,
63 PROP_SWAP_COMPRESSION,
64 PROP_TILE_WIDTH,
65 PROP_TILE_HEIGHT,
66 PROP_THREADS,
67 PROP_USE_OPENCL,
68 PROP_QUEUE_SIZE,
69 PROP_APPLICATION_LICENSE,
70 PROP_MIPMAP_RENDERING
73 gint _gegl_threads = 1;
75 static void
76 gegl_config_get_property (GObject *gobject,
77 guint property_id,
78 GValue *value,
79 GParamSpec *pspec)
81 GeglConfig *config = GEGL_CONFIG (gobject);
83 switch (property_id)
85 case PROP_TILE_CACHE_SIZE:
86 g_value_set_uint64 (value, config->tile_cache_size);
87 break;
89 case PROP_CHUNK_SIZE:
90 g_value_set_int (value, config->chunk_size);
91 break;
93 case PROP_TILE_WIDTH:
94 g_value_set_int (value, config->tile_width);
95 break;
97 case PROP_TILE_HEIGHT:
98 g_value_set_int (value, config->tile_height);
99 break;
101 case PROP_QUALITY:
102 g_value_set_double (value, config->quality);
103 break;
105 case PROP_SWAP:
106 g_value_set_string (value, config->swap);
107 break;
109 case PROP_SWAP_COMPRESSION:
110 g_value_set_string (value, config->swap_compression);
111 break;
113 case PROP_THREADS:
114 g_value_set_int (value, _gegl_threads);
115 break;
117 case PROP_USE_OPENCL:
118 g_value_set_boolean (value, gegl_cl_is_accelerated());
119 break;
121 case PROP_QUEUE_SIZE:
122 g_value_set_int (value, config->queue_size);
123 break;
125 case PROP_APPLICATION_LICENSE:
126 g_value_set_string (value, config->application_license);
127 break;
129 case PROP_MIPMAP_RENDERING:
130 g_value_set_boolean (value, config->mipmap_rendering);
131 break;
133 default:
134 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
135 break;
139 static void
140 gegl_config_set_property (GObject *gobject,
141 guint property_id,
142 const GValue *value,
143 GParamSpec *pspec)
145 GeglConfig *config = GEGL_CONFIG (gobject);
147 switch (property_id)
149 case PROP_TILE_CACHE_SIZE:
150 config->tile_cache_size = g_value_get_uint64 (value);
151 break;
152 case PROP_CHUNK_SIZE:
153 config->chunk_size = g_value_get_int (value);
154 break;
155 case PROP_TILE_WIDTH:
156 config->tile_width = g_value_get_int (value);
157 break;
158 case PROP_TILE_HEIGHT:
159 config->tile_height = g_value_get_int (value);
160 break;
161 case PROP_QUALITY:
162 config->quality = g_value_get_double (value);
163 return;
164 case PROP_SWAP:
165 g_free (config->swap);
166 config->swap = g_value_dup_string (value);
167 break;
168 case PROP_SWAP_COMPRESSION:
169 g_free (config->swap_compression);
170 config->swap_compression = g_value_dup_string (value);
171 break;
172 case PROP_THREADS:
173 _gegl_threads = g_value_get_int (value);
174 return;
175 case PROP_USE_OPENCL:
176 config->use_opencl = g_value_get_boolean (value);
177 break;
178 case PROP_MIPMAP_RENDERING:
179 config->mipmap_rendering = g_value_get_boolean (value);
180 break;
181 case PROP_QUEUE_SIZE:
182 config->queue_size = g_value_get_int (value);
183 break;
184 case PROP_APPLICATION_LICENSE:
185 g_free (config->application_license);
186 config->application_license = g_value_dup_string (value);
187 break;
188 default:
189 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
190 break;
194 static void
195 gegl_config_finalize (GObject *gobject)
197 GeglConfig *config = GEGL_CONFIG (gobject);
199 g_free (config->swap);
200 g_free (config->swap_compression);
201 g_free (config->application_license);
203 G_OBJECT_CLASS (gegl_config_parent_class)->finalize (gobject);
206 static void
207 gegl_config_class_init (GeglConfigClass *klass)
209 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
211 parent_class = g_type_class_peek_parent (klass);
213 gobject_class->set_property = gegl_config_set_property;
214 gobject_class->get_property = gegl_config_get_property;
215 gobject_class->finalize = gegl_config_finalize;
218 g_object_class_install_property (gobject_class, PROP_TILE_WIDTH,
219 g_param_spec_int ("tile-width",
220 "Tile width",
221 "default tile width for created buffers.",
222 0, G_MAXINT, 128,
223 G_PARAM_READWRITE |
224 G_PARAM_STATIC_STRINGS));
226 g_object_class_install_property (gobject_class, PROP_TILE_HEIGHT,
227 g_param_spec_int ("tile-height",
228 "Tile height",
229 "default tile height for created buffers.",
230 0, G_MAXINT, 128,
231 G_PARAM_READWRITE |
232 G_PARAM_STATIC_STRINGS));
235 uint64_t default_tile_cache_size = 1024l * 1024 * 1024;
236 uint64_t mem_total = default_tile_cache_size;
237 uint64_t mem_min = 512 << 20; // 512mb
238 uint64_t mem_available = mem_min;
240 #ifdef G_OS_WIN32
241 # if defined(_MSC_VER) && (_MSC_VER <= 1200)
242 MEMORYSTATUS memory_status;
243 memory_status.dwLength = sizeof (memory_status);
245 GlobalMemoryStatus (&memory_status);
246 mem_total = memory_status.dwTotalPhys;
247 mem_available = memory_status.dwAvailPhys;
248 # else
249 /* requires w2k and newer SDK than provided with msvc6 */
250 MEMORYSTATUSEX memory_status;
252 memory_status.dwLength = sizeof (memory_status);
254 if (GlobalMemoryStatusEx (&memory_status))
256 mem_total = memory_status.ullTotalPhys;
257 mem_available = memory_status.ullAvailPhys;
259 # endif
260 #elif defined(__APPLE__)
261 /* get total memory from the HW_MEMSIZE */
262 int64_t usermem;
263 size_t len = sizeof usermem;
264 static int mib[2] = { CTL_HW, HW_MEMSIZE };
266 if (sysctl (mib, 2, &usermem, &len, NULL, 0) == 0) {
267 mem_total = usermem;
269 /* and available mem from host_statistics64 */
270 vm_size_t page_size = sysconf (_SC_PAGESIZE);
271 mach_port_t host = mach_host_self ();
272 vm_statistics64_data_t vm_stat;
273 kern_return_t kret;
274 unsigned int count = HOST_VM_INFO64_COUNT;
276 kret = host_statistics64 (host, HOST_VM_INFO64, (host_info64_t)&vm_stat, &count);
278 if (kret == KERN_SUCCESS)
280 mem_available = (long) (vm_stat.free_count + vm_stat.active_count
281 + vm_stat.inactive_count
282 # ifdef MAC_OS_X_VERSION_10_9
283 + vm_stat.compressor_page_count
284 # endif
285 ) * page_size;
286 mach_port_deallocate (mach_task_self (), host);
288 #elif defined(__FreeBSD__)
289 bool ok = true;
291 unsigned long physmem;
292 ok = ok && sysctl ((int[2]){ CTL_HW, HW_PHYSMEM }, 2, &physmem,
293 &(size_t){ sizeof physmem }, NULL, 0) == 0;
294 if (ok)
295 mem_total = physmem;
297 uint32_t active_count;
298 uint32_t wired_count;
299 ok = ok && sysctlbyname ("vm.stats.vm.v_active_count", &active_count,
300 &(size_t){ sizeof active_count }, NULL, 0) == 0;
301 ok = ok && sysctlbyname ("vm.stats.vm.v_wire_count", &wired_count,
302 &(size_t){ sizeof wired_count }, NULL, 0) == 0;
304 if (ok) {
305 uint32_t laundry_count;
306 uint64_t zfs_arc_size;
307 if (sysctlbyname ("vm.stats.vm.v_laundry_count", &laundry_count,
308 &(size_t){ sizeof laundry_count }, NULL, 0) != 0)
309 laundry_count = 0;
310 if (sysctlbyname ("kstat.zfs.misc.arcstats.size", &zfs_arc_size,
311 &(size_t){ sizeof zfs_arc_size }, NULL, 0) != 0)
312 zfs_arc_size = 0;
314 int page_size = getpagesize ();
315 mem_available = physmem - (uint64_t) active_count * page_size
316 - (uint64_t) wired_count * page_size
317 - (uint64_t) laundry_count * page_size
318 + zfs_arc_size;
320 #else
321 mem_total = (uint64_t) sysconf (_SC_PHYS_PAGES) * sysconf (_SC_PAGESIZE);
322 mem_available = (uint64_t) sysconf (_SC_AVPHYS_PAGES) * sysconf (_SC_PAGESIZE);
323 #endif
325 default_tile_cache_size = mem_total;
326 if (default_tile_cache_size > mem_available)
328 default_tile_cache_size = mem_available;
330 if (default_tile_cache_size < mem_min)
331 default_tile_cache_size = mem_min;
333 if (getenv ("GEGL_BUILD")) /* make .gir reproducible */
334 default_tile_cache_size = 1024 * 1024 * 256;
336 g_object_class_install_property (gobject_class, PROP_TILE_CACHE_SIZE,
337 g_param_spec_uint64 ("tile-cache-size",
338 "Tile Cache size",
339 "size of tile cache in bytes",
340 0, G_MAXUINT64, default_tile_cache_size,
341 G_PARAM_READWRITE |
342 G_PARAM_STATIC_STRINGS));
345 g_object_class_install_property (gobject_class, PROP_CHUNK_SIZE,
346 g_param_spec_int ("chunk-size",
347 "Chunk size",
348 "the number of pixels processed simultaneously by GEGL.",
349 1, G_MAXINT, 1024 * 1024,
350 G_PARAM_READWRITE |
351 G_PARAM_STATIC_STRINGS |
352 G_PARAM_CONSTRUCT));
354 g_object_class_install_property (gobject_class, PROP_QUALITY,
355 g_param_spec_double ("quality",
356 "Quality",
357 "quality/speed trade off 1.0 = full quality, 0.0 = full speed",
358 0.0, 1.0, 1.0,
359 G_PARAM_READWRITE |
360 G_PARAM_STATIC_STRINGS |
361 G_PARAM_CONSTRUCT));
363 g_object_class_install_property (gobject_class, PROP_SWAP,
364 g_param_spec_string ("swap",
365 "Swap",
366 "where gegl stores it's swap files",
367 NULL,
368 G_PARAM_READWRITE |
369 G_PARAM_STATIC_STRINGS));
371 g_object_class_install_property (gobject_class, PROP_SWAP_COMPRESSION,
372 g_param_spec_string ("swap-compression",
373 "Swap compression",
374 "compression algorithm used for data stored in the swap",
375 NULL,
376 G_PARAM_READWRITE |
377 G_PARAM_STATIC_STRINGS));
379 _gegl_threads = g_get_num_processors ();
380 _gegl_threads = MIN (_gegl_threads, GEGL_MAX_THREADS);
382 if (getenv ("GEGL_BUILD")) // to make .gir reproducible
383 _gegl_threads = GEGL_MAX_THREADS;
385 g_object_class_install_property (gobject_class, PROP_THREADS,
386 g_param_spec_int ("threads",
387 "Number of threads",
388 "Number of concurrent evaluation threads",
389 0, GEGL_MAX_THREADS,
390 _gegl_threads,
391 G_PARAM_READWRITE |
392 G_PARAM_STATIC_STRINGS |
393 G_PARAM_CONSTRUCT));
395 g_object_class_install_property (gobject_class, PROP_MIPMAP_RENDERING,
396 g_param_spec_boolean ("mipmap-rendering",
397 "mipmap rendering",
398 "Enable code paths for mipmap preview rendering, uses approximations for 50% 25% etc zoom factors to reduce processing.",
399 FALSE,
400 G_PARAM_READWRITE |
401 G_PARAM_STATIC_STRINGS |
402 G_PARAM_CONSTRUCT));
404 g_object_class_install_property (gobject_class, PROP_USE_OPENCL,
405 g_param_spec_boolean ("use-opencl",
406 "Use OpenCL",
407 "Try to use OpenCL",
408 FALSE,
409 G_PARAM_READWRITE |
410 G_PARAM_STATIC_STRINGS |
411 G_PARAM_CONSTRUCT));
413 g_object_class_install_property (gobject_class, PROP_QUEUE_SIZE,
414 g_param_spec_int ("queue-size",
415 "Queue size",
416 "Maximum size of a file backend's writer thread queue (in bytes)",
417 2, G_MAXINT, 50 * 1024 *1024,
418 G_PARAM_READWRITE |
419 G_PARAM_STATIC_STRINGS));
421 g_object_class_install_property (gobject_class, PROP_APPLICATION_LICENSE,
422 g_param_spec_string ("application-license",
423 "Application license",
424 "A list of additional licenses to allow for operations",
426 G_PARAM_READWRITE |
427 G_PARAM_STATIC_STRINGS |
428 G_PARAM_CONSTRUCT));
431 static void
432 gegl_config_init (GeglConfig *self)
434 char *forward_props[]={"swap",
435 "swap-compression",
436 "queue-size",
437 "tile-width",
438 "tile-height",
439 "tile-cache-size",
440 NULL};
441 GeglBufferConfig *bconf = gegl_buffer_config ();
442 for (int i = 0; forward_props[i]; i++)
443 g_object_bind_property (bconf, forward_props[i],
444 self, forward_props[i],
445 G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
448 #undef gegl_config_threads
449 int gegl_config_threads(void);
450 int gegl_config_threads(void)
452 return _gegl_threads;