Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 7 commits
  • 6 files changed
  • 0 comments
  • 1 contributor
Jan 14, 2012
Werner Almesberger gui/performance.c (patches): convert array to doubly linked list
This eliminates the MAX_PATCHES limit, which we were about to hit.
Also makes the code look a bit tidier.
44722c4
Werner Almesberger gui/performance.c: wrap remaining oversized lines; minor whitespace c…
…orrection
a605f4e
Werner Almesberger gui/performance.c: cache patches for later reuse (WIP)
This cache is not persistent. Patches are lost when rebooting.

To do:
- need to check error handling
- need to check whether images have changed
23ce54d
Werner Almesberger compiler: record file name and stat for images; report problems (WIP)
This is a preparation for correct image caching. (Current image
caching is overzealous.)

This patch also adds basic error reporting if the image file is not
found or if there is a problem loading it.

To do:
- do the actual cache check
- find out why free() complains if assign_image_name returns an
  error
ea44cff
Werner Almesberger compiler: corrected cleanup after failed assign_image_name 5f6566e
Werner Almesberger also consider images when checking patch cache for uptodateness 3fd3e84
Werner Almesberger Merge branch 'cache' a7e1867
74  src/compiler/compiler.c
@@ -21,6 +21,7 @@
21 21
 #include <stdlib.h>
22 22
 #include <stdarg.h>
23 23
 #include <string.h>
  24
+#include <sys/stat.h>
24 25
 
25 26
 #include <fpvm/fpvm.h>
26 27
 #include <fpvm/symbol.h>
@@ -399,9 +400,12 @@ static const char *assign_image_name(struct parser_comm *comm,
399 400
 #ifndef STANDALONE
400 401
 	struct compiler_sc *sc = comm->u.sc;
401 402
 	char *totalname;
  403
+	struct image *img;
  404
+#endif
402 405
 
403 406
 	if(number > IMAGE_COUNT)
404 407
 		return strdup("image number out of bounds");
  408
+#ifndef STANDALONE
405 409
 	number--;
406 410
 	
407 411
 	if(*name == '/')
@@ -413,10 +417,25 @@ static const char *assign_image_name(struct parser_comm *comm,
413 417
 		strcpy(totalname, sc->basedir);
414 418
 		strcat(totalname, name);
415 419
 	}
416  
-	pixbuf_dec_ref(sc->p->images[number]);
417  
-	sc->p->images[number] = pixbuf_get(totalname);
418  
-	free(totalname);
419  
-#endif /* STANDALONE */
  420
+
  421
+	img = sc->p->images+number;
  422
+	pixbuf_dec_ref(img->pixbuf);
  423
+	free((void *) img->filename);
  424
+	img->pixbuf = NULL;
  425
+	img->filename = NULL;
  426
+
  427
+	if(lstat(totalname, &img->st) < 0) {
  428
+		free(totalname);
  429
+		return strdup("image file not found");
  430
+	}
  431
+	img->pixbuf = pixbuf_get(totalname);
  432
+	if(img->pixbuf) {
  433
+		img->filename = totalname;
  434
+	} else {
  435
+		free(totalname);
  436
+		return strdup("cannot load image file");
  437
+	}
  438
+#endif /* !STANDALONE */
420 439
 	return NULL;
421 440
 }
422 441
 
@@ -456,8 +475,11 @@ struct patch *patch_compile(const char *basedir, const char *patch_code,
456 475
 		free(sc);
457 476
 		return NULL;
458 477
 	}
459  
-	for(i=0;i<IMAGE_COUNT;i++)
460  
-		sc->p->images[i] = NULL;
  478
+	for(i=0;i<IMAGE_COUNT;i++) {
  479
+		sc->p->images[i].pixbuf = NULL;
  480
+		sc->p->images[i].filename = NULL;
  481
+	}
  482
+	sc->p->ref = 1;
461 483
 	sc->p->require = 0;
