Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/main/python/preponderous/graphik/graphik.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,13 @@ def drawImage(self, filePath, xpos, ypos, width, height):
# mid-run will not be picked up -- the normal tradeoff for a game
# asset cache.
if filePath not in self._images:
self._images[filePath] = pygame.image.load(filePath)
# convert_alpha() rebuilds the surface in the display's pixel
# format (and preserves any per-pixel alpha), which is what makes
# repeated blit() calls fast -- an unconverted surface is
# reformatted on every single blit. Doing it once here, alongside
# the load, keeps that cost out of the per-frame path this cache
# exists to protect.
self._images[filePath] = pygame.image.load(filePath).convert_alpha()
image = self._images[filePath]

size = (width, height)
Expand Down
20 changes: 20 additions & 0 deletions src/test/python/preponderous/graphik/test_graphik.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,26 @@ def test_draw_image_rescales_when_size_changes(monkeypatch, tmp_path):
assert [args[1] for args in scaled] == [(10, 10), (12, 12), (10, 10)]


def test_draw_image_converts_loaded_surface_for_faster_blits(monkeypatch, tmp_path):
# pygame.Surface is a builtin type (its methods can't be monkeypatched),
# so observe the conversion through the surface actually handed to
# transform.scale rather than spying on convert_alpha() directly.
graphik = _make_graphik()
image_path = tmp_path / "red.bmp"
_write_solid_image(image_path, (255, 0, 0))

rawImage = pygame.image.load(str(image_path))
scaled = _count_image_scales(monkeypatch)

graphik.drawImage(str(image_path), 0, 0, 10, 10)

sourcePassedToScale = scaled[0][0]
# convert_alpha() adds a per-pixel alpha channel that a plain BMP load
# does not have; its presence proves the cached surface was converted.
assert not rawImage.get_flags() & pygame.SRCALPHA
assert sourcePassedToScale.get_flags() & pygame.SRCALPHA


def test_draw_image_still_blits_correctly_after_caching(tmp_path):
pygame.display.init()
display = pygame.display.set_mode((20, 20))
Expand Down
Loading