espruino / Espruino

The Espruino JavaScript interpreter - Official Repo
http://www.espruino.com/
Other
2.78k stars 746 forks source link

Bangle.js: extra graphics modes #1794

Closed gfwilliams closed 4 years ago

gfwilliams commented 4 years ago

We currently have Normal, DoubleBuffer, 120x120 and 80x80 modes.

However Widgets will only work in the 'Normal' mode.

While realistically they can't be made to work in the Doublebuffer mode due to LCD controller constraints, we could have versions of the 120x120 and 80x80 modes that are hybrids - allowing unbuffered access to the top and bottom 24px for the widgets, and buffered access to the middle section for the app.

These could be new 120x96 and 80x64 modes

They would be trivial to add, however the issue is how to swap between unbuffered and buffered modes.

We'd need an extra function like start to change to buffered mode so we could do something like:

g.start();
// draw to buffer here
g.flip(); // draws buffer and reverts to unbuffered mode for widgets

Any other ideas? What should it be called? start seems like a bad name.

Other option is to allow:

Bangle.setLCDMode("80x64buffer");
// draw here
g.flip(); // reverts to '80x64unbuffer' automatically
MaBecker commented 4 years ago

What about naming it g.popup()?

nebbishhacker commented 4 years ago

Why not just

Bangle.setLCDMode();
Bangle.drawWidgets();
Bangle.setLCDMode("80x64");
// draw to buffer
g.flip();

?

Even better would be if the drawWidgets() call itself switched to unbuffered mode and back again automatically.

gfwilliams commented 4 years ago

The issue is that widgets redraw themselves automatically (eg when power plugged/unplugged).

Also Bangle.setLCDMode() will try and free the 80x64 buffer, and reallocation will be slow so we want to avoid that if possible :)

But yeah, I think just:

Bangle.setLCDMode("80x64");
// draw to buffer
g.flip();

Would work well? So g.flip() drops back to unbuffered mode, but keeps the 80x64 buffer?

nebbishhacker commented 4 years ago

g.flip() dropping to unbuffered mode in some graphics modes but not others could be a bit confusing. That might not be an issue if it's well documented, though. (Or documented at all - I don't see flip() anywhere on https://banglejs.com/reference).

Alternatively, could the app manage the buffer itself? This general approach seems to work in the emulator:

var b = Graphics.createArrayBuffer(120, 96, 16);

function step() {
    // draw using b instead of g
    g.drawImage({width: 120, height: 96, bpp: 16, buffer: b.buffer}, 0, 24, { scale: 2 });
}
gfwilliams commented 4 years ago

I don't see flip() anywhere

That got added to the docs at http://www.espruino.com/Reference#l_Graphics_flip but the Bangle specific docs are a little out of date

Alternatively, could the app manage the buffer itself?

Yes, you can do that right now - however it'll be slower, both to write to the offscreen buffer and to flip. I guess there's a lot to be said for just trying to provide a fast path for scale=2 and 3 instead of a special graphics mode. It'd be backwards compatible too.