GC issues + some late invokes

This commit is contained in:
downthecrop 2024-10-26 09:59:25 -07:00
parent 71afb2b385
commit 83fe4805ac
2 changed files with 99 additions and 80 deletions

View file

@ -9,6 +9,7 @@ import org.openrs2.deob.annotation.OriginalMember;
import org.openrs2.deob.annotation.Pc; import org.openrs2.deob.annotation.Pc;
import java.awt.*; import java.awt.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.IntBuffer; import java.nio.IntBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -24,7 +25,10 @@ public final class GlRenderer {
public static float hFOV = 0; public static float hFOV = 0;
public static int[] pixelData = null;
private static ByteBuffer pixelByteBuffer;
private static IntBuffer pixelIntBuffer;
public static int[] pixelData;
@OriginalMember(owner = "client!tf", name = "c", descriptor = "F") @OriginalMember(owner = "client!tf", name = "c", descriptor = "F")
private static float aFloat30; private static float aFloat30;
@ -201,18 +205,33 @@ public final class GlRenderer {
@OriginalMember(owner = "client!tf", name = "d", descriptor = "()V") @OriginalMember(owner = "client!tf", name = "d", descriptor = "()V")
public static void swapBuffers() { public static void swapBuffers() {
try { try {
pixelData = readPixels(); readPixels();
drawable.swapBuffers(); drawable.swapBuffers();
} catch (@Pc(3) Exception local3) { } catch (@Pc(3) Exception local3) {
} }
} }
@OriginalMember(owner = "client!tf", name = "readPixels", descriptor = "()int[]") public static void initializePixelBuffer(int width, int height) {
public static int[] readPixels() { // Allocate ByteBuffer for BGRA pixels (4 bytes per pixel)
int[] pixels = new int[canvasWidth * canvasHeight]; pixelByteBuffer = ByteBuffer.allocateDirect(width * height * 4).order(ByteOrder.nativeOrder());
IntBuffer buffer = IntBuffer.wrap(pixels); pixelIntBuffer = pixelByteBuffer.asIntBuffer();
gl.glReadPixels(0, 0, canvasWidth, canvasHeight, GL2.GL_BGRA, GlRenderer.bigEndian ? GL2.GL_UNSIGNED_INT_8_8_8_8_REV : GL2.GL_UNSIGNED_BYTE, buffer); pixelData = new int[width * height];
return pixels; }
public static void readPixels() {
// Ensure the pixel buffer is initialized with the correct size
if (pixelByteBuffer == null || pixelIntBuffer.capacity() != canvasWidth * canvasHeight) {
initializePixelBuffer(canvasWidth, canvasHeight);
}
// Read pixels into the direct ByteBuffer
gl.glReadPixels(0, 0, canvasWidth, canvasHeight, GL2.GL_BGRA,
GlRenderer.bigEndian ? GL2.GL_UNSIGNED_INT_8_8_8_8_REV : GL2.GL_UNSIGNED_BYTE,
pixelByteBuffer);
// Convert to int array if needed
pixelIntBuffer.rewind(); // Prepare the IntBuffer for reading
pixelIntBuffer.get(pixelData, 0, pixelData.length); // Transfer to pixelData array if necessary
} }
@OriginalMember(owner = "client!tf", name = "a", descriptor = "(Z)V") @OriginalMember(owner = "client!tf", name = "a", descriptor = "(Z)V")

View file

@ -150,6 +150,8 @@ class plugin : Plugin() {
class AltCanvas : Canvas() { class AltCanvas : Canvas() {
private var gameImage: VolatileImage? = null private var gameImage: VolatileImage? = null
private var flippedPixels: IntArray? = null
private var bufferImage: BufferedImage? = null
private var scaleX = 1.0 private var scaleX = 1.0
private var scaleY = 1.0 private var scaleY = 1.0
private var offsetX = 0 private var offsetX = 0
@ -158,6 +160,8 @@ class plugin : Plugin() {
init { init {
validateGameImage() validateGameImage()
isFocusable = true
requestFocusInWindow()
addMouseListener(object : MouseAdapter() { addMouseListener(object : MouseAdapter() {
override fun mousePressed(e: MouseEvent) { override fun mousePressed(e: MouseEvent) {
@ -212,6 +216,11 @@ class plugin : Plugin() {
paint(g) paint(g)
} }
override fun addNotify() {
super.addNotify()
//createBufferStrategy(2) // Double buffering for V-Sync, called only after the peer is created
}
private fun validateGameImage() { private fun validateGameImage() {
val gc = GraphicsEnvironment.getLocalGraphicsEnvironment().defaultScreenDevice.defaultConfiguration val gc = GraphicsEnvironment.getLocalGraphicsEnvironment().defaultScreenDevice.defaultConfiguration
if (gameImage == null) { if (gameImage == null) {
@ -294,6 +303,9 @@ class plugin : Plugin() {
val x = offsetX val x = offsetX
val y = offsetY val y = offsetY
g2d.drawImage(image, x, y, drawWidth, drawHeight, null) g2d.drawImage(image, x, y, drawWidth, drawHeight, null)
g2d.dispose()
//bufferStrategy.show() // Shows the buffer with V-Sync enabled
Toolkit.getDefaultToolkit().sync() // Ensures V-Sync on some systems
} }
} }
@ -322,30 +334,27 @@ class plugin : Plugin() {
repaint() repaint()
} }
private fun renderGlRaster() { private fun renderGlRaster() {
val pixels = GlRenderer.pixelData // Assuming this holds the int[] BGRA pixel data from GlRenderer.readPixels() if (flippedPixels == null || flippedPixels!!.size != gameImage!!.width * gameImage!!.height) {
val width = gameImage!!.width flippedPixels = IntArray(gameImage!!.width * gameImage!!.height)
val height = gameImage!!.height
// Create a BufferedImage with the same dimensions as the gameImage
val bufferedImage = BufferedImage(width, height, BufferedImage.TYPE_INT_BGR)
// Flip the image vertically by reversing the rows
val flippedPixels = IntArray(width * height)
for (y in 0 until height) {
// Calculate the source row (bottom to top)
val srcY = height - 1 - y
System.arraycopy(pixels, srcY * width, flippedPixels, y * width, width)
} }
// Set the flipped pixel data into the BufferedImage // Initialize bufferImage only once and reuse it
bufferedImage.setRGB(0, 0, width, height, flippedPixels, 0, width) if (bufferImage == null || bufferImage!!.width != gameImage!!.width || bufferImage!!.height != gameImage!!.height) {
bufferImage = BufferedImage(gameImage!!.width, gameImage!!.height, BufferedImage.TYPE_INT_BGR)
}
// Draw the BufferedImage onto the VolatileImage val width = gameImage!!.width
val g = gameImage!!.createGraphics() val height = gameImage!!.height
try { val pixels = GlRenderer.pixelData // Retrieve BGRA pixel data
g.drawImage(bufferedImage, 0, 0, null) for (y in 0 until height) {
} finally { System.arraycopy(pixels, (height - 1 - y) * width, flippedPixels, y * width, width)
g.dispose() }
bufferImage!!.setRGB(0, 0, width, height, flippedPixels, 0, width)
gameImage?.createGraphics()?.apply {
drawImage(bufferImage, 0, 0, null)
dispose()
} }
} }
@ -404,10 +413,8 @@ class plugin : Plugin() {
rightPanelWrapper?.preferredSize = Dimension(currentScrollPaneWidth, frame.height) rightPanelWrapper?.preferredSize = Dimension(currentScrollPaneWidth, frame.height)
rightPanelWrapper?.let { it.isDoubleBuffered = true } rightPanelWrapper?.let { it.isDoubleBuffered = true }
rightPanelWrapper?.revalidate() rightPanelWrapper?.revalidate()
SwingUtilities.invokeLater {
rightPanelWrapper?.repaint() rightPanelWrapper?.repaint()
} }
}
fun OnKondoValueUpdated(){ fun OnKondoValueUpdated(){
StoreData("kondoUseRemoteGE", useLiveGEPrices) StoreData("kondoUseRemoteGE", useLiveGEPrices)
@ -462,9 +469,7 @@ class plugin : Plugin() {
override fun OnPluginsReloaded(): Boolean { override fun OnPluginsReloaded(): Boolean {
if (!initialized) return true if (!initialized) return true
UpdateDisplaySettings() UpdateDisplaySettings()
frame.remove(rightPanelWrapper) frame.remove(rightPanelWrapper)
frame.layout = BorderLayout() frame.layout = BorderLayout()
frame.add(rightPanelWrapper, BorderLayout.EAST) frame.add(rightPanelWrapper, BorderLayout.EAST)
@ -475,18 +480,17 @@ class plugin : Plugin() {
} }
override fun OnXPUpdate(skillId: Int, xp: Int) { override fun OnXPUpdate(skillId: Int, xp: Int) {
SwingUtilities.invokeLater{
if (!initialXP.containsKey(skillId)) { if (!initialXP.containsKey(skillId)) {
initialXP[skillId] = xp initialXP[skillId] = xp
return return@invokeLater
} }
var xpWidget = xpWidgets[skillId] var xpWidget = xpWidgets[skillId]
if (xpWidget != null) { if (xpWidget != null) {
updateWidget(xpWidget, xp) updateWidget(xpWidget, xp)
} else { } else {
val previousXp = initialXP[skillId] ?: xp val previousXp = initialXP[skillId] ?: xp
if (xp == initialXP[skillId]) return if (xp == initialXP[skillId]) return@invokeLater
xpWidget = createXPWidget(skillId, previousXp) xpWidget = createXPWidget(skillId, previousXp)
xpWidgets[skillId] = xpWidget xpWidgets[skillId] = xpWidget
@ -494,15 +498,15 @@ class plugin : Plugin() {
xpTrackerView?.add(wrappedWidget(xpWidget.container)) xpTrackerView?.add(wrappedWidget(xpWidget.container))
xpTrackerView?.add(Box.createVerticalStrut(5)) xpTrackerView?.add(Box.createVerticalStrut(5))
if(focusedView == XPTrackerView.VIEW_NAME) {
xpTrackerView?.revalidate() xpTrackerView?.revalidate()
if(focusedView == XPTrackerView.VIEW_NAME)
SwingUtilities.invokeLater {
xpTrackerView?.repaint() xpTrackerView?.repaint()
} }
updateWidget(xpWidget, xp) updateWidget(xpWidget, xp)
} }
} }
}
override fun Draw(timeDelta: Long) { override fun Draw(timeDelta: Long) {
if (GlRenderer.enabled && GlRenderer.canvasWidth != GameShell.canvasWidth) { if (GlRenderer.enabled && GlRenderer.canvasWidth != GameShell.canvasWidth) {
@ -545,16 +549,19 @@ class plugin : Plugin() {
override fun LateDraw(timeDelta: Long){ override fun LateDraw(timeDelta: Long){
if(!initialized) return if(!initialized) return
SwingUtilities.invokeLater {
if (GetWindowMode() == WindowMode.FIXED) { if (GetWindowMode() == WindowMode.FIXED) {
if (canvas.parent !== hiddenFrame?.contentPane) { if (canvas.parent !== hiddenFrame?.contentPane) {
if(altCanvas?.parent != frame) {
frame.add(altCanvas)
}
println("Moving canvas to hidden frame") println("Moving canvas to hidden frame")
initializeHiddenFrame() initializeHiddenFrame()
frame.remove(canvas) // Remove from main frame if necessary frame.remove(canvas) // Remove from main frame if necessary
hiddenFrame?.contentPane?.add(canvas) hiddenFrame?.contentPane?.add(canvas)
hiddenFrame?.pack() hiddenFrame?.pack()
} }
} } else {
frame.remove(altCanvas)
} }
altCanvas?.updateGameImage() // Update the game image as needed altCanvas?.updateGameImage() // Update the game image as needed
} }
@ -716,9 +723,9 @@ class plugin : Plugin() {
val elapsedTime = (System.currentTimeMillis() - xpWidget.startTime) / 1000.0 / 60.0 / 60.0 val elapsedTime = (System.currentTimeMillis() - xpWidget.startTime) / 1000.0 / 60.0 / 60.0
val xpPerHour = if (elapsedTime > 0) (xpWidget.totalXpGained / elapsedTime).toInt() else 0 val xpPerHour = if (elapsedTime > 0) (xpWidget.totalXpGained / elapsedTime).toInt() else 0
val formattedXpPerHour = formatNumber(xpPerHour) val formattedXpPerHour = formatNumber(xpPerHour)
SwingUtilities.invokeLater{
xpWidget.xpPerHourLabel.text = xpWidget.xpPerHourLabel.text =
formatHtmlLabelText("XP /hr: ", primaryColor, formattedXpPerHour, secondaryColor) formatHtmlLabelText("XP /hr: ", primaryColor, formattedXpPerHour, secondaryColor)
SwingUtilities.invokeLater{
xpWidget.container.repaint() xpWidget.container.repaint()
} }
} }
@ -727,9 +734,9 @@ class plugin : Plugin() {
val elapsedTime = (System.currentTimeMillis() - totalXPWidget.startTime) / 1000.0 / 60.0 / 60.0 val elapsedTime = (System.currentTimeMillis() - totalXPWidget.startTime) / 1000.0 / 60.0 / 60.0
val totalXPPerHour = if (elapsedTime > 0) (totalXPWidget.totalXpGained / elapsedTime).toInt() else 0 val totalXPPerHour = if (elapsedTime > 0) (totalXPWidget.totalXpGained / elapsedTime).toInt() else 0
val formattedTotalXpPerHour = formatNumber(totalXPPerHour) val formattedTotalXpPerHour = formatNumber(totalXPPerHour)
SwingUtilities.invokeLater{
totalXPWidget.xpPerHourLabel.text = totalXPWidget.xpPerHourLabel.text =
formatHtmlLabelText("XP /hr: ", primaryColor, formattedTotalXpPerHour, secondaryColor) formatHtmlLabelText("XP /hr: ", primaryColor, formattedTotalXpPerHour, secondaryColor)
SwingUtilities.invokeLater{
totalXPWidget.container.repaint() totalXPWidget.container.repaint()
} }
} }
@ -759,11 +766,9 @@ class plugin : Plugin() {
rightPanelWrapper?.revalidate() rightPanelWrapper?.revalidate()
frame?.revalidate() frame?.revalidate()
SwingUtilities.invokeLater{
mainContentPanel.repaint() mainContentPanel.repaint()
rightPanelWrapper?.repaint() rightPanelWrapper?.repaint()
frame?.repaint() frame?.repaint()
}
focusedView = viewName focusedView = viewName
} }
@ -826,22 +831,17 @@ class plugin : Plugin() {
override fun mouseEntered(e: MouseEvent?) { override fun mouseEntered(e: MouseEvent?) {
background = WIDGET_COLOR.darker() background = WIDGET_COLOR.darker()
imageCanvas.fillColor = WIDGET_COLOR.darker() imageCanvas.fillColor = WIDGET_COLOR.darker()
SwingUtilities.invokeLater{
imageCanvas.repaint() imageCanvas.repaint()
repaint() repaint()
} }
}
override fun mouseExited(e: MouseEvent?) { override fun mouseExited(e: MouseEvent?) {
background = WIDGET_COLOR background = WIDGET_COLOR
imageCanvas.fillColor = WIDGET_COLOR imageCanvas.fillColor = WIDGET_COLOR
SwingUtilities.invokeLater{
imageCanvas.repaint() imageCanvas.repaint()
repaint() repaint()
} }
}
override fun mouseClicked(e: MouseEvent?) { override fun mouseClicked(e: MouseEvent?) {
actionListener.actionPerformed(null) actionListener.actionPerformed(null)
} }