Skip to content
This repository was archived by the owner on Dec 23, 2021. It is now read-only.

Commit b8101e7

Browse files
committed
performance improvements
1 parent 6f957a3 commit b8101e7

File tree

1 file changed

+64
-51
lines changed

1 file changed

+64
-51
lines changed

src/base_circuitpython/displayio/tile_grid.py

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from PIL import Image
1+
from PIL import Image, ImageColor
22
from . import constants as CONSTANTS
33
import threading
4+
import queue
45

56
# TileGrid implementation loosely based on the
67
# displayio.TileGrid class in Adafruit CircuitPython
@@ -13,7 +14,7 @@
1314

1415
# Create a new black (default) image
1516
img = Image.new(
16-
"RGB", (CONSTANTS.SCREEN_HEIGHT_WIDTH, CONSTANTS.SCREEN_HEIGHT_WIDTH), "black"
17+
"RGBA", (CONSTANTS.SCREEN_HEIGHT_WIDTH, CONSTANTS.SCREEN_HEIGHT_WIDTH), (0, 0, 0, 0)
1718
)
1819

1920
# Create the pixel map
@@ -84,59 +85,71 @@ def draw(self, x, y, scale):
8485
x = self.x * scale + x
8586
y = self.y * scale + y
8687

87-
if self.tile_height > 1 and self.tile_width > 1:
88-
y_mid = int(self.tile_height / 2)
89-
x_mid = int(self.tile_width / 2)
90-
thread_1 = threading.Thread(
91-
target=self.draw_group, args=(x, y, 0, y_mid, 0, x_mid, scale,),
92-
)
93-
thread_2 = threading.Thread(
94-
target=self.draw_group,
95-
args=(x, y, 0, y_mid, x_mid, self.tile_width, scale),
96-
)
97-
thread_3 = threading.Thread(
98-
target=self.draw_group,
99-
args=(x, y, y_mid, self.tile_height, 0, x_mid, scale),
100-
)
101-
thread_4 = threading.Thread(
102-
target=self.draw_group,
103-
args=(x, y, y_mid, self.tile_height, x_mid, self.tile_width, scale,),
104-
)
105-
thread_1.start()
106-
thread_2.start()
107-
thread_3.start()
108-
thread_4.start()
109-
110-
thread_1.join()
111-
thread_2.join()
112-
thread_3.join()
113-
thread_4.join()
114-
else:
115-
self.draw_group(
116-
x, y, 0, self.tile_height, 0, self.tile_width, scale,
117-
)
88+
new_shape = self.draw_group(
89+
x, y, 0, self.tile_height, 0, self.tile_width, scale
90+
)
91+
92+
img.paste(new_shape, (x, y), new_shape)
11893

11994
def draw_group(self, x, y, y_start, y_end, x_start, x_end, scale):
120-
# return
95+
height = y_end - y_start
96+
width = x_end - x_start
97+
98+
this_img = Image.new("RGBA", (width * scale, height * scale), (0, 0, 0, 0))
99+
this_img.putalpha(0)
100+
this_bmp_img = this_img.load()
101+
121102
for i in range(y_start, y_end):
122103
for j in range(x_start, x_end):
123-
self.fill_pixel(i, j, x, y, scale)
104+
x_offset = j * scale
105+
y_offset = i * scale
106+
107+
x_max = min(x_offset + scale, width * scale)
108+
y_max = min(y_offset + scale, height * scale)
109+
110+
curr_val = self.bitmap[j, i]
111+
transparent = self.pixel_shader._Palette__contents[curr_val].transparent
112+
113+
if not transparent and x_offset >= 0 and y_offset >= 0:
114+
115+
curr_colour = self.pixel_shader[curr_val]
116+
self.fill_pixel(
117+
curr_val,
118+
curr_colour,
119+
x_offset,
120+
y_offset,
121+
scale,
122+
x_max,
123+
y_max,
124+
this_bmp_img,
125+
)
126+
127+
return this_img
124128

125129
# helper method for drawing pixels on bmp_img
126130
# given the src, offset, and scale
127-
def fill_pixel(self, i, j, x, y, scale):
128-
129-
curr_val = self.bitmap[j, i]
130-
transparent = self.pixel_shader._Palette__contents[curr_val].transparent
131-
x_offset = x + (j * scale)
132-
y_offset = y + (i * scale)
133-
if not transparent and x_offset >= 0 and y_offset >= 0:
134-
135-
x_max = min(x_offset + scale, 240)
136-
y_max = min(y_offset + scale, 240)
137-
138-
curr_colour = self.pixel_shader[curr_val]
139-
for new_y in range(y_offset, y_max):
140-
for new_x in range(x_offset, x_max):
141-
if curr_val != bmp_img[new_x, new_y]:
142-
bmp_img[new_x, new_y] = curr_colour
131+
def fill_pixel(
132+
self,
133+
curr_val,
134+
curr_colour,
135+
x_offset,
136+
y_offset,
137+
scale,
138+
x_max,
139+
y_max,
140+
this_bmp_img,
141+
):
142+
143+
for new_y in range(y_offset, y_max):
144+
for new_x in range(x_offset, x_max):
145+
try:
146+
if isinstance(curr_colour, tuple):
147+
this_bmp_img[new_x, new_y] = curr_colour
148+
else:
149+
this_bmp_img[new_x, new_y] = (
150+
(curr_colour >> 16) & 255,
151+
(curr_colour >> 8) & 255,
152+
(curr_colour) & 255,
153+
)
154+
except IndexError:
155+
pass

0 commit comments

Comments
 (0)