From f71070f7f3734a71c480b0582f788e7e2decc123 Mon Sep 17 00:00:00 2001 From: LoafyLemon Date: Fri, 24 Mar 2023 15:36:21 +0000 Subject: [PATCH] Memory Leak fix * Fixed a memory leak inside ScreenshotImage class due to unsafe access and storage of list of renders --- game/scripts/gui/_gui_.rpy | 10 ++++---- game/scripts/utility/screenshot_image.rpy | 28 +++++++++-------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/game/scripts/gui/_gui_.rpy b/game/scripts/gui/_gui_.rpy index 1ab8c550..2ce161e8 100644 --- a/game/scripts/gui/_gui_.rpy +++ b/game/scripts/gui/_gui_.rpy @@ -6,7 +6,7 @@ init offset = -2 init python in gui: import store - from store import settings, ScreenshotImage + from store import settings init(1080, 600) @@ -60,11 +60,11 @@ init python in gui: renpy.store.disable_game_menu() renpy.choice_for_skipping() renpy.pause(0.001) # Give renderer the chance to catch up with transitions - bg = ScreenshotImage.capture() - renpy.call_in_new_context("gui_init_context", bg, label, *args, **kwargs) + renpy.store.screenshot.capture() + renpy.call_in_new_context("gui_init_context", label, *args, **kwargs) -label gui_init_context(bg, label, *args , **kwargs): - $ renpy.show("screenshot", what=bg, at_list=[Transform(size=(config.screen_width, config.screen_height))]) +label gui_init_context(label, *args , **kwargs): + $ renpy.show("screenshot", what=screenshot.image, at_list=[Transform(size=(config.screen_width, config.screen_height))]) $ renpy.call(label, *args, **kwargs) return diff --git a/game/scripts/utility/screenshot_image.rpy b/game/scripts/utility/screenshot_image.rpy index 23f8a28c..1432bd54 100644 --- a/game/scripts/utility/screenshot_image.rpy +++ b/game/scripts/utility/screenshot_image.rpy @@ -1,25 +1,19 @@ init -10 python: - class ScreenshotImage(im.ImageBase): - def __init__(self, root, **properties): - super(ScreenshotImage, self).__init__(root, **properties) - self.root = root - # self.cache = False - # Sometimes causes segfault, maybe only if cache = True? + class ScreenshotImage(NoRollback): + _image = None - def load(self): - sw, sh = config.screen_width, config.screen_height - render = renpy.display.render.render_screen(self.root, sw, sh) - return renpy.display.draw.screenshot(render) + def __init__(self): + pass - @staticmethod - def capture(retain=True): - if retain: - # Prevent the image from being recaptured after load - renpy.retain_after_load() + def capture(self): + self._image = Transform(im.Data(renpy.screenshot_to_bytes(None), "screenshot.png"), size=(config.screen_width, config.screen_height)) - root = renpy.display.core.scene_lists().make_layer("screens", {}) - return ScreenshotImage(root) + @property + def image(self): + return self._image + + screenshot = ScreenshotImage() def displayable_to_file(d, path, size=(config.screen_width, config.screen_height), crop=None, coloralpha=(0, 255, 0)): crop = crop or (0, 0, size[0], size[1])