Skip to content

Commit ea4c8a5

Browse files
committed
driver: Rewrite most of sdl preview logic
The driver hasn't seen a lot of love for a while now because I shifted my testing almost entirely to the Blender plugin. After removing the isBorderless option in the previous commit, I kept stumbling on more and more redundant/baffling state management, and more than a few bugs. It's still not good, but it's better than it was. Summary: - Removed redundant json display.isFullscreen option - Removed useless mutex (the renderer invokes all callbacks on the same thread, but I guess I forgot that at some point?) - flip should_save bool -> skip_save, so zero becomes the default - Simplified async SDL init logic a lot. This stuff was so overbuilt and convoluted, it's not even funny. The display "enabled" boolean was being passed all the way through all the async machinery, only to be used in an early return. Now it just skips even registering the on_start callback that invokes that stuff. - Rewrote most of the SDL setup code to handle errors better.
1 parent 2b78427 commit ea4c8a5

File tree

4 files changed

+200
-226
lines changed

4 files changed

+200
-226
lines changed

input/hdr.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414
"width": 1280,
1515
"height": 800
1616
},
17-
"display": {
18-
"isFullscreen": false,
19-
"windowScale": 1.0
20-
},
17+
"display": {},
2118
"camera": [
2219
{
2320
"FOV": 30.0,

src/driver/main.c

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@
2121
#include <args.h>
2222
#include <sdl.h>
2323

24-
struct usr_data {
24+
struct cb_context {
2525
struct cr_renderer *r;
26-
struct v_mutex *win_mutex;
2726
struct sdl_window *w;
28-
struct sdl_prefs p;
29-
bool should_save;
27+
bool skip_save;
28+
29+
const struct cr_bitmap **temp_rbuf;
3030
};
3131

3232
/*
@@ -39,67 +39,61 @@ struct usr_data {
3939
when it has allocated a render buffer and is ready to render. We then pass a a ref
4040
to that buffer and some context to this async win_init_task().
4141
*/
42-
struct win_init_data {
43-
struct usr_data *driver;
44-
struct cr_renderer_cb_info *cb_info;
45-
};
46-
4742
static void *win_init_task(void *arg) {
48-
struct win_init_data *w = arg;
49-
if (!w) return NULL;
50-
struct usr_data *d = w->driver;
51-
struct cr_renderer_cb_info *cb_info = w->cb_info;
52-
struct sdl_window *win = win_try_init(&d->p, (*cb_info->fb)->width, (*cb_info->fb)->height);
53-
v_mutex_lock(d->win_mutex);
54-
if (d->p.enabled && *cb_info->fb) d->w = win;
55-
v_mutex_release(d->win_mutex);
56-
#if !defined(__APPLE__)
57-
free(w);
58-
#endif
43+
struct cb_context *d = arg;
44+
d->w = win_try_init(d->temp_rbuf);
45+
d->temp_rbuf = NULL;
5946
return NULL;
6047
}
6148

6249
static void on_start(struct cr_renderer_cb_info *cb_info, void *user_data) {
63-
struct usr_data *d = user_data;
50+
struct cb_context *d = user_data;
51+
d->temp_rbuf = cb_info->fb;
6452
#if defined(__APPLE__)
6553
// The SDL2 Cocoa backend on macOS will crash the program if it's invoked from a background thread.
6654
// Solution is to init SDL2 synchronously on macOS.
67-
win_init_task((void *)&(struct win_init_data){ .cb_info = cb_info, .driver = d });
55+
win_init_task(d);;
6856
#else
69-
struct win_init_data *data = malloc(sizeof(*data));
70-
*data = (struct win_init_data){
71-
.cb_info = cb_info,
72-
.driver = d,
73-
};
7457
v_thread_ctx ctx = {
7558
.thread_fn = win_init_task,
76-
.ctx = data,
59+
.ctx = d,
7760
};
7861
v_thread *ret = v_thread_create(ctx, v_thread_type_detached);
79-
if (!ret) { // Try synchronously, then.
80-
win_init_task(data);
81-
}
62+
if (!ret) // Fall back to running synchronously.
63+
win_init_task(d);
8264
#endif
8365
}
8466

8567
static void on_stop(struct cr_renderer_cb_info *info, void *user_data) {
8668
(void)info;
87-
struct usr_data *d = user_data;
88-
if (d->w) win_destroy(d->w);
69+
struct cb_context *d = user_data;
70+
if (d->w)
71+
win_destroy(d->w);
8972
if (info->aborted)
90-
d->should_save = false;
73+
d->skip_save = true;
9174
}
9275

9376
static void status(struct cr_renderer_cb_info *state, void *user_data) {
9477
static int pauser = 0;
95-
struct usr_data *d = user_data;
96-
if (!d) return;
97-
v_mutex_lock(d->win_mutex);
98-
struct input_state in = win_update(d->w, state->tiles, state->tiles_count, *((struct texture **)state->fb));
99-
v_mutex_release(d->win_mutex);
100-
d->should_save = in.should_save;
101-
if (in.stop_render) cr_renderer_stop(d->r);
102-
if (in.pause_render) cr_renderer_toggle_pause(d->r);
78+
struct cb_context *d = user_data;
79+
if (!d)
80+
return;
81+
if (d->w) {
82+
enum input_event e = win_update(d->w, state->tiles, state->tiles_count);
83+
switch (e) {
84+
case ev_stop_nosave:
85+
d->skip_save = true;
86+
cr_renderer_stop(d->r);
87+
break;
88+
case ev_stop:
89+
cr_renderer_stop(d->r);
90+
break;
91+
case ev_pause:
92+
cr_renderer_toggle_pause(d->r);
93+
default:
94+
break;
95+
}
96+
}
10397

10498
//Run the status printing about 4x/s
10599
if (++pauser >= 16) {
@@ -239,14 +233,14 @@ int main(int argc, char *argv[]) {
239233
}
240234
}
241235

242-
struct usr_data usrdata = (struct usr_data){
243-
.p = sdl_parse(cJSON_GetObjectItem(input_json, "display")),
236+
struct cb_context usrdata = {
244237
.r = renderer,
245-
.should_save = true,
246-
.win_mutex = v_mutex_create(),
247238
};
248-
if (!args_is_set(opts, "no_sdl"))
239+
240+
const cJSON *display = cJSON_GetObjectItem(input_json, "display");
241+
if (!args_is_set(opts, "no_sdl") && display && !cJSON_IsFalse(cJSON_GetObjectItem(display, "enabled")))
249242
cr_renderer_set_callback(renderer, cr_cb_on_start, on_start, &usrdata);
243+
250244
cr_renderer_set_callback(renderer, cr_cb_on_stop, on_stop, &usrdata);
251245
cr_renderer_set_callback(renderer, cr_cb_status_update, status, &usrdata);
252246

@@ -298,7 +292,9 @@ int main(int argc, char *argv[]) {
298292
logr(plain, "\n");
299293
logr(info, "Finished render in %s\n", ms_to_readable(ms, buf));
300294

301-
if (usrdata.should_save) {
295+
if (usrdata.skip_save) {
296+
logr(info, "Abort pressed, image won't be saved.\n");
297+
} else {
302298
struct imageFile file = (struct imageFile){
303299
.filePath = output_path,
304300
.fileName = output_name,
@@ -316,8 +312,6 @@ int main(int argc, char *argv[]) {
316312
};
317313
writeImage(&file);
318314
logr(info, "Render finished, exiting.\n");
319-
} else {
320-
logr(info, "Abort pressed, image won't be saved.\n");
321315
}
322316

323317
if (output_path) free(output_path);

0 commit comments

Comments
 (0)