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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user