Add smart overlay logic to fballoc

When fballoc is called and there's space to put what's requested in SRAM
this is done instead of putting it in SDRAM. This results in a huge
performance boost to most algorithms that use only a small amount of
fballoc ram.

In particular, apriltags is usable in speed with this fix...
This commit is contained in:
Kwabena W. Agyeman 2019-09-09 22:40:31 -07:00
parent 1e42f12e5d
commit 30c4cf4a8c
4 changed files with 89 additions and 26 deletions

View File

@ -70,6 +70,8 @@
#define OMV_JPEG_MEMORY DRAM // JPEG buffer memory buffer.
#define OMV_JPEG_MEMORY_OFFSET (31M) // JPEG buffer is placed after FB/fballoc memory.
#define OMV_VOSPI_MEMORY SRAM4 // VoSPI buffer memory.
#define OMV_FB_OVERLAY_MEMORY AXI_SRAM // _fballoc_overlay memory.
#define OMV_FB_OVERLAY_MEMORY_OFFSET (480*1024) // _fballoc_overlay
#define OMV_FB_SIZE (30M) // FB memory: header + VGA/GS image
#define OMV_FB_ALLOC_SIZE (1M) // minimum fb alloc size
@ -97,9 +99,10 @@
#define OMV_AXI_SRAM_LENGTH 512K
#define OMV_DRAM_ORIGIN 0xC0000000
#define OMV_DRAM_LENGTH 32M
#define OMV_FB_OVERLAY_MEMORY_ORIGIN OMV_AXI_SRAM_ORIGIN
// Use the MPU to set an uncacheable memory region.
#define OMV_DMA_REGION_BASE (OMV_AXI_SRAM_ORIGIN)
#define OMV_DMA_REGION_BASE (OMV_AXI_SRAM_ORIGIN+OMV_FB_OVERLAY_MEMORY_OFFSET)
#define OMV_DMA_REGION_SIZE MPU_REGION_SIZE_32KB
/* SCCB/I2C */

View File

