0

textures: cache when a texture couldn't be found

Previously, textures that couldn't be found the first time around
would not have this fact cached, so we'd run through the whole
slow path of find_file with each blockid and data entry.

This is what caused the chests texture generation function to take
almost 12 seconds on my system, as it is looking for "normal.png"
that hasn't existed in Minecraft textures for ages.

Shoving the exception, if one is encountered, into the cache, and
then re-raising it if we load it from the texture cache brings this
number down to about 2 seconds. That's six times as fast!

Concerns issue #1604.
This commit is contained in:
Nicolas F
2019-07-04 16:40:11 +02:00
parent 1e8735328e
commit 864be71667

View File

@@ -357,10 +357,21 @@ class Textures(object):
def load_image(self, filename):
"""Returns an image object"""
if filename in self.texture_cache:
return self.texture_cache[filename]
try:
img = self.texture_cache[filename]
if isinstance(img, Exception): # Did we cache an exception?
raise img # Okay then, raise it.
return img
except KeyError:
pass
try:
fileobj = self.find_file(filename)
except (TextureException, IOError) as e:
# We cache when our good friend find_file can't find
# a texture, so that we do not repeatedly search for it.
self.texture_cache[filename] = e
raise e
buffer = BytesIO(fileobj.read())
img = Image.open(buffer).convert("RGBA")
self.texture_cache[filename] = img