Skip to content

Commit

Permalink
fix line masking for esp32
Browse files Browse the repository at this point in the history
  • Loading branch information
vroland committed Sep 4, 2024
1 parent 196ba57 commit e884db8
Show file tree
Hide file tree
Showing 11 changed files with 43 additions and 49 deletions.
4 changes: 1 addition & 3 deletions examples/fb_mode_test/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ void test_8ppB() {
uint8_t* line_address = framebuffer + (line_bytes * (start_line + line));
memset(line_address + black_start_column / 8, 0, 32);
}

// update the display. In the first update, white pixels are no-opps,
// in the second update, black pixels are no-ops.
epd_poweron();
Expand All @@ -127,7 +127,6 @@ void test_8ppB() {
// draw white triangles on the black background
draw_8bpp_triangles(start_line, black_start_column + 16);


epd_poweron();
mode = MODE_PACKING_8PPB | MODE_DU | PREVIOUSLY_BLACK;
checkError(epd_draw_base(area, framebuffer, area, mode, 25, NULL, NULL, &epdiy_ED047TC2));
Expand Down Expand Up @@ -167,7 +166,6 @@ void test_2ppB() {
// draw white triangles on the black background
draw_2bpp_triangles(start_line, black_start_column + 16, 255);


epd_poweron();
mode = MODE_PACKING_2PPB | MODE_DU | PREVIOUSLY_BLACK;
checkError(
Expand Down
23 changes: 1 addition & 22 deletions src/output_common/line_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ static inline int ceil_div(int x, int y) {
}

/// Initialize the line queue and allocate memory.
LineQueue_t lq_init(int queue_len, int element_size, bool use_mask) {
LineQueue_t lq_init(int queue_len, int element_size) {
LineQueue_t queue;
queue.element_size = element_size;
queue.size = queue_len;
Expand All @@ -30,16 +30,6 @@ LineQueue_t lq_init(int queue_len, int element_size, bool use_mask) {
assert(queue.bufs[i] != NULL);
}

if (use_mask) {
queue.mask_buffer_len = elem_buf_size;
queue.mask_buffer
= heap_caps_aligned_alloc(16, elem_buf_size, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
assert(queue.mask_buffer != NULL);
} else {
queue.mask_buffer_len = 0;
queue.mask_buffer = NULL;
}

return queue;
}

Expand All @@ -49,9 +39,6 @@ void lq_free(LineQueue_t* queue) {
heap_caps_free(queue->bufs[i]);
}

if (queue->mask_buffer != NULL) {
heap_caps_free(queue->mask_buffer);
}
free(queue->bufs);
}

Expand All @@ -67,14 +54,6 @@ uint8_t* IRAM_ATTR lq_current(LineQueue_t* queue) {

void IRAM_ATTR lq_commit(LineQueue_t* queue) {
int current = atomic_load_explicit(&queue->current, memory_order_acquire);
#ifdef RENDER_METHOD_LCD
void epd_apply_line_mask_VE(uint8_t * line, const uint8_t* mask, int mask_len);
epd_apply_line_mask_VE(queue->bufs[current], queue->mask_buffer, queue->mask_buffer_len);
#else
for (int i = 0; i < queue->mask_buffer_len / 4; i++) {
((uint32_t*)(queue->bufs[current]))[i] &= ((uint32_t*)(queue->mask_buffer))[i];
}
#endif

if (current == queue->size - 1) {
queue->current = 0;
Expand Down
7 changes: 1 addition & 6 deletions src/output_common/line_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,10 @@ typedef struct {
uint8_t** bufs;
// size of an element
size_t element_size;
// size of the mask buffer
size_t mask_buffer_len;
// mask to appyl to the output buffer, NULL if none.
// mut be elem_buf_size long.
uint8_t* mask_buffer;
} LineQueue_t;

/// Initialize the line queue and allocate memory.
LineQueue_t lq_init(int queue_len, int element_size, bool use_mask);
LineQueue_t lq_init(int queue_len, int element_size);

/// Deinitialize the line queue and free memory.
void lq_free(LineQueue_t* queue);
Expand Down
7 changes: 7 additions & 0 deletions src/output_common/lut.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "lut.h"

#include "epdiy.h"
#include "esp_attr.h"
#include "render_context.h"
#include "render_method.h"

Expand Down Expand Up @@ -433,6 +434,12 @@ static void build_8ppB_lut_256b_from_black(
memcpy(lut, lut_8ppB_start_at_black, sizeof(lut_8ppB_start_at_black));
}

void IRAM_ATTR epd_apply_line_mask(uint8_t* buf, const uint8_t* mask, int len) {
for (int i = 0; i < len / 4; i++) {
((uint32_t*)buf)[i] &= ((uint32_t*)mask)[i];
}
}

LutFunctionPair find_lut_functions(enum EpdDrawMode mode, uint32_t lut_size) {
LutFunctionPair pair;
pair.build_func = NULL;
Expand Down
6 changes: 6 additions & 0 deletions src/output_common/lut.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ LutFunctionPair find_lut_functions(enum EpdDrawMode mode, uint32_t lut_size);
*/
void reorder_line_buffer(uint32_t* line_data, int buf_len);

/**
* Apply a mask to a line buffer.
* `len` must be divisible by 4.
*/
void epd_apply_line_mask(uint8_t* buf, const uint8_t* mask, int len);

// legacy functions
void bit_shift_buffer_right(uint8_t* buf, uint32_t len, int shift);
void nibble_shift_buffer_right(uint8_t* buf, uint32_t len);
4 changes: 4 additions & 0 deletions src/output_common/render_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <freertos/semphr.h>
#include <freertos/task.h>
#include <stdatomic.h>
#include <stdint.h>

#include "../epdiy.h"
#include "line_queue.h"
Expand Down Expand Up @@ -68,6 +69,9 @@ typedef struct {
LineQueue_t line_queues[NUM_RENDER_THREADS];
uint8_t* line_threads;

// Output line mask
uint8_t* line_mask;

/// track line skipping when working in old i2s mode
int skipping;
} RenderContext_t;
Expand Down
5 changes: 2 additions & 3 deletions src/output_i2s/i2s_data_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ static void IRAM_ATTR i2s_int_hdl(void* arg) {
dev->int_clr.val = dev->int_raw.val;
}

volatile uint8_t IRAM_ATTR* i2s_get_current_buffer() {
return (volatile uint8_t*)(current_buffer ? i2s_state.dma_desc_a->buf
: i2s_state.dma_desc_b->buf);
uint8_t* IRAM_ATTR i2s_get_current_buffer() {
return (uint8_t*)(current_buffer ? i2s_state.dma_desc_a->buf : i2s_state.dma_desc_b->buf);
}

bool IRAM_ATTR i2s_is_busy() {
Expand Down
2 changes: 1 addition & 1 deletion src/output_i2s/i2s_data_bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void i2s_gpio_detach(i2s_bus_config* cfg);
/**
* Get the currently writable line buffer.
*/
volatile uint8_t* i2s_get_current_buffer();
uint8_t* i2s_get_current_buffer();

/**
* Switches front and back line buffer.
Expand Down
5 changes: 5 additions & 0 deletions src/output_i2s/render_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,17 @@ void IRAM_ATTR i2s_output_frame(RenderContext_t* ctx, int thread_id) {
continue;
}

// lookup pixel actions in the waveform LUT
ctx->lut_lookup_func(
(uint32_t*)line_buf,
(uint8_t*)i2s_get_current_buffer(),
ctx->conversion_lut,
ctx->display_width
);

// apply the line mask
epd_apply_line_mask(i2s_get_current_buffer(), ctx->line_mask, ctx->display_width / 4);

reorder_line_buffer((uint32_t*)i2s_get_current_buffer(), ctx->display_width / 4);
i2s_write_row(ctx, frame_time);
}
Expand Down
4 changes: 4 additions & 0 deletions src/output_lcd/render_lcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ lcd_calculate_frame(RenderContext_t* ctx, int thread_id) {

ctx->lut_lookup_func(lp, buf, ctx->conversion_lut, ctx->display_width);

// apply the line mask
void epd_apply_line_mask_VE(uint8_t * line, const uint8_t* mask, int mask_len);
epd_apply_line_mask_VE(buf, ctx->line_mask, ctx->display_width / 4);

lq_commit(lq);
}
}
Expand Down
25 changes: 11 additions & 14 deletions src/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,10 @@ enum EpdDrawError IRAM_ATTR epd_draw_base(
if (waveform_phases != NULL && waveform_phases->phase_times != NULL) {
render_context.phase_times = waveform_phases->phase_times;
}

for (int i = 0; i < NUM_RENDER_THREADS; i++) {
LineQueue_t* queue = &render_context.line_queues[i];
_epd_populate_line_mask(queue->mask_buffer, drawn_columns, queue->mask_buffer_len);


for (int i = 0; i < queue->mask_buffer_len / 4; i++) {
printf("%X\n", ((uint32_t*)(queue->mask_buffer))[i]);
}
}

_epd_populate_line_mask(
render_context.line_mask, drawn_columns, render_context.display_width / 4
);

#ifdef RENDER_METHOD_I2S
i2s_do_update(&render_context);
Expand Down Expand Up @@ -326,16 +320,18 @@ void epd_renderer_init(enum EpdInitOptions options) {
abort();
}

render_context.line_mask
= heap_caps_aligned_alloc(16, epd_width() / 4, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
assert(render_context.line_mask != NULL);

#ifdef RENDER_METHOD_LCD
bool use_lq_mask = true;
size_t queue_elem_size = render_context.display_width / 4;
#elif defined(RENDER_METHOD_I2S)
bool use_lq_mask = false;
size_t queue_elem_size = epd_width();
size_t queue_elem_size = render_context.display_width;
#endif

for (int i = 0; i < NUM_RENDER_THREADS; i++) {
render_context.line_queues[i] = lq_init(queue_len, queue_elem_size, use_lq_mask);
render_context.line_queues[i] = lq_init(queue_len, queue_elem_size);
render_context.feed_line_buffers[i] = (uint8_t*)heap_caps_malloc(
render_context.display_width, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL
);
Expand Down Expand Up @@ -376,6 +372,7 @@ void epd_renderer_deinit() {

heap_caps_free(render_context.conversion_lut);
heap_caps_free(render_context.line_threads);
heap_caps_free(render_context.line_mask);
vSemaphoreDelete(render_context.frame_done);
}

Expand Down

0 comments on commit e884db8

Please sign in to comment.