mirror of
https://github.com/processing/processing4.git
synced 2026-02-04 06:09:17 +01:00
use weak references to PGraphicsOpenGL instances in resource classes
(framebuffers, texture, etc), should take care of #3858
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
package processing.opengl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URL;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
@@ -51,7 +52,7 @@ public abstract class PGL {
|
||||
// Basic fields
|
||||
|
||||
/** The PGraphics and PApplet objects using this interface */
|
||||
protected PGraphicsOpenGL graphics;
|
||||
protected WeakReference<PGraphicsOpenGL> graphics;
|
||||
protected PApplet sketch;
|
||||
|
||||
/** OpenGL thread */
|
||||
@@ -427,7 +428,7 @@ public abstract class PGL {
|
||||
|
||||
|
||||
public PGL(PGraphicsOpenGL pg) {
|
||||
this.graphics = pg;
|
||||
this.graphics = new WeakReference<PGraphicsOpenGL>(pg);
|
||||
if (glColorTex == null) {
|
||||
glColorFbo = allocateIntBuffer(1);
|
||||
glColorTex = allocateIntBuffer(2);
|
||||
@@ -562,14 +563,16 @@ public abstract class PGL {
|
||||
|
||||
protected Texture wrapBackTexture(Texture texture) {
|
||||
if (texture == null) {
|
||||
texture = new Texture(graphics);
|
||||
texture.init(graphics.width, graphics.height,
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return null;
|
||||
texture = new Texture(g);
|
||||
texture.init(g.width, g.height,
|
||||
glColorTex.get(backTex), TEXTURE_2D, RGBA,
|
||||
fboWidth, fboHeight, NEAREST, NEAREST,
|
||||
CLAMP_TO_EDGE, CLAMP_TO_EDGE);
|
||||
texture.invertedY(true);
|
||||
texture.colorBuffer(true);
|
||||
graphics.setCache(graphics, texture);
|
||||
g.setCache(g, texture);
|
||||
} else {
|
||||
texture.glName = glColorTex.get(backTex);
|
||||
}
|
||||
@@ -579,8 +582,10 @@ public abstract class PGL {
|
||||
|
||||
protected Texture wrapFrontTexture(Texture texture) {
|
||||
if (texture == null) {
|
||||
texture = new Texture(graphics);
|
||||
texture.init(graphics.width, graphics.height,
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return null;
|
||||
texture = new Texture(g);
|
||||
texture.init(g.width, g.height,
|
||||
glColorTex.get(frontTex), TEXTURE_2D, RGBA,
|
||||
fboWidth, fboHeight, NEAREST, NEAREST,
|
||||
CLAMP_TO_EDGE, CLAMP_TO_EDGE);
|
||||
@@ -623,7 +628,8 @@ public abstract class PGL {
|
||||
bindFramebufferImpl(READ_FRAMEBUFFER, glMultiFbo.get(0));
|
||||
bindFramebufferImpl(DRAW_FRAMEBUFFER, glColorFbo.get(0));
|
||||
int mask = COLOR_BUFFER_BIT;
|
||||
if (graphics.getHint(PConstants.ENABLE_BUFFER_READING)) {
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g != null && g.getHint(PConstants.ENABLE_BUFFER_READING)) {
|
||||
mask |= DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT;
|
||||
}
|
||||
blitFramebuffer(0, 0, fboWidth, fboHeight,
|
||||
@@ -688,8 +694,11 @@ public abstract class PGL {
|
||||
|
||||
|
||||
protected void beginRender() {
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return;
|
||||
|
||||
if (sketch == null) {
|
||||
sketch = graphics.parent;
|
||||
sketch = g.parent;
|
||||
}
|
||||
|
||||
pgeomCount = geomCount;
|
||||
@@ -723,12 +732,11 @@ public abstract class PGL {
|
||||
|
||||
if (sketch.frameCount == 0) {
|
||||
// No need to draw back color buffer because we are in the first frame.
|
||||
int argb = graphics.backgroundColor;
|
||||
float a = ((argb >> 24) & 0xff) / 255.0f;
|
||||
float r = ((argb >> 16) & 0xff) / 255.0f;
|
||||
float g = ((argb >> 8) & 0xff) / 255.0f;
|
||||
float b = ((argb) & 0xff) / 255.0f;
|
||||
clearColor(r, g, b, a);
|
||||
float ba = ((g.backgroundColor >> 24) & 0xff) / 255.0f;
|
||||
float br = ((g.backgroundColor >> 16) & 0xff) / 255.0f;
|
||||
float bg = ((g.backgroundColor >> 8) & 0xff) / 255.0f;
|
||||
float bb = ((g.backgroundColor) & 0xff) / 255.0f;
|
||||
clearColor(br, bg, bb, ba);
|
||||
clear(COLOR_BUFFER_BIT);
|
||||
} else if (!pclearColor || !sketch.isLooping()) {
|
||||
// Render previous back texture (now is the front) as background,
|
||||
@@ -741,15 +749,18 @@ public abstract class PGL {
|
||||
}
|
||||
float scale = getPixelScale();
|
||||
drawTexture(TEXTURE_2D, glColorTex.get(frontTex), fboWidth, fboHeight,
|
||||
x, y, graphics.width, graphics.height,
|
||||
0, 0, (int)(scale * graphics.width), (int)(scale * graphics.height),
|
||||
0, 0, graphics.width, graphics.height);
|
||||
x, y, g.width, g.height,
|
||||
0, 0, (int)(scale * g.width), (int)(scale * g.height),
|
||||
0, 0, g.width, g.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void endRender(int windowColor) {
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return;
|
||||
|
||||
if (fboLayerEnabled) {
|
||||
syncBackTexture();
|
||||
|
||||
@@ -757,13 +768,12 @@ public abstract class PGL {
|
||||
bindFramebufferImpl(FRAMEBUFFER, 0);
|
||||
|
||||
if (presentMode) {
|
||||
int argb = windowColor;
|
||||
float a = ((argb >> 24) & 0xff) / 255.0f;
|
||||
float r = ((argb >> 16) & 0xff) / 255.0f;
|
||||
float g = ((argb >> 8) & 0xff) / 255.0f;
|
||||
float b = (argb & 0xff) / 255.0f;
|
||||
float wa = ((windowColor >> 24) & 0xff) / 255.0f;
|
||||
float wr = ((windowColor >> 16) & 0xff) / 255.0f;
|
||||
float wg = ((windowColor >> 8) & 0xff) / 255.0f;
|
||||
float wb = (windowColor & 0xff) / 255.0f;
|
||||
clearDepth(1);
|
||||
clearColor(r, g, b, a);
|
||||
clearColor(wr, wg, wb, wa);
|
||||
clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT);
|
||||
|
||||
if (closeBtnTex == null) {
|
||||
@@ -800,9 +810,9 @@ public abstract class PGL {
|
||||
float scale = getPixelScale();
|
||||
drawTexture(TEXTURE_2D, glColorTex.get(backTex),
|
||||
fboWidth, fboHeight,
|
||||
x, y, graphics.width, graphics.height,
|
||||
0, 0, (int)(scale * graphics.width), (int)(scale * graphics.height),
|
||||
0, 0, graphics.width, graphics.height);
|
||||
x, y, g.width, g.height,
|
||||
0, 0, (int)(scale * g.width), (int)(scale * g.height),
|
||||
0, 0, g.width, g.height);
|
||||
|
||||
// Swapping front and back textures.
|
||||
int temp = frontTex;
|
||||
@@ -855,14 +865,17 @@ public abstract class PGL {
|
||||
|
||||
|
||||
private void createFBOLayer() {
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return;
|
||||
|
||||
float scale = getPixelScale();
|
||||
|
||||
if (hasNpotTexSupport()) {
|
||||
fboWidth = (int)(scale * graphics.width);
|
||||
fboHeight = (int)(scale * graphics.height);
|
||||
fboWidth = (int)(scale * g.width);
|
||||
fboHeight = (int)(scale * g.height);
|
||||
} else {
|
||||
fboWidth = nextPowerOfTwo((int)(scale * graphics.width));
|
||||
fboHeight = nextPowerOfTwo((int)(scale * graphics.height));
|
||||
fboWidth = nextPowerOfTwo((int)(scale * g.width));
|
||||
fboHeight = nextPowerOfTwo((int)(scale * g.height));
|
||||
}
|
||||
|
||||
int maxs = maxSamples();
|
||||
@@ -886,7 +899,7 @@ public abstract class PGL {
|
||||
texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);
|
||||
texImage2D(TEXTURE_2D, 0, RGBA, fboWidth, fboHeight, 0,
|
||||
RGBA, UNSIGNED_BYTE, null);
|
||||
initTexture(TEXTURE_2D, RGBA, fboWidth, fboHeight, graphics.backgroundColor);
|
||||
initTexture(TEXTURE_2D, RGBA, fboWidth, fboHeight, g.backgroundColor);
|
||||
}
|
||||
bindTexture(TEXTURE_2D, 0);
|
||||
|
||||
@@ -898,7 +911,7 @@ public abstract class PGL {
|
||||
framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D,
|
||||
glColorTex.get(backTex), 0);
|
||||
|
||||
if (!multisample || graphics.getHint(PConstants.ENABLE_BUFFER_READING)) {
|
||||
if (!multisample || g.getHint(PConstants.ENABLE_BUFFER_READING)) {
|
||||
// If not multisampled, this is the only depth and stencil buffer.
|
||||
// If multisampled and depth reading enabled, these are going to
|
||||
// hold downsampled depth and stencil buffers.
|
||||
@@ -927,12 +940,11 @@ public abstract class PGL {
|
||||
// Clear all buffers.
|
||||
clearDepth(1);
|
||||
clearStencil(0);
|
||||
int argb = graphics.backgroundColor;
|
||||
float a = ((argb >> 24) & 0xff) / 255.0f;
|
||||
float r = ((argb >> 16) & 0xff) / 255.0f;
|
||||
float g = ((argb >> 8) & 0xff) / 255.0f;
|
||||
float b = ((argb) & 0xff) / 255.0f;
|
||||
clearColor(r, g, b, a);
|
||||
float ba = ((g.backgroundColor >> 24) & 0xff) / 255.0f;
|
||||
float br = ((g.backgroundColor >> 16) & 0xff) / 255.0f;
|
||||
float bg = ((g.backgroundColor >> 8) & 0xff) / 255.0f;
|
||||
float bb = ((g.backgroundColor) & 0xff) / 255.0f;
|
||||
clearColor(br, bg, bb, ba);
|
||||
clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT);
|
||||
|
||||
bindFramebufferImpl(FRAMEBUFFER, 0);
|
||||
@@ -1194,7 +1206,9 @@ public abstract class PGL {
|
||||
|
||||
|
||||
protected PGL initTex2DShader() {
|
||||
PGL ppgl = primaryPGL ? this : graphics.getPrimaryPGL();
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return null;
|
||||
PGL ppgl = primaryPGL ? this : g.getPrimaryPGL();
|
||||
|
||||
if (!ppgl.loadedTex2DShader || ppgl.tex2DShaderContext != ppgl.glContext) {
|
||||
String[] preprocVertSrc = preprocessVertexSource(texVertShaderSource, getGLSLVersion());
|
||||
@@ -1326,7 +1340,9 @@ public abstract class PGL {
|
||||
|
||||
|
||||
protected PGL initTexRectShader() {
|
||||
PGL ppgl = primaryPGL ? this : graphics.getPrimaryPGL();
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return null;
|
||||
PGL ppgl = primaryPGL ? this : g.getPrimaryPGL();
|
||||
|
||||
if (!ppgl.loadedTexRectShader || ppgl.texRectShaderContext != ppgl.glContext) {
|
||||
String[] preprocVertSrc = preprocessVertexSource(texVertShaderSource, getGLSLVersion());
|
||||
@@ -1459,33 +1475,42 @@ public abstract class PGL {
|
||||
|
||||
|
||||
protected int getColorValue(int scrX, int scrY) {
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return 0;
|
||||
|
||||
if (colorBuffer == null) {
|
||||
colorBuffer = IntBuffer.allocate(1);
|
||||
}
|
||||
colorBuffer.rewind();
|
||||
readPixels(scrX, graphics.height - scrY - 1, 1, 1, RGBA, UNSIGNED_BYTE,
|
||||
readPixels(scrX, g.height - scrY - 1, 1, 1, RGBA, UNSIGNED_BYTE,
|
||||
colorBuffer);
|
||||
return colorBuffer.get();
|
||||
}
|
||||
|
||||
|
||||
protected float getDepthValue(int scrX, int scrY) {
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return 0;
|
||||
|
||||
if (depthBuffer == null) {
|
||||
depthBuffer = FloatBuffer.allocate(1);
|
||||
}
|
||||
depthBuffer.rewind();
|
||||
readPixels(scrX, graphics.height - scrY - 1, 1, 1, DEPTH_COMPONENT, FLOAT,
|
||||
readPixels(scrX, g.height - scrY - 1, 1, 1, DEPTH_COMPONENT, FLOAT,
|
||||
depthBuffer);
|
||||
return depthBuffer.get(0);
|
||||
}
|
||||
|
||||
|
||||
protected byte getStencilValue(int scrX, int scrY) {
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return 0;
|
||||
|
||||
if (stencilBuffer == null) {
|
||||
stencilBuffer = ByteBuffer.allocate(1);
|
||||
}
|
||||
stencilBuffer.rewind();
|
||||
readPixels(scrX, graphics.height - scrY - 1, 1, 1, STENCIL_INDEX,
|
||||
readPixels(scrX, g.height - scrY - 1, 1, 1, STENCIL_INDEX,
|
||||
UNSIGNED_BYTE, stencilBuffer);
|
||||
return stencilBuffer.get(0);
|
||||
}
|
||||
@@ -2935,8 +2960,11 @@ public abstract class PGL {
|
||||
// to glReadPixels() should be done in readPixelsImpl().
|
||||
|
||||
public void readPixels(int x, int y, int width, int height, int format, int type, Buffer buffer){
|
||||
boolean multisampled = isMultisampled() || graphics.offscreenMultisample;
|
||||
boolean depthReadingEnabled = graphics.getHint(PConstants.ENABLE_BUFFER_READING);
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return;
|
||||
|
||||
boolean multisampled = isMultisampled() || g.offscreenMultisample;
|
||||
boolean depthReadingEnabled = g.getHint(PConstants.ENABLE_BUFFER_READING);
|
||||
boolean depthRequested = format == STENCIL_INDEX || format == DEPTH_COMPONENT || format == DEPTH_STENCIL;
|
||||
|
||||
if (multisampled && depthRequested && !depthReadingEnabled) {
|
||||
@@ -2944,9 +2972,9 @@ public abstract class PGL {
|
||||
return;
|
||||
}
|
||||
|
||||
graphics.beginReadPixels();
|
||||
g.beginReadPixels();
|
||||
readPixelsImpl(x, y, width, height, format, type, buffer);
|
||||
graphics.endReadPixels();
|
||||
g.endReadPixels();
|
||||
}
|
||||
|
||||
protected abstract void readPixelsImpl(int x, int y, int width, int height, int format, int type, Buffer buffer);
|
||||
@@ -3138,9 +3166,12 @@ public abstract class PGL {
|
||||
// Framebuffers Objects
|
||||
|
||||
public void bindFramebuffer(int target, int framebuffer) {
|
||||
graphics.beginBindFramebuffer(target, framebuffer);
|
||||
PGraphicsOpenGL g = graphics.get();
|
||||
if (g == null) return;
|
||||
|
||||
g.beginBindFramebuffer(target, framebuffer);
|
||||
bindFramebufferImpl(target, framebuffer);
|
||||
graphics.endBindFramebuffer(target, framebuffer);
|
||||
g.endBindFramebuffer(target, framebuffer);
|
||||
}
|
||||
protected abstract void bindFramebufferImpl(int target, int framebuffer);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user