Fix thread unsafety in OpenGlToBitmapProcessor

Sharing the temporary `row` and `rowSwap` buffers between different calls to the
processor is not safe because it will be used by multiple threads.
As a result some of the rows in the image could randomly get corrupted.

This commit gets rid of the cached buffers (the value of which questionable
anyway) and simply re-uses the same code which other processors use.
This commit is contained in:
Jonas Herzig
2022-07-17 16:28:56 +02:00
parent 633ac10d89
commit 6e3d30e41b

View File

@@ -2,42 +2,25 @@ package com.replaymod.render.processor;
import com.replaymod.render.frame.OpenGlFrame;
import com.replaymod.render.frame.BitmapFrame;
import com.replaymod.render.utils.ByteBufferPool;
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
import java.nio.ByteBuffer;
public class OpenGlToBitmapProcessor extends AbstractFrameProcessor<OpenGlFrame, BitmapFrame> {
import static com.replaymod.render.utils.Utils.openGlBytesToBitmap;
private byte[] row, rowSwap;
public class OpenGlToBitmapProcessor extends AbstractFrameProcessor<OpenGlFrame, BitmapFrame> {
@Override
public BitmapFrame process(OpenGlFrame rawFrame) {
// Flip whole image in place
ReadableDimension size = rawFrame.getSize();
int width = size.getWidth();
int height = size.getHeight();
int bpp = rawFrame.getBytesPerPixel();
int rowSize = size.getWidth() * bpp;
if (row == null || row.length < rowSize) {
row = new byte[rowSize];
rowSwap = new byte[rowSize];
}
ByteBuffer buffer = rawFrame.getByteBuffer();
int rows = size.getHeight();
byte[] row = this.row;
byte[] rowSwap = this.rowSwap;
for (int i = 0; i < rows / 2; i++) {
int from = rowSize * i;
int to = rowSize * (rows - i - 1);
buffer.position(from);
buffer.get(row);
buffer.position(to);
buffer.get(rowSwap);
buffer.position(to);
buffer.put(row);
buffer.position(from);
buffer.put(rowSwap);
}
buffer.rewind();
return new BitmapFrame(rawFrame.getFrameId(), size, bpp, buffer);
ByteBuffer result = ByteBufferPool.allocate(width * height * bpp);
openGlBytesToBitmap(rawFrame, 0, 0, result, width);
ByteBufferPool.release(rawFrame.getByteBuffer());
return new BitmapFrame(rawFrame.getFrameId(), new Dimension(width, height), bpp, result);
}
}