Skip to content

Instantly share code, notes, and snippets.

@Col-E
Created June 2, 2025 17:39
Show Gist options
  • Save Col-E/b6427eade7410663c97ec0b5a5f7fc02 to your computer and use it in GitHub Desktop.
Save Col-E/b6427eade7410663c97ec0b5a5f7fc02 to your computer and use it in GitHub Desktop.
GLCanvas PixelBuffer patch
Subject: [PATCH] Refactor to use PixelBuffer
---
Index: src/main/java/software/coley/glcanvasfx/GLCanvas.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/software/coley/glcanvasfx/GLCanvas.java b/src/main/java/software/coley/glcanvasfx/GLCanvas.java
--- a/src/main/java/software/coley/glcanvasfx/GLCanvas.java (revision 0b9c86da003f4529142f481ecc8ec37e2268605c)
+++ b/src/main/java/software/coley/glcanvasfx/GLCanvas.java (date 1748885813652)
@@ -5,10 +5,11 @@
import com.jogamp.opengl.GLEventListener;
import jakarta.annotation.Nonnull;
import javafx.animation.AnimationTimer;
+import javafx.geometry.Rectangle2D;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.image.PixelBuffer;
import javafx.scene.image.PixelFormat;
-import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
@@ -51,12 +52,16 @@
private final GraphicsContext gc = canvas.getGraphicsContext2D();
/** Intermediate buffer to communicate between our {@link #image WritableImage} and the {@link GLAutoDrawable#getGL() GL} frame buffer. */
private final ByteBuffer buffer;
+ /** Pixel buffer backing the {@link #image}. */
+ private PixelBuffer<ByteBuffer> pixelBuffer;
/** The image to draw to the {@link #canvas} which holds a snapshot of the {@link GLAutoDrawable#getGL() GL} frame buffer. */
private WritableImage image;
/** Current width of {@link #image}. */
private int imageWidth;
/** Current height of {@link #image}. */
private int imageHeight;
+ /** Bounds for {@link #imageWidth} x {@link #imageHeight}. */
+ private Rectangle2D imageBounds;
/** Last millis timestamp of a resize event observed. Used to prevent visual tearing when updating the {@link #canvas} display. */
private long lastResizeTimeMs;
/** Flag indicating if {@link #display(GLAutoDrawable)} needs to update {@link #image}. */
@@ -169,11 +174,6 @@
int w = Math.max(1, Math.min(drawable.getSurfaceWidth(), imageWidth));
int h = Math.max(1, Math.min(drawable.getSurfaceHeight(), imageHeight));
drawable.getGL().glReadPixels(0, 0, w, h, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, buffer);
-
- // Update our image.
- buffer.position(0);
- PixelWriter writer = image.getPixelWriter();
- writer.setPixels(0, 0, w, h, PixelFormat.getByteBgraInstance(), buffer, w * COLOR_BYTES);
imageBufferUpdated = true;
}
@@ -194,8 +194,10 @@
private void refitBuffers(int width, int height) {
imageWidth = Math.max(1, width);
imageHeight = Math.max(1, height);
+ imageBounds = new Rectangle2D(0, 0, imageWidth, imageHeight);
buffer.limit((imageWidth * imageHeight * COLOR_BYTES) + COLOR_BYTES);
- image = new WritableImage(imageWidth, imageHeight);
+ pixelBuffer = new PixelBuffer<>(width, height, buffer, PixelFormat.getByteBgraPreInstance());
+ image = new WritableImage(pixelBuffer);
}
/**
@@ -210,6 +212,7 @@
// Don't update the canvas if our image hasn't been updated since our last draw.
if (!imageBufferUpdated)
return;
+ pixelBuffer.updateBuffer(_ -> imageBounds);
imageBufferUpdated = false;
// Transform the coordinate space of the image buffer so that the y-axis is inverted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment