circuitpython/ports/broadcom/common-hal/videocore/Framebuffer.c

74 lines
2.3 KiB
C

#include "bindings/videocore/Framebuffer.h"
#include "py/gc.h"
#include "py/runtime.h"
#include "peripherals/broadcom/caches.h"
#include "peripherals/broadcom/vcmailbox.h"
void common_hal_videocore_framebuffer_construct(videocore_framebuffer_obj_t *self,
mp_uint_t width, mp_uint_t height) {
// These will be modified on success to indicate actual values.
uint32_t virtual_width = width;
uint32_t virtual_height = height;
uint32_t physical_width = width;
// TODO: Make the FB twice as tall if double buffering.
uint32_t physical_height = height;
uint32_t pitch = 0;
uint32_t bits_per_pixel = 0;
self->framebuffer = vcmailbox_get_framebuffer(&virtual_width,
&virtual_height,
&physical_width,
&physical_height,
&pitch,
&bits_per_pixel);
if (self->framebuffer == NULL) {
if (gc_alloc_possible()) {
mp_raise_ValueError(translate("no fb"));
} else {
mp_printf(&mp_plat_print, "no fb\n");
}
self->width = 0;
self->height = 0;
return;
}
self->width = virtual_width;
self->height = virtual_height;
self->pitch = pitch;
}
void common_hal_videocore_framebuffer_deinit(videocore_framebuffer_obj_t *self) {
if (vcmailbox_release_framebuffer()) {
self->framebuffer = NULL;
}
}
bool common_hal_videocore_framebuffer_deinited(videocore_framebuffer_obj_t *self) {
return self->framebuffer == NULL;
}
void common_hal_videocore_framebuffer_refresh(videocore_framebuffer_obj_t *self) {
data_clean(self->framebuffer, sizeof(uint32_t) * self->width * self->height);
}
int common_hal_videocore_framebuffer_get_width(videocore_framebuffer_obj_t *self) {
return self->width;
}
int common_hal_videocore_framebuffer_get_height(videocore_framebuffer_obj_t *self) {
return self->height;
}
mp_int_t common_hal_videocore_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
videocore_framebuffer_obj_t *self = (videocore_framebuffer_obj_t *)self_in;
bufinfo->buf = self->framebuffer;
bufinfo->typecode = 'L';
bufinfo->len = self->pitch * self->height * sizeof(uint32_t);
return 0;
}
int common_hal_videocore_framebuffer_get_row_stride(videocore_framebuffer_obj_t *self) {
return self->pitch;
}