Skip to content

Commit

Permalink
Add buffer flushing function to the Python module definition
Browse files Browse the repository at this point in the history
Additional improves error checking and exitcode for this function to react if the buffer update has not been suceeded
  • Loading branch information
RossAdrian committed Jul 28, 2024
1 parent f5d0bc0 commit 4437b60
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
33 changes: 20 additions & 13 deletions native/framebuffers.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ void pyfb_init(void) {
framebuffers[i].users = 0;
framebuffers[i].fb_info.fb_size_b = 0;
framebuffers[i].u32_buffer = NULL;

atomic_flag flag = ATOMIC_FLAG_INIT;

framebuffers[i].fb_lock = flag;
atomic_flag flag = ATOMIC_FLAG_INIT;
framebuffers[i].fb_lock = flag;
}
}

Expand Down Expand Up @@ -110,9 +108,6 @@ int pyfb_open(uint8_t fbnum) {

if(buffer == NULL) {
// got out of memory for the offscreen buffers
if(buffer != NULL) {
free(buffer);
}

// free up all other resources for the new buffer
close(fb_fd);
Expand Down Expand Up @@ -234,10 +229,10 @@ void pyfb_vinfo(uint8_t fbnum, struct pyfb_videomode_info* info_ptr) {
unlock(framebuffers[fbnum].fb_lock);
}

void pyfb_flushBuffer(uint8_t fbnum) {
int pyfb_flushBuffer(uint8_t fbnum) {
// first test if this device number is valid
if(fbnum >= MAX_FRAMEBUFFERS) {
return;
return -1;
}

lock(framebuffers[fbnum].fb_lock);
Expand All @@ -246,19 +241,27 @@ void pyfb_flushBuffer(uint8_t fbnum) {
if(framebuffers[fbnum].fb_fd == -1) {
// this framebuffer is not in use, so ignore
unlock(framebuffers[fbnum].fb_lock);
return;
return -1;
}

// if we get here, flush the offscreen buffer to the framebuffer
lseek(framebuffers[fbnum].fb_fd, 0L, SEEK_SET);
if(lseek(framebuffers[fbnum].fb_fd, 0L, SEEK_SET) == -1) {
unlock(framebuffers[fbnum].fb_lock);
return -1;
}

size_t buf_len = (size_t)framebuffers[fbnum].fb_info.fb_size_b;
unsigned long int exitcode = 0;

if(framebuffers[fbnum].fb_info.vinfo.bits_per_pixel == 32) {
write(framebuffers[fbnum].fb_fd, (void*)framebuffers[fbnum].u32_buffer, (size_t)framebuffers[fbnum].fb_info.fb_size_b);
exitcode = (unsigned int)write(framebuffers[fbnum].fb_fd, (void*)framebuffers[fbnum].u32_buffer, buf_len);
} else {
write(framebuffers[fbnum].fb_fd, (void*)framebuffers[fbnum].u16_buffer, (size_t)framebuffers[fbnum].fb_info.fb_size_b);
exitcode = (unsigned int)write(framebuffers[fbnum].fb_fd, (void*)framebuffers[fbnum].u16_buffer, buf_len);
}

// okay, ready flushed
unlock(framebuffers[fbnum].fb_lock);
return buf_len == exitcode ? 0 : -1;
}

/**
Expand Down Expand Up @@ -308,6 +311,7 @@ void __APISTATUS_internal pyfb_setPixel(uint8_t fbnum,
// do
unsigned int xres = framebuffers[fbnum].fb_info.vinfo.xres;
unsigned int width = framebuffers[fbnum].fb_info.vinfo.bits_per_pixel;

if(width == 16) {
pyfb_pixel16(fbnum, x, y, color, xres);
} else {
Expand Down Expand Up @@ -343,6 +347,7 @@ void pyfb_ssetPixel(uint8_t fbnum, unsigned long int x, unsigned long int y, con

// else all is okay and we can continue
unsigned int width = framebuffers[fbnum].fb_info.vinfo.bits_per_pixel;

if(width == 16) {
pyfb_pixel16(fbnum, x, y, color, xres);
} else {
Expand Down Expand Up @@ -388,6 +393,7 @@ void pyfb_sdrawHorizontalLine(uint8_t fbnum,
// Now test if the ranges are okay
unsigned long int xres = framebuffers[fbnum].fb_info.vinfo.xres;
unsigned long int yres = framebuffers[fbnum].fb_info.vinfo.yres;

if(y >= yres) {
unlock(framebuffers[fbnum].fb_lock);
return;
Expand Down Expand Up @@ -440,6 +446,7 @@ void pyfb_sdrawVerticalLine(uint8_t fbnum,
// Now test if the ranges are okay
unsigned long int xres = framebuffers[fbnum].fb_info.vinfo.xres;
unsigned long int yres = framebuffers[fbnum].fb_info.vinfo.yres;

if(y >= yres || (y + len - 1) >= yres) {
unlock(framebuffers[fbnum].fb_lock);
return;
Expand Down
22 changes: 22 additions & 0 deletions native/module_pyfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,27 @@ static PyObject* pyfunc_pyfb_sdrawVerticalLine(PyObject* self, PyObject* args) {
return PyLong_FromLong(exitcode);
}

/**
* Python wrapper for the pyfb_flushBuffer function.
*
* @param self The function
* @param args The arguments, expecting long of the fbnum
*
* @return The exitstatus
*/
static PyObject* pyfunc_pyfb_flushBuffer(PyObject* self, PyObject* args) {
unsigned char fbnum_c;

if(!PyArg_ParseTuple(args, "b", &fbnum_c)) {
PyErr_SetString(PyExc_TypeError, "Expecting arguments of type (byte)");
return NULL;
}

// Now invoke the function
int exitcode = pyfb_flushBuffer((uint8_t)fbnum_c);
return PyLong_FromLong(exitcode);
}

// The module def

/**
Expand All @@ -151,6 +172,7 @@ static PyMethodDef pyfb_methods[] = {
{"pyfb_setPixel", pyfunc_pyfb_ssetPixel, METH_VARARGS, "Draw a pixel on the framebuffer"},
{"pyfb_drawHorizontalLine", pyfunc_pyfb_sdrawHorizontalLine, METH_VARARGS, "Draw a horizontal line on the framebuffer"},
{"pyfb_drawVerticalLine", pyfunc_pyfb_sdrawVerticalLine, METH_VARARGS, "Draw a vertical line on the framebuffer"},
{"pyfb_flushBuffer", pyfunc_pyfb_flushBuffer, METH_VARARGS, "Flush the offscreen buffer to the framebuffer"},
{NULL, NULL, 0, NULL}};

static struct PyModuleDef module__pyfb = {PyModuleDef_HEAD_INIT,
Expand Down
4 changes: 3 additions & 1 deletion native/pyframebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,9 @@ extern void __APISTATUS_internal pyfb_drawVerticalLine(uint8_t fbnum,
* it says that it can take something between 20 and 100 milliseconds.
*
* @param fbnum The framebuffer number of which to flush all buffers
*
* @return If succeeded 0, else -1
*/
extern void pyfb_flushBuffer(uint8_t fbnum);
extern int pyfb_flushBuffer(uint8_t fbnum);

#endif

0 comments on commit 4437b60

Please sign in to comment.