Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
test_drawlayer_batch_raster.c File Reference

Pins the drawlayer batch rasterizer against the per-dab one. More...

#include "iop/drawlayer/brush.h"
#include "iop/drawlayer/cache.h"
#include "iop/drawlayer/paint.h"
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <cmocka.h>
+ Include dependency graph for test_drawlayer_batch_raster.c:

Go to the source code of this file.

Data Structures

struct  plane_t
 

Macros

#define W   96
 
#define H   96
 

Typedefs

typedef struct plane_t plane_t
 

Functions

static void _plane_init (plane_t *p)
 
static void _plane_free (plane_t *p)
 
static void _build_dabs_tex (dt_drawlayer_brush_dab_t *dabs, const int count, const int mode, const float opacity, const float radius, const float step, const float sprinkles)
 A short stroke of overlapping dabs, uniform in everything the gate tests.
 
static void _build_dabs (dt_drawlayer_brush_dab_t *dabs, const int count, const int mode, const float opacity, const float radius, const float step)
 
static void _run_serial (plane_t *p, const dt_drawlayer_brush_dab_t *dabs, const int count)
 Run the reference path: one dt_drawlayer_brush_rasterize per dab, in order.
 
static void _run_batch (plane_t *p, const dt_drawlayer_brush_dab_t *dabs, const int count)
 
static double _max_abs_diff (const float *a, const float *b, const size_t n)
 
static void _compare_tex (const int mode, const float opacity, const float radius, const float step, const int count, const float sprinkles)
 
static void _compare (const int mode, const float opacity, const float radius, const float step, const int count)
 
static void test_batch_matches_serial_sprinkles (void **state)
 Texture on: the batch shares ONE sprinkle field across every dab.
 
static void test_batch_matches_serial_paint_dense (void **state)
 Heavy overlap, the shipped regime: spacing far below the diameter.
 
static void test_batch_matches_serial_paint_capped (void **state)
 The cap binds mid-batch: opacity well below 1 with many overlapping dabs.
 
static void test_batch_matches_serial_paint_sparse (void **state)
 Sparse dabs, barely overlapping.
 
static void test_batch_matches_serial_erase (void **state)
 
static void test_gate_refuses_non_uniform (void **state)
 The gate must refuse everything the closed form is not derived for.
 
static void test_batch_is_thread_count_independent (void **state)
 The batch result must not depend on the thread count.
 
static void _clear_mask (float *const mask, const size_t px)
 Time both paths on the shipped regime, so the speedup is measured and not derived.
 
static void _report_speedup (const float sprinkles)
 
static void test_report_batch_speedup (void **state)
 
int main (void)
 

Detailed Description

Pins the drawlayer batch rasterizer against the per-dab one.

dt_drawlayer_brush_rasterize_batch accumulates a product of per-dab transmittance factors and composites once, where dt_drawlayer_brush_rasterize composites per dab. The two are algebraically equal ONLY under the conditions dt_drawlayer_brush_batch_is_uniform tests for, and that equality is the whole basis of the fast path – so it is pinned here rather than argued about.

The comparison is a tolerance, not equality: the batch form evaluates a different (shorter) sequence of floating-point operations, so the two agree to rounding and not to the bit. The tolerance is tight enough that a real algebraic mistake – a dropped cap, a wrong order of operations, a missing clamp – moves it by orders of magnitude.

Definition in file test_drawlayer_batch_raster.c.

Macro Definition Documentation

◆ H

#define H   96

Definition at line 52 of file test_drawlayer_batch_raster.c.

◆ W

#define W   96

Definition at line 51 of file test_drawlayer_batch_raster.c.

Typedef Documentation

◆ plane_t

Function Documentation

◆ _build_dabs()

static void _build_dabs ( dt_drawlayer_brush_dab_t *  dabs,
const int  count,
const int  mode,
const float  opacity,
const float  radius,
const float  step 
)
static

◆ _build_dabs_tex()

static void _build_dabs_tex ( dt_drawlayer_brush_dab_t *  dabs,
const int  count,
const int  mode,
const float  opacity,
const float  radius,
const float  step,
const float  sprinkles 
)
static

A short stroke of overlapping dabs, uniform in everything the gate tests.

Definition at line 79 of file test_drawlayer_batch_raster.c.

References color, DT_DRAWLAYER_BRUSH_SHAPE_LINEAR, DT_DRAWLAYER_PAINT_STROKE_FIRST, DT_DRAWLAYER_PAINT_STROKE_MIDDLE, i, and dt_drawlayer_brush_dab_t::x.

Referenced by _build_dabs(), _compare_tex(), and test_gate_refuses_non_uniform().

◆ _clear_mask()

static void _clear_mask ( float *const  mask,
const size_t  px 
)
static

Time both paths on the shipped regime, so the speedup is measured and not derived.