462 484
 	sc->p->original = NULL;
463 485
 	sc->p->next = NULL;
@@ -517,25 +539,51 @@ struct patch *patch_compile_filename(const char *filename,
517 539
 struct patch *patch_copy(struct patch *p)
518 540
 {
519 541
 	struct patch *new_patch;
520  
-	int i;
  542
+	struct image *img;
521 543
 
522 544
 	new_patch = malloc(sizeof(struct patch));
523 545
 	assert(new_patch != NULL);
524 546
 	memcpy(new_patch, p, sizeof(struct patch));
  547
+	new_patch->ref = 1;
525 548
 	new_patch->original = p;
526 549
 	new_patch->next = NULL;
527  
-	for(i=0;i<IMAGE_COUNT;i++)
528  
-		pixbuf_inc_ref(new_patch->images[i]);
  550
+	for(img = new_patch->images;
  551
+	    img != new_patch->images+IMAGE_COUNT; img++) {
  552
+		if(img->filename)
  553
+			img->filename = strdup(img->filename);
  554
+		pixbuf_inc_ref(img->pixbuf);
  555
+	}
529 556
 	return new_patch;
530 557
 }
531 558
 
532 559
 void patch_free(struct patch *p)
533 560
 {
534  
-	int i;
535  
-
536  
-	for(i=0;i<IMAGE_COUNT;i++)
537  
-		pixbuf_dec_ref(p->images[i]);
  561
+	struct image *img;
  562
+
  563
+	assert(p->ref);
  564
+	if(--p->ref);
  565
+		return;
  566
+	for(img = p->images; img != p->images+IMAGE_COUNT; img++) {
  567
+		pixbuf_dec_ref(img->pixbuf);
  568
+		free((void *) img->filename);
  569
+	}
538 570
 	free(p);
539 571
 }
540 572
 
  573
+int patch_images_uptodate(const struct patch *p)
  574
+{
  575
+	const struct image *img;
  576
+	struct stat st;
  577
+
  578
+	for(img = p->images; img != p->images+IMAGE_COUNT; img++) {
  579
+		if(!img->pixbuf)
  580
+			continue;
  581
+		if(lstat(img->filename, &st) < 0)
  582
+			return 0;
  583
+		if(st.st_mtime != img->st.st_mtime)
  584
+			return 0;
  585
+	}
  586
+	return 1;
  587
+}
  588
+
541 589
 #endif
18  src/compiler/compiler.h
@@ -25,6 +25,8 @@
25 25
 #include STANDALONE
26 26
 #endif /* STANDALONE */
27 27
 
  28
+#include <sys/stat.h>
  29
+
28 30
 #include <fpvm/fpvm.h>
29 31
 
30 32
 #include "../renderer/framedescriptor.h"
@@ -217,9 +219,15 @@ enum {
217 219
 #define REQUIRE_MIDI	(1 << 2)
218 220
 #define REQUIRE_VIDEO	(1 << 3)
219 221
 
  222
+struct image {
  223
+	struct pixbuf *pixbuf;	/* NULL if unused */
  224
+	const char *filename;	/* undefined if unused */
  225
+	struct stat st;
  226
+};
  227
+
220 228
 struct patch {
221 229
 	/* per-frame */
222  
-	struct pixbuf *images[IMAGE_COUNT];		/* < images used in this patch */
  230
+	struct image images[IMAGE_COUNT];		/* < images used in this patch */
223 231
 	float pfv_initial[COMP_PFV_COUNT]; 		/* < patch initial conditions */
224 232
 	int pfv_allocation[COMP_PFV_COUNT];		/* < where per-frame variables are mapped in PFPU regf, -1 if unmapped */
225 233
 	int perframe_prog_length;			/* < how many instructions in perframe_prog */
@@ -233,14 +241,22 @@ struct patch {
233 241
 	/* meta */
234 242
 	unsigned int require;				/* < bitmask: dmx, osc, midi, video */
235 243
 	void *original;					/* < original patch (with initial register values) */
  244
+	int ref;					/* reference count */
236 245
 	struct patch *next;				/* < used when chaining patches in mashups */
237 246
 };
238 247
 
239 248
 typedef void (*report_message)(const char *);
240 249
 
  250
+static inline struct patch *patch_clone(struct patch *p)
  251
+{
  252
+	p->ref++;
  253
+	return p;
  254
+}
  255
+
241 256
 struct patch *patch_compile(const char *basedir, const char *patch_code, report_message rmc);
242 257
 struct patch *patch_compile_filename(const char *filename, const char *patch_code, report_message rmc);
243 258
 struct patch *patch_copy(struct patch *p);
244 259
 void patch_free(struct patch *p);
  260
+int patch_images_uptodate(const struct patch *p);
245 261
 
246 262
 #endif /* __COMPILER_H */
4  src/compiler/parser.y
@@ -293,14 +293,12 @@ assignment ::= TOK_IMAGEFILE(I) TOK_ASSIGN TOK_FNAME(N). {
293 293
 
294 294
 	msg = state->comm->assign_image_name(state->comm,
295 295
 	    atoi(I->label+9), N->fname);
296  
-	free(I);
297 296
 	if(msg) {
298 297
 		FAIL(msg);
299 298
 		free((void *) msg);
300  
-		free((void *) N->fname);
301  
-		free(N);
302 299
 		return;
303 300
 	}
  301
+	free(I);
304 302
 	free((void *) N->fname);
305 303
 	free(N);
306 304
 }
18  src/compiler/test/image
@@ -66,4 +66,22 @@ expect <<EOF
66 66
 image 1 = "*** test  -  robust & ness ***"
67 67
 EOF
68 68
 
  69
+#------------------------------------------------------------------------------
  70
+
  71
+ptest_fail "image: imagefile0=foo" -c <<EOF
  72
+imagefile0=foo
  73
+EOF
  74
+expect <<EOF
  75
+line 2: can initialize non-system variables only to zero near 'EOF'
  76
+EOF
  77
+
  78
+#------------------------------------------------------------------------------
  79
+
  80
+ptest_fail "image: imagefile3=foo" -c <<EOF
  81
+imagefile3=foo
  82
+EOF
  83
+expect <<EOF
  84
+line 2: image number out of bounds near 'EOF'
  85
+EOF
  86
+
69 87
 ###############################################################################
236  src/gui/performance.c
@@ -41,41 +41,54 @@
41 41
 
42 42
 #define FILENAME_LEN 384
43 43
 
44  
-#define MAX_PATCHES 64
45  
-
46 44
 struct patch_info {
47 45
 	char filename[FILENAME_LEN];
48 46
 	struct patch *p;
  47
+	struct stat st;
  48
+	struct patch_info *prev, *next;
49 49
 };
50 50
 
51 51
 static int npatches;
52  
-static struct patch_info patches[MAX_PATCHES];
  52
+static struct patch_info *patches = NULL;
  53
+static struct patch_info *cache = NULL;
  54
+static struct patch_info *last_patch = NULL;
53 55
 static int simple_mode;
54  
-static int simple_mode_current;
  56
+static struct patch_info *simple_mode_current;
55 57
 static int dt_mode;
56 58
 static int as_mode;
57 59
 static int input_video;
58 60
 static int showing_title;
59 61
 
60  
-static int add_patch(const char *filename)
  62
+static struct patch_info *add_patch(const char *filename)
61 63
 {
62  
-	int i;
  64
+	struct patch_info *pi;
63 65
 
64  
-	for(i=0;i<npatches;i++) {
65  
-		if(strcmp(patches[i].filename, filename) == 0)
66  
-			return i;
67  
-	}
68  
-	if(npatches == MAX_PATCHES) return -1;
69  
-	strcpy(patches[npatches].filename, filename);
70  
-	patches[npatches].p = NULL;
71  
-	return npatches++;
72  
-}
  66
+	for(pi = patches; pi; pi = pi->next)
  67
+		if(strcmp(pi->filename, filename) == 0)
  68
+			return pi;
73 69
 
74  
-static int keyboard_patches[26];
75  
-static int ir_patches[64];
  70
+	pi = malloc(sizeof(struct patch_info));
  71
+	if(!pi)
  72
+		return NULL;
  73
+	strcpy(pi->filename, filename);
  74
+	pi->p = NULL;
  75
+	if(last_patch)
  76
+		last_patch->next = pi;
  77
+	else
  78
+		patches = pi;
  79
+	pi->next = NULL;
  80
+	pi->prev = last_patch;
  81
+	last_patch = pi;
  82
+	npatches++;
  83
+
  84
+	return pi;
  85
+}
  86
+
  87
+static struct patch_info *keyboard_patches[26];
  88
+static struct patch_info *ir_patches[64];
76 89
 static int midi_channel;
77  
-static int midi_patches[128];
78  
-static int osc_patches[64];
  90
+static struct patch_info *midi_patches[128];
  91
+static struct patch_info *osc_patches[64];
79 92
 
80 93
 static void add_firstpatch(void)
81 94
 {
@@ -100,7 +113,7 @@ static void add_keyboard_patches(void)
100 113
 		if(filename != NULL)
101 114
 			keyboard_patches[i] = add_patch(filename);
102 115
 		else
103  
-			keyboard_patches[i] = -1;
  116
+			keyboard_patches[i] = NULL;
104 117
 	}
105 118
 }
106 119
 
@@ -116,7 +129,7 @@ static void add_ir_patches(void)
116 129
 		if(filename != NULL)
117 130
 			ir_patches[i] = add_patch(filename);
118 131
 		else
119  
-			ir_patches[i] = -1;
  132
+			ir_patches[i] = NULL;
120 133
 	}
