From 8e5da844b6c4db28be47778ab1264a969101d2c7 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 3 Jan 2019 14:11:27 -0500 Subject: [PATCH] client: copy screenshot image in draw manager callback The image backed by the client buffer which will change on the next frame, however the screenshot plugin uses both executor thread and EDT thread to paint the full screenshot, and so it requires the image will not change. Note the gpu plugin already returns a new image because it has to pull it out of the GL. --- .../net/runelite/client/callback/Hooks.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index 81c15d13f6..77f4de94bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -347,7 +347,7 @@ public class Hooks implements Callbacks : RenderingHints.VALUE_INTERPOLATION_BILINEAR); stretchedGraphics.drawImage(image, 0, 0, stretchedDimensions.width, stretchedDimensions.height, null); - finalImage = image = stretchedImage; + finalImage = stretchedImage; } else { @@ -355,9 +355,27 @@ public class Hooks implements Callbacks } // Draw the image onto the game canvas - graphics.drawImage(image, 0, 0, client.getCanvas()); + graphics.drawImage(finalImage, 0, 0, client.getCanvas()); - drawManager.processDrawComplete(() -> finalImage); + // finalImage is backed by the client buffer which will change soon. make a copy + // so that callbacks can safely use it later from threads. + drawManager.processDrawComplete(() -> copy(finalImage)); + } + + /** + * Copy an image + * @param src + * @return + */ + private static Image copy(Image src) + { + final int width = src.getWidth(null); + final int height = src.getHeight(null); + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics graphics = image.getGraphics(); + graphics.drawImage(src, 0, 0, width, height, null); + graphics.dispose(); + return image; } @Override