From 66c03577e02e91ebfa4a212bcd1723e473c6555d Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 17 Sep 2024 10:57:58 +0100 Subject: [PATCH] Graphics: allow arraybuffer graphics to be instantiated with an ArrayBuffer (rather than it always allocating one) --- libs/graphics/jswrap_graphics.c | 13 +++++++++++-- libs/graphics/lcd_arraybuffer.c | 10 +++++++--- libs/graphics/lcd_arraybuffer.h | 2 +- libs/hexbadge/jswrap_hexbadge.c | 2 +- libs/pixljs/jswrap_pixljs.c | 2 +- 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/libs/graphics/jswrap_graphics.c b/libs/graphics/jswrap_graphics.c index da4fa4b2d..784bf3abc 100644 --- a/libs/graphics/jswrap_graphics.c +++ b/libs/graphics/jswrap_graphics.c @@ -603,7 +603,8 @@ static bool isValidBPP(int bpp) { "`vertical_byte` = whether to align bits in a byte vertically or not", "`msb` = when bits<8, store pixels most significant bit first, when bits>8, store most significant byte first", "`interleavex` = Pixels 0,2,4,etc are from the top half of the image, 1,3,5,etc from the bottom half. Used for P3 LED panels.", - "`color_order` = re-orders the colour values that are supplied via setColor" + "`color_order` = re-orders the colour values that are supplied via setColor", + "`buffer` = if specified, createArrayBuffer won't create a new buffer but will use the given one" ]] ], "return" : ["JsVar","The new Graphics object"], @@ -632,6 +633,7 @@ JsVar *jswrap_graphics_createArrayBuffer(int width, int height, int bpp, JsVar * gfx.data.flags = JSGRAPHICSFLAGS_NONE; gfx.graphicsVar = parent; + JsVar *optionalBuffer = 0; if (jsvIsObject(options)) { if (jsvObjectGetBoolChild(options, "zigzag")) gfx.data.flags = (JsGraphicsFlags)(gfx.data.flags | JSGRAPHICSFLAGS_ARRAYBUFFER_ZIGZAG); @@ -668,9 +670,16 @@ JsVar *jswrap_graphics_createArrayBuffer(int width, int height, int bpp, JsVar * jsWarn("color_order must be 3 characters"); jsvUnLock(colorv); } + optionalBuffer = jsvObjectGetChildIfExists(options, "buffer"); + if (optionalBuffer && !jsvIsArrayBuffer(optionalBuffer)) { + jsExceptionHere(JSET_ERROR, "'buffer' should be ArrayBuffer, got %t", optionalBuffer); + jsvUnLock(optionalBuffer); + return 0; + } } - lcdInit_ArrayBuffer(&gfx); + lcdInit_ArrayBuffer(&gfx, optionalBuffer); + jsvUnLock(optionalBuffer); graphicsSetVarInitial(&gfx); return parent; } diff --git a/libs/graphics/lcd_arraybuffer.c b/libs/graphics/lcd_arraybuffer.c index 5399aabc2..3526e108e 100644 --- a/libs/graphics/lcd_arraybuffer.c +++ b/libs/graphics/lcd_arraybuffer.c @@ -315,10 +315,14 @@ void lcdScroll_ArrayBuffer_flat8(JsGraphics *gfx, int xdir, int ydir, int x1, in -void lcdInit_ArrayBuffer(JsGraphics *gfx) { +void lcdInit_ArrayBuffer(JsGraphics *gfx, JsVar *optionalBuffer) { // create buffer - JsVar *buf = jswrap_arraybuffer_constructor((int)graphicsGetMemoryRequired(gfx)); - jsvAddNamedChildAndUnLock(gfx->graphicsVar, buf, "buffer"); + if (optionalBuffer) { + jsvAddNamedChild(gfx->graphicsVar, optionalBuffer, "buffer"); + } else { + JsVar *buf = jswrap_arraybuffer_constructor((int)graphicsGetMemoryRequired(gfx)); + jsvAddNamedChildAndUnLock(gfx->graphicsVar, buf, "buffer"); + } } void lcdSetCallbacks_ArrayBuffer(JsGraphics *gfx) { diff --git a/libs/graphics/lcd_arraybuffer.h b/libs/graphics/lcd_arraybuffer.h index f330c04f7..9dc961485 100644 --- a/libs/graphics/lcd_arraybuffer.h +++ b/libs/graphics/lcd_arraybuffer.h @@ -13,7 +13,7 @@ */ #include "graphics.h" -void lcdInit_ArrayBuffer(JsGraphics *gfx); +void lcdInit_ArrayBuffer(JsGraphics *gfx, JsVar *optionalBuffer); void lcdSetCallbacks_ArrayBuffer(JsGraphics *gfx); // these use gfx->backendData as a pointer to data. They're exported so lcd_st7789_8bit can use them for fast offscreen rendering diff --git a/libs/hexbadge/jswrap_hexbadge.c b/libs/hexbadge/jswrap_hexbadge.c index cf69fab43..b4d008274 100644 --- a/libs/hexbadge/jswrap_hexbadge.c +++ b/libs/hexbadge/jswrap_hexbadge.c @@ -280,7 +280,7 @@ void jswrap_badge_init() { gfx.data.type = JSGRAPHICSTYPE_ARRAYBUFFER; gfx.data.flags = JSGRAPHICSFLAGS_ARRAYBUFFER_VERTICAL_BYTE | JSGRAPHICSFLAGS_INVERT_X; gfx.graphicsVar = graphics; - lcdInit_ArrayBuffer(&gfx); + lcdInit_ArrayBuffer(&gfx, NULL); graphicsSetVarInitial(&gfx); jsvObjectSetChild(execInfo.root,"g",graphics); // Set initial image diff --git a/libs/pixljs/jswrap_pixljs.c b/libs/pixljs/jswrap_pixljs.c index 0baec5ca7..3f7f6bf54 100644 --- a/libs/pixljs/jswrap_pixljs.c +++ b/libs/pixljs/jswrap_pixljs.c @@ -364,7 +364,7 @@ void jswrap_pixljs_init() { gfx.data.type = JSGRAPHICSTYPE_ARRAYBUFFER; gfx.data.flags = JSGRAPHICSFLAGS_ARRAYBUFFER_MSB; gfx.graphicsVar = graphics; - lcdInit_ArrayBuffer(&gfx); + lcdInit_ArrayBuffer(&gfx, NULL); graphicsSetVarInitial(&gfx); jsvObjectSetChild(execInfo.root, "g", graphics); jsvObjectSetChild(execInfo.hiddenRoot, JS_GRAPHICS_VAR, graphics);