121 134
 }
122 135
 
@@ -133,7 +146,7 @@ static void add_midi_patches(void)
133 146
 		if(filename != NULL)
134 147
 			midi_patches[i] = add_patch(filename);
135 148
 		else
136  
-			midi_patches[i] = -1;
  149
+			midi_patches[i] = NULL;
137 150
 	}
138 151
 }
139 152
 
@@ -149,7 +162,7 @@ static void add_osc_patches(void)
149 162
 		if(filename != NULL)
150 163
 			osc_patches[i] = add_patch(filename);
151 164
 		else
152  
-			osc_patches[i] = -1;
  165
+			osc_patches[i] = NULL;
153 166
 	}
154 167
 }
155 168
 
@@ -189,10 +202,14 @@ static void close_callback(mtk_event *e, void *arg)
189 202
 
190 203
 static void update_buttons(void)
191 204
 {
192  
-	mtk_cmdf(appid, "b_mode_simple.set(-state %s)", simple_mode ? "on" : "off");
193  
-	mtk_cmdf(appid, "b_mode_file.set(-state %s)", !simple_mode ? "on" : "off");
194  
-	mtk_cmdf(appid, "b_mode_simple_dt.set(-state %s)", dt_mode ? "on" : "off");
195  
-	mtk_cmdf(appid, "b_mode_simple_as.set(-state %s)", as_mode ? "on" : "off");
  205
+	mtk_cmdf(appid, "b_mode_simple.set(-state %s)",
  206
+	    simple_mode ? "on" : "off");
  207
+	mtk_cmdf(appid, "b_mode_file.set(-state %s)",
  208
+	    !simple_mode ? "on" : "off");
  209
+	mtk_cmdf(appid, "b_mode_simple_dt.set(-state %s)",
  210
+	    dt_mode ? "on" : "off");
  211
+	mtk_cmdf(appid, "b_mode_simple_as.set(-state %s)",
  212
+	    as_mode ? "on" : "off");
196 213
 }
