waveshare213v2: Implement flicker-free partial updates

Update both image buffers (B/W and red) and configure the controller to
only refresh the changed areas. With this change the "DrawPartial"
function becomes equivalent to "Draw" and is thus marked as deprecated.
It didn't really provide additional functionality before as partial
updates weren't truly implemented.

Signed-off-by: Michael Hanselmann <public@hansmi.ch>
pull/41/head
Michael Hanselmann 4 years ago
parent 04d108ccac
commit 8ec566564c

@ -78,8 +78,15 @@ func configDisplayMode(ctrl controller, mode PartialUpdate, lut LUT) {
} }
func updateDisplay(ctrl controller, mode PartialUpdate) { func updateDisplay(ctrl controller, mode PartialUpdate) {
var displayUpdateFlags byte
if mode == Partial {
// Make use of red buffer
displayUpdateFlags = 0b1000_0000
}
ctrl.sendCommand(displayUpdateControl1) ctrl.sendCommand(displayUpdateControl1)
ctrl.sendData([]byte{0}) ctrl.sendData([]byte{displayUpdateFlags})
ctrl.sendCommand(displayUpdateControl2) ctrl.sendCommand(displayUpdateControl2)
ctrl.sendData([]byte{0xC7}) ctrl.sendData([]byte{0xC7})

@ -138,7 +138,7 @@ func TestUpdateDisplay(t *testing.T) {
name: "partial", name: "partial",
mode: Partial, mode: Partial,
want: []record{ want: []record{
{cmd: displayUpdateControl1, data: []byte{0}}, {cmd: displayUpdateControl1, data: []byte{0x80}},
{cmd: displayUpdateControl2, data: []byte{0xc7}}, {cmd: displayUpdateControl2, data: []byte{0xc7}},
{cmd: masterActivation}, {cmd: masterActivation},
}, },

@ -239,30 +239,10 @@ func (d *Dev) Bounds() image.Rectangle {
return image.Rect(0, 0, d.opts.Width, d.opts.Height) return image.Rect(0, 0, d.opts.Width, d.opts.Height)
} }
// Draw draws the given image to the display. // Draw draws the given image to the display. Only the destination area is
// uploaded. Depending on the update mode the whole display or the destination
// area is refreshed.
func (d *Dev) Draw(dstRect image.Rectangle, src image.Image, srcPts image.Point) error { func (d *Dev) Draw(dstRect image.Rectangle, src image.Image, srcPts image.Point) error {
opts := drawOpts{
cmd: writeRAMBW,
devSize: image.Pt(d.opts.Width, d.opts.Height),
buffer: d.buffer,
dstRect: dstRect,
src: src,
srcPts: srcPts,
}
eh := errorHandler{d: *d}
drawImage(&eh, &opts)
if eh.err == nil {
updateDisplay(&eh, d.mode)
}
return eh.err
}
// DrawPartial draws the given image to the display. Display will update only changed pixel.
func (d *Dev) DrawPartial(dstRect image.Rectangle, src image.Image, srcPts image.Point) error {
opts := drawOpts{ opts := drawOpts{
devSize: image.Pt(d.opts.Width, d.opts.Height), devSize: image.Pt(d.opts.Width, d.opts.Height),
buffer: d.buffer, buffer: d.buffer,
@ -273,6 +253,7 @@ func (d *Dev) DrawPartial(dstRect image.Rectangle, src image.Image, srcPts image
eh := errorHandler{d: *d} eh := errorHandler{d: *d}
// Keep the two buffers in sync.
for _, cmd := range []byte{writeRAMBW, writeRAMRed} { for _, cmd := range []byte{writeRAMBW, writeRAMRed} {
opts.cmd = cmd opts.cmd = cmd
@ -290,6 +271,13 @@ func (d *Dev) DrawPartial(dstRect image.Rectangle, src image.Image, srcPts image
return eh.err return eh.err
} }
// DrawPartial draws the given image to the display.
//
// Deprecated: Use Draw instead. DrawPartial merely forwards all calls.
func (d *Dev) DrawPartial(dstRect image.Rectangle, src image.Image, srcPts image.Point) error {
return d.Draw(dstRect, src, srcPts)
}
// Halt clears the display. // Halt clears the display.
func (d *Dev) Halt() error { func (d *Dev) Halt() error {
return d.Clear(image1bit.On) return d.Clear(image1bit.On)

Loading…
Cancel
Save