@ -9,6 +9,7 @@
#include <mp.h>
#include "fb_alloc.h"
#include "framebuffer.h"
#include "omv_boardconfig.h"
extern char _fballoc;
static char *pointer = &_fballoc;
@ -17,6 +18,11 @@ static int marks = 0;
static uint32_t alloc_bytes;
static uint32_t alloc_bytes_peak;
#endif
#if defined(OMV_FB_OVERLAY_MEMORY)
#define FB_OVERLAY_MEMORY_FLAG 0x1
extern char _fballoc_overlay;
static char *pointer_overlay = &_fballoc_overlay;
#endif
__weak NORETURN void fb_alloc_fail()
{
@ -29,11 +35,14 @@ void fb_alloc_init0()
{
pointer = &_fballoc;
marks = 0;
#if defined(OMV_FB_OVERLAY_MEMORY)
pointer_overlay = &_fballoc_overlay;
#endif
}
uint32_t fb_avail()
{
int32_t temp = pointer - ((char *) MAIN_FB_PIXELS()) - sizeof(uint32_t);
uint32_t temp = pointer - ((char *) MAIN_FB_PIXELS()) - sizeof(uint32_t);
return (temp < sizeof(uint32_t)) ? 0 : temp;
}
@ -65,7 +74,13 @@ void fb_alloc_free_till_mark()
{
if (!marks) return;
while (pointer < &_fballoc) {
int size = *((uint32_t *) pointer);
uint32_t size = *((uint32_t *) pointer);
#if defined(OMV_FB_OVERLAY_MEMORY)
if (size & FB_OVERLAY_MEMORY_FLAG) { // Check for fast flag.
size &= ~FB_OVERLAY_MEMORY_FLAG; // Remove it.
pointer_overlay += size - sizeof(uint32_t);
}
#endif
pointer += size; // Get size and pop.
if (size == sizeof(uint32_t)) break; // Break on first marker.
}
@ -101,6 +116,14 @@ void *fb_alloc(uint32_t size)
}
printf("fb_alloc %lu bytes\n", size);
#endif
#if defined(OMV_FB_OVERLAY_MEMORY)
if (((uint32_t) (pointer_overlay - OMV_FB_OVERLAY_MEMORY_ORIGIN)) >= size) {
// Return overlay memory instead.
pointer_overlay -= size;
result = pointer_overlay;
*new_pointer |= FB_OVERLAY_MEMORY_FLAG; // Add flag.
}
#endif
return result;
}
@ -114,13 +137,17 @@ void *fb_alloc0(uint32_t size)
void *fb_alloc_all(uint32_t *size)
{
int32_t temp = pointer - ((char *) MAIN_FB_PIXELS()) - sizeof(uint32_t);
uint32_t temp = pointer - ((char *) MAIN_FB_PIXELS()) - sizeof(uint32_t);
if (temp < sizeof(uint32_t)) {
*size = 0;
return NULL;
}
#if defined(OMV_FB_OVERLAY_MEMORY)
*size = (uint32_t) (pointer_overlay - OMV_FB_OVERLAY_MEMORY_ORIGIN);
temp = IM_MIN(temp, *size);
#endif
*size = (temp / sizeof(uint32_t)) * sizeof(uint32_t); // Round Down
char *result = pointer - *size;
char *new_pointer = result - sizeof(uint32_t);
@ -135,6 +162,12 @@ void *fb_alloc_all(uint32_t *size)
}
printf("fb_alloc_all %lu bytes\n", *size);
#endif
#if defined(OMV_FB_OVERLAY_MEMORY)
// Return overlay memory instead.
pointer_overlay -= *size;
result = pointer_overlay;
*new_pointer |= FB_OVERLAY_MEMORY_FLAG; // Add flag.
#endif
return result;
}
@ -149,20 +182,34 @@ void *fb_alloc0_all(uint32_t *size)
void fb_free()
{
if (pointer < &_fballoc) {
#if defined(FB_ALLOC_STATS)
alloc_bytes -= *((uint32_t *) pointer);
uint32_t size = *((uint32_t *) pointer);
#if defined(OMV_FB_OVERLAY_MEMORY)
if (size & FB_OVERLAY_MEMORY_FLAG) { // Check for fast flag.
size &= ~FB_OVERLAY_MEMORY_FLAG; // Remove it.
pointer_overlay += size - sizeof(uint32_t);
}
#endif
pointer += *((uint32_t *) pointer); // Get size and pop.
#if defined(FB_ALLOC_STATS)
alloc_bytes -= size;
#endif
pointer += size; // Get size and pop.
}
}
void fb_free_all()
{
while (pointer < &_fballoc) {
#if defined(FB_ALLOC_STATS)
alloc_bytes -= *((uint32_t *) pointer);
uint32_t size = *((uint32_t *) pointer);
#if defined(OMV_FB_OVERLAY_MEMORY)
if (size & FB_OVERLAY_MEMORY_FLAG) { // Check for fast flag.
size &= ~FB_OVERLAY_MEMORY_FLAG; // Remove it.
pointer_overlay += size - sizeof(uint32_t);
}
#endif
pointer += *((uint32_t *) pointer); // Get size and pop.
#if defined(FB_ALLOC_STATS)
alloc_bytes -= size;
#endif
pointer += size; // Get size and pop.
}
marks = 0;
}

View File

