Merge pull request #861 from kwagyeman/kwabena/make_frame_buffer_respect_fb_alloc

Frame buffer respects fb alloc now
This commit is contained in:
Ibrahim Abd Elkader 2020-07-21 01:28:39 +02:00 committed by GitHub
commit 4638f2bb3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 34 deletions

View File

@ -31,6 +31,11 @@ static char *fb_alloc_min_address()
return (char *) (framebuffer_get_buffer() + framebuffer_get_frame_size());
}
char *fb_alloc_stack_pointer()
{
return pointer;
}
__weak NORETURN void fb_alloc_fail()
{
nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError,

View File

@ -12,6 +12,7 @@
#define FB_ALLOC_NO_HINT 0
#define FB_ALLOC_PREFER_SPEED 1
#define FB_ALLOC_PREFER_SIZE 2
char *fb_alloc_stack_pointer();
void fb_alloc_fail();
void fb_alloc_init0();
uint32_t fb_avail();

View File

@ -16,7 +16,6 @@
#define CONSERVATIVE_JPEG_BUF_SIZE (OMV_JPEG_BUF_SIZE-64)
extern char _fb_base;
extern char _fballoc;
framebuffer_t *framebuffer = (framebuffer_t *) &_fb_base;
extern char _jpeg_buf;
@ -200,32 +199,19 @@ int32_t framebuffer_get_depth()
uint32_t framebuffer_get_frame_size()
{
switch (framebuffer->bpp) {
case -1: {
// Invalid frame.
return 0;
}
case IMAGE_BPP_BINARY: {
return ((framebuffer->w + UINT32_T_MASK) >> UINT32_T_SHIFT) * framebuffer->h;
}
case IMAGE_BPP_GRAYSCALE: {
return (framebuffer->w * framebuffer->h) * sizeof(uint8_t);
}
case IMAGE_BPP_RGB565: {
return (framebuffer->w * framebuffer->h) * sizeof(uint16_t);
}
case IMAGE_BPP_BAYER: {
return framebuffer->w * framebuffer->h;
}
default: { // JPEG
return framebuffer->bpp;
}
}
image_t img;
framebuffer_initialize_image(&img);
return image_size(&img);
}
uint32_t framebuffer_get_buffer_size()
{
return &_fballoc - (char *) framebuffer->pixels;
uint32_t size = (uint32_t) (fb_alloc_stack_pointer() - ((char *) framebuffer->pixels));
// We don't want to give all of the frame buffer RAM to the frame buffer. So, we will limit the
// maximum amount of RAM we return.
size = IM_MIN(size, OMV_RAW_BUF_SIZE);
// Needs to be a multiple of 32 for DMA transfers...
return (size / 32) * 32;
}
uint8_t *framebuffer_get_buffer()

View File

@ -64,7 +64,8 @@ int32_t framebuffer_get_depth();
// otherwise return 0 if the framebuffer is unintialized or invalid (e.g. first frame).
uint32_t framebuffer_get_frame_size();
// Return the max frame size that fits the framebuffer (i.e OMV_RAW_BUF_SIZE - sizeof(framebuffer_t))
// Return the max frame size that fits the framebuffer
// (i.e OMV_RAW_BUF_SIZE - sizeof(framebuffer_t))
uint32_t framebuffer_get_buffer_size();
// Return the current buffer address.

View File

@ -475,7 +475,7 @@ static int sensor_check_buffsize(sensor_t *sensor)
break;
}
if ((MAIN_FB()->w * MAIN_FB()->h * bpp) > OMV_RAW_BUF_SIZE) {
if ((MAIN_FB()->w * MAIN_FB()->h * bpp) > framebuffer_get_buffer_size()) {
return -1;
}

View File

@ -550,10 +550,11 @@ int sensor_set_pixformat(pixformat_t pixformat)
// This code is explicitly here to allow users to set the resolution to RGB565 and have it
// switch to BAYER only once even though they are setting the resolution to RGB565 repeatedly
// in a loop. Only RGB565->BAYER has this problem and needs this fix because of sensor_check_buffsize().
uint32_t size = framebuffer_get_buffer_size();
if ((sensor.pixformat == PIXFORMAT_BAYER)
&& (pixformat == PIXFORMAT_RGB565)
&& (MAIN_FB()->u * MAIN_FB()->v * 2 > OMV_RAW_BUF_SIZE)
&& (MAIN_FB()->u * MAIN_FB()->v * 1 <= OMV_RAW_BUF_SIZE)) {
&& (MAIN_FB()->u * MAIN_FB()->v * 2 > size)
&& (MAIN_FB()->u * MAIN_FB()->v * 1 <= size)) {
// No change
return 0;
}
@ -921,6 +922,7 @@ void DCMI_VsyncExtiCallback()
// within the RAM we have onboard the system.
static void sensor_check_buffsize()
{
uint32_t size = framebuffer_get_buffer_size();
uint32_t bpp;
switch (sensor.pixformat) {
@ -938,7 +940,7 @@ static void sensor_check_buffsize()
}
// MAIN_FB() fits, we are done.
if ((MAIN_FB()->u * MAIN_FB()->v * bpp) <= OMV_RAW_BUF_SIZE) {
if ((MAIN_FB()->u * MAIN_FB()->v * bpp) <= size) {
return;
}
@ -948,7 +950,7 @@ static void sensor_check_buffsize()
bpp = 1;
// MAIN_FB() fits, we are done (bpp is 1).
if (MAIN_FB()->u * MAIN_FB()->v <= OMV_RAW_BUF_SIZE) {
if (MAIN_FB()->u * MAIN_FB()->v <= size) {
return;
}
}
@ -995,7 +997,7 @@ static void sensor_check_buffsize()
}
// Crop the frame buffer while keeping the aspect ratio and keeping the width/height even.
while (((MAIN_FB()->u * MAIN_FB()->v * bpp) > OMV_RAW_BUF_SIZE) || (MAIN_FB()->u % 2) || (MAIN_FB()->v % 2)) {
while (((MAIN_FB()->u * MAIN_FB()->v * bpp) > size) || (MAIN_FB()->u % 2) || (MAIN_FB()->v % 2)) {
MAIN_FB()->u -= u_sub;
MAIN_FB()->v -= v_sub;
}
@ -1109,7 +1111,7 @@ void DCMI_DMAConvCpltUser(uint32_t addr)
//
uint16_t size = __REV16(*src16);
// Prevent a buffer overflow when writing the jpeg data.
if (offset + size > OMV_RAW_BUF_SIZE) {
if (offset + size > framebuffer_get_buffer_size()) {
jpeg_buffer_overflow = true;
return;
}
@ -1301,7 +1303,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_c
}
// If two frames fit in ram, use double buffering in streaming mode.
doublebuf = ((length*2) <= OMV_RAW_BUF_SIZE);
doublebuf = ((length*2) <= framebuffer_get_buffer_size());
#if OMV_ENABLE_HM01B0
HAL_DCMI_EnableCrop(&DCMIHandle);
@ -1471,8 +1473,9 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_c
// within a transfer we have to look at the DMA counter and see how much data was moved.
MAIN_FB()->bpp = (offset * MAX_XFER_SIZE) + ((MAX_XFER_SIZE/4) - __HAL_DMA_GET_COUNTER(&DMAHandle))*4;
uint32_t size = framebuffer_get_buffer_size();
// DMA has most likely corrupted FB alloc state and or more.
if (MAIN_FB()->bpp > OMV_RAW_BUF_SIZE) {
if (MAIN_FB()->bpp > size) {
__fatal_error("JPEG Overflow!");
}
@ -1480,7 +1483,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_c
// In JPEG mode, the DMA uses the frame buffer memory directly instead of the line buffer, which is
// located in a cacheable region and therefore must be invalidated before the CPU can access it again.
// Note: The frame buffer address is 32-byte aligned, and the size is a multiple of 32-bytes for all boards.
SCB_InvalidateDCache_by_Addr((uint32_t*)MAIN_FB()->pixels, OMV_RAW_BUF_SIZE);
SCB_InvalidateDCache_by_Addr((uint32_t*)MAIN_FB()->pixels, size);
#endif
}
// Clean trailing data.