Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions core/src/processing/core/PApplet.java
Original file line number Diff line number Diff line change
Expand Up @@ -3634,6 +3634,18 @@ public void dispose() {
// run dispose() methods registered by libraries
handleMethods("dispose");
}

if (platform == MACOSX) {
try {
final String td = "processing.core.ThinkDifferent";
final Class<?> thinkDifferent =
Thread.currentThread().getContextClassLoader().loadClass(td);
thinkDifferent.getMethod("cleanup").invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
}

}


Expand Down
6 changes: 6 additions & 0 deletions core/src/processing/core/ThinkDifferent.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ public void handleQuitRequestWith(QuitEvent event, QuitResponse response) {
});
}

static public void cleanup() {
if (application == null) {
application = Application.getApplication();
}
application.setQuitHandler(null);
}

// Called via reflection from PSurfaceAWT and others
static public void setIconImage(Image image) {
Expand Down
200 changes: 68 additions & 132 deletions core/src/processing/opengl/PGraphicsOpenGL.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,44 @@ public class PGraphicsOpenGL extends PGraphics {

// ........................................................

// Disposal of native resources
// Using the technique alternative to finalization described in:
// http://www.oracle.com/technetwork/articles/java/finalization-137655.html
private static ReferenceQueue<Object> refQueue = new ReferenceQueue<>();
private static List<Disposable<? extends Object>> reachableWeakReferences =
new LinkedList<>();

static final private int MAX_DRAIN_GLRES_ITERATIONS = 10;

static void drainRefQueueBounded() {
int iterations = 0;
while (iterations < MAX_DRAIN_GLRES_ITERATIONS) {
Disposable<? extends Object> res =
(Disposable<? extends Object>) refQueue.poll();
if (res == null) {
break;
}
res.dispose();
++iterations;
}
}

private static abstract class Disposable<T> extends WeakReference<T> {
protected Disposable(T obj) {
super(obj, refQueue);
drainRefQueueBounded();
reachableWeakReferences.add(this);
}

public void dispose() {
System.err.println("disposing " + this );
reachableWeakReferences.remove(this);
disposeNative();
}

abstract public void disposeNative();
}

// Basic rendering parameters:

/** Whether the PGraphics object is ready to render or not. */
Expand Down Expand Up @@ -820,54 +858,27 @@ protected void removeFontTexture(PFont font) {

//////////////////////////////////////////////////////////////

// RESOURCE HANDLING
// Using the technique alternative to finalization described in:
// http://www.oracle.com/technetwork/articles/java/finalization-137655.html

static final private int MAX_DRAIN_GLRES_ITERATIONS = 10;

protected static class GLResourceTexture extends WeakReference<Texture> {
protected static class GLResourceTexture extends Disposable<Texture> {
int glName;

private PGL pgl;
private int context;

static private ReferenceQueue<Texture> refQueue = new ReferenceQueue<Texture>();
static private List<GLResourceTexture> refList = new ArrayList<GLResourceTexture>();

static void drainRefQueueBounded() {
ReferenceQueue<Texture> refQueue = GLResourceTexture.referenceQueue();
int iterations = 0;
while (iterations < MAX_DRAIN_GLRES_ITERATIONS) {
GLResourceTexture res = (GLResourceTexture)refQueue.poll();
if (res == null) {
break;
}
res.dispose();
++iterations;
}
}

static ReferenceQueue<Texture> referenceQueue() {
return refQueue;
}

public GLResourceTexture(Texture tex) {
super(tex, refQueue);
super(tex);

drainRefQueueBounded();

pgl = tex.pg.getPrimaryPGL();
pgl.genTextures(1, intBuffer);
tex.glName = intBuffer.get(0);

this.glName = tex.glName;
this.context = tex.context;

refList.add(this);
}

private void disposeNative() {
@Override
public void disposeNative() {
if (pgl != null) {
if (glName != 0) {
intBuffer.put(0, glName);
Expand All @@ -878,13 +889,11 @@ private void disposeNative() {
}
}

void dispose() {
refList.remove(this);
disposeNative();
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof GLResourceTexture)) {
return false;
}
GLResourceTexture other = (GLResourceTexture)obj;
return other.glName == glName &&
other.context == context;
Expand All @@ -900,48 +909,25 @@ public int hashCode() {
}


protected static class GLResourceVertexBuffer extends WeakReference<VertexBuffer> {
protected static class GLResourceVertexBuffer extends Disposable<VertexBuffer> {
int glId;

private PGL pgl;
private int context;

static private ReferenceQueue<VertexBuffer> refQueue = new ReferenceQueue<VertexBuffer>();
static private List<GLResourceVertexBuffer> refList = new ArrayList<GLResourceVertexBuffer>();

static void drainRefQueueBounded() {
ReferenceQueue<VertexBuffer> refQueue = GLResourceVertexBuffer.referenceQueue();
int iterations = 0;
while (iterations < MAX_DRAIN_GLRES_ITERATIONS) {
GLResourceVertexBuffer res = (GLResourceVertexBuffer)refQueue.poll();
if (res == null) {
break;
}
res.dispose();
++iterations;
}
}

static ReferenceQueue<VertexBuffer> referenceQueue() {
return refQueue;
}

public GLResourceVertexBuffer(VertexBuffer vbo) {
super(vbo, refQueue);

drainRefQueueBounded();
super(vbo);

pgl = vbo.pgl.graphics.getPrimaryPGL();
pgl.genBuffers(1, intBuffer);
vbo.glId = intBuffer.get(0);

this.glId = vbo.glId;
this.context = vbo.context;

refList.add(this);
}

private void disposeNative() {
@Override
public void disposeNative() {
if (pgl != null) {
if (glId != 0) {
intBuffer.put(0, glId);
Expand All @@ -952,13 +938,11 @@ private void disposeNative() {
}
}

void dispose() {
refList.remove(this);
disposeNative();
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof GLResourceVertexBuffer)) {
return false;
}
GLResourceVertexBuffer other = (GLResourceVertexBuffer)obj;
return other.glId == glId &&
other.context == context;
Expand All @@ -974,38 +958,16 @@ public int hashCode() {
}


protected static class GLResourceShader extends WeakReference<PShader> {
protected static class GLResourceShader extends Disposable<PShader> {
int glProgram;
int glVertex;
int glFragment;

private PGL pgl;
private int context;

static private ReferenceQueue<PShader> refQueue = new ReferenceQueue<PShader>();
static private List<GLResourceShader> refList = new ArrayList<GLResourceShader>();

static void drainRefQueueBounded() {
ReferenceQueue<PShader> refQueue = GLResourceShader.referenceQueue();
int iterations = 0;
while (iterations < MAX_DRAIN_GLRES_ITERATIONS) {
GLResourceShader res = (GLResourceShader)refQueue.poll();
if (res == null) {
break;
}
res.dispose();
++iterations;
}
}

static ReferenceQueue<PShader> referenceQueue() {
return refQueue;
}

public GLResourceShader(PShader sh) {
super(sh, refQueue);

drainRefQueueBounded();
super(sh);

this.pgl = sh.pgl.graphics.getPrimaryPGL();
sh.glProgram = pgl.createProgram();
Expand All @@ -1017,11 +979,10 @@ public GLResourceShader(PShader sh) {
this.glFragment = sh.glFragment;

this.context = sh.context;

refList.add(this);
}

private void disposeNative() {
@Override
public void disposeNative() {
if (pgl != null) {
if (glFragment != 0) {
pgl.deleteShader(glFragment);
Expand All @@ -1039,13 +1000,11 @@ private void disposeNative() {
}
}

void dispose() {
refList.remove(this);
disposeNative();
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof GLResourceShader)) {
return false;
}
GLResourceShader other = (GLResourceShader)obj;
return other.glProgram == glProgram &&
other.glVertex == glVertex &&
Expand All @@ -1065,7 +1024,7 @@ public int hashCode() {
}


protected static class GLResourceFrameBuffer extends WeakReference<FrameBuffer> {
protected static class GLResourceFrameBuffer extends Disposable<FrameBuffer> {
int glFbo;
int glDepth;
int glStencil;
Expand All @@ -1075,30 +1034,8 @@ protected static class GLResourceFrameBuffer extends WeakReference<FrameBuffer>
private PGL pgl;
private int context;

static private ReferenceQueue<FrameBuffer> refQueue = new ReferenceQueue<FrameBuffer>();
static private List<GLResourceFrameBuffer> refList = new ArrayList<GLResourceFrameBuffer>();

static void drainRefQueueBounded() {
ReferenceQueue<FrameBuffer> refQueue = GLResourceFrameBuffer.referenceQueue();
int iterations = 0;
while (iterations < MAX_DRAIN_GLRES_ITERATIONS) {
GLResourceFrameBuffer res = (GLResourceFrameBuffer)refQueue.poll();
if (res == null) {
break;
}
res.dispose();
++iterations;
}
}

static ReferenceQueue<FrameBuffer> referenceQueue() {
return refQueue;
}

public GLResourceFrameBuffer(FrameBuffer fb) {
super(fb, refQueue);

drainRefQueueBounded();
super(fb);

pgl = fb.pg.getPrimaryPGL();
if (!fb.screenFb) {
Expand Down Expand Up @@ -1132,11 +1069,10 @@ public GLResourceFrameBuffer(FrameBuffer fb) {
}

this.context = fb.context;

refList.add(this);
}

private void disposeNative() {
@Override
public void disposeNative() {
if (pgl != null) {
if (glFbo != 0) {
intBuffer.put(0, glFbo);
Expand Down Expand Up @@ -1167,13 +1103,11 @@ private void disposeNative() {
}
}

void dispose() {
refList.remove(this);
disposeNative();
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof GLResourceFrameBuffer)) {
return false;
}
GLResourceFrameBuffer other = (GLResourceFrameBuffer)obj;
return other.glFbo == glFbo &&
other.glDepth == glDepth &&
Expand Down Expand Up @@ -6586,6 +6520,8 @@ protected void deleteSurfaceTextures() {
if (filterTexture != null) {
filterTexture.dispose();
}


}


Expand Down
Loading