GFXcanvas: Allow subclass to take charge of buffer allocations (#465)

* GFXcanvas: Allow subclass to take charge of buffer allocations

In Adafruit_dvhstx, the low level driver takes charge of the framebuffer
allocations. Consequently, any allocation by the GFXcanvas class would be
an unused waste of memory.

Introduce a new constructor parameter `bool allocate_buffer=true`. The
default preserves the old behavior of allocating the buffer in the
constructor and freeing it in the destructor, while passing in `false`
skips buffer allocation & freeing.

In this case, the subclass must allocate the buffer before the first
drawing operation (such as in its constructor or begin method), and
free it in its own destructor or end method.

The subclass can also freely change the buffer pointer at runtime, for
instance in a swap method if the underlying framebuffer is double-buffered.

* experimentally run a different clang-format

This runs version 19.1.7: uvx clang-format -i *.cpp *.h

the changes look similar to what was shown during CI

* undo one edit that ci doesn't like
This commit is contained in:
Jeff Epler authored and GitHub committed 2025-02-19 10:15:01 -05:00
1 parent 1124b157d5
commit f80daa51c9
4 files changed
+89 -57

No files matched your search

+42 -16
View File
@@ -1758,12 +1758,21 @@ const uint8_t PROGMEM GFXcanvas1::GFXclrBit[] = {0x7F, 0xBF, 0xDF, 0xEF,
@brief Instatiate a GFX 1-bit canvas context for graphics
@param w Display width, in pixels
@param h Display height, in pixels
@param allocate_buffer If true, a buffer is allocated with malloc. If
false, the subclass must initialize the buffer before any drawing operation,
and free it in the destructor. If false (the default), the buffer is
allocated and freed by the library.
*/
/**************************************************************************/
GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
uint32_t bytes = ((w + 7) / 8) * h;
if ((buffer = (uint8_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h, bool allocate_buffer)
: Adafruit_GFX(w, h), buffer_owned(allocate_buffer) {
if (allocate_buffer) {
uint32_t bytes = ((w + 7) / 8) * h;
if ((buffer = (uint8_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
}
} else {
buffer = nullptr;
}
}
@@ -1773,7 +1782,7 @@ GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
*/
/**************************************************************************/
GFXcanvas1::~GFXcanvas1(void) {
if (buffer)
if (buffer && buffer_owned)
free(buffer);
}
@@ -2111,13 +2120,21 @@ void GFXcanvas1::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
@brief Instatiate a GFX 8-bit canvas context for graphics
@param w Display width, in pixels
@param h Display height, in pixels
@param allocate_buffer If true, a buffer is allocated with malloc. If
false, the subclass must initialize the buffer before any drawing operation,
and free it in the destructor. If false (the default), the buffer is
allocated and freed by the library.
*/
/**************************************************************************/
GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
uint32_t bytes = w * h;
if ((buffer = (uint8_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
}
GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h, bool allocate_buffer)
: Adafruit_GFX(w, h), buffer_owned(allocate_buffer) {
if (allocate_buffer) {
uint32_t bytes = w * h;
if ((buffer = (uint8_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
}
} else
buffer = nullptr;
}
/**************************************************************************/
@@ -2126,7 +2143,7 @@ GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
*/
/**************************************************************************/
GFXcanvas8::~GFXcanvas8(void) {
if (buffer)
if (buffer && buffer_owned)
free(buffer);
}
@@ -2379,12 +2396,21 @@ void GFXcanvas8::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
@brief Instatiate a GFX 16-bit canvas context for graphics
@param w Display width, in pixels
@param h Display height, in pixels
@param allocate_buffer If true, a buffer is allocated with malloc. If
false, the subclass must initialize the buffer before any drawing operation,
and free it in the destructor. If false (the default), the buffer is
allocated and freed by the library.
*/
/**************************************************************************/
GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
uint32_t bytes = w * h * 2;
if ((buffer = (uint16_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h, bool allocate_buffer)
: Adafruit_GFX(w, h), buffer_owned(allocate_buffer) {
if (allocate_buffer) {
uint32_t bytes = w * h * 2;
if ((buffer = (uint16_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
}
} else {
buffer = nullptr;
}
}
@@ -2394,7 +2420,7 @@ GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
*/
/**************************************************************************/
GFXcanvas16::~GFXcanvas16(void) {
if (buffer)
if (buffer && buffer_owned)
free(buffer);
}