Skip to content

Commit

Permalink
add diff and mask test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
vroland committed Mar 29, 2024
1 parent e292ec7 commit fac2a2b
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 9 deletions.
2 changes: 2 additions & 0 deletions examples/test/main/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <unity.h>
#include "unity_test_runner.h"

static void print_banner(const char* text)
{
Expand All @@ -11,6 +12,7 @@ void app_main(void)
{
print_banner("Running all the registered tests");
UNITY_BEGIN();
//unity_run_tests_by_tag("unit", false);
unity_run_all_tests();
UNITY_END();
}
Expand Down
7 changes: 7 additions & 0 deletions src/output_common/render_method.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@
#else
#error "unknown chip, cannot choose render method!"
#endif

#ifdef __clang__
#define IRAM_ATTR
// define this if we're using clangd to make it accept the GCC builtin
void __assert_func (const char* file, int line, const char* func,
const char* failedexpr);
#endif
3 changes: 2 additions & 1 deletion src/output_lcd/lcd_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ static void check_cache_configuration() {
ESP_LOGE(
"epdiy",
"cache line size is set to %d (< 64B)! This will degrade performance, please update "
"this option in menuconfig."
"this option in menuconfig.",
CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE
);
ESP_LOGE(
"epdiy",
Expand Down
14 changes: 8 additions & 6 deletions src/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,15 @@ static inline int rounded_display_height() {
/**
* Populate an output line mask from line dirtyness with one nibble per pixel.
* If the dirtyness data is NULL, set the mask to neutral.
*
* don't inline for to ensure availability in tests.
*/
static void populate_line_mask(uint8_t* line_mask, const uint8_t* dirty_columns, int mask_len) {
void __attribute__ ((noinline)) _epd_populate_line_mask(uint8_t* line_mask, const uint8_t* dirty_columns, int mask_len) {
if (dirty_columns == NULL) {
memset(line_mask, 0xFF, mask_len);
} else {
assert(epd_width() / 4 <= mask_len);
for (int c = 0; c < epd_width() / 2; c += 2) {
int pixels = mask_len * 4;
for (int c = 0; c < pixels / 2; c += 2) {
uint8_t mask = 0;
mask |= (dirty_columns[c + 1] & 0xF0) != 0 ? 0xC0 : 0x00;
mask |= (dirty_columns[c + 1] & 0x0F) != 0 ? 0x30 : 0x00;
Expand Down Expand Up @@ -191,7 +193,7 @@ enum EpdDrawError IRAM_ATTR epd_draw_base(
#elif defined(RENDER_METHOD_LCD)
for (int i = 0; i < NUM_RENDER_THREADS; i++) {
LineQueue_t* queue = &render_context.line_queues[i];
populate_line_mask(queue->mask_buffer, drawn_columns, queue->mask_buffer_len);
_epd_populate_line_mask(queue->mask_buffer, drawn_columns, queue->mask_buffer_len);
}

lcd_do_update(&render_context);
Expand Down Expand Up @@ -368,7 +370,7 @@ uint32_t epd_interlace_4bpp_line_VE(
* Interlaces the lines at `to`, `from` into `interlaced`.
* returns `1` if there are differences, `0` otherwise.
*/
static bool interlace_line(
bool _epd_interlace_line(
const uint8_t* to,
const uint8_t* from,
uint8_t* interlaced,
Expand Down Expand Up @@ -433,7 +435,7 @@ EpdRect epd_difference_image_base(

for (int y = crop_to.y; y < y_end; y++) {
uint32_t offset = y * fb_width / 2;
int dirty = interlace_line(
int dirty = _epd_interlace_line(
to + offset, from + offset, interlaced + offset * 2, col_dirtyness, fb_width
);
dirty_lines[y] = dirty;
Expand Down
75 changes: 75 additions & 0 deletions test/test_diff.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <esp_heap_caps.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <unity.h>


bool _epd_interlace_line(
const uint8_t* to,
const uint8_t* from,
uint8_t* interlaced,
uint8_t* col_dirtyness,
int fb_width
);

static const uint8_t from_pattern[8] = {0xFF, 0xF0, 0x0F, 0x01, 0x55, 0xAA, 0xFF, 0x80};
static const uint8_t to_pattern[8] = {0xFF, 0xFF, 0x0F, 0x10, 0xAA, 0x55, 0xFF, 0x00};

static const uint8_t expected_interlaced_pattern[16] = {
0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x00, 0x01, 0x10, 0xA5, 0xA5, 0x5A, 0x5A, 0xFF, 0xFF, 0x00, 0x08};
static const uint8_t expected_col_dirtyness_pattern[8] = {0x00, 0x0F, 0x00, 0x11,
0xFF, 0xFF, 0x00, 0x80};

TEST_CASE("line diff works", "[epdiy,unit]") {
int example_len = 176;
bool dirty;

uint8_t* from = heap_caps_aligned_alloc(16, example_len, MALLOC_CAP_DEFAULT);
uint8_t* to = heap_caps_aligned_alloc(16, example_len, MALLOC_CAP_DEFAULT);
uint8_t* interlaced = heap_caps_aligned_alloc(16, 2 * example_len, MALLOC_CAP_DEFAULT);
uint8_t* col_dirtyness = heap_caps_aligned_alloc(16, example_len, MALLOC_CAP_DEFAULT);
uint8_t* expected_interlaced = malloc(2 * example_len);
uint8_t* expected_col_dirtyness = malloc(example_len);

for (int i = 0; i < example_len / 8; i++) {
memcpy(from + (8 * i), from_pattern, 8);
memcpy(to + (8 * i), to_pattern, 8);
memcpy(expected_interlaced + (16 * i), expected_interlaced_pattern, 16);
memcpy(expected_col_dirtyness + (8 * i), expected_col_dirtyness_pattern, 8);
}
memset(col_dirtyness, 0, example_len);

// This should trigger use of vector extensions on the S3
TEST_ASSERT((uint32_t)to % 16 == 0)

// fully aligned
dirty = _epd_interlace_line(to, from, interlaced, col_dirtyness, 2 * example_len);

TEST_ASSERT(dirty == true);
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_col_dirtyness, col_dirtyness, example_len);
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_interlaced, interlaced, 2 * example_len);

// force an unaligned line end
dirty = _epd_interlace_line(to, from, interlaced, col_dirtyness, 2 * (example_len - 8));

TEST_ASSERT(dirty == true);
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_col_dirtyness, col_dirtyness, example_len - 8);
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_interlaced, interlaced, 2 * (example_len - 8));

// force an unaligned line start
dirty = _epd_interlace_line(
to + 8, from + 8, interlaced + 16, col_dirtyness + 8, 2 * (example_len - 8)
);

TEST_ASSERT(dirty == true);
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_col_dirtyness + 8, col_dirtyness + 8, example_len - 8);
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_interlaced + 16, interlaced + 16, 2 * (example_len - 8));

heap_caps_free(from);
heap_caps_free(to);
heap_caps_free(interlaced);
heap_caps_free(col_dirtyness);
free(expected_interlaced);
free(expected_col_dirtyness);
}
4 changes: 2 additions & 2 deletions test/test_initialization.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#define TEST_BOARD epd_board_v7
#endif

TEST_CASE("initialization and deinitialization works", "[epdiy]")
TEST_CASE("initialization and deinitialization works", "[epdiy,e2e]")
{
epd_init(&TEST_BOARD, &ED097TC2, EPD_OPTIONS_DEFAULT);

Expand All @@ -25,7 +25,7 @@ TEST_CASE("initialization and deinitialization works", "[epdiy]")
epd_deinit();
}

TEST_CASE("re-initialization works", "[epdiy]")
TEST_CASE("re-initialization works", "[epdiy,e2e]")
{
epd_init(&TEST_BOARD, &ED097TC2, EPD_OPTIONS_DEFAULT);

Expand Down
27 changes: 27 additions & 0 deletions test/test_line_mask.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <esp_heap_caps.h>
#include <stdint.h>
#include <sys/types.h>
#include <unity.h>


void _epd_populate_line_mask(uint8_t* line_mask, const uint8_t* dirty_columns, int mask_len);

const uint8_t col_dirtyness_example[8] = {0x00, 0x0F, 0x00, 0x11, 0xFF, 0xFF, 0x00, 0x80};


TEST_CASE("mask populated correctly", "[epdiy,unit]") {
const uint8_t expected_mask[8] = {0x30, 0xF0, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00};
uint8_t mask[8] = {0};
_epd_populate_line_mask(mask, col_dirtyness_example, 4);

TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_mask, mask, 8);
}

TEST_CASE("neutral mask with null dirtyness", "[epdiy,unit]") {
const uint8_t expected_mask[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00};
uint8_t mask[8] = {0};

_epd_populate_line_mask(mask, NULL, 4);

TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_mask, mask, 8);
}

0 comments on commit fac2a2b

Please sign in to comment.