draw manager: lazily fetch screenshot image

Also no longer pass images to every frame listener. With GPU rendering
it is expensive to get Images each frame.
This commit is contained in:
Adam
2018-11-13 18:45:24 -05:00
parent e603a2a157
commit 3c84d98638
3 changed files with 35 additions and 12 deletions

View File

@@ -283,6 +283,7 @@ public class Hooks implements Callbacks
} }
Image image = mainBufferProvider.getImage(); Image image = mainBufferProvider.getImage();
final Image finalImage;
final Graphics2D graphics2d = (Graphics2D) image.getGraphics(); final Graphics2D graphics2d = (Graphics2D) image.getGraphics();
try try
@@ -334,13 +335,17 @@ public class Hooks implements Callbacks
: RenderingHints.VALUE_INTERPOLATION_BILINEAR); : RenderingHints.VALUE_INTERPOLATION_BILINEAR);
stretchedGraphics.drawImage(image, 0, 0, stretchedDimensions.width, stretchedDimensions.height, null); stretchedGraphics.drawImage(image, 0, 0, stretchedDimensions.width, stretchedDimensions.height, null);
image = stretchedImage; finalImage = image = stretchedImage;
}
else
{
finalImage = image;
} }
// Draw the image onto the game canvas // Draw the image onto the game canvas
graphics.drawImage(image, 0, 0, client.getCanvas()); graphics.drawImage(image, 0, 0, client.getCanvas());
drawManager.processDrawComplete(image); drawManager.processDrawComplete(() -> finalImage);
} }
@Override @Override

View File

@@ -24,8 +24,6 @@
*/ */
package net.runelite.client.plugins.fps; package net.runelite.client.plugins.fps;
import java.awt.Image;
import java.util.function.Consumer;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.events.FocusChanged; import net.runelite.api.events.FocusChanged;
@@ -42,7 +40,7 @@ import net.runelite.api.events.FocusChanged;
* Enforcing FPS in the draw code does not impact the client engine's ability to run including its audio, * Enforcing FPS in the draw code does not impact the client engine's ability to run including its audio,
* even when forced to 1 FPS with this plugin. * even when forced to 1 FPS with this plugin.
*/ */
public class FpsDrawListener implements Consumer<Image> public class FpsDrawListener implements Runnable
{ {
private static final int SAMPLE_SIZE = 4; private static final int SAMPLE_SIZE = 4;
@@ -90,7 +88,7 @@ public class FpsDrawListener implements Consumer<Image>
} }
@Override @Override
public void accept(Image image) public void run()
{ {
if (!isEnforced()) if (!isEnforced())

View File

@@ -30,6 +30,7 @@ import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -37,10 +38,10 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class DrawManager public class DrawManager
{ {
private final List<Consumer<Image>> everyFrame = new CopyOnWriteArrayList<>(); private final List<Runnable> everyFrame = new CopyOnWriteArrayList<>();
private final Queue<Consumer<Image>> nextFrame = new ConcurrentLinkedQueue<>(); private final Queue<Consumer<Image>> nextFrame = new ConcurrentLinkedQueue<>();
public void registerEveryFrameListener(Consumer<Image> everyFrameListener) public void registerEveryFrameListener(Runnable everyFrameListener)
{ {
if (!everyFrame.contains(everyFrameListener)) if (!everyFrame.contains(everyFrameListener))
{ {
@@ -48,7 +49,7 @@ public class DrawManager
} }
} }
public void unregisterEveryFrameListener(Consumer<Image> everyFrameListener) public void unregisterEveryFrameListener(Runnable everyFrameListener)
{ {
everyFrame.remove(everyFrameListener); everyFrame.remove(everyFrameListener);
} }
@@ -58,13 +59,13 @@ public class DrawManager
nextFrame.add(nextFrameListener); nextFrame.add(nextFrameListener);
} }
public void processDrawComplete(Image image) public void processDrawComplete(Supplier<Image> imageSupplier)
{ {
for (Consumer<Image> everyFrameListener : everyFrame) for (Runnable everyFrameListener : everyFrame)
{ {
try try
{ {
everyFrameListener.accept(image); everyFrameListener.run();
} }
catch (Exception e) catch (Exception e)
{ {
@@ -73,8 +74,27 @@ public class DrawManager
} }
Consumer<Image> nextFrameListener = nextFrame.poll(); Consumer<Image> nextFrameListener = nextFrame.poll();
Image image = null;
while (nextFrameListener != null) while (nextFrameListener != null)
{ {
if (image == null)
{
try
{
image = imageSupplier.get();
}
catch (Exception ex)
{
log.warn("error getting screenshot", ex);
}
}
if (image == null)
{
nextFrame.clear();
break;
}
try try
{ {
nextFrameListener.accept(image); nextFrameListener.accept(image);