Defaults are size 64 (a 128 px diameter) and distance 0 (1 px spacing), which is ~128x overdraw – the case the batch path exists for. Reported, never asserted: a wall-clock assertion on a shared runner is a flaky test, and the equality tests above are what actually protect the behaviour.

Definition at line 343 of file test_drawlayer_batch_raster.c.

References i.

Referenced by _report_speedup().

◆ _compare()

static void _compare ( const int  mode,
const float  opacity,
const float  radius,
const float  step,
const int  count 
)
static

◆ _compare_tex()

static void _compare_tex ( const int  mode,
const float  opacity,
const float  radius,
const float  step,
const int  count,
const float  sprinkles 
)
static

◆ _max_abs_diff()

static double _max_abs_diff ( const float *  a,
const float *  b,
const size_t  n 
)
static

Definition at line 139 of file test_drawlayer_batch_raster.c.

References d, i, L, and n.

Referenced by _compare_tex().

◆ _plane_free()

static void _plane_free ( plane_t *  p)
static

Definition at line 72 of file test_drawlayer_batch_raster.c.

References p.

Referenced by _compare_tex(), and test_batch_is_thread_count_independent().

◆ _plane_init()

static void _plane_init ( plane_t *  p)
static

◆ _report_speedup()

◆ _run_batch()

◆ _run_serial()

static void _run_serial ( plane_t *  p,
const dt_drawlayer_brush_dab_t *  dabs,
const int  count 
)
static

Run the reference path: one dt_drawlayer_brush_rasterize per dab, in order.

Definition at line 116 of file test_drawlayer_batch_raster.c.

References dt_drawlayer_brush_rasterize(), dt_drawlayer_paint_runtime_private_create(), dt_drawlayer_paint_runtime_private_destroy(), i, L, and p.

Referenced by _compare_tex().

◆ main()

◆ test_batch_is_thread_count_independent()

static void test_batch_is_thread_count_independent ( void **  state)
static

The batch result must not depend on the thread count.

This is the property the tile-lock scheme it replaces did NOT have: omp_lock_t per tile gives mutual exclusion but says nothing about the order two threads take a tile in, and the per-pixel alpha depends on the running stroke alpha – so that path produced a different picture run to run. Accumulating a commutative product removes the dependence entirely, and rows are disjoint, so this must be BIT-identical, not merely close.

Definition at line 297 of file test_drawlayer_batch_raster.c.

References _build_dabs(), _plane_free(), _plane_init(), _run_batch(), DT_DRAWLAYER_BRUSH_MODE_PAINT, H, L, omp_get_max_threads, state, void(), and W.

Referenced by main().

◆ test_batch_matches_serial_erase()

static void test_batch_matches_serial_erase ( void **  state)
static

Definition at line 236 of file test_drawlayer_batch_raster.c.

References _compare(), DT_DRAWLAYER_BRUSH_MODE_ERASE, state, and void().

Referenced by main().

◆ test_batch_matches_serial_paint_capped()

static void test_batch_matches_serial_paint_capped ( void **  state)
static

The cap binds mid-batch: opacity well below 1 with many overlapping dabs.

Definition at line 223 of file test_drawlayer_batch_raster.c.

References _compare(), DT_DRAWLAYER_BRUSH_MODE_PAINT, state, and void().

Referenced by main().

◆ test_batch_matches_serial_paint_dense()

static void test_batch_matches_serial_paint_dense ( void **  state)
static

Heavy overlap, the shipped regime: spacing far below the diameter.

Definition at line 216 of file test_drawlayer_batch_raster.c.

References _compare(), DT_DRAWLAYER_BRUSH_MODE_PAINT, state, and void().

Referenced by main().

◆ test_batch_matches_serial_paint_sparse()

static void test_batch_matches_serial_paint_sparse ( void **  state)
static

Sparse dabs, barely overlapping.

Definition at line 230 of file test_drawlayer_batch_raster.c.

References _compare(), DT_DRAWLAYER_BRUSH_MODE_PAINT, state, and void().

Referenced by main().

◆ test_batch_matches_serial_sprinkles()

static void test_batch_matches_serial_sprinkles ( void **  state)
static

Texture on: the batch shares ONE sprinkle field across every dab.

The field is a function of layer position and the stroke seed alone, so every overlapping dab samples the same value – which is why the gate also requires the sprinkle parameters to match. _cellular_grain_2d costs 9 cells x 4 splitmix32 per octave, up to three octaves, so sharing it divides the dominant per-pixel cost by the overdraw factor.

Definition at line 209 of file test_drawlayer_batch_raster.c.

References _compare_tex(), DT_DRAWLAYER_BRUSH_MODE_PAINT, state, and void().

Referenced by main().

◆ test_gate_refuses_non_uniform()

◆ test_report_batch_speedup()

static void test_report_batch_speedup ( void **  state)
static

Definition at line 424 of file test_drawlayer_batch_raster.c.

References _report_speedup(), state, and void().

Referenced by main().