Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
test_pipe_cleanup_nodes_masks.c
Go to the documentation of this file.
1/*
2 This file is part of Ansel,
3 Copyright (C) 2026 Guillaume Stutin.
4
5 Ansel is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 Ansel is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Ansel. If not, see <http://www.gnu.org/licenses/>.
17*/
18
36#include "develop/imageop.h"
37#include "develop/pixelpipe.h"
39#include "system/atomic.h"
40
41#include <stdarg.h>
42#include <stddef.h>
43// cmocka.h declares `extern jmp_buf global_expect_assert_env' at file scope without including
44// <setjmp.h> itself. Same suppression as test_metadata_notify.c, and for the same reason.
45#include <setjmp.h> // NOLINT(misc-include-cleaner)
46#include <stdint.h>
47#include <string.h>
48#include <cmocka.h>
49
50#include <glib.h>
51
52#ifdef _WIN32
53#include "win/main_wrapper.h"
54#endif
55
56#define LINE_BYTES (256 * 1024)
57#define HASH_RASTER 0x0B0B0B0B0B0B0B0BULL
58#define HASH_DETAIL 0x0C0C0C0C0C0C0C0CULL
59
60static int _setup(void **state __attribute__((unused)))
61{
62 return dt_dev_pixelpipe_cache_init((size_t)64 * 1024 * 1024, FALSE, FALSE) ? 0 : -1;
63}
64
65static int _teardown(void **state __attribute__((unused)))
66{
68 return 0;
69}
70
71/* A written mask, still referenced once by its creator: the reference the pipe takes over when a
72 * provider publishes it. */
74{
75 void *data = NULL;
76 dt_pixel_cache_entry_t *entry = NULL;
77 assert_int_equal(dt_dev_pixelpipe_cache_get(hash, LINE_BYTES, "test mask", 0, TRUE, &data, &entry), 1);
78 assert_non_null(entry);
79 assert_non_null(data);
81 return entry;
82}
83
84/* A pipe whose graph holds one raster mask and the detail mask, as after a render. */
86{
87 memset(pipe, 0, sizeof(*pipe));
88 pipe->raster_mask_hashes = g_array_new(FALSE, FALSE, sizeof(uint64_t));
89 const uint64_t raster = HASH_RASTER;
91 g_array_append_val(pipe->raster_mask_hashes, raster);
94}
95
98{
101
103
104 assert_int_equal(dt_atomic_get_int(&dt_dev_pixelpipe_cache_get_entry(HASH_RASTER)->refcount), 0);
105 assert_int_equal(dt_atomic_get_int(&dt_dev_pixelpipe_cache_get_entry(HASH_DETAIL)->refcount), 0);
106 assert_int_equal(pipe.raster_mask_hashes->len, 0);
108
109 g_array_free(pipe.raster_mask_hashes, TRUE);
110}
111
126
127#define HASH_OUTPUT 0x0D0D0D0D0D0D0D0DULL
128
129/* A detailmask piece, and its cached output: a written line nobody holds, as after a render. */
131{
132 memset(module, 0, sizeof(*module));
133 memset(piece, 0, sizeof(*piece));
134 g_strlcpy(module->op, op, sizeof(module->op));
135 piece->module = module;
136 piece->global_hash = 0x0E0E0E0E0E0E0E0EULL;
137 piece->roi_out.width = 16;
138 piece->roi_out.height = 8;
140}
141
144{
146 memset(&pipe, 0, sizeof(pipe));
147 pipe.raster_mask_hashes = g_array_new(FALSE, FALSE, sizeof(uint64_t));
149 dt_iop_module_t module;
151 _detailmask_output(&module, &piece, "detailmask");
154
157 assert_true(pipe.rawdetail_mask_hash == mask_hash);
158 assert_int_equal(dt_atomic_get_int(&dt_dev_pixelpipe_cache_get_entry(mask_hash)->refcount), 1);
159 assert_int_equal(pipe.rawdetail_mask_roi.width, 16);
160
162 g_array_free(pipe.raster_mask_hashes, TRUE);
163}
164
179
193
194int main(int argc, char *argv[])
195{
196 const struct CMUnitTest tests[] = {
197 cmocka_unit_test_setup_teardown(_cleanup_nodes_releases_the_masks, _setup, _teardown),
198 cmocka_unit_test_setup_teardown(_released_masks_go_with_the_flush, _setup, _teardown),
199 cmocka_unit_test_setup_teardown(_detail_output_with_its_mask_stands, _setup, _teardown),
200 cmocka_unit_test_setup_teardown(_detail_output_without_its_mask_goes, _setup, _teardown),
201 cmocka_unit_test_setup_teardown(_other_output_stands, _setup, _teardown),
202 };
203 return cmocka_run_group_tests(tests, NULL, NULL);
204}
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
int dt_atomic_get_int(dt_atomic_int *var)
static const dt_dev_pixelpipe_t * pipe
Definition layers.h:49
static const dt_dev_pixelpipe_t const dt_dev_pixelpipe_iop_t * piece
Definition layers.h:50
hash
Definition layers.h:90
uint64_t dt_dev_pixelpipe_rawdetail_mask_hash(const dt_dev_pixelpipe_iop_t *piece)
Definition pixelpipe.c:45
void dt_dev_pixelpipe_cache_wrlock_entry(gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Lock or release the write lock on the entry.
void dt_dev_pixelpipe_cache_unref_entry(dt_pixel_cache_entry_t *entry)
Release one reference held on entry, by POINTER.
void dt_dev_pixelpipe_cache_cleanup(void)
Release everything dt_dev_pixelpipe_cache_init() created, the instance included. Only after a success...
void dt_dev_pixelpipe_cache_flush(const int id)
Remove cache lines matching id. Entries locked in read/write or having reference count greater than 0...
int dt_dev_pixelpipe_cache_get(const uint64_t hash, const size_t size, const char *name, const int id, const gboolean alloc, void **data, dt_pixel_cache_entry_t **entry)
Get a cache line from the cache.
dt_pixel_cache_entry_t * dt_dev_pixelpipe_cache_get_entry(const uint64_t hash)
Get an internal reference to the cache entry matching hash. If you are going to access this entry mor...
gboolean dt_dev_pixelpipe_cache_init(size_t max_memory, const gboolean verbose, const gboolean verbose_detail)
Reserve the cache's arena and start it.
Pixelpipe cache for storing intermediate results in the pixelpipe.
#define DT_PIXELPIPE_CACHE_HASH_INVALID
void dt_dev_pixelpipe_cleanup_nodes(dt_dev_pixelpipe_t *pipe)
gboolean dt_dev_pixelpipe_rawdetail_mask_check_hit(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const uint64_t output_hash)
Whether a cached output of piece may stand for it, called before that output is looked up.
int main()
Definition prova.c:47
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Apply one channel's tone curve to each of the three colour channels, or pass the channel through unto...
Definition simd.h:55
const float uint32_t state[4]
unsigned __int64 uint64_t
Definition strptime.c:75
uint64_t rawdetail_mask_hash
struct dt_iop_roi_t rawdetail_mask_roi
GArray * raster_mask_hashes
dt_dev_operation_t op
Definition imageop.h:259
int width
Definition format.h:50
static void _detail_output_without_its_mask_goes(void **state __attribute__((unused)))
#define HASH_RASTER
static int _teardown(void **state __attribute__((unused)))
static void _pipe_holding_masks(dt_dev_pixelpipe_t *pipe)
static void _detail_output_with_its_mask_stands(void **state __attribute__((unused)))
static void _detailmask_output(dt_iop_module_t *module, dt_dev_pixelpipe_iop_t *piece, const char *op)
static void _released_masks_go_with_the_flush(void **state __attribute__((unused)))
static int _setup(void **state __attribute__((unused)))
#define HASH_DETAIL
static dt_pixel_cache_entry_t * _publish(const uint64_t hash)
static void _cleanup_nodes_releases_the_masks(void **state __attribute__((unused)))
static void _other_output_stands(void **state __attribute__((unused)))