197 214
 
198 215
 static void simple_callback(mtk_event *e, void *arg)
@@ -277,6 +294,7 @@ void init_performance(void)
277 294
 }
278 295
 
279 296
 static int compiled_patches;
  297
+struct patch_info *error_patch;
280 298
 #define UPDATE_PERIOD 20
281 299
 static rtems_interval next_update;
282 300
 
@@ -284,10 +302,9 @@ static void dummy_rmc(const char *msg)
284 302
 {
285 303
 }
286 304
 
287  
-static struct patch *compile_patch(const char *filename)
  305
+static struct patch *compile_patch(const char *filename, const struct stat *st)
288 306
 {
289 307
 	FILE *file;
290  
-	struct stat st;
291 308
 	int r;
292 309
 	char *buf = NULL;
293 310
 	struct patch *p;
@@ -295,44 +312,65 @@ static struct patch *compile_patch(const char *filename)
295 312
 	file = fopen(filename, "r");
296 313
 	if(file == NULL)
297 314
 		return NULL;
298  
-	if(fstat(fileno(file), &st) < 0)
299  
-		goto fail;
300  
-	buf = malloc(st.st_size+1);
301  
-	r = fread(buf, 1, st.st_size, file);
302  
-	if(r <= 0)
303  
-		goto fail;
  315
+	buf = malloc(st->st_size+1);
  316
+	r = fread(buf, 1, st->st_size, file);
  317
+	if(r <= 0) {
  318
+		free(buf);
  319
+		fclose(file);
  320
+		return NULL;
  321
+	}
  322
+
304 323
 	buf[r] = 0;
305 324
 	fclose(file);
306 325
 
307 326
 	p = patch_compile_filename(filename, buf, dummy_rmc);
308 327
 	free(buf);
309 328
 	return p;
  329
+}
310 330
 
