Skip to content

Commit 36fd637

Browse files
committed
Improve idle performance and other enhancements
- Add dirty flag to only render after draw commands - Modify oscilloscope draw command to suppress empty redraws - Add ability to make a debug build from the command line - Slightly optimize byte copies to SLIP parser
1 parent 8ed6e05 commit 36fd637

File tree

3 files changed

+61
-32
lines changed

3 files changed

+61
-32
lines changed

Makefile

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ INCLUDES = $(shell pkg-config --libs sdl2 libserialport)
1010

1111

1212
#Set any compiler flags you want to use (e.g. -I/usr/include/somefolder `pkg-config --cflags gtk+-3.0` ), or leave blank
13-
CFLAGS = $(shell pkg-config --cflags sdl2 libserialport) -Wall -O2 -pipe -I.
13+
local_CFLAGS = $(CFLAGS) $(shell pkg-config --cflags sdl2 libserialport) -Wall -O2 -pipe -I.
1414

1515
#Set the compiler you are using ( gcc for C or g++ for C++ )
1616
CC = gcc
@@ -20,12 +20,12 @@ EXTENSION = .c
2020

2121
#define a rule that applies to all files ending in the .o suffix, which says that the .o file depends upon the .c version of the file and all the .h files included in the DEPS macro. Compile each object file
2222
%.o: %$(EXTENSION) $(DEPS)
23-
$(CC) -c -o $@ $< $(CFLAGS)
23+
$(CC) -c -o $@ $< $(local_CFLAGS)
2424

2525
#Combine them into the output file
2626
#Set your desired exe output file name here
2727
m8c: $(OBJ)
28-
$(CC) -o $@ $^ $(CFLAGS) $(INCLUDES)
28+
$(CC) -o $@ $^ $(local_CFLAGS) $(INCLUDES)
2929

3030
font.c: inline_font.h
3131
@echo "#include <SDL.h>" > $@-tmp1
@@ -35,7 +35,7 @@ font.c: inline_font.h
3535
@rm $@-tmp2
3636
@mv $@-tmp1 $@
3737
@echo "[~cat] inline_font.h inprint2.c > font.c"
38-
# $(CC) -c -o font.o font.c $(CFLAGS)
38+
# $(CC) -c -o font.o font.c $(local_CFLAGS)
3939

4040
#Cleanup
4141
.PHONY: clean

main.c

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Copyright 2021 Jonne Kokkonen
22
// Released under the MIT licence, https://opensource.org/licenses/MIT
33

4+
// Uncomment this line to enable debug messages or call make with `make CFLAGS=-DDEBUG_MSG`
5+
// #define DEBUG_MSG
6+
47
#include <SDL.h>
58
#include <libserialport.h>
69
#include <signal.h>
@@ -64,6 +67,10 @@ int main(int argc, char *argv[]) {
6467
if (initialize_sdl(conf.init_fullscreen, conf.init_use_gpu) == -1)
6568
run = 0;
6669

70+
#ifdef DEBUG_MSG
71+
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
72+
#endif
73+
6774
uint8_t prev_input = 0;
6875

6976
// main loop
@@ -106,8 +113,6 @@ int main(int argc, char *argv[]) {
106113
}
107114
}
108115

