mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
Improved context recreation mechanism
This commit is contained in:
@@ -25,6 +25,9 @@
|
||||
package processing.opengl;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.media.opengl.GLContext;
|
||||
|
||||
import processing.core.PApplet;
|
||||
import processing.core.PConstants;
|
||||
import processing.core.PFont;
|
||||
@@ -50,6 +53,7 @@ import processing.core.PImage;
|
||||
class PFontTexture implements PConstants {
|
||||
protected PApplet parent;
|
||||
protected PGraphicsOpenGL ogl;
|
||||
protected GLContext context;
|
||||
protected PFont font;
|
||||
|
||||
protected int maxTexWidth;
|
||||
@@ -68,38 +72,11 @@ class PFontTexture implements PConstants {
|
||||
this.parent = parent;
|
||||
this.font = font;
|
||||
ogl = (PGraphicsOpenGL)parent.g;
|
||||
context = ogl.getContext();
|
||||
|
||||
initTexture(maxw, maxh);
|
||||
}
|
||||
|
||||
/*
|
||||
public void delete() {
|
||||
for (int i = 0; i < textures.length; i++) {
|
||||
textures[i].delete();
|
||||
}
|
||||
ogl.unregisterPGLObject(this);
|
||||
}
|
||||
|
||||
|
||||
public void backup() {
|
||||
// Nothing to do here: the font textures will backup
|
||||
// themselves.
|
||||
}
|
||||
|
||||
|
||||
public void restore() {
|
||||
// Restoration we have to do explicitly because the font
|
||||
// textures don't have a backing PImage object, so the
|
||||
// updateTex() method is in charge of updating each appropriate
|
||||
// section of the font textures.
|
||||
for (int i = 0; i < PApplet.min(font.getGlyphCount(), glyphTexinfos.length); i++) {
|
||||
TextureInfo tinfo = glyphTexinfos[i];
|
||||
textures[tinfo.texIndex].bind();
|
||||
tinfo.updateTex();
|
||||
textures[tinfo.texIndex].unbind();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
protected void allocate() {
|
||||
// Nothing to do here: the font textures will allocate
|
||||
@@ -147,7 +124,7 @@ class PFontTexture implements PConstants {
|
||||
textures = new PTexture[1];
|
||||
textures[0] = tex;
|
||||
images = new PImage[1];
|
||||
images[0] = PTexture.wrap(ogl, tex);
|
||||
images[0] = ogl.wrapTexture(tex);
|
||||
currentTex = 0;
|
||||
} else if (resize) {
|
||||
// Replacing old smaller texture with larger one.
|
||||
@@ -171,7 +148,7 @@ class PFontTexture implements PConstants {
|
||||
PImage[] tempImg = images;
|
||||
images = new PImage[textures.length + 1];
|
||||
PApplet.arrayCopy(tempImg, images, tempImg.length);
|
||||
images[tempImg.length] = PTexture.wrap(ogl, tex);
|
||||
images[tempImg.length] = ogl.wrapTexture(tex);
|
||||
}
|
||||
lastTex = currentTex;
|
||||
|
||||
|
||||
@@ -151,42 +151,22 @@ public class PFramebuffer implements PConstants {
|
||||
backupTexture = new PTexture(parent, width, height, new PTexture.Parameters(ARGB, POINT));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public void delete() {
|
||||
release();
|
||||
for (int i = 0; i < numColorBuffers; i++) {
|
||||
colorBufferTex[i] = null;
|
||||
}
|
||||
ogl.unregisterPGLObject(this);
|
||||
}
|
||||
|
||||
public void backup() {
|
||||
}
|
||||
|
||||
public void restore() {
|
||||
setColorBuffers(colorBufferTex.clone(), colorBufferTex.length);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (glFboID != 0) {
|
||||
ogl.finalizeFrameBufferObject(glFboID);
|
||||
}
|
||||
|
||||
}
|
||||
if (glDepthBufferID != 0) {
|
||||
ogl.finalizeRenderBufferObject(glDepthBufferID);
|
||||
}
|
||||
|
||||
}
|
||||
if (glStencilBufferID != 0) {
|
||||
ogl.finalizeRenderBufferObject(glStencilBufferID);
|
||||
}
|
||||
|
||||
if (glColorBufferMultisampleID != 0) {
|
||||
ogl.finalizeRenderBufferObject(glColorBufferMultisampleID);
|
||||
}
|
||||
|
||||
if (glDepthStencilBufferID != 0) {
|
||||
ogl.finalizeRenderBufferObject(glDepthStencilBufferID);
|
||||
}
|
||||
|
||||
@@ -670,21 +670,37 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
int[] temp = new int[1];
|
||||
gl.glGenTextures(1, temp, 0);
|
||||
int idx = temp[0];
|
||||
int id = temp[0];
|
||||
|
||||
if (glTextureObjects.containsKey(idx)) {
|
||||
if (glTextureObjects.containsKey(id)) {
|
||||
showWarning("Adding same texture twice");
|
||||
} else {
|
||||
glTextureObjects.put(idx, false);
|
||||
glTextureObjects.put(id, false);
|
||||
}
|
||||
|
||||
return idx;
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void deleteTextureObject(int id) {
|
||||
if (glTextureObjects.containsKey(id)) {
|
||||
int[] temp = { id };
|
||||
gl.glDeleteTextures(1, temp, 0);
|
||||
glTextureObjects.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteAllTextureObjects() {
|
||||
for (Integer id : glTextureObjects.keySet()) {
|
||||
int[] temp = { id.intValue() };
|
||||
gl.glDeleteTextures(1, temp, 0);
|
||||
}
|
||||
glTextureObjects.clear();
|
||||
}
|
||||
|
||||
// This is synchronized because it is called from the GC thread.
|
||||
synchronized protected void finalizeTextureObject(int idx) {
|
||||
if (glTextureObjects.containsKey(idx)) {
|
||||
glTextureObjects.put(idx, true);
|
||||
synchronized protected void finalizeTextureObject(int id) {
|
||||
if (glTextureObjects.containsKey(id)) {
|
||||
glTextureObjects.put(id, true);
|
||||
} else {
|
||||
showWarning("Trying to finalize non-existing texture");
|
||||
}
|
||||
@@ -693,17 +709,16 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected void deleteFinalizedTextureObjects() {
|
||||
Set<Integer> finalized = new HashSet<Integer>();
|
||||
|
||||
for (Integer idx : glTextureObjects.keySet()) {
|
||||
if (glTextureObjects.get(idx)) {
|
||||
finalized.add(idx);
|
||||
int id = idx.intValue();
|
||||
int[] temp = { id };
|
||||
for (Integer id : glTextureObjects.keySet()) {
|
||||
if (glTextureObjects.get(id)) {
|
||||
finalized.add(id);
|
||||
int[] temp = { id.intValue() };
|
||||
gl.glDeleteTextures(1, temp, 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (Integer idx : finalized) {
|
||||
glTextureObjects.remove(idx);
|
||||
for (Integer id : finalized) {
|
||||
glTextureObjects.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -733,6 +748,14 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteAllVertexBufferObjects() {
|
||||
for (Integer id : glVertexBuffers.keySet()) {
|
||||
int[] temp = { id.intValue() };
|
||||
gl.glDeleteBuffers(1, temp, 0);
|
||||
}
|
||||
glVertexBuffers.clear();
|
||||
}
|
||||
|
||||
// This is synchronized because it is called from the GC thread.
|
||||
synchronized protected void finalizeVertexBufferObject(int id) {
|
||||
if (glVertexBuffers.containsKey(id)) {
|
||||
@@ -765,21 +788,37 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
int[] temp = new int[1];
|
||||
gl.glGenFramebuffers(1, temp, 0);
|
||||
int idx = temp[0];
|
||||
int id = temp[0];
|
||||
|
||||
if (glFrameBuffers.containsKey(idx)) {
|
||||
if (glFrameBuffers.containsKey(id)) {
|
||||
showWarning("Adding same FBO twice");
|
||||
} else {
|
||||
glFrameBuffers.put(idx, false);
|
||||
glFrameBuffers.put(id, false);
|
||||
}
|
||||
|
||||
return idx;
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void deleteFrameBufferObject(int id) {
|
||||
if (glFrameBuffers.containsKey(id)) {
|
||||
int[] temp = { id };
|
||||
gl.glDeleteFramebuffers(1, temp, 0);
|
||||
glFrameBuffers.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteAllFrameBufferObjects() {
|
||||
for (Integer id : glFrameBuffers.keySet()) {
|
||||
int[] temp = { id.intValue() };
|
||||
gl.glDeleteFramebuffers(1, temp, 0);
|
||||
}
|
||||
glFrameBuffers.clear();
|
||||
}
|
||||
|
||||
// This is synchronized because it is called from the GC thread.
|
||||
synchronized protected void finalizeFrameBufferObject(int idx) {
|
||||
if (glFrameBuffers.containsKey(idx)) {
|
||||
glFrameBuffers.put(idx, true);
|
||||
synchronized protected void finalizeFrameBufferObject(int id) {
|
||||
if (glFrameBuffers.containsKey(id)) {
|
||||
glFrameBuffers.put(id, true);
|
||||
} else {
|
||||
showWarning("Trying to finalize non-existing FBO");
|
||||
}
|
||||
@@ -788,17 +827,16 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected void deleteFinalizedFrameBufferObjects() {
|
||||
Set<Integer> finalized = new HashSet<Integer>();
|
||||
|
||||
for (Integer idx : glFrameBuffers.keySet()) {
|
||||
if (glFrameBuffers.get(idx)) {
|
||||
finalized.add(idx);
|
||||
int id = idx.intValue();
|
||||
int[] temp = { id };
|
||||
for (Integer id : glFrameBuffers.keySet()) {
|
||||
if (glFrameBuffers.get(id)) {
|
||||
finalized.add(id);
|
||||
int[] temp = { id.intValue() };
|
||||
gl.glDeleteFramebuffers(1, temp, 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (Integer idx : finalized) {
|
||||
glFrameBuffers.remove(idx);
|
||||
for (Integer id : finalized) {
|
||||
glFrameBuffers.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -809,21 +847,37 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
int[] temp = new int[1];
|
||||
gl.glGenRenderbuffers(1, temp, 0);
|
||||
int idx = temp[0];
|
||||
int id = temp[0];
|
||||
|
||||
if (glRenderBuffers.containsKey(idx)) {
|
||||
if (glRenderBuffers.containsKey(id)) {
|
||||
showWarning("Adding same renderbuffer twice");
|
||||
} else {
|
||||
glRenderBuffers.put(idx, false);
|
||||
glRenderBuffers.put(id, false);
|
||||
}
|
||||
|
||||
return idx;
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void deleteRenderBufferObject(int id) {
|
||||
if (glRenderBuffers.containsKey(id)) {
|
||||
int[] temp = { id };
|
||||
gl.glDeleteRenderbuffers(1, temp, 0);
|
||||
glRenderBuffers.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteAllRenderBufferObjects() {
|
||||
for (Integer id : glRenderBuffers.keySet()) {
|
||||
int[] temp = { id.intValue() };
|
||||
gl.glDeleteRenderbuffers(1, temp, 0);
|
||||
}
|
||||
glRenderBuffers.clear();
|
||||
}
|
||||
|
||||
// This is synchronized because it is called from the GC thread.
|
||||
synchronized protected void finalizeRenderBufferObject(int idx) {
|
||||
if (glRenderBuffers.containsKey(idx)) {
|
||||
glRenderBuffers.put(idx, true);
|
||||
synchronized protected void finalizeRenderBufferObject(int id) {
|
||||
if (glRenderBuffers.containsKey(id)) {
|
||||
glRenderBuffers.put(id, true);
|
||||
} else {
|
||||
showWarning("Trying to finalize non-existing renderbuffer");
|
||||
}
|
||||
@@ -832,17 +886,16 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected void deleteFinalizedRenderBufferObjects() {
|
||||
Set<Integer> finalized = new HashSet<Integer>();
|
||||
|
||||
for (Integer idx : glRenderBuffers.keySet()) {
|
||||
if (glRenderBuffers.get(idx)) {
|
||||
finalized.add(idx);
|
||||
int id = idx.intValue();
|
||||
int[] temp = { id };
|
||||
for (Integer id : glRenderBuffers.keySet()) {
|
||||
if (glRenderBuffers.get(id)) {
|
||||
finalized.add(id);
|
||||
int[] temp = { id.intValue() };
|
||||
gl.glDeleteRenderbuffers(1, temp, 0);
|
||||
}
|
||||
}
|
||||
|
||||
for (Integer idx : finalized) {
|
||||
glRenderBuffers.remove(idx);
|
||||
for (Integer id : finalized) {
|
||||
glRenderBuffers.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -853,21 +906,35 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
ogl.report("before delete");
|
||||
deleteFinalizedGLSLProgramObjects();
|
||||
|
||||
int idx = gl2x.glCreateProgram();
|
||||
int id = gl2x.glCreateProgram();
|
||||
|
||||
if (glslPrograms.containsKey(idx)) {
|
||||
if (glslPrograms.containsKey(id)) {
|
||||
showWarning("Adding same glsl program twice");
|
||||
} else {
|
||||
glslPrograms.put(idx, false);
|
||||
glslPrograms.put(id, false);
|
||||
}
|
||||
|
||||
return idx;
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void deleteGLSLProgramObject(int id) {
|
||||
if (glslPrograms.containsKey(id)) {
|
||||
gl2x.glDeleteProgram(id);
|
||||
glslPrograms.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteAllGLSLProgramObjects() {
|
||||
for (Integer id : glslPrograms.keySet()) {
|
||||
gl2x.glDeleteProgram(id);
|
||||
}
|
||||
glslPrograms.clear();
|
||||
}
|
||||
|
||||
// This is synchronized because it is called from the GC thread.
|
||||
synchronized protected void finalizeGLSLProgramObject(int idx) {
|
||||
if (glslPrograms.containsKey(idx)) {
|
||||
glslPrograms.put(idx, true);
|
||||
synchronized protected void finalizeGLSLProgramObject(int id) {
|
||||
if (glslPrograms.containsKey(id)) {
|
||||
glslPrograms.put(id, true);
|
||||
} else {
|
||||
showWarning("Trying to finalize non-existing glsl program");
|
||||
}
|
||||
@@ -876,16 +943,15 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected void deleteFinalizedGLSLProgramObjects() {
|
||||
Set<Integer> finalized = new HashSet<Integer>();
|
||||
|
||||
for (Integer idx : glslPrograms.keySet()) {
|
||||
if (glslPrograms.get(idx)) {
|
||||
finalized.add(idx);
|
||||
int id = idx.intValue();
|
||||
gl2x.glDeleteProgram(id);
|
||||
for (Integer id : glslPrograms.keySet()) {
|
||||
if (glslPrograms.get(id)) {
|
||||
finalized.add(id);
|
||||
gl2x.glDeleteProgram(id.intValue());
|
||||
}
|
||||
}
|
||||
|
||||
for (Integer idx : finalized) {
|
||||
glslPrograms.remove(idx);
|
||||
for (Integer id : finalized) {
|
||||
glslPrograms.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -894,21 +960,35 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected int createGLSLVertShaderObject() {
|
||||
deleteFinalizedGLSLVertShaderObjects();
|
||||
|
||||
int idx = gl2x.glCreateShader(GL2.GL_VERTEX_SHADER);
|
||||
int id = gl2x.glCreateShader(GL2.GL_VERTEX_SHADER);
|
||||
|
||||
if (glslVertexShaders.containsKey(idx)) {
|
||||
if (glslVertexShaders.containsKey(id)) {
|
||||
showWarning("Adding same glsl vertex shader twice");
|
||||
} else {
|
||||
glslVertexShaders.put(idx, false);
|
||||
glslVertexShaders.put(id, false);
|
||||
}
|
||||
|
||||
return idx;
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void deleteGLSLVertShaderObject(int id) {
|
||||
if (glslVertexShaders.containsKey(id)) {
|
||||
gl2x.glDeleteShader(id);
|
||||
glslVertexShaders.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteAllGLSLVertShaderObjects() {
|
||||
for (Integer id : glslVertexShaders.keySet()) {
|
||||
gl2x.glDeleteShader(id);
|
||||
}
|
||||
glslVertexShaders.clear();
|
||||
}
|
||||
|
||||
// This is synchronized because it is called from the GC thread.
|
||||
synchronized protected void finalizeGLSLVertShaderObject(int idx) {
|
||||
if (glslVertexShaders.containsKey(idx)) {
|
||||
glslVertexShaders.put(idx, true);
|
||||
synchronized protected void finalizeGLSLVertShaderObject(int id) {
|
||||
if (glslVertexShaders.containsKey(id)) {
|
||||
glslVertexShaders.put(id, true);
|
||||
} else {
|
||||
showWarning("Trying to finalize non-existing glsl vertex shader");
|
||||
}
|
||||
@@ -917,16 +997,15 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected void deleteFinalizedGLSLVertShaderObjects() {
|
||||
Set<Integer> finalized = new HashSet<Integer>();
|
||||
|
||||
for (Integer idx : glslVertexShaders.keySet()) {
|
||||
if (glslVertexShaders.get(idx)) {
|
||||
finalized.add(idx);
|
||||
int id = idx.intValue();
|
||||
gl2x.glDeleteShader(id);
|
||||
for (Integer id : glslVertexShaders.keySet()) {
|
||||
if (glslVertexShaders.get(id)) {
|
||||
finalized.add(id);
|
||||
gl2x.glDeleteShader(id.intValue());
|
||||
}
|
||||
}
|
||||
|
||||
for (Integer idx : finalized) {
|
||||
glslVertexShaders.remove(idx);
|
||||
for (Integer id : finalized) {
|
||||
glslVertexShaders.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -936,21 +1015,35 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected int createGLSLFragShaderObject() {
|
||||
deleteFinalizedGLSLFragShaderObjects();
|
||||
|
||||
int idx = gl2x.glCreateShader(GL2.GL_FRAGMENT_SHADER);
|
||||
int id = gl2x.glCreateShader(GL2.GL_FRAGMENT_SHADER);
|
||||
|
||||
if (glslFragmentShaders.containsKey(idx)) {
|
||||
if (glslFragmentShaders.containsKey(id)) {
|
||||
showWarning("Adding same glsl fragment shader twice");
|
||||
} else {
|
||||
glslFragmentShaders.put(idx, false);
|
||||
glslFragmentShaders.put(id, false);
|
||||
}
|
||||
|
||||
return idx;
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void deleteGLSLFragShaderObject(int id) {
|
||||
if (glslFragmentShaders.containsKey(id)) {
|
||||
gl2x.glDeleteShader(id);
|
||||
glslFragmentShaders.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteAllGLSLFragShaderObjects() {
|
||||
for (Integer id : glslFragmentShaders.keySet()) {
|
||||
gl2x.glDeleteShader(id);
|
||||
}
|
||||
glslFragmentShaders.clear();
|
||||
}
|
||||
|
||||
// This is synchronized because it is called from the GC thread.
|
||||
synchronized protected void finalizeGLSLFragShaderObject(int idx) {
|
||||
if (glslFragmentShaders.containsKey(idx)) {
|
||||
glslFragmentShaders.put(idx, true);
|
||||
synchronized protected void finalizeGLSLFragShaderObject(int id) {
|
||||
if (glslFragmentShaders.containsKey(id)) {
|
||||
glslFragmentShaders.put(id, true);
|
||||
} else {
|
||||
showWarning("Trying to finalize non-existing glsl fragment shader");
|
||||
}
|
||||
@@ -959,16 +1052,15 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected void deleteFinalizedGLSLFragShaderObjects() {
|
||||
Set<Integer> finalized = new HashSet<Integer>();
|
||||
|
||||
for (Integer idx : glslFragmentShaders.keySet()) {
|
||||
if (glslFragmentShaders.get(idx)) {
|
||||
finalized.add(idx);
|
||||
int id = idx.intValue();
|
||||
gl2x.glDeleteShader(id);
|
||||
for (Integer id : glslFragmentShaders.keySet()) {
|
||||
if (glslFragmentShaders.get(id)) {
|
||||
finalized.add(id);
|
||||
gl2x.glDeleteShader(id.intValue());
|
||||
}
|
||||
}
|
||||
|
||||
for (Integer idx : finalized) {
|
||||
glslFragmentShaders.remove(idx);
|
||||
for (Integer id : finalized) {
|
||||
glslFragmentShaders.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -983,6 +1075,15 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
deleteFinalizedGLSLFragShaderObjects();
|
||||
}
|
||||
|
||||
protected void deleteAllGLResources() {
|
||||
deleteAllTextureObjects();
|
||||
deleteAllVertexBufferObjects();
|
||||
deleteAllFrameBufferObjects();
|
||||
deleteAllRenderBufferObjects();
|
||||
deleteAllGLSLProgramObjects();
|
||||
deleteAllGLSLVertShaderObjects();
|
||||
deleteAllGLSLFragShaderObjects();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1059,6 +1160,8 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
|
||||
protected void releaseResources() {
|
||||
// First, releasing the resources used by
|
||||
// renderer itself.
|
||||
if (texture != null) {
|
||||
texture.release();
|
||||
texture = null;
|
||||
@@ -1085,7 +1188,11 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
if (pointVBOsCreated) {
|
||||
releasePointBuffers();
|
||||
pointVBOsCreated = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now, releasing the remaining resources
|
||||
// (from user's objects).
|
||||
deleteAllGLResources();
|
||||
}
|
||||
|
||||
|
||||
@@ -1102,14 +1209,8 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
* the current OpenGL objects remain valid afterward.
|
||||
*/
|
||||
public void restartContext() {
|
||||
//backupPGLObjects();
|
||||
|
||||
// This releases the objects holding OpenGL resources
|
||||
// that are used by this renderer, so they are recreated
|
||||
// later... but what TODO with the objects such as PImages
|
||||
// or PShapes that might have been created by the user?
|
||||
releaseResources();
|
||||
deleteFinalizedGLResources();
|
||||
releaseResources();
|
||||
//deleteFinalizedGLResources();
|
||||
|
||||
releaseContext();
|
||||
context.destroy();
|
||||
@@ -1118,9 +1219,6 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
detainContext();
|
||||
|
||||
updateGLInterfaces();
|
||||
// allocatePGLObjects();
|
||||
// clearPGLFramebuffers();
|
||||
// restorePGLObjects();
|
||||
}
|
||||
|
||||
protected void createFillBuffers() {
|
||||
@@ -1440,8 +1538,6 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
drawing = false;
|
||||
|
||||
//deleteFinalizedGLResources();
|
||||
|
||||
report("bot endDraw()");
|
||||
}
|
||||
|
||||
@@ -1459,26 +1555,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
public void endGL() {
|
||||
restoreGLState();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public void allocateGL() {
|
||||
allocatePGLObjects();
|
||||
}
|
||||
|
||||
|
||||
public void backupGL() {
|
||||
backupPGLObjects();
|
||||
}
|
||||
|
||||
|
||||
public void restoreGL() {
|
||||
clearPGLFramebuffers();
|
||||
restorePGLObjects();
|
||||
}
|
||||
*/
|
||||
|
||||
public void updateGLInterfaces() {
|
||||
gl = context.getGL();
|
||||
|
||||
@@ -3100,7 +3179,16 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
if (textTex == null) {
|
||||
textTex = new PFontTexture(parent, textFont, maxTextureSize, maxTextureSize);
|
||||
textFont.setCache(this, textTex);
|
||||
}
|
||||
} else {
|
||||
if (context.hashCode() != textTex.context.hashCode()) {
|
||||
for (int i = 0; i < textTex.textures.length; i++) {
|
||||
textTex.textures[i].glID = 0; // To avoid finalization (texture objects were already deleted when context changed).
|
||||
textTex.textures[i] = null;
|
||||
}
|
||||
textTex = new PFontTexture(parent, textFont, maxTextureSize, maxTextureSize);
|
||||
textFont.setCache(this, textTex);
|
||||
}
|
||||
}
|
||||
textTex.setFirstTexture();
|
||||
|
||||
// Saving style parameters modified by text rendering.
|
||||
@@ -5274,7 +5362,6 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
texture.setFlippedY(true);
|
||||
this.setCache(ogl, texture);
|
||||
this.setParams(ogl, params);
|
||||
texture.setImage(this);
|
||||
|
||||
texCrop = new int[4];
|
||||
texCrop[0] = 0;
|
||||
@@ -5713,11 +5800,26 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
PTexture tex = (PTexture)img.getCache(ogl);
|
||||
if (tex == null) {
|
||||
tex = addTexture(img);
|
||||
} else if (img.isModified()) {
|
||||
if (img.width != tex.width || img.height != tex.height) {
|
||||
tex.init(img.width, img.height);
|
||||
} else {
|
||||
if (context.hashCode() != tex.context.hashCode()) {
|
||||
// The texture was created with a different context. We need
|
||||
// to recreate it. First, we make sure that the old GL id
|
||||
// is not used to delete the texture object (it was already
|
||||
// deleted when the context changed).
|
||||
tex.glID = 0;
|
||||
tex = addTexture(img);
|
||||
// TODO: apply this mechanism to all the Processing objects using
|
||||
// GL resources (PShape, PShader, PFramebuffer). They will probably
|
||||
// need the cache thingy as well.
|
||||
}
|
||||
updateTexture(img, tex);
|
||||
|
||||
if (img.isModified()) {
|
||||
if (img.width != tex.width || img.height != tex.height) {
|
||||
tex.init(img.width, img.height);
|
||||
}
|
||||
updateTexture(img, tex);
|
||||
}
|
||||
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
@@ -5735,12 +5837,24 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
PTexture tex = new PTexture(img.parent, img.width, img.height, params);
|
||||
img.loadPixels();
|
||||
tex.set(img.pixels);
|
||||
if (img.pixels != null) tex.set(img.pixels);
|
||||
img.setCache(ogl, tex);
|
||||
tex.setImage(img); // The parent image so the texture can regenerate itself upon re-allocation.
|
||||
return tex;
|
||||
}
|
||||
|
||||
protected PImage wrapTexture(PTexture tex) {
|
||||
// We don't use the PImage(int width, int height, int mode) constructor to
|
||||
// avoid initializing the pixels array.
|
||||
PImage img = new PImage();
|
||||
img.parent = parent;
|
||||
img.width = tex.width;
|
||||
img.height = tex.height;
|
||||
img.format = ARGB;
|
||||
img.setCache(ogl, tex);
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void updateTexture(PImage img, PTexture tex) {
|
||||
if (tex != null) {
|
||||
|
||||
@@ -86,7 +86,15 @@ public class PShader {
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
release();
|
||||
if (vertexShader != 0) {
|
||||
ogl.finalizeGLSLVertShaderObject(vertexShader);
|
||||
}
|
||||
if (fragmentShader != 0) {
|
||||
ogl.finalizeGLSLFragShaderObject(fragmentShader);
|
||||
}
|
||||
if (programObject != 0) {
|
||||
ogl.finalizeGLSLProgramObject(programObject);
|
||||
}
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
@@ -492,15 +500,15 @@ public class PShader {
|
||||
|
||||
protected void release() {
|
||||
if (vertexShader != 0) {
|
||||
ogl.finalizeGLSLVertShaderObject(vertexShader);
|
||||
ogl.deleteGLSLVertShaderObject(vertexShader);
|
||||
vertexShader = 0;
|
||||
}
|
||||
if (fragmentShader != 0) {
|
||||
ogl.finalizeGLSLFragShaderObject(fragmentShader);
|
||||
ogl.deleteGLSLFragShaderObject(fragmentShader);
|
||||
fragmentShader = 0;
|
||||
}
|
||||
if (programObject != 0) {
|
||||
ogl.finalizeGLSLProgramObject(programObject);
|
||||
ogl.deleteGLSLProgramObject(programObject);
|
||||
programObject = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,13 +297,80 @@ public class PShape3D extends PShape {
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
release();
|
||||
finalizeFillBuffers();
|
||||
finalizeLineBuffers();
|
||||
finalizePointBuffers();
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalizeFillBuffers() {
|
||||
if (glFillVertexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glFillVertexBufferID);
|
||||
}
|
||||
|
||||
if (glFillColorBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glFillColorBufferID);
|
||||
}
|
||||
|
||||
if (glFillNormalBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glFillNormalBufferID);
|
||||
}
|
||||
|
||||
if (glFillTexCoordBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glFillTexCoordBufferID);
|
||||
}
|
||||
|
||||
if (glFillIndexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glFillIndexBufferID);
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalizeLineBuffers() {
|
||||
if (glLineVertexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glLineVertexBufferID);
|
||||
}
|
||||
|
||||
if (glLineColorBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glLineColorBufferID);
|
||||
}
|
||||
|
||||
if (glLineNormalBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glLineNormalBufferID);
|
||||
}
|
||||
|
||||
if (glLineAttribBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glLineAttribBufferID);
|
||||
}
|
||||
|
||||
if (glLineIndexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glLineIndexBufferID);
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalizePointBuffers() {
|
||||
if (glPointVertexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glPointVertexBufferID);
|
||||
}
|
||||
|
||||
if (glPointColorBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glPointColorBufferID);
|
||||
}
|
||||
|
||||
if (glPointNormalBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glPointNormalBufferID);
|
||||
}
|
||||
|
||||
if (glPointAttribBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glPointAttribBufferID);
|
||||
}
|
||||
|
||||
if (glPointIndexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glPointIndexBufferID);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
@@ -1622,81 +1689,81 @@ public class PShape3D extends PShape {
|
||||
|
||||
protected void deleteFillBuffers() {
|
||||
if (glFillVertexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glFillVertexBufferID);
|
||||
ogl.deleteVertexBufferObject(glFillVertexBufferID);
|
||||
glFillVertexBufferID = 0;
|
||||
}
|
||||
|
||||
if (glFillColorBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glFillColorBufferID);
|
||||
ogl.deleteVertexBufferObject(glFillColorBufferID);
|
||||
glFillColorBufferID = 0;
|
||||
}
|
||||
|
||||
if (glFillNormalBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glFillNormalBufferID);
|
||||
ogl.deleteVertexBufferObject(glFillNormalBufferID);
|
||||
glFillNormalBufferID = 0;
|
||||
}
|
||||
|
||||
if (glFillTexCoordBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glFillTexCoordBufferID);
|
||||
ogl.deleteVertexBufferObject(glFillTexCoordBufferID);
|
||||
glFillTexCoordBufferID = 0;
|
||||
}
|
||||
|
||||
if (glFillIndexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glFillIndexBufferID);
|
||||
ogl.deleteVertexBufferObject(glFillIndexBufferID);
|
||||
glFillIndexBufferID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected void deleteLineBuffers() {
|
||||
if (glLineVertexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glLineVertexBufferID);
|
||||
ogl.deleteVertexBufferObject(glLineVertexBufferID);
|
||||
glLineVertexBufferID = 0;
|
||||
}
|
||||
|
||||
if (glLineColorBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glLineColorBufferID);
|
||||
ogl.deleteVertexBufferObject(glLineColorBufferID);
|
||||
glLineColorBufferID = 0;
|
||||
}
|
||||
|
||||
if (glLineNormalBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glLineNormalBufferID);
|
||||
ogl.deleteVertexBufferObject(glLineNormalBufferID);
|
||||
glLineNormalBufferID = 0;
|
||||
}
|
||||
|
||||
if (glLineAttribBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glLineAttribBufferID);
|
||||
ogl.deleteVertexBufferObject(glLineAttribBufferID);
|
||||
glLineAttribBufferID = 0;
|
||||
}
|
||||
|
||||
if (glLineIndexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glLineIndexBufferID);
|
||||
ogl.deleteVertexBufferObject(glLineIndexBufferID);
|
||||
glLineIndexBufferID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected void deletePointBuffers() {
|
||||
if (glPointVertexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glPointVertexBufferID);
|
||||
ogl.deleteVertexBufferObject(glPointVertexBufferID);
|
||||
glPointVertexBufferID = 0;
|
||||
}
|
||||
|
||||
if (glPointColorBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glPointColorBufferID);
|
||||
ogl.deleteVertexBufferObject(glPointColorBufferID);
|
||||
glPointColorBufferID = 0;
|
||||
}
|
||||
|
||||
if (glPointNormalBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glPointNormalBufferID);
|
||||
ogl.deleteVertexBufferObject(glPointNormalBufferID);
|
||||
glPointNormalBufferID = 0;
|
||||
}
|
||||
|
||||
if (glPointAttribBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glPointAttribBufferID);
|
||||
ogl.deleteVertexBufferObject(glPointAttribBufferID);
|
||||
glPointAttribBufferID = 0;
|
||||
}
|
||||
|
||||
if (glPointIndexBufferID != 0) {
|
||||
ogl.finalizeVertexBufferObject(glPointIndexBufferID);
|
||||
ogl.deleteVertexBufferObject(glPointIndexBufferID);
|
||||
glPointIndexBufferID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ package processing.opengl;
|
||||
|
||||
import javax.media.opengl.GL;
|
||||
import javax.media.opengl.GL2;
|
||||
import javax.media.opengl.GLContext;
|
||||
|
||||
import java.nio.*;
|
||||
import processing.core.PApplet;
|
||||
import processing.core.PConstants;
|
||||
@@ -37,11 +39,11 @@ import processing.core.PImage;
|
||||
*/
|
||||
public class PTexture implements PConstants {
|
||||
public int width, height;
|
||||
|
||||
|
||||
protected PApplet parent; // The Processing applet
|
||||
protected PGraphicsOpenGL ogl; // The main renderer
|
||||
protected PImage img; // The parent image
|
||||
|
||||
protected GLContext context; // The context that created this texture.
|
||||
|
||||
// These are public but use at your own risk!
|
||||
public int glID;
|
||||
public int glTarget;
|
||||
@@ -92,6 +94,7 @@ public class PTexture implements PConstants {
|
||||
this.parent = parent;
|
||||
|
||||
ogl = (PGraphicsOpenGL)parent.g;
|
||||
context = ogl.getContext();
|
||||
|
||||
glID = 0;
|
||||
|
||||
@@ -99,17 +102,6 @@ public class PTexture implements PConstants {
|
||||
}
|
||||
|
||||
|
||||
static public PImage wrap(PGraphicsOpenGL ogl, PTexture tex) {
|
||||
// We don't use the PImage(int width, int height, int mode) constructor to
|
||||
// avoid initializing the pixels array.
|
||||
PImage img = new PImage();
|
||||
img.width = tex.width;
|
||||
img.height = tex.height;
|
||||
img.format = ARGB;
|
||||
img.setCache(ogl, tex);
|
||||
return img;
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (glID != 0) {
|
||||
@@ -119,28 +111,8 @@ public class PTexture implements PConstants {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public void backup() {
|
||||
if (img != null) {
|
||||
img.loadPixels();
|
||||
if (img.pixels != null && (img instanceof PGraphicsOpenGL)) {
|
||||
// When img is an offscreen renderer, the loadPixels() call above
|
||||
// already takes care of copying the contents of the color buffer
|
||||
// to the pixels array.
|
||||
get(img.pixels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void restore() {
|
||||
if (img != null && img.pixels != null) {
|
||||
set(img.pixels);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -257,6 +229,7 @@ public class PTexture implements PConstants {
|
||||
|
||||
public void set(int[] pixels, int x, int y, int w, int h, int format) {
|
||||
if (pixels == null) {
|
||||
pixels = null;
|
||||
PGraphics.showWarning("The pixels array is null.");
|
||||
return;
|
||||
}
|
||||
@@ -938,11 +911,7 @@ public class PTexture implements PConstants {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Utilities
|
||||
|
||||
protected void setImage(PImage img) {
|
||||
this.img = img;
|
||||
}
|
||||
|
||||
|
||||
protected GL getGl() {
|
||||
return ogl.gl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user