Cosmic Unicorn: Implement RGB888 frame convert.

pull/641/head
Phil Howard 2023-02-09 11:25:09 +00:00 zatwierdzone przez Phil Howard
rodzic aa9c5b6538
commit bbeac41785
4 zmienionych plików z 46 dodań i 7 usunięć

Wyświetl plik

@ -567,16 +567,16 @@ namespace pimoroni {
}
else if(graphics->pen_type == PicoGraphics::PEN_P8 || graphics->pen_type == PicoGraphics::PEN_P4) {
int offset = 0;
graphics->frame_convert(PicoGraphics::PEN_RGB565, [this, offset](void *data, size_t length) mutable {
uint16_t *p = (uint16_t *)data;
for(auto i = 0u; i < length / 2; i++) {
graphics->frame_convert(PicoGraphics::PEN_RGB888, [this, offset](void *data, size_t length) mutable {
uint32_t *p = (uint32_t *)data;
for(auto i = 0u; i < length / 4; i++) {
int x = offset % 32;
int y = offset / 32;
uint16_t col = __builtin_bswap16(*p);
uint8_t r = (col & 0b1111100000000000) >> 8;
uint8_t g = (col & 0b0000011111100000) >> 3;
uint8_t b = (col & 0b0000000000011111) << 3;
uint32_t col = *p;
uint8_t r = (col & 0xff0000) >> 16;
uint8_t g = (col & 0x00ff00) >> 8;
uint8_t b = (col & 0x0000ff) >> 0;
set_pixel(x, y, r, g, b);
offset++;

Wyświetl plik

@ -420,4 +420,34 @@ namespace pimoroni {
// Callback with zero length to ensure previous buffer is fully written
callback(row_buf[buf_idx], 0);
}
// Common function for frame buffer conversion to 565 pixel format
void PicoGraphics::frame_convert_rgb888(conversion_callback_func callback, next_pixel_func_rgb888 get_next_pixel)
{
// Allocate two temporary buffers, as the callback may transfer by DMA
// while we're preparing the next part of the row
const int BUF_LEN = 64;
RGB888 row_buf[2][BUF_LEN];
int buf_idx = 0;
int buf_entry = 0;
for(auto i = 0; i < bounds.w * bounds.h; i++) {
row_buf[buf_idx][buf_entry] = get_next_pixel();
buf_entry++;
// Transfer a filled buffer and swap to the next one
if (buf_entry == BUF_LEN) {
callback(row_buf[buf_idx], BUF_LEN * sizeof(RGB888));
buf_idx ^= 1;
buf_entry = 0;
}
}
// Transfer any remaining pixels ( < BUF_LEN )
if(buf_entry > 0) {
callback(row_buf[buf_idx], buf_entry * sizeof(RGB888));
}
// Callback with zero length to ensure previous buffer is fully written
callback(row_buf[buf_idx], 0);
}
}

Wyświetl plik

@ -183,6 +183,7 @@ namespace pimoroni {
typedef std::function<void(void *data, size_t length)> conversion_callback_func;
typedef std::function<RGB565()> next_pixel_func;
typedef std::function<RGB888()> next_pixel_func_rgb888;
//typedef std::function<void(int y)> scanline_interrupt_func;
//scanline_interrupt_func scanline_interrupt = nullptr;
@ -271,6 +272,7 @@ namespace pimoroni {
protected:
void frame_convert_rgb565(conversion_callback_func callback, next_pixel_func get_next_pixel);
void frame_convert_rgb888(conversion_callback_func callback, next_pixel_func_rgb888 get_next_pixel);
};
class PicoGraphics_Pen1Bit : public PicoGraphics {

Wyświetl plik

@ -112,6 +112,13 @@ namespace pimoroni {
frame_convert_rgb565(callback, [&]() {
return cache[*src++];
});
} else if (type == PEN_RGB888) {
// Treat our void* frame_buffer as uint8_t
uint8_t *src = (uint8_t *)frame_buffer;
frame_convert_rgb888(callback, [&]() {
return palette[*src++].to_rgb888();
});
}
}
}