From 6be30622602603cbc944a860fb2580e937dd1874 Mon Sep 17 00:00:00 2001 From: "Kwabena W. Agyeman" Date: Sun, 29 Dec 2024 16:14:29 -0800 Subject: [PATCH] imlib/imlib: xalloc image to be cache aligned. --- src/omv/imlib/bmp.c | 2 +- src/omv/imlib/imlib.c | 14 ++++++++++++++ src/omv/imlib/imlib.h | 4 ++++ src/omv/imlib/jpege.c | 2 +- src/omv/imlib/png.c | 2 +- src/omv/imlib/ppm.c | 2 +- src/omv/modules/py_image.c | 15 ++++++++++----- src/omv/modules/py_imageio.c | 2 +- src/omv/modules/py_tof.c | 2 +- 9 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/omv/imlib/bmp.c b/src/omv/imlib/bmp.c index e9f9c014f..f2af26a19 100644 --- a/src/omv/imlib/bmp.c +++ b/src/omv/imlib/bmp.c @@ -270,7 +270,7 @@ void bmp_read(image_t *img, const char *path) { file_open(&fp, path, true, FA_READ | FA_OPEN_EXISTING); bmp_read_geometry(&fp, img, path, &rs); if (!img->pixels) { - img->pixels = xalloc(img->w * img->h * img->bpp); + image_xalloc(img, img->w * img->h * img->bpp); } bmp_read_pixels(&fp, img, img->h, &rs); file_close(&fp); diff --git a/src/omv/imlib/imlib.c b/src/omv/imlib/imlib.c index a7b5bf2d3..43afe8b4d 100644 --- a/src/omv/imlib/imlib.c +++ b/src/omv/imlib/imlib.c @@ -262,6 +262,20 @@ void rectangle_united(rectangle_t *dst, rectangle_t *src) { // Image Stuff // ///////////////// +void image_xalloc(image_t *img, size_t size) { + // Round the size up to ensure that the allocation is a multiple of the alignment in bytes. + // This ensures after address alignment that the data can be modified without affecting other cache lines. + size = ((size + OMV_ALLOC_ALIGNMENT - 1) / OMV_ALLOC_ALIGNMENT) * OMV_ALLOC_ALIGNMENT; + img->_raw = xalloc(size + OMV_ALLOC_ALIGNMENT - 1); + // Offset the data pointer to ensure it is aligned. + img->data = (void *) (((uintptr_t) img->_raw + OMV_ALLOC_ALIGNMENT - 1) & ~(OMV_ALLOC_ALIGNMENT - 1)); +} + +void image_xalloc0(image_t *img, size_t size) { + image_xalloc(img, size); + memset(img->data, 0, size); +} + void image_init(image_t *ptr, int w, int h, pixformat_t pixfmt, uint32_t size, void *pixels) { ptr->w = w; ptr->h = h; diff --git a/src/omv/imlib/imlib.h b/src/omv/imlib/imlib.h index 61c56dba7..91f09de98 100644 --- a/src/omv/imlib/imlib.h +++ b/src/omv/imlib/imlib.h @@ -559,12 +559,16 @@ typedef struct image { int32_t w; int32_t h; PIXFORMAT_STRUCT; + // Keeps a reference to the GC block when used with image_xalloc/image_xalloc0. + uint8_t *_raw; union { uint8_t *pixels; uint8_t *data; }; } image_t; +void image_xalloc(image_t *img, size_t size); +void image_xalloc0(image_t *img, size_t size); void image_init(image_t *ptr, int w, int h, pixformat_t pixfmt, uint32_t size, void *pixels); void image_copy(image_t *dst, image_t *src); size_t image_line_size(image_t *ptr); diff --git a/src/omv/imlib/jpege.c b/src/omv/imlib/jpege.c index e3dc9b509..b6fdf945a 100644 --- a/src/omv/imlib/jpege.c +++ b/src/omv/imlib/jpege.c @@ -1371,7 +1371,7 @@ void jpeg_read(image_t *img, const char *path) { jpeg_read_geometry(&fp, img, path, &rs); if (!img->pixels) { - img->pixels = xalloc(img->size); + image_xalloc(img, img->size); } jpeg_read_pixels(&fp, img); diff --git a/src/omv/imlib/png.c b/src/omv/imlib/png.c index d45935d1c..0e2ce4f55 100644 --- a/src/omv/imlib/png.c +++ b/src/omv/imlib/png.c @@ -302,7 +302,7 @@ void png_read(image_t *img, const char *path) { png_read_geometry(&fp, img, path, &rs); if (!img->pixels) { - img->pixels = xalloc(img->size); + image_xalloc(img, img->size); } png_read_pixels(&fp, img); diff --git a/src/omv/imlib/ppm.c b/src/omv/imlib/ppm.c index 8b17a16cf..1e5a31e05 100644 --- a/src/omv/imlib/ppm.c +++ b/src/omv/imlib/ppm.c @@ -143,7 +143,7 @@ void ppm_read(image_t *img, const char *path) { ppm_read_geometry(&fp, img, path, &rs); if (!img->pixels) { - img->pixels = xalloc(img->w * img->h * img->bpp); + image_xalloc(img, img->w * img->h * img->bpp); } ppm_read_pixels(&fp, img, img->h, &rs); file_close(&fp); diff --git a/src/omv/modules/py_image.c b/src/omv/modules/py_image.c index 0e3489065..81e27e72e 100644 --- a/src/omv/modules/py_image.c +++ b/src/omv/modules/py_image.c @@ -1149,7 +1149,7 @@ static mp_obj_t py_image_to(pixformat_t pixfmt, mp_rom_obj_t default_color_palet py_helper_set_to_framebuffer(&dst_img); } else if (args[ARG_copy].u_bool) { // Create dynamic copy. - dst_img.data = xalloc(size); + image_xalloc(&dst_img, size); } else { // Convert in place. bool fb = py_helper_is_equal_to_framebuffer(src_img); @@ -1980,7 +1980,12 @@ static mp_obj_t py_image_binary(uint n_args, const mp_obj_t *pos_args, mp_map_t out.w = image->w; out.h = image->h; out.pixfmt = args[ARG_to_bitmap].u_bool ? PIXFORMAT_BINARY : image->pixfmt; - out.data = args[ARG_copy].u_bool ? xalloc(image_size(&out)) : image->pixels; + + if (args[ARG_copy].u_bool) { + image_xalloc(&out, image_size(&out)); + } else { + out.data = image->data; + } fb_alloc_mark(); image_t *mask = NULL; @@ -6120,7 +6125,7 @@ mp_obj_t py_image_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw if (args[ARG_copy_to_fb].u_bool) { py_helper_set_to_framebuffer(&image); } else { - image.data = xalloc(image_size(&image)); + image_xalloc(&image, image_size(&image)); } imlib_load_image(&image, path); @@ -6161,7 +6166,7 @@ mp_obj_t py_image_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw mp_raise_ValueError(MP_ERROR_TEXT("Buffer is too small")); } } else { - image.data = xalloc(image_size(&image)); + image_xalloc(&image, image_size(&image)); } mp_float_t *farray = (mp_float_t *) array->array; @@ -6221,7 +6226,7 @@ mp_obj_t py_image_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw mp_raise_ValueError(MP_ERROR_TEXT("Buffer is too small")); } } else { - image.data = xalloc0(image_size(&image)); + image_xalloc0(&image, image_size(&image)); } } diff --git a/src/omv/modules/py_imageio.c b/src/omv/modules/py_imageio.c index b47ae3a0b..394b3c667 100644 --- a/src/omv/modules/py_imageio.c +++ b/src/omv/modules/py_imageio.c @@ -374,7 +374,7 @@ static mp_obj_t py_imageio_read(uint n_args, const mp_obj_t *pos_args, mp_map_t if (args[ARG_copy_to_fb].u_bool) { py_helper_set_to_framebuffer(&image); } else { - image.data = xalloc(size); + image_xalloc(&image, size); } if (0) { diff --git a/src/omv/modules/py_tof.c b/src/omv/modules/py_tof.c index 723a88ffe..3c0a7ca71 100644 --- a/src/omv/modules/py_tof.c +++ b/src/omv/modules/py_tof.c @@ -527,7 +527,7 @@ mp_obj_t py_tof_snapshot(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_arg if (args[ARG_copy_to_fb].u_bool) { py_helper_set_to_framebuffer(&dst_img); } else { - dst_img.data = xalloc(image_size(&dst_img)); + image_xalloc(&dst_img, image_size(&dst_img)); } float min = FLT_MAX;