109-
110-
int total_received_bytes = 0;
111116
while (1) {
112117
// read serial port
113118
int bytes_read = sp_blocking_read(port, serial_buf, serial_read_size, 1);
@@ -117,11 +122,11 @@ int main(int argc, char *argv[]) {
117122
run = 0;
118123
break;
119124
} else if (bytes_read > 0) {
120-
total_received_bytes += bytes_read;
121-
for (int i = 0; i < bytes_read; i++) {
122-
uint8_t rx = serial_buf[i];
125+
uint8_t *cur = serial_buf;
126+
const uint8_t *end = serial_buf+bytes_read;
127+
while (cur<end) {
123128
// process the incoming bytes into commands and draw them
124-
int n = slip_read_byte(&slip, rx);
129+
int n = slip_read_byte(&slip, *(cur++));
125130
if (n != SLIP_NO_ERROR) {
126131
if (n == SLIP_ERROR_INVALID_PACKET) {
127132
reset_display(port);
@@ -134,9 +139,7 @@ int main(int argc, char *argv[]) {
134139
break;
135140
}
136141
}
137-
if (total_received_bytes > 0) {
138-
render_screen();
139-
}
142+
render_screen();
140143
}
141144

142145
// exit, clean up

render.c

+45-19
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ static uint32_t ticks_fps;
2020
static int fps;
2121
uint8_t fullscreen = 0;
2222

23+
static uint8_t dirty = 0;
24+
2325
// Initializes SDL and creates a renderer and required surfaces
2426
int initialize_sdl(int init_fullscreen, int init_use_gpu) {
2527
ticks = SDL_GetTicks();
@@ -55,8 +57,7 @@ int initialize_sdl(int init_fullscreen, int init_use_gpu) {
5557

5658
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_INFO);
5759

58-
// Uncomment this for debug level logging
59-
// SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
60+
dirty = 1;
6061

6162
return 1;
6263
}
@@ -73,6 +74,8 @@ void toggle_fullscreen() {
7374

7475
SDL_SetWindowFullscreen(win, fullscreen_state ? 0 : SDL_WINDOW_FULLSCREEN);
7576
SDL_ShowCursor(fullscreen_state);
77+
78+
dirty = 1;
7679
}
7780

7881
int draw_character(struct draw_character_command *command) {
@@ -91,6 +94,8 @@ int draw_character(struct draw_character_command *command) {
9194
fgcolor, bgcolor);
9295
}
9396

97+
dirty = 1;
98+
9499
return 1;
95100
}
96101

@@ -115,31 +120,49 @@ void draw_rectangle(struct draw_rectangle_command *command) {
115120
SDL_SetRenderDrawColor(rend, command->color.r, command->color.g,
116121
command->color.b, 0xFF);
117122
SDL_RenderFillRect(rend, &render_rect);
123+
124+
dirty = 1;
118125
}
119126

120127
void draw_waveform(struct draw_oscilloscope_waveform_command *command) {
121128

122-
const SDL_Rect wf_rect = {0, 0, 320, 21};
129+
static uint8_t wfm_cleared = 0;
123130

124-
SDL_SetRenderDrawColor(rend, background_color.r, background_color.g,
125-
background_color.b, background_color.a);
126-
SDL_RenderFillRect(rend, &wf_rect);
131+
// If the waveform is not being displayed and it's already been cleared, skip rendering it
132+
if (! (wfm_cleared && command->waveform_size == 0)) {
127133

128-
SDL_SetRenderDrawColor(rend, command->color.r, command->color.g,
129-
command->color.b, 255);
134+
const SDL_Rect wf_rect = {0, 0, 320, 21};
130135

131-
// Create a SDL_Point array of the waveform pixels for batch drawing
132-
SDL_Point waveform_points[command->waveform_size];
136+
SDL_SetRenderDrawColor(rend, background_color.r, background_color.g,
137+
background_color.b, background_color.a);
138+
SDL_RenderFillRect(rend, &wf_rect);
133139

134-
for (int i = 0; i < command->waveform_size; i++) {
135-
// Limit value because the oscilloscope commands seem to glitch occasionally
136-
if (command->waveform[i] > 20)
137-
command->waveform[i] = 20;
138-
waveform_points[i].x = i;
139-
waveform_points[i].y = command->waveform[i];
140-
}
140+
SDL_SetRenderDrawColor(rend, command->color.r, command->color.g,
141+
command->color.b, 255);
141142

142-
SDL_RenderDrawPoints(rend, waveform_points, command->waveform_size);
143+
// Create a SDL_Point array of the waveform pixels for batch drawing
144+
SDL_Point waveform_points[command->waveform_size];
145+
146+
for (int i = 0; i < command->waveform_size; i++) {
147+
// Limit value because the oscilloscope commands seem to glitch occasionally
148+
if (command->waveform[i] > 20)
149+
command->waveform[i] = 20;
150+
waveform_points[i].x = i;
151+
waveform_points[i].y = command->waveform[i];
152+
}
153+
154+
SDL_RenderDrawPoints(rend, waveform_points, command->waveform_size);
155+
156+
// The packet we just drew was an empty waveform
157+
if (command->waveform_size == 0) {
158+
wfm_cleared = 1;
159+
}
160+
else {
161+
wfm_cleared = 0;
162+
}
163+
164+
dirty = 1;
165+
}
143166
}
144167

145168
void display_keyjazz_overlay(uint8_t show, uint8_t base_octave) {
@@ -175,10 +198,13 @@ void display_keyjazz_overlay(uint8_t show, uint8_t base_octave) {
175198

176199
draw_rectangle(&drc);
177200
}
201+
202+
dirty = 1;
178203
}
179204

180205
void render_screen() {
181-
if (SDL_GetTicks() - ticks > 14) {
206+
if (dirty && (SDL_GetTicks() - ticks > 14)) {
207+
dirty = 0;
182208
ticks = SDL_GetTicks();
183209
SDL_SetRenderTarget(rend, NULL);
184210
SDL_SetRenderDrawColor(rend, 0, 0, 0, 0);

0 commit comments

Comments
 (0)