summaryrefslogtreecommitdiff
path: root/src/modules/snow/snow.c
blob: 64a2d0dc153d61a11c5dfc77cbe05f809af5964c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <stdint.h>
#include <stdlib.h>
#include <time.h>

#include "til.h"
#include "til_fb.h"
#include "til_module_context.h"

/* Copyright (C) 2019 - Vito Caputo <vcaputo@pengaru.com> */

/* This implements white noise / snow just using rand() */

typedef union snow_seed_t {
	char			__padding[256];		/* prevent seeds sharing a cache-line */
	unsigned		seed;
} snow_seed_t;

typedef struct snow_context_t {
	til_module_context_t	til_module_context;
	unsigned		unused;
	snow_seed_t		seeds[];
} snow_context_t;


static til_module_context_t * snow_create_context(const til_module_t *module, til_stream_t *stream, unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup)
{
	snow_context_t	*ctxt;

	ctxt = til_module_context_new(module, sizeof(snow_context_t) + n_cpus * sizeof(snow_seed_t), stream, seed, ticks, n_cpus, setup);
	if (!ctxt)
		return NULL;

	for (unsigned i = 0; i < n_cpus; i++)
		ctxt->seeds[i].seed = rand_r(&seed);

	return &ctxt->til_module_context;
}


static void snow_prepare_frame(til_module_context_t *context, til_stream_t *stream, unsigned ticks, til_fb_fragment_t **fragment_ptr, til_frame_plan_t *res_frame_plan)
{
	*res_frame_plan = (til_frame_plan_t){ .fragmenter = til_fragmenter_slice_per_cpu_x16 };
}


static void snow_render_fragment(til_module_context_t *context, til_stream_t *stream, unsigned ticks, unsigned cpu, til_fb_fragment_t **fragment_ptr)
{
	snow_context_t		*ctxt = (snow_context_t *)context;
	til_fb_fragment_t	*fragment = *fragment_ptr;

	unsigned	*seed = &ctxt->seeds[cpu].seed;

	for (unsigned y = fragment->y; y < fragment->y + fragment->height; y++) {
		for (unsigned x = fragment->x; x < fragment->x + fragment->width; x++) {
#ifdef __WIN32__
			uint32_t	pixel = rand();
#else
			uint32_t	pixel = rand_r(seed) % 256;
#endif

			til_fb_fragment_put_pixel_unchecked(fragment, 0, x, y, pixel << 16 | pixel << 8 | pixel);
		}
	}
}


til_module_t	snow_module = {
	.create_context = snow_create_context,
	.prepare_frame = snow_prepare_frame,
	.render_fragment = snow_render_fragment,
	.name = "snow",
	.description = "TV snow / white noise (threaded)",
	.author = "Vito Caputo <vcaputo@pengaru.com>",
};
© All Rights Reserved