@ -42,23 +42,23 @@ _ram_end = ORIGIN(OMV_MAIN_MEMORY) + LENGTH(OMV_MAIN_MEMORY);
#if defined(OMV_FFS_MEMORY)
#if !defined(OMV_FFS_MEMORY_OFFSET)
#define OMV_FFS_MEMORY_OFFSET (0)
#define OMV_FFS_MEMORY_OFFSET (0)
#endif
_ffs_cache = ORIGIN(OMV_FFS_MEMORY) + OMV_FFS_MEMORY_OFFSET;
_ffs_cache = ORIGIN(OMV_FFS_MEMORY) + OMV_FFS_MEMORY_OFFSET;
#endif
#if defined(OMV_JPEG_MEMORY)
#if !defined(OMV_JPEG_MEMORY_OFFSET)
#define OMV_JPEG_MEMORY_OFFSET (0)
#define OMV_JPEG_MEMORY_OFFSET (0)
#endif
_jpeg_buf = ORIGIN(OMV_JPEG_MEMORY) + OMV_JPEG_MEMORY_OFFSET;
_jpeg_buf = ORIGIN(OMV_JPEG_MEMORY) + OMV_JPEG_MEMORY_OFFSET;
#endif
#if defined(OMV_VOSPI_MEMORY)
#if !defined(OMV_VOSPI_MEMORY_OFFSET)
#define OMV_VOSPI_MEMORY_OFFSET (0)
#define OMV_VOSPI_MEMORY_OFFSET (0)
#endif
_vospi_buf = ORIGIN(OMV_VOSPI_MEMORY) + OMV_VOSPI_MEMORY_OFFSET;
_vospi_buf = ORIGIN(OMV_VOSPI_MEMORY) + OMV_VOSPI_MEMORY_OFFSET;
#endif
_heap_size = OMV_HEAP_SIZE; /* required amount of heap */
@ -107,6 +107,11 @@ SECTIONS
/* Misc DMA buffers kept in uncachable region */
.dma_memory (NOLOAD) :
{
#if defined(OMV_FB_OVERLAY_MEMORY)
. = ALIGN(4) + OMV_FB_OVERLAY_MEMORY_OFFSET;
_fballoc_overlay = .;
#endif
. = ALIGN(4);
_line_buf = .; // Image line buffer.
. = . + OMV_LINE_BUF_SIZE;

View File

@ -41,15 +41,24 @@ _estack = ORIGIN(OMV_MAIN_MEMORY) + LENGTH(OMV_MAIN_MEMORY);
_ram_end = ORIGIN(OMV_MAIN_MEMORY) + LENGTH(OMV_MAIN_MEMORY);
#if defined(OMV_FFS_MEMORY)
_ffs_cache = ORIGIN(OMV_FFS_MEMORY);
#if !defined(OMV_FFS_MEMORY_OFFSET)
#define OMV_FFS_MEMORY_OFFSET (0)
#endif
_ffs_cache = ORIGIN(OMV_FFS_MEMORY) + OMV_FFS_MEMORY_OFFSET;
#endif
#if defined(OMV_JPEG_MEMORY)
_jpeg_buf = ORIGIN(OMV_JPEG_MEMORY);
#if !defined(OMV_JPEG_MEMORY_OFFSET)
#define OMV_JPEG_MEMORY_OFFSET (0)
#endif
_jpeg_buf = ORIGIN(OMV_JPEG_MEMORY) + OMV_JPEG_MEMORY_OFFSET;
#endif
#if defined(OMV_VOSPI_MEMORY)
_vospi_buf = ORIGIN(OMV_VOSPI_MEMORY);
#if !defined(OMV_VOSPI_MEMORY_OFFSET)
#define OMV_VOSPI_MEMORY_OFFSET (0)
#endif
_vospi_buf = ORIGIN(OMV_VOSPI_MEMORY) + OMV_VOSPI_MEMORY_OFFSET;
#endif
_heap_size = OMV_HEAP_SIZE; /* required amount of heap */
@ -87,19 +96,18 @@ SECTIONS
. = ALIGN(4);
_fballoc = .;
#if defined(OMV_FB_JPEG_MEMORY)
. = ALIGN(4);
_jpeg_buf = .; // IDE JPEG buffer
. = . + OMV_JPEG_BUF_SIZE;
#endif
} >OMV_FB_MEMORY
/* Misc DMA buffers kept in uncachable region */
/* NOTE: on H7 DMA buffers are kept in cached AXI RAM and cache maintenance is performed */
.dma_memory (NOLOAD) :
{
#if defined(OMV_FB_OVERLAY_MEMORY)
. = ALIGN(4) + OMV_FB_OVERLAY_MEMORY_OFFSET;
_fballoc_overlay = .;
#endif
. = ALIGN(4);
_line_buf = .; // Image line buffer.
. = . + OMV_LINE_BUF_SIZE;
@ -118,7 +126,7 @@ SECTIONS
. = . + OMV_FFS_BUF_SIZE;
#endif
#if !defined(OMV_JPEG_MEMORY) && !defined(OMV_FB_JPEG_MEMORY)
#if !defined(OMV_JPEG_MEMORY)
. = ALIGN(4);
_jpeg_buf = .; // IDE JPEG buffer
. = . + OMV_JPEG_BUF_SIZE;