summaryrefslogtreecommitdiff
path: root/wasp/draw565.py
diff options
context:
space:
mode:
authorDaniel Thompson <daniel@redfelineninja.org.uk>2020-04-08 20:50:42 (GMT)
committerDaniel Thompson <daniel@redfelineninja.org.uk>2020-04-08 20:50:42 (GMT)
commitfd64abe882a2064bad0131424835c169e365d83f (patch)
treed63acda8b2afb03e8ed6ee4f5dfea48d9f30f2a7 /wasp/draw565.py
parentac61d8a1c114d7f4ca8000afc02c843db5fd6245 (diff)
wasp: draw565: Optimize the 2-bit RLE drawing functions
There's a bunch of different changes here but there are only really three big wins. The biggest win comes from restructuring the 2-bit RLE decode loop to avoid the inner function (~20%) but the switch to 16-bit writes in _fill() and adoption of quick_write (e.g. no CS toggling) are also note worthy (and about 5% each).
Diffstat (limited to 'wasp/draw565.py')
-rw-r--r--wasp/draw565.py61
1 files changed, 31 insertions, 30 deletions
diff --git a/wasp/draw565.py b/wasp/draw565.py
index 50ff592..8dd8de5 100644
--- a/wasp/draw565.py
+++ b/wasp/draw565.py
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
# Copyright (C) 2020 Daniel Thompson
+import array
import fonts.sans24
import micropython
@@ -45,13 +46,10 @@ def _expand_rgb(eightbit: int) -> int:
@micropython.viper
def _fill(mv, color: int, count: int, offset: int):
- p = ptr8(mv)
- colorhi = color >> 8
- colorlo = color & 0xff
+ p = ptr16(mv)
- for x in range(count):
- p[2*(x+offset) ] = colorhi
- p[2*(x+offset) + 1] = colorlo
+ for x in range(offset, offset+count):
+ p[x] = color
def _bounding_box(s, font):
w = 0
@@ -110,6 +108,7 @@ class Draw565(object):
def rleblit(self, image, pos=(0, 0), fg=0xffff, bg=0):
"""Decode and draw a 1-bit RLE image."""
display = self._display
+ write_data = display.write_data
(sx, sy, rle) = image
display.set_window(pos[0], pos[1], sx, sy)
@@ -126,7 +125,7 @@ class Draw565(object):
rl -= count
if bp >= sx:
- display.write_data(buf)
+ write_data(buf)
bp = 0
if color == bg:
@@ -138,48 +137,50 @@ class Draw565(object):
def rle2bit(self, image, x, y):
"""Decode and draw a 2-bit RLE image."""
display = self._display
+ quick_write = display.quick_write
(sx, sy, rle) = image
display.set_window(x, y, sx, sy)
+ palette = array.array('H', (0, 0xfffe, 0x7bef, 0xffff))
+ next_color = 1
+ rl = 0
buf = memoryview(display.linebuffer)[0:2*sx]
bp = 0
- rl = 0
- palette = [ 0, 0xfffe, 0x7bef, 0xffff ]
- next_color = 1
-
- def blit_run(color, rl):
- nonlocal bp
- while rl:
- count = min(sx - bp, rl)
- _fill(buf, color, count, bp)
- bp += count
- rl -= count
-
- if bp >= sx:
- display.write_data(buf)
- bp = 0
+ display.quick_start()
for op in rle:
if rl == 0:
px = op >> 6
rl = op & 0x3f
if 0 == rl:
rl = -1
- elif rl < 63:
- blit_run(palette[px], rl)
- rl = 0
+ continue
+ if rl >= 63:
+ continue
elif rl > 0:
rl += op
- if op < 255:
- blit_run(palette[px], rl)
- rl = 0
+ if op >= 255:
+ continue
else:
palette[next_color] = _expand_rgb(op)
- next_color += 1
- if next_color >= len(palette):
+ if next_color < 3:
+ next_color += 1
+ else:
next_color = 1
rl = 0
+ continue
+
+ while rl:
+ count = min(sx - bp, rl)
+ _fill(buf, palette[px], count, bp)
+ bp += count
+ rl -= count
+
+ if bp >= sx:
+ quick_write(buf)
+ bp = 0
+ display.quick_end()
def set_color(self, color, bg=0):
"""Set the foreground (color) and background (bg) color.