Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PicoGraphics: Layers. (EXPERIMENTAL) #1011

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/micropython.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ on:
types: [created]

env:
MICROPYTHON_VERSION: v1.23.0
MICROPYTHON_VERSION: feature/psram
MICROPYTHON_FLAVOUR: pimoroni

jobs:
build:
Expand Down Expand Up @@ -87,7 +88,7 @@ jobs:
uses: actions/checkout@v4
with:
repository: gadgetoid/py_decl
ref: v0.0.1
ref: v0.0.4
path: py_decl

- name: Build MPY Cross
Expand Down
6 changes: 2 additions & 4 deletions ci/micropython.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ function log_warning {
}

function micropython_clone {
log_inform "Using MicroPython $MICROPYTHON_VERSION"
git clone https://github.com/micropython/micropython
log_inform "Using MicroPython $MICROPYTHON_FLAVOUR/$MICROPYTHON_VERSION"
git clone https://github.com/$MICROPYTHON_FLAVOUR/micropython -b $MICROPYTHON_VERSION --depth=1
cd micropython
git checkout $MICROPYTHON_VERSION
git cherry-pick -n 932f76c6ba64c5a3e68de3324556d9979f09303b
git submodule update --init lib/pico-sdk
git submodule update --init lib/cyw43-driver
git submodule update --init lib/lwip
Expand Down
2 changes: 1 addition & 1 deletion drivers/st7735/st7735.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ namespace pimoroni {

// Native 16-bit framebuffer update
void ST7735::update(PicoGraphics *graphics) {
if(graphics->pen_type == PicoGraphics::PEN_RGB565) {
if(graphics->pen_type == PicoGraphics::PEN_RGB565 && graphics->layers == 1) {
command(reg::RAMWR, width * height * sizeof(uint16_t), (const char*)graphics->frame_buffer);
} else {
command(reg::RAMWR);
Expand Down
2 changes: 1 addition & 1 deletion drivers/st7789/st7789.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ namespace pimoroni {
void ST7789::update(PicoGraphics *graphics) {
uint8_t cmd = reg::RAMWR;

if(graphics->pen_type == PicoGraphics::PEN_RGB565) { // Display buffer is screen native
if(graphics->pen_type == PicoGraphics::PEN_RGB565 && graphics->layers == 1) { // Display buffer is screen native
command(cmd, width * height * sizeof(uint16_t), (const char*)graphics->frame_buffer);
} else {
gpio_put(dc, 0); // command mode
Expand Down
3 changes: 2 additions & 1 deletion drivers/st7789/st7789.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ namespace pimoroni {
cs(pins.cs), dc(pins.dc), wr_sck(pins.wr_sck), rd_sck(pins.rd_sck), d0(pins.d0), bl(pins.bl) {

parallel_pio = pio1;
pio_set_gpio_base(parallel_pio, d0 + 8 >= 32 ? 16 : 0);
parallel_sm = pio_claim_unused_sm(parallel_pio, true);
parallel_offset = pio_add_program(parallel_pio, &st7789_parallel_program);

//gpio_init(wr_sck);
//gpio_set_dir(wr_sck, GPIO_OUT);
//gpio_set_function(wr_sck, GPIO_FUNC_SIO);
Expand Down
4 changes: 2 additions & 2 deletions drivers/uc8151/uc8151.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ namespace pimoroni {
}

void UC8151::power_off() {
command(POF);
//command(POF);
}

void UC8151::read(uint8_t reg, size_t len, uint8_t *data) {
Expand Down Expand Up @@ -534,7 +534,7 @@ namespace pimoroni {

void UC8151::off() {
busy_wait();
command(POF); // turn off
//command(POF); // turn off
}

}
8 changes: 8 additions & 0 deletions libraries/pico_graphics/pico_graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ namespace pimoroni {
RGB* PicoGraphics::get_palette() {return nullptr;}
bool PicoGraphics::supports_alpha_blend() {return false;}

void PicoGraphics::set_layer(uint l) {
this->layer = l;
this->layer_offset = this->bounds.w * this->bounds.h * l;
};
uint PicoGraphics::get_layer() {
return this->layer;
};

void PicoGraphics::set_dimensions(int width, int height) {
bounds = clip = {0, 0, width, height};
}
Expand Down
34 changes: 25 additions & 9 deletions libraries/pico_graphics/pico_graphics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ namespace pimoroni {
}
}

constexpr operator bool() {return r || g || b;};
constexpr RGB operator+ (const RGB& c) const {return RGB(r + c.r, g + c.g, b + c.b);}
constexpr RGB& operator+=(const RGB& c) {r += c.r; g += c.g; b += c.b; return *this;}
constexpr RGB& operator-=(const RGB& c) {r -= c.r; g -= c.g; b -= c.b; return *this;}
Expand Down Expand Up @@ -226,6 +227,10 @@ namespace pimoroni {
Rect clip;
uint thickness = 1;

uint layers = 1;
uint layer = 0;
uint layer_offset = 0;

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;
Expand Down Expand Up @@ -270,6 +275,12 @@ namespace pimoroni {
PicoGraphics(uint16_t width, uint16_t height, void *frame_buffer)
: frame_buffer(frame_buffer), bounds(0, 0, width, height), clip(0, 0, width, height) {
set_font(&font6);
layers = 1;
};

PicoGraphics(uint16_t width, uint16_t height, uint16_t layers, void *frame_buffer)
: frame_buffer(frame_buffer), bounds(0, 0, width, height), clip(0, 0, width, height), layers(layers) {
set_font(&font6);
};

virtual void set_pen(uint c) = 0;
Expand All @@ -278,6 +289,9 @@ namespace pimoroni {
virtual void set_pixel_span(const Point &p, uint l) = 0;
void set_thickness(uint t);

void set_layer(uint l);
uint get_layer();

virtual int get_palette_size();
virtual RGB* get_palette();
virtual bool supports_alpha_blend();
Expand Down Expand Up @@ -330,7 +344,7 @@ namespace pimoroni {
public:
uint8_t color;

PicoGraphics_Pen1Bit(uint16_t width, uint16_t height, void *frame_buffer);
PicoGraphics_Pen1Bit(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
void set_pen(uint c) override;
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;

Expand All @@ -346,7 +360,7 @@ namespace pimoroni {
public:
uint8_t color;

PicoGraphics_Pen1BitY(uint16_t width, uint16_t height, void *frame_buffer);
PicoGraphics_Pen1BitY(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
void set_pen(uint c) override;
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;

Expand Down Expand Up @@ -387,7 +401,7 @@ namespace pimoroni {
bool cache_built = false;
std::array<uint8_t, 16> candidates;

PicoGraphics_Pen3Bit(uint16_t width, uint16_t height, void *frame_buffer);
PicoGraphics_Pen3Bit(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);

void set_pen(uint c) override;
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
Expand Down Expand Up @@ -420,7 +434,7 @@ namespace pimoroni {
bool cache_built = false;
std::array<uint8_t, 16> candidates;

PicoGraphics_PenP4(uint16_t width, uint16_t height, void *frame_buffer);
PicoGraphics_PenP4(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
void set_pen(uint c) override;
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
int update_pen(uint8_t i, uint8_t r, uint8_t g, uint8_t b) override;
Expand Down Expand Up @@ -453,7 +467,7 @@ namespace pimoroni {
bool cache_built = false;
std::array<uint8_t, 16> candidates;

PicoGraphics_PenP8(uint16_t width, uint16_t height, void *frame_buffer);
PicoGraphics_PenP8(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
void set_pen(uint c) override;
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
int update_pen(uint8_t i, uint8_t r, uint8_t g, uint8_t b) override;
Expand All @@ -478,7 +492,7 @@ namespace pimoroni {
class PicoGraphics_PenRGB332 : public PicoGraphics {
public:
RGB332 color;
PicoGraphics_PenRGB332(uint16_t width, uint16_t height, void *frame_buffer);
PicoGraphics_PenRGB332(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
void set_pen(uint c) override;
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
Expand All @@ -503,7 +517,7 @@ namespace pimoroni {
public:
RGB src_color;
RGB565 color;
PicoGraphics_PenRGB565(uint16_t width, uint16_t height, void *frame_buffer);
PicoGraphics_PenRGB565(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
void set_pen(uint c) override;
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
Expand All @@ -513,13 +527,15 @@ namespace pimoroni {
static size_t buffer_size(uint w, uint h) {
return w * h * sizeof(RGB565);
}

void frame_convert(PenType type, conversion_callback_func callback) override;
};

class PicoGraphics_PenRGB888 : public PicoGraphics {
public:
RGB src_color;
RGB888 color;
PicoGraphics_PenRGB888(uint16_t width, uint16_t height, void *frame_buffer);
PicoGraphics_PenRGB888(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers = 1);
void set_pen(uint c) override;
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
Expand Down Expand Up @@ -597,7 +613,7 @@ namespace pimoroni {
uint color;
IDirectDisplayDriver<uint8_t> &driver;

PicoGraphics_PenInky7(uint16_t width, uint16_t height, IDirectDisplayDriver<uint8_t> &direct_display_driver);
PicoGraphics_PenInky7(uint16_t width, uint16_t height, IDirectDisplayDriver<uint8_t> &direct_display_driver, uint16_t layers = 1);
void set_pen(uint c) override;
void set_pen(uint8_t r, uint8_t g, uint8_t b) override;
int create_pen(uint8_t r, uint8_t g, uint8_t b) override;
Expand Down
6 changes: 3 additions & 3 deletions libraries/pico_graphics/pico_graphics_pen_1bit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

namespace pimoroni {

PicoGraphics_Pen1Bit::PicoGraphics_Pen1Bit(uint16_t width, uint16_t height, void *frame_buffer)
: PicoGraphics(width, height, frame_buffer) {
PicoGraphics_Pen1Bit::PicoGraphics_Pen1Bit(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
: PicoGraphics(width, height, layers, frame_buffer) {
this->pen_type = PEN_1BIT;
if(this->frame_buffer == nullptr) {
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height) * layers]);
}
}

Expand Down
4 changes: 2 additions & 2 deletions libraries/pico_graphics/pico_graphics_pen_1bitY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace pimoroni {

PicoGraphics_Pen1BitY::PicoGraphics_Pen1BitY(uint16_t width, uint16_t height, void *frame_buffer)
: PicoGraphics(width, height, frame_buffer) {
PicoGraphics_Pen1BitY::PicoGraphics_Pen1BitY(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
: PicoGraphics(width, height, layers, frame_buffer) {
this->pen_type = PEN_1BIT;
if(this->frame_buffer == nullptr) {
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
Expand Down
4 changes: 2 additions & 2 deletions libraries/pico_graphics/pico_graphics_pen_3bit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace pimoroni {

PicoGraphics_Pen3Bit::PicoGraphics_Pen3Bit(uint16_t width, uint16_t height, void *frame_buffer)
: PicoGraphics(width, height, frame_buffer) {
PicoGraphics_Pen3Bit::PicoGraphics_Pen3Bit(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
: PicoGraphics(width, height, layers, frame_buffer) {
this->pen_type = PEN_3BIT;
if(this->frame_buffer == nullptr) {
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
Expand Down
4 changes: 2 additions & 2 deletions libraries/pico_graphics/pico_graphics_pen_inky7.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "pico_graphics.hpp"

namespace pimoroni {
PicoGraphics_PenInky7::PicoGraphics_PenInky7(uint16_t width, uint16_t height, IDirectDisplayDriver<uint8_t> &direct_display_driver)
: PicoGraphics(width, height, nullptr),
PicoGraphics_PenInky7::PicoGraphics_PenInky7(uint16_t width, uint16_t height, IDirectDisplayDriver<uint8_t> &direct_display_driver, uint16_t layers)
: PicoGraphics(width, height, layers, nullptr),
driver(direct_display_driver) {
this->pen_type = PEN_INKY7;
}
Expand Down
49 changes: 37 additions & 12 deletions libraries/pico_graphics/pico_graphics_pen_p4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace pimoroni {

PicoGraphics_PenP4::PicoGraphics_PenP4(uint16_t width, uint16_t height, void *frame_buffer)
: PicoGraphics(width, height, frame_buffer) {
PicoGraphics_PenP4::PicoGraphics_PenP4(uint16_t width, uint16_t height, void *frame_buffer, uint16_t layers)
: PicoGraphics(width, height, layers, frame_buffer) {
this->pen_type = PEN_P4;
if(this->frame_buffer == nullptr) {
this->frame_buffer = (void *)(new uint8_t[buffer_size(width, height)]);
Expand Down Expand Up @@ -59,6 +59,7 @@ namespace pimoroni {

// pointer to byte in framebuffer that contains this pixel
uint8_t *buf = (uint8_t *)frame_buffer;
buf += this->layer_offset / 2;
uint8_t *f = &buf[i / 2];

uint8_t o = (~i & 0b1) * 4; // bit offset within byte
Expand All @@ -74,6 +75,7 @@ namespace pimoroni {

// pointer to byte in framebuffer that contains this pixel
uint8_t *buf = (uint8_t *)frame_buffer;
buf += this->layer_offset / 2;
uint8_t *f = &buf[i / 2];

// doubled up color value, so the color is stored in both nibbles
Expand Down Expand Up @@ -144,16 +146,39 @@ namespace pimoroni {
uint8_t *src = (uint8_t *)frame_buffer;
uint8_t o = 4;

frame_convert_rgb565(callback, [&]() {
uint8_t c = *src;
uint8_t b = (c >> o) & 0xf; // bit value shifted to position

// Increment to next 4-bit entry
o ^= 4;
if (o != 0) ++src;

return cache[b];
});
if(this->layers > 1) {

uint offset = this->bounds.w * this->bounds.h / 2;

frame_convert_rgb565(callback, [&]() {
uint8_t b = 0;

// Iterate through layers in reverse order
// Return the first nonzero (not transparent) pixel
for(auto layer = this->layers; layer > 0; layer--) {
uint8_t c = *(src + offset * (layer - 1));
b = (c >> o) & 0xf; // bit value shifted to position
if (b) break;
}

// Increment to next 4-bit entry
o ^= 4;
if (o != 0) src++;

return cache[b];
});
} else {
frame_convert_rgb565(callback, [&]() {
uint8_t c = *src;
uint8_t b = (c >> o) & 0xf; // bit value shifted to position

// Increment to next 4-bit entry
o ^= 4;
if (o != 0) ++src;

return cache[b];
});
}
}
}
}
Loading