Skip to content

Commit bbeac41

Browse files
committed
Cosmic Unicorn: Implement RGB888 frame convert.
1 parent aa9c5b6 commit bbeac41

File tree

4 files changed

+46
-7
lines changed

4 files changed

+46
-7
lines changed

libraries/cosmic_unicorn/cosmic_unicorn.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -567,16 +567,16 @@ namespace pimoroni {
567567
}
568568
else if(graphics->pen_type == PicoGraphics::PEN_P8 || graphics->pen_type == PicoGraphics::PEN_P4) {
569569
int offset = 0;
570-
graphics->frame_convert(PicoGraphics::PEN_RGB565, [this, offset](void *data, size_t length) mutable {
571-
uint16_t *p = (uint16_t *)data;
572-
for(auto i = 0u; i < length / 2; i++) {
570+
graphics->frame_convert(PicoGraphics::PEN_RGB888, [this, offset](void *data, size_t length) mutable {
571+
uint32_t *p = (uint32_t *)data;
572+
for(auto i = 0u; i < length / 4; i++) {
573573
int x = offset % 32;
574574
int y = offset / 32;
575575

576-
uint16_t col = __builtin_bswap16(*p);
577-
uint8_t r = (col & 0b1111100000000000) >> 8;
578-
uint8_t g = (col & 0b0000011111100000) >> 3;
579-
uint8_t b = (col & 0b0000000000011111) << 3;
576+
uint32_t col = *p;
577+
uint8_t r = (col & 0xff0000) >> 16;
578+
uint8_t g = (col & 0x00ff00) >> 8;
579+
uint8_t b = (col & 0x0000ff) >> 0;
580580

581581
set_pixel(x, y, r, g, b);
582582
offset++;

libraries/pico_graphics/pico_graphics.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,4 +420,34 @@ namespace pimoroni {
420420
// Callback with zero length to ensure previous buffer is fully written
421421
callback(row_buf[buf_idx], 0);
422422
}
423+
424+
// Common function for frame buffer conversion to 565 pixel format
425+
void PicoGraphics::frame_convert_rgb888(conversion_callback_func callback, next_pixel_func_rgb888 get_next_pixel)
426+
{
427+
// Allocate two temporary buffers, as the callback may transfer by DMA
428+
// while we're preparing the next part of the row
429+
const int BUF_LEN = 64;
430+
RGB888 row_buf[2][BUF_LEN];
431+
int buf_idx = 0;
432+
int buf_entry = 0;
433+
for(auto i = 0; i < bounds.w * bounds.h; i++) {
434+
row_buf[buf_idx][buf_entry] = get_next_pixel();
435+
buf_entry++;
436+
437+
// Transfer a filled buffer and swap to the next one
438+
if (buf_entry == BUF_LEN) {
439+
callback(row_buf[buf_idx], BUF_LEN * sizeof(RGB888));
440+
buf_idx ^= 1;
441+
buf_entry = 0;
442+
}
443+
}
444+
445+
// Transfer any remaining pixels ( < BUF_LEN )
446+
if(buf_entry > 0) {
447+
callback(row_buf[buf_idx], buf_entry * sizeof(RGB888));
448+
}
449+
450+
// Callback with zero length to ensure previous buffer is fully written
451+
callback(row_buf[buf_idx], 0);
452+
}
423453
}

libraries/pico_graphics/pico_graphics.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ namespace pimoroni {
183183

184184
typedef std::function<void(void *data, size_t length)> conversion_callback_func;
185185
typedef std::function<RGB565()> next_pixel_func;
186+
typedef std::function<RGB888()> next_pixel_func_rgb888;
186187
//typedef std::function<void(int y)> scanline_interrupt_func;
187188

188189
//scanline_interrupt_func scanline_interrupt = nullptr;
@@ -271,6 +272,7 @@ namespace pimoroni {
271272

272273
protected:
273274
void frame_convert_rgb565(conversion_callback_func callback, next_pixel_func get_next_pixel);
275+
void frame_convert_rgb888(conversion_callback_func callback, next_pixel_func_rgb888 get_next_pixel);
274276
};
275277

276278
class PicoGraphics_Pen1Bit : public PicoGraphics {

libraries/pico_graphics/pico_graphics_pen_p8.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ namespace pimoroni {
112112
frame_convert_rgb565(callback, [&]() {
113113
return cache[*src++];
114114
});
115+
} else if (type == PEN_RGB888) {
116+
// Treat our void* frame_buffer as uint8_t
117+
uint8_t *src = (uint8_t *)frame_buffer;
118+
119+
frame_convert_rgb888(callback, [&]() {
120+
return palette[*src++].to_rgb888();
121+
});
115122
}
116123
}
117124
}

0 commit comments

Comments
 (0)