311  
-fail:
312  
-	free(buf);
313  
-	fclose(file);
  331
+static struct patch *cache_lookup(const struct patch_info *pi)
  332
+{
  333
+	const struct patch_info *c;
  334
+
  335
+	for(c = cache; c; c = c->next)
  336
+		if(c->st.st_mtime == pi->st.st_mtime &&
  337
+		    !strcmp(c->filename, pi->filename) &&
  338
+		    patch_images_uptodate(c->p))
  339
+			return patch_clone(c->p);
314 340
 	return NULL;
315 341
 }
316 342
 
317 343
 static rtems_task comp_task(rtems_task_argument argument)
318 344
 {
319  
-	for(;compiled_patches<npatches;compiled_patches++) {
320  
-		patches[compiled_patches].p = compile_patch(patches[compiled_patches].filename);
321  
-		if(patches[compiled_patches].p == NULL) {
322  
-			compiled_patches = -compiled_patches-1;
  345
+	struct patch_info *pi;
  346
+
  347
+	for(pi = patches; pi; pi = pi->next) {
  348
+		if(lstat(pi->filename, &pi->st) < 0) {
  349
+			pi->p = NULL;
  350
+		} else {
  351
+			pi->p = cache_lookup(pi);
  352
+			if(!pi->p)
  353
+				pi->p = compile_patch(pi->filename, &pi->st);
  354
+		}
  355
+		if(!pi->p) {
  356
+			error_patch = pi;
323 357
 			break;
324 358
 		}
  359
+		compiled_patches++;
325 360
 	}
326 361
 	rtems_task_delete(RTEMS_SELF);
327 362
 }
328 363
 
329  
-static void free_patches(void)
  364
+static void free_patches(struct patch_info *list)
330 365
 {
331  
-	int i;
  366
+	struct patch_info *next;
332 367
 
333  
-	for(i=0;i<npatches;i++) {
334  
-		if(patches[i].p != NULL)
335  
-			patch_free(patches[i].p);
  368
+	while(list) {
  369
+		next = list->next;
  370
+		if(list->p)
  371
+			patch_free(list->p);
  372
+		free(list);
  373
+		list = next;
336 374
 	}
337 375
 }
338 376
 
@@ -378,7 +416,8 @@ static void update_next_as_time(void)
378 416
 	rtems_interval t;
379 417
 	
380 418
 	t = rtems_clock_get_ticks_since_boot();
381  
-	next_as_time = t + AUTOSWITCH_PERIOD_MIN + (rand() % (AUTOSWITCH_PERIOD_MAX - AUTOSWITCH_PERIOD_MIN));
  419
+	next_as_time = t + AUTOSWITCH_PERIOD_MIN +
  420
+	    (rand() % (AUTOSWITCH_PERIOD_MAX - AUTOSWITCH_PERIOD_MIN));
382 421
 }
383 422
 
384 423
 static int suitable_for_simple(struct patch *p)
@@ -395,16 +434,21 @@ static int suitable_for_simple(struct patch *p)
395 434
 
396 435
 static void skip_unsuitable(int next)
397 436
 {
398  
-	int looped;
  437
+	const struct patch_info *looped;
399 438
 
400 439
 	looped = simple_mode_current;
401 440
 	while(1) {
402  
-		simple_mode_current += next;
403  
-		if(simple_mode_current == npatches)
404  
-			simple_mode_current = 0;
405  
-		if(simple_mode_current < 0)
406  
-			simple_mode_current = npatches - 1;
407  
-		if(suitable_for_simple(patches[simple_mode_current].p))
  441
+		if(next == 1) {
  442
+			simple_mode_current = simple_mode_current->next;
  443
+			if(!simple_mode_current)
  444
+				simple_mode_current = patches;
  445
+		}
  446
+		if(next == -1) {
  447
+			simple_mode_current = simple_mode_current->prev;
  448
+			if(!simple_mode_current)
  449
+				simple_mode_current = last_patch;
  450
+		}
  451
+		if(suitable_for_simple(simple_mode_current->p))
408 452
 			break;
409 453
 		if(!next) {
410 454
 			next = 1;
@@ -425,7 +469,7 @@ static void simple_mode_event(mtk_event *e, int *next)
425 469
 	if(e->type != EVENT_TYPE_PRESS)
426 470
 		return;
427 471
 	if(e->press.code == MTK_KEY_F1) {
428  
-		osd_event_cb(patches[simple_mode_current].filename, osd_off);
  472
+		osd_event_cb(simple_mode_current->filename, osd_off);
429 473
 		showing_title = 1;
430 474
 	}
431 475
 	if(e->press.code == MTK_KEY_F11)
@@ -437,55 +481,56 @@ static void simple_mode_event(mtk_event *e, int *next)
437 481
 static void simple_mode_next(int next)
438 482
 {
439 483
 	skip_unsuitable(next);
440  
-	renderer_pulse_patch(patches[simple_mode_current].p);
  484
+	renderer_pulse_patch(simple_mode_current->p);
441 485
 	if(as_mode)
442 486
 		update_next_as_time();
443 487
 	if(dt_mode || showing_title)
444  
-		osd_event_cb(patches[simple_mode_current].filename, osd_off);
  488
+		osd_event_cb(simple_mode_current->filename, osd_off);
445 489
 }
446 490
 
447 491
 static void configured_mode_event(mtk_event *e)
448 492
 {
  493
+	struct patch_info *pi;
449 494
 	int index;
450 495
 
451 496
 	if(e->type == EVENT_TYPE_PRESS) {
452 497
 		index = keycode_to_index(e->press.code);
453 498
 		if(index != -1) {
454  
-			index = keyboard_patches[index];
455  
-			if(index != -1)
456  
-				renderer_add_patch(patches[index].p);
457  
-				}
  499
+			pi = keyboard_patches[index];
  500
+			if(pi)
  501
+				renderer_add_patch(pi->p);
  502
+		}
458 503
 	} else if(e->type == EVENT_TYPE_RELEASE) {
459 504
 		index = keycode_to_index(e->release.code);
460 505
 		if(index != -1) {
461  
-			index = keyboard_patches[index];
462  
-			if(index != -1)
463  
-				renderer_del_patch(patches[index].p);
  506
+			pi = keyboard_patches[index];
  507
+			if(pi)
  508
+				renderer_del_patch(pi->p);
464 509
 		}
465 510
 	} else if(e->type == EVENT_TYPE_IR) {
466 511
 		index = e->press.code;
467  
-		index = ir_patches[index];
468  
-		if(index != -1)
469  
-			renderer_pulse_patch(patches[index].p);
  512
+		pi = ir_patches[index];
  513
+		if(pi)
  514
+			renderer_pulse_patch(pi->p);
470 515
 	} else if(e->type == EVENT_TYPE_MIDI_NOTEON) {
471 516
 		if(((e->press.code & 0x0f0000) >> 16) == midi_channel) {
472 517
 			index = e->press.code & 0x7f;
473  
-			index = midi_patches[index];
474  
-			if(index != -1)
475  
-				renderer_add_patch(patches[index].p);
  518
+			pi = midi_patches[index];
  519
+			if(pi)
  520
+				renderer_add_patch(pi->p);
476 521
 		}
477 522
 	} else if(e->type == EVENT_TYPE_MIDI_NOTEOFF) {
478 523
 		if(((e->press.code & 0x0f0000) >> 16) == midi_channel) {
479 524
 			index = e->press.code & 0x7f;
480  
-			index = midi_patches[index];
481  
-			if(index != -1)
482  
-				renderer_del_patch(patches[index].p);
  525
+			pi = midi_patches[index];
  526
+			if(pi)
  527
+				renderer_del_patch(pi->p);
483 528
 		}
484 529
 	} else if(e->type == EVENT_TYPE_OSC) {
485 530
 		index = e->press.code & 0x3f;
486  
-		index = osc_patches[index];
487  
-		if(index != -1)
488  
-			renderer_pulse_patch(patches[index].p);
  531
+		pi = osc_patches[index];
  532
+		if(pi)
  533
+			renderer_pulse_patch(pi->p);
489 534
 	}
490 535
 }
491 536
 
@@ -500,8 +545,8 @@ static void event_callback(mtk_event *e, int count)
500 545
 		 * We can can't show the first title in start_rendering
501 546
 		 * because the renderer isn't up yet. So we do it here.
502 547
 		 */
503  
-		if (first_event && dt_mode)
504  
-			osd_event(patches[simple_mode_current].filename);
  548
+		if(first_event && dt_mode)
  549
+			osd_event(simple_mode_current->filename);
505 550
 		next = 0;
506 551
 		for(i=0;i<count;i++)
507 552
 			simple_mode_event(e+i, &next);
@@ -521,14 +566,18 @@ static void event_callback(mtk_event *e, int count)
521 566
 
522 567
 static void stop_callback(void)
523 568
 {
524  
-	free_patches();
  569
+	free_patches(cache);
  570
+	cache = patches;
  571
+	patches = NULL;
  572
+	last_patch = NULL;
  573
+
525 574
 	started = 0;
526 575
 	input_delete_callback(event_callback);
527 576
 }
528 577
 
529 578
 static void start_rendering(void)
530 579
 {
531  
-	int index = 0;
  580
+	struct patch_info *first = patches;
532 581
 
533 582
 	update_next_as_time();
534 583
 	input_add_callback(event_callback);
@@ -536,11 +585,11 @@ static void start_rendering(void)
536 585
 				
537 586
 	if(simple_mode) {
538 587
 		skip_unsuitable(0);
539  
-		index = simple_mode_current;
  588
+		first = simple_mode_current;
540 589
 	}
541 590
 
542 591
 	first_event = 1;
543  
-	if(!guirender(appid, patches[index].p, stop_callback))
  592
+	if(!guirender(appid, first->p, stop_callback))
544 593
 		stop_callback();
545 594
 }
546 595
 
@@ -551,7 +600,7 @@ static void refresh_callback(mtk_event *e, int count)
551 600
 	t = rtems_clock_get_ticks_since_boot();
552 601
 	if(t < next_update)
553 602
 		return;
554  
-	if(compiled_patches >= 0) {
  603
+	if(!error_patch) {
555 604
 		mtk_cmdf(appid, "progress.barconfig(load, -value %d)",
556 605
 		    (100*compiled_patches)/npatches);
557 606
 		if(compiled_patches == npatches) {
@@ -561,15 +610,14 @@ static void refresh_callback(mtk_event *e, int count)
561 610
 			return;
562 611
 		}
563 612
 	} else {
564  
-		int error_patch;
565  
-
566  
-		error_patch = -compiled_patches-1;
567 613
 		mtk_cmdf(appid,
568 614
 		    "l_status.set(-text \"Failed to compile patch %s\")",
569  
-		    patches[error_patch].filename);
  615
+		    error_patch->filename);
570 616
 		input_delete_callback(refresh_callback);
571 617
 		started = 0;
572  
-		free_patches();
  618
+		free_patches(patches);
  619
+		patches = NULL;
  620
+		last_patch = NULL;
573 621
 		fb_unblank();
574 622
 		return;
575 623
 	}
@@ -615,7 +663,6 @@ void start_performance(int simple, int dt, int as)
615 663
 
616 664
 	/* build patch list */
617 665
 	npatches = 0;
618  
-	simple_mode_current = 0;
619 666
 	if(simple) {
620 667
 		input_video = check_input_video();
621 668
 		add_simple_patches();
@@ -638,16 +685,19 @@ void start_performance(int simple, int dt, int as)
638 685
 		add_midi_patches();
639 686
 		add_osc_patches();
640 687
 	}
  688
+	simple_mode_current = patches;
641 689
 
642 690
 	/* start patch compilation task */
643 691
 	compiled_patches = 0;
  692
+	error_patch = NULL;
644 693
 	mtk_cmd(appid, "l_status.set(-text \"Compiling patches...\")");
645 694
 	mtk_cmd(appid, "progress.barconfig(load, -value 0)");
646 695
 	next_update = rtems_clock_get_ticks_since_boot() + UPDATE_PERIOD;
647 696
 	input_add_callback(refresh_callback);
648  
-	sc = rtems_task_create(rtems_build_name('C', 'O', 'M', 'P'), 20, 300*1024,
649  
-		RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR,
650  
-		0, &comp_task_id);
  697
+	sc = rtems_task_create(rtems_build_name('C', 'O', 'M', 'P'),
  698
+	    20, 300*1024,
  699
+	    RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR,
  700
+	    0, &comp_task_id);
651 701
 	assert(sc == RTEMS_SUCCESSFUL);
652 702
 	sc = rtems_task_start(comp_task_id, comp_task, 0);
653 703
 	assert(sc == RTEMS_SUCCESSFUL);
2  src/renderer/eval.c
@@ -312,7 +312,7 @@ static rtems_task eval_task(rtems_task_argument argument)
312 312
 		 * will be valid until the renderer has fully stopped.
313 313
 		 */
314 314
 		for(i=0;i<IMAGE_COUNT;i++)
315  
-			frd->images[i] = p->images[i];
  315
+			frd->images[i] = p->images[i].pixbuf;
316 316
 		
317 317
 		reinit_all_pfv(p);
318 318
 		set_pfv_from_frd(p, frd);

No commit comments for this range

Something went wrong with that request. Please try again.