@@ 36,6 36,12 @@ struct context {
int width;
int height;
+ bool dirty;
+ bool pending;
+
+ double val;
+ double peak;
+
struct wl_egl_window *wl_egl_window;
EGLConfig egl_config;
EGLContext egl_context;
@@ 198,7 204,29 @@ static void draw_vert(double val) {
glVertex2f(-1, 2*val-1);
}
-static int draw(struct context *ctx, double val, double peak) {
+static int draw(struct context *ctx);
+static void frame_handle_done(void *data, struct wl_callback *callback,
+ uint32_t time) {
+ (void)time;
+ wl_callback_destroy(callback);
+ struct context *ctx = data;
+ ctx->pending = false;
+ draw(ctx);
+}
+
+const struct wl_callback_listener frame_listener = {
+ .done = frame_handle_done,
+};
+
+static int draw(struct context *ctx) {
+ if (ctx->pending) {
+ return 0;
+ }
+ if (!ctx->dirty) {
+ return 0;
+ }
+ ctx->dirty = false;
+
glClear(GL_COLOR_BUFFER_BIT);
void (*draw_bar)(double val);
@@ 208,20 236,24 @@ static int draw(struct context *ctx, double val, double peak) {
draw_bar = draw_horiz;
}
- if (peak > 0.9) {
+ if (ctx->peak > 0.9) {
glColor3f(.5, 0.0, 0.0);
} else {
glColor3f(0.25, .25, 0.25);
}
glBegin(GL_POLYGON);
- draw_bar(peak);
+ draw_bar(ctx->peak);
glEnd();
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POLYGON);
- draw_bar(val);
+ draw_bar(ctx->val);
glEnd();
+ ctx->pending = true;
+ struct wl_callback *callback = wl_surface_frame(ctx->surface);
+ wl_callback_add_listener(callback, &frame_listener, ctx);
+
if (!eglSwapBuffers(ctx->egl_display, ctx->egl_surface)) {
fprintf(stderr, "eglSwapBuffers failed\n");
return -1;
@@ 231,7 263,7 @@ static int draw(struct context *ctx, double val, double peak) {
}
#define PEAK_DURATION 20
-#define HYSTERESIS 0.001
+#define HYSTERESIS 0.0005
static int max_s16(void *buffer, int frames, int channels) {
int max = 0;
@@ 420,6 452,9 @@ int main(int argc, char **argv) {
.height = bar_width,
.width = 1024,
.running = true,
+ .val = 0.0,
+ .peak = 0.0,
+ .dirty = true,
};
void *buffer = NULL;
@@ 532,7 567,6 @@ int main(int argc, char **argv) {
eglSwapInterval(ctx.egl_display, 0);
-
int polln = snd_pcm_poll_descriptors_count(handle_capture) + 1;
struct pollfd *pfd = calloc(polln, sizeof(struct pollfd));
if (pfd == NULL) {
@@ 544,7 578,7 @@ int main(int argc, char **argv) {
// For some reason we must read at least once
snd_pcm_readi(handle_capture, buffer, frame_capacity);
- draw(&ctx, 0.0, 0.0);
+ draw(&ctx);
double peak;
int peak_timer = 0;
@@ 580,7 614,13 @@ int main(int argc, char **argv) {
peak_timer--;
}
- draw(&ctx, val, peak);
+ if (val < ctx.val - HYSTERESIS || val > ctx.val + HYSTERESIS ||
+ peak < ctx.peak - HYSTERESIS || peak > ctx.peak + HYSTERESIS) {
+ ctx.dirty = true;
+ ctx.val = val;
+ ctx.peak = peak;
+ draw(&ctx);
+ }
}
snd_pcm_close(handle_capture);