From 73d24fad2fb8ecd33495375d329f30f14cdf2926 Mon Sep 17 00:00:00 2001 From: Ben Steffensmeier Date: Mon, 20 Feb 2012 15:25:28 -0600 Subject: [PATCH] Issue #345 fix issues with gl contexts and creation and deletion of gl objects! Change-Id: Ied6c7a814478e21f3cd0eccabfecb00a92e698db Former-commit-id: e0f697c492eecff4bb8d83d05efbcaf2876125c9 --- .../raytheon/viz/core/gl/AbstractGLMesh.java | 5 +- .../raytheon/viz/core/gl/GLCanvasCache.java | 73 ------ .../raytheon/viz/core/gl/GLContextBridge.java | 203 ++++++++++++++++ .../viz/core/gl/GLDisposalManager.java | 127 ++++++++++ .../viz/core/gl/GLFactoryAdapter.java | 18 +- .../viz/core/gl/GLGeometryObject2D.java | 55 +---- .../viz/core/gl/GLGeometryPainter.java | 9 +- .../raytheon/viz/core/gl/GLVBOCleaner.java | 138 ----------- .../src/com/raytheon/viz/core/gl/IGLFont.java | 8 - .../com/raytheon/viz/core/gl/IGLTarget.java | 23 +- .../raytheon/viz/core/gl/SharedCoordMap.java | 3 +- .../viz/core/gl/images/AbstractGLImage.java | 135 +++-------- .../viz/core/gl/images/GLCMTextureData.java | 29 +-- .../core/gl/images/GLColormappedImage.java | 15 +- .../raytheon/viz/core/gl/images/GLImage.java | 15 +- .../viz/core/gl/internal/FontFactory.java | 7 +- .../viz/core/gl/internal/GLAbstractView.java | 5 +- .../raytheon/viz/core/gl/internal/GLFont.java | 27 +-- .../viz/core/gl/internal/GLTarget.java | 226 +++++------------- .../core/gl/internal/GLWireframeShape2D.java | 22 +- .../gl/internal/PreferenceBasedGLFont.java | 14 +- .../core/gl/internal/TextRendererCache.java | 12 +- .../core/gl/internal/UnmodifiableGLFont.java | 15 +- .../core/gl/internal/cache/ImageCache.java | 26 +- .../ext/GLColormapShadedShapeExtension.java | 1 - .../ext/GLOffscreenRenderingExtension.java | 6 +- .../core/gl/objects/GLFrameBufferObject.java | 120 ++++++++++ .../viz/core/gl/objects/GLIdWrapper.java | 96 ++++++++ .../viz/core/gl/objects/GLRenderBuffer.java | 84 +++++++ .../viz/core/gl/objects/GLTextureObject.java | 88 +++++++ .../core/gl/objects/GLVertexBufferObject.java | 88 +++++++ 31 files changed, 1006 insertions(+), 687 deletions(-) delete mode 100644 cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLCanvasCache.java create mode 100644 cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLContextBridge.java create mode 100644 cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLDisposalManager.java delete mode 100644 cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLVBOCleaner.java create mode 100644 cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLFrameBufferObject.java create mode 100644 cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLIdWrapper.java create mode 100644 cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLRenderBuffer.java create mode 100644 cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLTextureObject.java create mode 100644 cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLVertexBufferObject.java diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/AbstractGLMesh.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/AbstractGLMesh.java index e250f57b1a..7ef7c820eb 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/AbstractGLMesh.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/AbstractGLMesh.java @@ -106,12 +106,11 @@ public abstract class AbstractGLMesh implements IMesh { } if (!compiled) { - vertexCoords.setTarget(glTarget); - vertexCoords.compile(); + vertexCoords.compile(glTarget.getGl()); compiled = true; } - GLGeometryPainter.paintGeometries(glTarget, vertexCoords, + GLGeometryPainter.paintGeometries(glTarget.getGl(), vertexCoords, sharedTextureCoords.getTextureCoords()); } diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLCanvasCache.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLCanvasCache.java deleted file mode 100644 index cdc95972d2..0000000000 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLCanvasCache.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ - -package com.raytheon.viz.core.gl; - -import org.eclipse.swt.opengl.GLCanvas; - -/** - * - * Caches the initial GLCanvas - * - * This is not ideal, since the SWT resources for the first canvas are always - * left open after the map is disposed, but due to limitations in JOGL and - * Eclipse, it is necessary. - * - *
- * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Jul 10, 2007            chammack    Initial Creation.	
- * 
- * 
- * - * @author chammack - * @version 1.0 - */ - -public class GLCanvasCache { - - private static GLCanvasCache instance; - - private GLCanvas canvas; - - public static synchronized GLCanvasCache getInstance() { - if (instance == null) { - instance = new GLCanvasCache(); - } - return instance; - } - - /** - * @return the canvas - */ - public GLCanvas getCanvas() { - return canvas; - } - - /** - * @param canvas - * the canvas to set - */ - public void setCanvas(GLCanvas canvas) { - this.canvas = canvas; - } - -} diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLContextBridge.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLContextBridge.java new file mode 100644 index 0000000000..21edf4d966 --- /dev/null +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLContextBridge.java @@ -0,0 +1,203 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.viz.core.gl; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLPbuffer; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.opengl.GLCanvas; +import org.eclipse.swt.opengl.GLData; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.viz.core.exception.VizException; + +/** + * + * Provide a mechanism for keeping JOGL GLContext in sync with the SWT GLCanvas + * context. The JOGL GLContext has most of the logic needed to manage contexts, + * except for when the context is external. Since our context is created by the + * SWT GLCanvas the JOGL GLContext does not actually control the active context + * in GL. This class contains a GLCanvas and a GLContext and keeps the active + * context in sync between the two. + * + * This class also provides static access to the "Master Context" which is a + * context with which all other contexts are sharing data. Ideally we would not + * need to use the master context however there is a bug in some Windows/Intel + * drivers which causes crashes if a texture is created on a context, then the + * context is deleted, then the texture is deleted on a different context. To + * resolve this all textures should be created and deleted on the master + * context. This is done by calling makeMasterContextCurrent before calling + * glGenTexture or glDeleteTexture and then calling releaseMasterContext + * immediately after to restore the previous context. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 17, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class GLContextBridge { + + private static GLContextBridge activeContext; + + private static GLContextBridge masterContext; + + private static GLContextBridge previousContext; + + private final GLCanvas canvas; + + private final GLContext context; + + public GLContextBridge(int width, int height) throws VizException { + GLCapabilities glCap = new GLCapabilities(); + if (!GLDrawableFactory.getFactory().canCreateGLPbuffer()) { + throw new VizException( + "Graphics card does not support GLPbuffer and " + + "therefore does not support offscreen rendering."); + } + GLPbuffer buf = GLDrawableFactory.getFactory().createGLPbuffer(glCap, + null, width, height, null); + this.context = buf.createContext(null); + this.canvas = null; + activeContext = this; + releaseContext(); + } + + public GLContextBridge(GLCanvas canvas) { + this.canvas = canvas; + this.canvas.setCurrent(); + this.context = GLDrawableFactory.getFactory().createExternalGLContext(); + activeContext = this; + releaseContext(); + } + + /** + * Make this context current for any GL Operations and release any + * previously active context. + * + * @return true if this context was not previously active and should + * therefore be released when you are done performing gl operations + */ + public boolean makeContextCurrent() { + if (canvas != null && !canvas.isDisposed()) { + canvas.setCurrent(); + } else if (canvas != null) { + throw new RuntimeException( + "Cannot make gl context current, GLCanvas is disposed"); + } + GLContext oldContext = GLContext.getCurrent(); + if (context != oldContext) { + if (oldContext != null) { + oldContext.release(); + } + if (context.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) { + throw new RuntimeException( + "Cannot make gl context current, Unknown error occured."); + } + } + boolean retVal = (activeContext != this); + activeContext = this; + return retVal; + } + + public void releaseContext() { + if (context == GLContext.getCurrent()) { + context.release(); + } + if (activeContext == this) { + activeContext = null; + } + } + + public void destroyContext() { + releaseContext(); + context.destroy(); + } + + /** + * get the GLData to use when creating a new GLCanvas, data.shareContext + * will contain the canvas for the "Master Context" + * + * @return + */ + public static GLData getGLData() { + return getGLData(true); + } + + private static GLData getGLData(boolean setContext) { + GLData data = new GLData(); + data.stencilSize = 1; + data.depthSize = 1; + data.doubleBuffer = true; + if (setContext) { + data.shareContext = getMasterContext().canvas; + } + return data; + } + + private static GLContextBridge getMasterContext() { + if (masterContext == null) { + GLCanvas canvas = new GLCanvas(new Shell(), SWT.NONE, + getGLData(false)); + masterContext = new GLContextBridge(canvas); + } + return masterContext; + } + + /** + * This method makes the shared master context the active contexts, it also + * stores the current active context to be restored on release. + * + */ + public static void makeMasterContextCurrent() { + if (masterContext != null) { + if (activeContext != null) { + previousContext = activeContext; + activeContext.releaseContext(); + } + masterContext.makeContextCurrent(); + } + } + + /** + * Releases the master context and restores the context that was active + * before makeMasterContextCurrent was called. + */ + public static void releaseMasterContext() { + if (masterContext != null) { + masterContext.releaseContext(); + if (previousContext != null) { + previousContext.makeContextCurrent(); + previousContext = null; + } + } + } + +} diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLDisposalManager.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLDisposalManager.java new file mode 100644 index 0000000000..aefaaceff8 --- /dev/null +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLDisposalManager.java @@ -0,0 +1,127 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.viz.core.gl; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; + +import javax.media.opengl.GL; + +/** + * + * This class provides a convenient way of disposing of GL resources on an + * active GLContext. + * + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 17, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class GLDisposalManager { + + private static ReferenceQueue refQueue = new ReferenceQueue(); + + private static List autoDisposers = new LinkedList(); + + private static Queue disposeQueue = new LinkedBlockingQueue(); + + /** + * This method should be used to dispose of a GL resource, at the end of a + * frame the target will make the context current and dispose of all + * resources. + * + * @param disposer + * a disposer object that is ready to dispose of a gl resource. + */ + private static void dispose(GLDisposer disposer) { + disposeQueue.add(disposer); + } + + /** + * Provide a backup mechanism to dispose. This uses WeakReference objects to + * call the disposer after the object is garbage collected. For this to work + * the disposer must have no references to object. Object should be the only + * thing using these GL resources, this will not work for anything which + * might be shared by multiple objects. This will also result in the dispose + * method of the disposer being called more than once so it should clear any + * + * @param disposer + * - a disposer that will be called when object is garbage + * collected + * @param object + * - an object which uses a gl resource. + */ + public static void autoDispose(GLDisposer disposer, Object object) { + autoDisposers.add(new GLAutoDisposer(object, disposer)); + } + + /** + * For use by the target only, the target should call this to dispose all + * unneeded resources + * + * @param gl + */ + public static void performDispose(GL gl) { + GLDisposer disposer = disposeQueue.poll(); + while (disposer != null) { + disposer.dispose(gl); + disposer = disposeQueue.poll(); + } + GLAutoDisposer autoDisposer = (GLAutoDisposer) refQueue.poll(); + while (autoDisposer != null) { + autoDisposers.remove(autoDisposer); + autoDisposer.disposer.dispose(); + autoDisposer = (GLAutoDisposer) refQueue.poll(); + } + } + + public static abstract class GLDisposer { + protected abstract void dispose(GL gl); + + final public void dispose() { + GLDisposalManager.dispose(this); + } + } + + private static class GLAutoDisposer extends WeakReference { + + private final GLDisposer disposer; + + public GLAutoDisposer(Object referent, GLDisposer disposer) { + super(referent, refQueue); + this.disposer = disposer; + } + + } + +} diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLFactoryAdapter.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLFactoryAdapter.java index 533a2eb94d..9efc266f01 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLFactoryAdapter.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLFactoryAdapter.java @@ -26,7 +26,6 @@ import org.eclipse.swt.opengl.GLCanvas; import org.eclipse.swt.opengl.GLData; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Shell; import org.opengis.coverage.grid.GridEnvelope; import com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter; @@ -145,19 +144,7 @@ public class GLFactoryAdapter extends AbstractGraphicsFactoryAdapter { @Override public Canvas constrcutCanvas(Composite canvasComp) throws VizException { GLCanvas canvas; - GLData data = new GLData(); - data.stencilSize = 1; - data.depthSize = 1; - data.doubleBuffer = true; - GLCanvas cachedCanvas = GLCanvasCache.getInstance().getCanvas(); - if (cachedCanvas == null) { - Shell invisibleShell = new Shell(); - cachedCanvas = new GLCanvas(invisibleShell, SWT.NONE, data); - GLCanvasCache.getInstance().setCanvas(cachedCanvas); - cachedCanvas.setCurrent(); - } - - data.shareContext = cachedCanvas; + GLData data = GLContextBridge.getGLData(); canvas = new GLCanvas(canvasComp, SWT.NONE, data); canvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); @@ -173,8 +160,7 @@ public class GLFactoryAdapter extends AbstractGraphicsFactoryAdapter { */ @Override public void disposeCanvas(Canvas canvas) { - GLCanvas cachedCanvas = GLCanvasCache.getInstance().getCanvas(); - if (cachedCanvas != canvas && !canvas.isDisposed()) { + if (!canvas.isDisposed()) { canvas.getParent().dispose(); } } diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLGeometryObject2D.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLGeometryObject2D.java index 33d0ad5235..2ae8676f91 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLGeometryObject2D.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLGeometryObject2D.java @@ -29,8 +29,8 @@ import java.util.List; import javax.media.opengl.GL; import com.raytheon.uf.viz.core.IExtent; -import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.viz.core.gl.objects.GLVertexBufferObject; /** * GL Geometry object, supports compiling into VBOs. Coordinates passed in will @@ -53,9 +53,6 @@ import com.raytheon.uf.viz.core.exception.VizException; public class GLGeometryObject2D { public static class GLGeometryObjectData { - private IGLTarget target; - - private GL gl; public IExtent worldExtent; @@ -72,12 +69,6 @@ public class GLGeometryObject2D { this.coordType = coordType; } - public void setTarget(IGLTarget target) { - this.target = target; - if (target != null) { - gl = target.getGl(); - } - } } protected static enum State { @@ -96,7 +87,7 @@ public class GLGeometryObject2D { protected int points; - protected int vboId; + protected GLVertexBufferObject vbo; protected State state; @@ -104,8 +95,6 @@ public class GLGeometryObject2D { public GLGeometryObject2D(GLGeometryObjectData data) { this.data = new GLGeometryObjectData(data.geometryType, data.coordType); - this.data.gl = data.gl; - this.data.target = data.target; this.data.manageIndicies = data.manageIndicies; this.data.mutable = data.mutable; this.data.worldExtent = data.worldExtent; @@ -119,16 +108,16 @@ public class GLGeometryObject2D { } compiledIndicies = null; points = 0; - vboId = -1; + vbo = null; state = State.MUTABLE; } - public void compile() throws VizException { + public void compile(GL gl) throws VizException { // We will use glMultiDrawArrays if the cardSupportsHighEndFeatures, so // we will keep track of a lenghts buffer state = State.COMPILED; int add = 1; - if (GLCapabilities.getInstance(data.gl).cardSupportsHighEndFeatures) { + if (GLCapabilities.getInstance(gl).cardSupportsHighEndFeatures) { state = State.COMPILED_HIGH_END; add = 0; } @@ -169,24 +158,21 @@ public class GLGeometryObject2D { copy.put(data.get()); } - GL gl = this.data.gl; - // clear the error bit. - this.data.target.makeContextCurrent(); gl.glGetError(); // generate vbo - vboId = GLVBOCleaner.allocateVBO(this, this.data.target); + vbo = new GLVertexBufferObject(this); // verify successful - if (vboId <= 0) { - vboId = -1; + if (!vbo.isValid()) { + vbo = null; throw new VizException("Error compiling wireframe shape, " + "could not generate vertex buffer object"); } // bind and load - gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboId); + vbo.bind(gl, GL.GL_ARRAY_BUFFER); gl.glBufferData(GL.GL_ARRAY_BUFFER, copy.capacity() * 4, copy.rewind(), GL.GL_STATIC_DRAW); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); @@ -223,16 +209,8 @@ public class GLGeometryObject2D { compiledLengths = null; state = State.INVALID; - if (vboId > -1) { - final int vbo = vboId; - vboId = -1; - VizApp.runAsync(new Runnable() { - @Override - public void run() { - GLVBOCleaner.unallocateVBO(GLGeometryObject2D.this, vbo, - data.target); - } - }); + if (vbo != null && vbo.isValid()) { + vbo.dispose(); } } @@ -368,15 +346,8 @@ public class GLGeometryObject2D { } } - public synchronized void paint() throws VizException { - GLGeometryPainter.paintGeometries(data.target, this); - } - - public void setTarget(IGLTarget target) { - data.target = target; - if (data.target != null) { - data.gl = target.getGl(); - } + public synchronized void paint(GL gl) throws VizException { + GLGeometryPainter.paintGeometries(gl, this); } // 2D specific functions, override for 3D support diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLGeometryPainter.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLGeometryPainter.java index d62cce561e..f7753e05a5 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLGeometryPainter.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLGeometryPainter.java @@ -50,9 +50,8 @@ public class GLGeometryPainter { private static int maxVertices = -1; - public static void paintGeometries(IGLTarget target, - GLGeometryObject2D... geoms) throws VizException { - GL gl = target.getGl(); + public static void paintGeometries(GL gl, GLGeometryObject2D... geoms) + throws VizException { State state = State.INVALID; Set states = new HashSet(); for (GLGeometryObject2D geom : geoms) { @@ -131,11 +130,11 @@ public class GLGeometryPainter { case COMPILED: case COMPILED_HIGH_END: { for (GLGeometryObject2D geom : geoms) { - if (geom.vboId <= 0) { + if (!geom.vbo.isValid()) { throw new VizException( "Could not paint geometry, VBO not set!"); } - gl.glBindBuffer(GL.GL_ARRAY_BUFFER, geom.vboId); + geom.vbo.bind(gl, GL.GL_ARRAY_BUFFER); switch (geom.data.coordType) { case GL.GL_VERTEX_ARRAY: { gl.glVertexPointer(geom.pointsPerCoordinate(), GL.GL_FLOAT, diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLVBOCleaner.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLVBOCleaner.java deleted file mode 100644 index 7bc0fd186c..0000000000 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/GLVBOCleaner.java +++ /dev/null @@ -1,138 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ -package com.raytheon.viz.core.gl; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import javax.media.opengl.GL; - -/** - * - * This class uses WeakReference to guarantee that all vbos are deallocated even - * if dispose is never called. It is still better to call dispose to avoid - * having "dead" vbos on the graphics card, which can slow down rendering. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Jun 9, 2011            bsteffen     Initial creation
- * 
- * 
- * - * @author bsteffen - * @version 1.0 - */ -public class GLVBOCleaner extends WeakReference { - - /** - * This is needed so when unallocate is called we can set the vboId to -1 - * and stop it from being redeleted - */ - private static List cleaners = new LinkedList(); - - /** - * THis queue will contain all garbage collected vbo objects, if everyone - * deallocates all vboIds will be -1. - */ - private static ReferenceQueue queue = new ReferenceQueue(); - - /** - * get a new vboId from gl which will be linked to object, if object is - * garbage collected then the vbo will still be freed. This should only be - * called on the main thread. - * - * @param object - * @param target - * @return - */ - public static int allocateVBO(Object object, IGLTarget target) { - target.makeContextCurrent(); - clean(target.getGl()); - GLVBOCleaner cleaner = new GLVBOCleaner(object, target.getGl()); - - target.handleError(target.getGl().glGetError()); - - // verify successful - if (cleaner.vboId > 0) { - cleaners.add(cleaner); - } - return cleaner.vboId; - } - - /** - * Immediately free a vbo which has been allocated, any method that uses - * allocate should also use deallocate. object must be the same as the - * object passed to allocate. - * - * @param object - * @param vboId - * @param target - */ - public static void unallocateVBO(Object object, int vboId, IGLTarget target) { - target.makeContextCurrent(); - clean(target.getGl()); - if (vboId <= 0) { - return; - } - Iterator iter = cleaners.iterator(); - while (iter.hasNext()) { - GLVBOCleaner cleaner = iter.next(); - if (cleaner.get() == object && cleaner.vboId == vboId) { - cleaner.freeVbo(target.getGl()); - iter.remove(); - } - } - } - - private static void clean(GL gl) { - GLVBOCleaner cleaner = (GLVBOCleaner) queue.poll(); - while (cleaner != null) { - if (cleaner.vboId > 0) { - System.err - .println("An object with a gl vertex buffer object has been garbage collected without being disposed. This can cause a delay in freeing vbos which can cause severe performance problems."); - cleaner.freeVbo(gl); - } - cleaners.remove(cleaner); - cleaner = (GLVBOCleaner) queue.poll(); - } - } - - private int vboId; - - private GLVBOCleaner(Object referent, GL gl) { - super(referent, queue); - int[] vbos = new int[1]; - gl.glGenBuffers(1, vbos, 0); - this.vboId = vbos[0]; - } - - private void freeVbo(GL gl) { - gl.glDeleteBuffers(1, new int[] { this.vboId }, 0); - this.vboId = -1; - } - -} diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/IGLFont.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/IGLFont.java index 1b445ed87b..e3e05e8ab5 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/IGLFont.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/IGLFont.java @@ -20,7 +20,6 @@ package com.raytheon.viz.core.gl; import com.raytheon.uf.viz.core.drawables.IFont; -import com.raytheon.viz.core.gl.internal.GLTarget; import com.sun.opengl.util.j2d.TextRenderer; /** @@ -49,13 +48,6 @@ public interface IGLFont extends IFont { */ public TextRenderer getTextRenderer(); - /** - * Get the target for the font - * - * @return - */ - public GLTarget getTarget(); - /** * Force a dispose */ diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/IGLTarget.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/IGLTarget.java index 99e05b48fe..ef117db9fa 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/IGLTarget.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/IGLTarget.java @@ -20,7 +20,6 @@ package com.raytheon.viz.core.gl; import javax.media.opengl.GL; -import javax.media.opengl.GLContext; import javax.media.opengl.glu.GLU; import org.eclipse.swt.graphics.Rectangle; @@ -54,6 +53,12 @@ public interface IGLTarget extends IGraphicsTarget { */ public abstract boolean makeContextCurrent(); + /** + * + * @return + */ + public abstract void releaseContext(); + /** * Get the modle view matrix settings * @@ -101,21 +106,6 @@ public interface IGLTarget extends IGraphicsTarget { */ public abstract Rectangle getBounds(); - /** - * Get the gl context - * - * @return - */ - public abstract GLContext getContext(); - - /** - * Dispose luminance texture - * - * @param id - * @param pboID - */ - public abstract void disposeLuminanceTexture(int id, int pboID); - /** * Dispose a vbo * @@ -186,4 +176,5 @@ public interface IGLTarget extends IGraphicsTarget { * Checks the glError state and does a UFStatus message */ public abstract void handleError(int errorid); + } diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/SharedCoordMap.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/SharedCoordMap.java index dd726c215a..9b7d794460 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/SharedCoordMap.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/SharedCoordMap.java @@ -98,9 +98,8 @@ public class SharedCoordMap { GL.GL_TRIANGLE_STRIP, GL.GL_TEXTURE_COORD_ARRAY); data.manageIndicies = false; textureCoords = new GLGeometryObject2D(data); - textureCoords.setTarget(glTarget); populateTextureGeom(key, textureCoords); - textureCoords.compile(); + textureCoords.compile(glTarget.getGl()); } private void incRef() { diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/AbstractGLImage.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/AbstractGLImage.java index ede7487e16..c27bf3f573 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/AbstractGLImage.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/AbstractGLImage.java @@ -20,14 +20,14 @@ package com.raytheon.viz.core.gl.images; import javax.media.opengl.GL; -import javax.media.opengl.GLContext; +import javax.media.opengl.glu.GLU; import com.raytheon.uf.viz.core.IGraphicsTarget; -import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.drawables.IImage; import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.viz.core.gl.IGLTarget; -import com.raytheon.viz.core.gl.internal.GLTarget; +import com.raytheon.viz.core.gl.GLContextBridge; +import com.raytheon.viz.core.gl.objects.GLFrameBufferObject; +import com.raytheon.viz.core.gl.objects.GLRenderBuffer; /** * @@ -48,9 +48,6 @@ import com.raytheon.viz.core.gl.internal.GLTarget; */ public abstract class AbstractGLImage implements IImage { - /** The GL graphics target */ - protected IGLTarget theTarget; - /** The brightness of the image */ private float brightness = 1.0f; @@ -67,13 +64,12 @@ public abstract class AbstractGLImage implements IImage { protected Throwable throwable; // Used for offscreen rendering - private int fbo = -1; + private GLFrameBufferObject fbo; // Used for offscreen rendering - private int rbuf = -1; + private GLRenderBuffer rbuf; - protected AbstractGLImage(IGLTarget target) { - this.theTarget = target; + protected AbstractGLImage() { } /** @@ -113,10 +109,10 @@ public abstract class AbstractGLImage implements IImage { * IGraphicsTarget) */ public void target(IGraphicsTarget target) throws VizException { - theTarget = (GLTarget) target; - GLContext ctx = theTarget.getContext(); // TextureLoaderJob.getInstance().requestLoadIntoTexture(this, ctx); - this.loadTexture(ctx); + GLContextBridge.makeMasterContextCurrent(); + this.loadTexture(GLU.getCurrentGL()); + GLContextBridge.releaseMasterContext(); } /* @@ -158,117 +154,64 @@ public abstract class AbstractGLImage implements IImage { } public void dispose() { - if (fbo > 0 || rbuf > 0) { - final int[] bufs = new int[] { -1, -1 }; - if (fbo > 0) { - bufs[0] = fbo; - fbo = -1; - } - if (rbuf > 0) { - bufs[1] = rbuf; - rbuf = -1; - } - - VizApp.runAsync(new Runnable() { - @Override - public void run() { - theTarget.makeContextCurrent(); - if (bufs[0] > 0) { - theTarget.getGl().glDeleteFramebuffersEXT(1, - new int[] { bufs[0] }, 0); - } - if (bufs[1] > 0) { - theTarget.getGl().glDeleteRenderbuffersEXT(1, - new int[] { bufs[1] }, 0); - } - } - }); + if (fbo != null) { + fbo.dispose(); + fbo = null; + } + if (rbuf != null) { + rbuf.dispose(); + rbuf = null; } } public void usaAsFrameBuffer() throws VizException { - GL gl = theTarget.getGl(); - if (fbo != -1) { - gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, fbo); + GL gl = GLU.getCurrentGL(); + if (fbo != null && fbo.isValid()) { + fbo.bind(gl); gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - if (rbuf != -1) { + if (rbuf != null && rbuf.isValid()) { gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); } else { gl.glClear(GL.GL_COLOR_BUFFER_BIT); } return; } + gl = GLU.getCurrentGL(); + gl.glBindTexture(getTextureStorageType(), 0); - int[] ids = new int[1]; - gl.glGenFramebuffersEXT(1, ids, 0); - fbo = ids[0]; - gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, fbo); + fbo = new GLFrameBufferObject(this); + fbo.bind(gl); if (gl.glIsEnabled(GL.GL_DEPTH_TEST)) { // Generate and bind a render buffer for the depth component - gl.glGenRenderbuffersEXT(1, ids, 0); - rbuf = ids[0]; - gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, rbuf); - gl.glRenderbufferStorageEXT(GL.GL_RENDERBUFFER_EXT, - GL.GL_DEPTH_COMPONENT, getWidth(), getHeight()); + rbuf = new GLRenderBuffer(this); + rbuf.bind(gl); + rbuf.createStorage(gl, GL.GL_DEPTH_COMPONENT, getWidth(), + getHeight()); gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, 0); // Attach render buffer to depth of fbo gl.glFramebufferRenderbufferEXT(GL.GL_FRAMEBUFFER_EXT, - GL.GL_DEPTH_ATTACHMENT_EXT, GL.GL_RENDERBUFFER_EXT, rbuf); + GL.GL_DEPTH_ATTACHMENT_EXT, GL.GL_RENDERBUFFER_EXT, + rbuf.getId()); } // Attach texture to color attachement on fbo gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT, getTextureStorageType(), getTextureid(), 0); - String errorMessage = null; - - switch (gl.glCheckFramebufferStatusEXT(GL.GL_FRAMEBUFFER_EXT)) { - case GL.GL_FRAMEBUFFER_COMPLETE_EXT: { - // Everything is ok. - break; - } - case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: { - errorMessage = "Error: Framebuffer incomplete, fbo attachement is NOT complete"; - break; - } - case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: { - errorMessage = "Error: Framebuffer incomplete, no image is attached to FBO"; - break; - } - case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: { - errorMessage = "Error: Framebuffer incomplete, attached images have different dimensions"; - break; - } - case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: { - errorMessage = "Error: Framebuffer incomplete, color attached images have different internal formats"; - break; - } - case GL.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: { - errorMessage = "Error: Framebuffer incomplete, draw buffer"; - break; - } - case GL.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: { - errorMessage = "Error: Framebuffer incomplete, read buffer"; - break; - } - case GL.GL_FRAMEBUFFER_UNSUPPORTED_EXT: { - errorMessage = "Error: Framebuffer not supported by hardware/drivers"; - break; - } - } + String errorMessage = fbo.checkStatus(gl); // use the window buffer if (errorMessage != null) { gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0); - if (fbo != -1) { - gl.glDeleteFramebuffersEXT(1, new int[] { fbo }, 0); - fbo = -1; + if (fbo != null) { + fbo.dispose(); + fbo = null; } - if (rbuf != -1) { - gl.glDeleteRenderbuffersEXT(1, new int[] { rbuf }, 0); - rbuf = -1; + if (rbuf != null) { + rbuf.dispose(); + rbuf = null; } throw new VizException(errorMessage); } @@ -280,6 +223,6 @@ public abstract class AbstractGLImage implements IImage { public abstract void stageTexture() throws VizException; - public abstract void loadTexture(GLContext ctx) throws VizException; + public abstract void loadTexture(GL gl) throws VizException; } diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLCMTextureData.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLCMTextureData.java index 54dd5c8051..e7ff4519c9 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLCMTextureData.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLCMTextureData.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.Map; import javax.media.opengl.GL; +import javax.media.opengl.glu.GLU; import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback; import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback.ColorMapData; @@ -33,6 +34,7 @@ import com.raytheon.viz.core.gl.dataformat.IGLColorMapDataFormatProvider; import com.raytheon.viz.core.gl.internal.cache.IImageCacheable; import com.raytheon.viz.core.gl.internal.cache.ImageCache; import com.raytheon.viz.core.gl.internal.cache.ImageCache.CacheType; +import com.raytheon.viz.core.gl.objects.GLTextureObject; /** * @@ -54,7 +56,7 @@ import com.raytheon.viz.core.gl.internal.cache.ImageCache.CacheType; */ public class GLCMTextureData implements IImageCacheable { - private int texId = -1; + private GLTextureObject tex; private final IColorMapDataRetrievalCallback callback; @@ -83,8 +85,8 @@ public class GLCMTextureData implements IImageCacheable { public synchronized void disposeTexture(GL gl) { if (isLoaded()) { - gl.glDeleteTextures(1, new int[] { texId }, 0); - texId = -1; + tex.dispose(); + tex = null; } ImageCache.getInstance(CacheType.TEXTURE).remove(this); } @@ -131,13 +133,10 @@ public class GLCMTextureData implements IImageCacheable { if (!stageTexture()) { return false; } - int type = getTextureStorageType(); - int[] t = null; - t = new int[1]; - gl.glGenTextures(1, t, 0); - gl.glBindTexture(type, t[0]); + tex = new GLTextureObject(this); + tex.bind(gl, type); gl.glTexParameteri(type, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); gl.glTexParameteri(type, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); @@ -162,9 +161,7 @@ public class GLCMTextureData implements IImageCacheable { getTextureFormat(), getTextureType(), data.getData().rewind()); gl.glPixelTransferf(GL.GL_RED_SCALE, 1.0f); gl.glPixelTransferf(GL.GL_RED_BIAS, 0.0f); - texId = t[0]; ImageCache.getInstance(CacheType.TEXTURE).put(this); - return true; } @@ -173,7 +170,7 @@ public class GLCMTextureData implements IImageCacheable { } public boolean isLoaded() { - return texId > 0; + return tex != null && tex.isValid(); } public int getDimensionSize(int dimension) { @@ -196,21 +193,25 @@ public class GLCMTextureData implements IImageCacheable { if (isLoaded()) { ImageCache.getInstance(CacheType.TEXTURE).put(this); } - return texId; + return tex.getId(); } public int getTextureStorageType() { return GL.GL_TEXTURE_2D; } - public double getValue(GL gl, int x, int y, float dataMin, float dataMax) { + public double getValue(int x, int y, float dataMin, float dataMax) { if (!isStaged() && isLoaded()) { + GL gl = GLU.getCurrentGL(); + if (gl == null || data == null) { + return Double.NaN; + } int textureStorageType = getTextureStorageType(); int copybackTextureType = data.getCopyBackTextureType(); Buffer copybackBuffer = data.getCopybackBuffer(); gl.glEnable(textureStorageType); gl.glActiveTexture(GL.GL_TEXTURE0); - gl.glBindTexture(textureStorageType, texId); + tex.bind(gl, textureStorageType); gl.glGetTexImage(textureStorageType, 0, getTextureFormat(), copybackTextureType, copybackBuffer.rewind()); gl.glActiveTexture(GL.GL_TEXTURE0); diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLColormappedImage.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLColormappedImage.java index 550d62fe63..28c59d934a 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLColormappedImage.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLColormappedImage.java @@ -19,7 +19,7 @@ **/ package com.raytheon.viz.core.gl.images; -import javax.media.opengl.GLContext; +import javax.media.opengl.GL; import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback; import com.raytheon.uf.viz.core.drawables.ColorMapParameters; @@ -52,7 +52,7 @@ public class GLColormappedImage extends AbstractGLImage implements public GLColormappedImage(IColorMapDataRetrievalCallback dataCallback, ColorMapParameters params, IGLTarget target) { - super(target); + super(); this.data = GLCMTextureData.getGlTextureId(dataCallback); this.colorMapParameters = params; } @@ -79,8 +79,8 @@ public class GLColormappedImage extends AbstractGLImage implements * .GLContext) */ @Override - public void loadTexture(GLContext ctx) throws VizException { - if (data.loadTexture(ctx.getGL())) { + public void loadTexture(GL gl) throws VizException { + if (data.loadTexture(gl)) { // Add to texture cache setStatus(Status.LOADED); data.disposeTextureData(); @@ -169,12 +169,7 @@ public class GLColormappedImage extends AbstractGLImage implements @Override public double getValue(int x, int y) { - double val = 0; - if (theTarget == null || data == null) { - return Double.NaN; - } - val = data.getValue(theTarget.getGl(), x, y, - colorMapParameters.getDataMin(), + double val = data.getValue(x, y, colorMapParameters.getDataMin(), colorMapParameters.getDataMax()); return val; } diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLImage.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLImage.java index 0b335bee24..df5d54e09c 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLImage.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/images/GLImage.java @@ -28,9 +28,7 @@ import java.util.Hashtable; import javax.media.jai.PlanarImage; import javax.media.opengl.GL; -import javax.media.opengl.GLContext; -import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.data.IRenderedImageCallback; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.viz.core.gl.IGLTarget; @@ -73,7 +71,7 @@ public class GLImage extends AbstractGLImage implements IImageCacheable { protected int size; public GLImage(IRenderedImageCallback preparer, IGLTarget target) { - super(target); + super(); theTexture = null; this.imagePreparer = preparer; } @@ -113,15 +111,8 @@ public class GLImage extends AbstractGLImage implements IImageCacheable { if (getStatus() == Status.LOADED) { if (theTexture != null) { - final Texture tex = theTexture; + theTexture.dispose(); theTexture = null; - VizApp.runAsync(new Runnable() { - @Override - public void run() { - theTarget.makeContextCurrent(); - tex.dispose(); - } - }); } if (theStagedData != null) { setStatus(Status.STAGED); @@ -154,7 +145,7 @@ public class GLImage extends AbstractGLImage implements IImageCacheable { * the OpenGL context * @throws VizException */ - public void loadTexture(GLContext ctx) throws VizException { + public void loadTexture(GL gl) throws VizException { synchronized (this) { Texture tex = TextureIO.newTexture(theStagedData); diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/FontFactory.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/FontFactory.java index 7a9cb7ab94..5db3be2865 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/FontFactory.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/FontFactory.java @@ -54,7 +54,8 @@ import com.raytheon.viz.core.gl.IGLFont; */ public class FontFactory { - private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(FontFactory.class); + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(FontFactory.class); public static final String DEFAULT_FONT_ID = "com.raytheon.uf.viz.core.defaultFont"; @@ -85,7 +86,7 @@ public class FontFactory { * @param target * @return The font to use, never null */ - public IGLFont getFont(String fontId, GLTarget target) { + public IGLFont getFont(String fontId) { if (!registry.hasValueFor(fontId)) { statusHandler.handle(Priority.PROBLEM, "No font registered with id: " + fontId); @@ -108,7 +109,7 @@ public class FontFactory { styles.add(IFont.Style.ITALIC); } - IGLFont font = new GLFont(target, name, size, + IGLFont font = new GLFont(name, size, styles.toArray(new IFont.Style[styles.size()])); if (fontId.equals(DEFAULT_FONT_ID)) { font = new UnmodifiableGLFont(font); diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLAbstractView.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLAbstractView.java index 386a3d14dd..9efb3dd254 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLAbstractView.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLAbstractView.java @@ -112,7 +112,7 @@ public abstract class GLAbstractView implements IView, Cloneable { public void setupView(IGraphicsTarget target) { IGLTarget glTarget = asIGLTarget(target); - glTarget.makeContextCurrent(); + boolean release = glTarget.makeContextCurrent(); glTarget.getGl().glMatrixMode(GL.GL_PROJECTION); glTarget.getGl().glLoadIdentity(); setProjectionMatrix(glTarget); @@ -126,6 +126,9 @@ public abstract class GLAbstractView implements IView, Cloneable { setViewArea(glTarget); // glTarget.setupClippingPlane(getClippingPlanes()); + if (release) { + glTarget.releaseContext(); + } } protected IGLTarget asIGLTarget(IGraphicsTarget target) { diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLFont.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLFont.java index 5ae746f4df..d5723118fd 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLFont.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLFont.java @@ -67,14 +67,11 @@ public class GLFont implements IGLFont { private boolean scaleFont = true; - private GLTarget target; - public GLFont() { ; } - public GLFont(GLTarget target, File font, float fontSize, Style[] styles) { - this.target = target; + public GLFont(File font, float fontSize, Style[] styles) { try { this.font = Font.createFont(Font.TRUETYPE_FONT, font).deriveFont( fontSize); @@ -98,9 +95,7 @@ public class GLFont implements IGLFont { this.textRenderer = TextRendererCache.getRenderer(this.font); } - public GLFont(GLTarget target, String fontName, float fontSize, - Style[] styles) { - this.target = target; + public GLFont(String fontName, float fontSize, Style[] styles) { this.fontName = fontName; this.currentFontSize = this.fontSize = fontSize; this.styles = styles; @@ -172,9 +167,9 @@ public class GLFont implements IGLFont { GLFont newFont = null; if (this.fontFile != null) { // File based construction - newFont = new GLFont(this.target, this.fontFile, size, styles); + newFont = new GLFont(this.fontFile, size, styles); } else { - newFont = new GLFont(this.target, this.fontName, size, styles); + newFont = new GLFont(this.fontName, size, styles); } return newFont; @@ -259,16 +254,6 @@ public class GLFont implements IGLFont { this.scaleFont = scaleFont; } - /* - * (non-Javadoc) - * - * @see com.raytheon.viz.core.gl.IGLFont#getTarget() - */ - @Override - public GLTarget getTarget() { - return target; - } - /* * (non-Javadoc) * @@ -278,15 +263,11 @@ public class GLFont implements IGLFont { public void disposeInternal() { if (!disposed) { if (this.textRenderer != null) { - boolean release = target.makeContextCurrent(); TextRendererCache.releaseRenderer(this.font); this.textRenderer = null; disposed = true; - if (release) { - target.releaseContext(); - } } } } diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLTarget.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLTarget.java index 5162894458..46832ed73a 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLTarget.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLTarget.java @@ -40,10 +40,6 @@ import java.util.Map.Entry; import java.util.Set; import javax.media.opengl.GL; -import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLContext; -import javax.media.opengl.GLDrawableFactory; -import javax.media.opengl.GLPbuffer; import javax.media.opengl.glu.GLU; import javax.media.opengl.glu.GLUquadric; import javax.vecmath.Vector3d; @@ -102,6 +98,8 @@ import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtensio import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.geom.PixelCoordinate; import com.raytheon.uf.viz.core.preferences.PreferenceConstants; +import com.raytheon.viz.core.gl.GLContextBridge; +import com.raytheon.viz.core.gl.GLDisposalManager; import com.raytheon.viz.core.gl.IGLFont; import com.raytheon.viz.core.gl.IGLTarget; import com.raytheon.viz.core.gl.TextureLoaderJob; @@ -111,9 +109,7 @@ import com.raytheon.viz.core.gl.glsl.GLShaderProgram; import com.raytheon.viz.core.gl.images.AbstractGLImage; import com.raytheon.viz.core.gl.images.GLColormappedImage; import com.raytheon.viz.core.gl.images.GLImage; -import com.raytheon.viz.core.gl.internal.cache.IImageCacheable; -import com.raytheon.viz.core.gl.internal.cache.ImageCache; -import com.raytheon.viz.core.gl.internal.cache.ImageCache.CacheType; +import com.raytheon.viz.core.gl.objects.GLTextureObject; import com.sun.opengl.util.Screenshot; import com.sun.opengl.util.j2d.TextRenderer; import com.sun.opengl.util.texture.Texture; @@ -182,7 +178,7 @@ public class GLTarget implements IGLTarget { protected final GLCanvas theCanvas; /** the GLContext */ - protected final GLContext theContext; + protected final GLContextBridge theContext; /** Has a texure load occurred during a draw operation */ protected boolean hasLoadedTextureOnLoop = false; @@ -216,12 +212,13 @@ public class GLTarget implements IGLTarget { /** The GLU object */ protected final GLU glu = new GLU(); - protected static final Map loadedColorMaps = new LinkedHashMap() { + protected static final Map loadedColorMaps = new LinkedHashMap() { private static final long serialVersionUID = 1L; @Override - protected boolean removeEldestEntry(Entry eldest) { + protected boolean removeEldestEntry( + Entry eldest) { if (size() > maxColorMapCacheSize) { handleRemove(eldest.getValue()); return true; @@ -231,15 +228,15 @@ public class GLTarget implements IGLTarget { } @Override - public Integer remove(Object key) { - Integer id = super.remove(key); + public GLTextureObject remove(Object key) { + GLTextureObject id = super.remove(key); handleRemove(id); return id; } - private void handleRemove(Integer value) { - if (value != null) { - currentGl.disposeLuminanceTexture(value, 0); + private void handleRemove(GLTextureObject value) { + if (value != null && value.isValid()) { + value.dispose(); } } @@ -257,8 +254,6 @@ public class GLTarget implements IGLTarget { protected final float textMagnification; - protected final GLContext sharedContext; - protected ColorMapParameters lastColormapUsed; protected double lastAlphaUsed = 1.0f; @@ -311,14 +306,11 @@ public class GLTarget implements IGLTarget { theCanvas = (GLCanvas) canvas; theCanvas.setCurrent(); - theContext = GLDrawableFactory.getFactory().createExternalGLContext(); + theContext = new GLContextBridge(theCanvas); - sharedContext = theContext; // extDrawable.createContext(theContext); - // sharedContext.makeCurrent(); + theContext.makeContextCurrent(); - makeContextCurrent(); - - gl = theContext.getGL(); + gl = GLU.getCurrentGL(); theWidth = width; theHeight = width; @@ -359,22 +351,12 @@ public class GLTarget implements IGLTarget { public GLTarget(float width, float height) throws VizException { theCanvas = null; canvasSize = new Rectangle(0, 0, (int) width, (int) height); - GLCapabilities glCap = new GLCapabilities(); - if (!GLDrawableFactory.getFactory().canCreateGLPbuffer()) { - throw new VizException( - "Graphics card does not support GLPbuffer and " - + "therefore does not support offscreen rendering."); - } - GLPbuffer buf = GLDrawableFactory.getFactory().createGLPbuffer(glCap, - null, (int) width, (int) height, null); - theContext = buf.createContext(null); - sharedContext = theContext; + theContext = new GLContextBridge((int) width, (int) height); - makeContextCurrent(); - - gl = theContext.getGL(); + theContext.makeContextCurrent(); + gl = GLU.getCurrentGL(); theWidth = width; theHeight = width; @@ -473,7 +455,6 @@ public class GLTarget implements IGLTarget { */ @Override public void clearClippingPlane() { - this.makeContextCurrent(); gl.glDisable(GL.GL_CLIP_PLANE0); gl.glDisable(GL.GL_CLIP_PLANE1); gl.glDisable(GL.GL_CLIP_PLANE2); @@ -501,7 +482,7 @@ public class GLTarget implements IGLTarget { @Override public IWireframeShape createWireframeShape(boolean mutableFlag, GeneralGridGeometry geom) { - return new GLWireframeShape2D(this, geom, mutableFlag); + return new GLWireframeShape2D(geom, mutableFlag); } /* @@ -519,7 +500,7 @@ public class GLTarget implements IGLTarget { return new GLWireframeShape(null, geom, mutable, simplificationLevel, spatialChopFlag, extent); } else { - return new GLWireframeShape2D(this, geom, mutable); + return new GLWireframeShape2D(geom, mutable); } } @@ -532,7 +513,7 @@ public class GLTarget implements IGLTarget { @Override public IWireframeShape createWireframeShape(boolean mutable, IDescriptor descriptor) { - return new GLWireframeShape2D(this, descriptor, mutable); + return new GLWireframeShape2D(descriptor, mutable); } /* @@ -548,7 +529,7 @@ public class GLTarget implements IGLTarget { return new GLWireframeShape(descriptor, mutable, simplificationLevel); } else { - return new GLWireframeShape2D(this, descriptor, mutable); + return new GLWireframeShape2D(descriptor, mutable); } } @@ -567,7 +548,7 @@ public class GLTarget implements IGLTarget { return new GLWireframeShape(descriptor, null, mutable, simplificationLevel, spatialChopFlag, extent); } else { - return new GLWireframeShape2D(this, descriptor, mutable); + return new GLWireframeShape2D(descriptor, mutable); } } @@ -578,7 +559,7 @@ public class GLTarget implements IGLTarget { */ @Override public void dispose() { - makeContextCurrent(); + theContext.makeContextCurrent(); if (defaultFont != null) { defaultFont.disposeInternal(); } @@ -586,8 +567,8 @@ public class GLTarget implements IGLTarget { colorbarFont.disposeInternal(); } - theContext.release(); - theContext.destroy(); + theContext.releaseContext(); + theContext.destroyContext(); if (theCanvas != null && theCanvas.isDisposed() == false) { theCanvas.removeListener(SWT.Resize, this.canvasResizeListener); } @@ -595,15 +576,6 @@ public class GLTarget implements IGLTarget { extensionManager.dispose(); } - public void disposeLuminanceTexture(int id, int pboID) { - makeContextCurrent(); - - gl.glDeleteTextures(1, new int[] { id }, 0); - if (pboID > 0) { - gl.glDeleteBuffers(1, new int[] { pboID }, 0); - } - } - /** * Dispose a vbo * @@ -668,7 +640,6 @@ public class GLTarget implements IGLTarget { } this.clearClippingPlane(); - this.makeContextCurrent(); this.pushGLState(); try { @@ -726,7 +697,6 @@ public class GLTarget implements IGLTarget { @Override public void drawColorRamp(DrawableColorMap drawableColorMap) throws VizException { - this.makeContextCurrent(); this.pushGLState(); try { final ColorMapParameters colorMapParams = drawableColorMap @@ -743,7 +713,7 @@ public class GLTarget implements IGLTarget { double y1 = pixelExtent.getMinY(); double y2 = pixelExtent.getMaxY(); - Integer i = getColorMapTexture(colorMapParams); + GLTextureObject i = getColorMapTexture(colorMapParams); GLColormappedImage alphaMaskTexture = null; if (colorMapParams.isUseMask() && capabilities.cardSupportsShaders) { @@ -767,7 +737,7 @@ public class GLTarget implements IGLTarget { gl.glEnable(GL.GL_TEXTURE_1D); gl.glActiveTexture(GL.GL_TEXTURE0); - gl.glBindTexture(GL.GL_TEXTURE_1D, i); + i.bind(gl, GL.GL_TEXTURE_1D); if (drawableColorMap.interpolate) { gl.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_MIN_FILTER, @@ -1040,7 +1010,6 @@ public class GLTarget implements IGLTarget { */ @Override public void drawLine(DrawableLine... lines) throws VizException { - this.makeContextCurrent(); this.pushGLState(); try { RGB prevColor = null; @@ -1191,7 +1160,6 @@ public class GLTarget implements IGLTarget { Set errorMsgs = new HashSet(); List notDrawn = new ArrayList(); - this.makeContextCurrent(); this.pushGLState(); try { gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); @@ -1293,7 +1261,7 @@ public class GLTarget implements IGLTarget { } // Get and stage colormap texture - Integer cmapTexture = getColorMapTexture(usedColorMapParameters); + GLTextureObject cmapTexture = getColorMapTexture(usedColorMapParameters); if (alphaMaskTexture != null) { gl.glActiveTexture(GL.GL_TEXTURE2); @@ -1303,7 +1271,7 @@ public class GLTarget implements IGLTarget { } gl.glActiveTexture(GL.GL_TEXTURE1); - gl.glBindTexture(GL.GL_TEXTURE_1D, cmapTexture); + cmapTexture.bind(gl, GL.GL_TEXTURE_1D); if (glImage.isInterpolated()) { gl.glTexParameteri(GL.GL_TEXTURE_1D, @@ -1461,25 +1429,6 @@ public class GLTarget implements IGLTarget { handleError(gl.glGetError()); - IImageCacheable[] pending = ImageCache.getInstance(CacheType.TEXTURE) - .getImagesWaitingToDispose(); - - if (pending != null) { - for (IImageCacheable glI : pending) { - glI.disposeTexture(getGl()); - } - } - - // Delete any pending resources - pending = ImageCache.getInstance(CacheType.MEMORY) - .getImagesWaitingToDispose(); - - if (pending != null) { - for (IImageCacheable glI : pending) { - glI.disposeTextureData(); - } - } - if (errorMsgs.size() > 0) { throw new VizException("Error rendering " + errorMsgs.size() + " images: " + errorMsgs); @@ -1572,7 +1521,6 @@ public class GLTarget implements IGLTarget { @Override public void drawRect(IExtent extent, RGB color, float lineWidth, double alpha) { - this.makeContextCurrent(); this.pushGLState(); try { gl.glPolygonMode(GL.GL_BACK, GL.GL_LINE); @@ -1605,7 +1553,6 @@ public class GLTarget implements IGLTarget { @Override public void drawShadedRect(IExtent pe, RGB color, double alpha, byte[] stipple) throws VizException { - this.makeContextCurrent(); this.pushGLState(); try { @@ -1644,7 +1591,6 @@ public class GLTarget implements IGLTarget { */ public void drawRect(PixelCoverage coverage, RGB color, float lineWidth, double alpha) { - this.makeContextCurrent(); this.pushGLState(); try { gl.glPolygonMode(GL.GL_FRONT, GL.GL_LINE); @@ -1718,7 +1664,6 @@ public class GLTarget implements IGLTarget { brightness = Math.max(brightness, 0.0f); brightness = Math.min(brightness, 1.0f); - this.makeContextCurrent(); pushGLState(); try { gl.glPolygonMode(GL.GL_BACK, GL.GL_FILL); @@ -1916,11 +1861,10 @@ public class GLTarget implements IGLTarget { float lineWidth, IGraphicsTarget.LineStyle lineStyle, IFont font, float alpha) throws VizException { if (shape instanceof GLWireframeShape2D) { - makeContextCurrent(); pushGLState(); try { - ((GLWireframeShape2D) shape).paint(viewExtent, canvasSize, - aColor, lineWidth, lineStyle, font, alpha); + ((GLWireframeShape2D) shape).paint(this, viewExtent, + canvasSize, aColor, lineWidth, lineStyle, font, alpha); } finally { popGLState(); } @@ -1934,7 +1878,6 @@ public class GLTarget implements IGLTarget { float lineWidth, LineStyle lineStyle, IGLFont font, float alpha) throws VizException { - this.makeContextCurrent(); this.pushGLState(); try { @@ -2085,7 +2028,7 @@ public class GLTarget implements IGLTarget { */ @Override public void endFrame() { - + makeContextCurrent(); try { if (this.lastColormapUsed != null && this.useBuiltinColorbar) { this.drawColorbar(this.lastColormapUsed); @@ -2098,27 +2041,6 @@ public class GLTarget implements IGLTarget { return; } - makeContextCurrent(); - - // Delete any pending resources - IImageCacheable[] pending = ImageCache.getInstance(CacheType.MEMORY) - .getImagesWaitingToDispose(); - - if (pending != null) { - for (IImageCacheable glI : pending) { - glI.disposeTextureData(); - } - } - - pending = ImageCache.getInstance(CacheType.TEXTURE) - .getImagesWaitingToDispose(); - - if (pending != null) { - for (IImageCacheable glI : pending) { - glI.disposeTexture(getGl()); - } - } - gl.glFinish(); if (theCanvas != null) { @@ -2129,13 +2051,12 @@ public class GLTarget implements IGLTarget { // redrawRetries++; // } } - if (GLContext.getCurrent() == theContext) { - theContext.release(); - } - } + GLContextBridge.makeMasterContextCurrent(); - public GLContext getContext() { - return this.theContext; + GLDisposalManager.performDispose(GLU.getCurrentGL()); + + GLContextBridge.releaseMasterContext(); + releaseContext(); } /* @@ -2184,10 +2105,6 @@ public class GLTarget implements IGLTarget { } - public GLContext getSharedContext() { - return this.sharedContext; - } - /* * (non-Javadoc) * @@ -2328,16 +2245,16 @@ public class GLTarget implements IGLTarget { gl.glLoadIdentity(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - this.colorbarFont = new UnmodifiableGLFont(new GLFont(this, - DEFAULT_FONT, (10 * textMagnification), null)); + this.colorbarFont = new UnmodifiableGLFont(new GLFont(DEFAULT_FONT, + (10 * textMagnification), null)); if (PlatformUI.isWorkbenchRunning()) { fontFactory = FontFactory.getInstance(); - this.defaultFont = new UnmodifiableGLFont(fontFactory.getFont( - FontFactory.DEFAULT_FONT_ID, this)); + this.defaultFont = new UnmodifiableGLFont( + fontFactory.getFont(FontFactory.DEFAULT_FONT_ID)); } else { this.defaultFont = new UnmodifiableGLFont( - new GLFont(this, java.awt.Font.MONOSPACED, 14.0f, + new GLFont(java.awt.Font.MONOSPACED, 14.0f, new Style[] { Style.BOLD })); } releaseContext(); @@ -2418,7 +2335,7 @@ public class GLTarget implements IGLTarget { */ @Override public IFont initializeFont(File fontFile, float size, Style[] styles) { - return new GLFont(this, fontFile, size, styles); + return new GLFont(fontFile, size, styles); } /* @@ -2430,7 +2347,7 @@ public class GLTarget implements IGLTarget { */ @Override public IFont initializeFont(String fontName, float size, Style[] styles) { - return new GLFont(this, fontName, size, styles); + return new GLFont(fontName, size, styles); } /* @@ -2442,7 +2359,7 @@ public class GLTarget implements IGLTarget { @Override public IFont initializeFont(String font) { if (fontFactory != null && fontFactory.hasId(font)) { - return fontFactory.getFont(font, this); + return fontFactory.getFont(font); } return defaultFont.deriveWithSize(defaultFont.getFontSize()); } @@ -2457,16 +2374,16 @@ public class GLTarget implements IGLTarget { return needsRefresh; } - protected int loadColormapIntoTexture(ColorMap glColorMap) { + protected GLTextureObject loadColormapIntoTexture(ColorMap glColorMap) { Buffer bb = glColorMap.getColorMap(); - - int[] t = new int[2]; - gl.glGenTextures(1, t, 0); + GLContextBridge.makeMasterContextCurrent(); + GLTextureObject t = new GLTextureObject(); + GLContextBridge.releaseMasterContext(); if (gl.isFunctionAvailable("glActiveTexture")) { gl.glActiveTexture(GL.GL_TEXTURE1); } gl.glEnable(GL.GL_TEXTURE_1D); - gl.glBindTexture(GL.GL_TEXTURE_1D, t[0]); + t.bind(gl, GL.GL_TEXTURE_1D); bb.rewind(); gl.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); @@ -2487,7 +2404,7 @@ public class GLTarget implements IGLTarget { 0, GL.GL_RGBA, GL.GL_FLOAT, bb); gl.glDisable(GL.GL_TEXTURE_1D); - return t[0]; + return t; } /* @@ -2496,22 +2413,7 @@ public class GLTarget implements IGLTarget { * @see com.raytheon.viz.core.gl.IGLTarget#makeContextCurrent() */ public boolean makeContextCurrent() { - boolean releaseContext = false; - - if (theContext != (GLContext.getCurrent())) { - GLContext oldContext = GLContext.getCurrent(); - if (oldContext != null) { - oldContext.release(); - } - - if (theCanvas != null && !theCanvas.isDisposed()) { - theCanvas.setCurrent(); - } - theContext.makeCurrent(); - currentGl = this; - releaseContext = true; - } - return releaseContext; + return theContext.makeContextCurrent(); } /** @@ -2521,7 +2423,7 @@ public class GLTarget implements IGLTarget { * */ public void releaseContext() { - theContext.release(); + theContext.releaseContext(); } /* @@ -2537,7 +2439,7 @@ public class GLTarget implements IGLTarget { Rectangle bounds = theCanvas.getClientArea(); - boolean needsDispose = makeContextCurrent(); + makeContextCurrent(); gl.glViewport(0, 0, bounds.width, bounds.height); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); @@ -2545,9 +2447,7 @@ public class GLTarget implements IGLTarget { gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); - if (needsDispose) { - releaseContext(); - } + releaseContext(); } @@ -2559,7 +2459,7 @@ public class GLTarget implements IGLTarget { @Override public BufferedImage screenshot() { - boolean grabbedContext = makeContextCurrent(); + makeContextCurrent(); if (theCanvas != null) { theCanvas.swapBuffers(); } @@ -2570,9 +2470,7 @@ public class GLTarget implements IGLTarget { theCanvas.swapBuffers(); } - if (grabbedContext) { - releaseContext(); - } + releaseContext(); return bi; } @@ -2621,7 +2519,6 @@ public class GLTarget implements IGLTarget { if (extent == null) { return; } - this.makeContextCurrent(); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPushMatrix(); @@ -2917,7 +2814,6 @@ public class GLTarget implements IGLTarget { @Override public void drawShadedPolygon(LinearRing poly, RGB color, double alpha, byte[] stipple) throws VizException { - this.makeContextCurrent(); this.pushGLState(); try { // set the shading and alpha @@ -2966,7 +2862,7 @@ public class GLTarget implements IGLTarget { this.updatedExtent = updatedExtent; } - private Integer getColorMapTexture(ColorMapParameters cmapParams) { + private GLTextureObject getColorMapTexture(ColorMapParameters cmapParams) { IColorMap cmap = cmapParams.getColorMap(); String name = cmap.getName(); if (name == null) { @@ -2974,7 +2870,7 @@ public class GLTarget implements IGLTarget { + cmapParams.hashCode(); } - Integer i = loadedColorMaps.get(name); + GLTextureObject i = loadedColorMaps.get(name); if (i == null || cmap.isChanged()) { if (i != null) { loadedColorMaps.remove(name); @@ -3220,7 +3116,6 @@ public class GLTarget implements IGLTarget { // function ends up calling begin/end rendering lots which slows it down // to the speed of a not bulk operation TextRenderer textRenderer = null; - makeContextCurrent(); pushGLState(); gl.glMatrixMode(GL.GL_MODELVIEW); @@ -3558,7 +3453,6 @@ public class GLTarget implements IGLTarget { return; } - this.makeContextCurrent(); this.pushGLState(); try { int pointsPerLocation = 1; diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLWireframeShape2D.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLWireframeShape2D.java index 29092b6f92..cc6e7b756f 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLWireframeShape2D.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/GLWireframeShape2D.java @@ -73,26 +73,20 @@ public class GLWireframeShape2D implements IWireframeShape { private boolean compiled = false; - private IGLTarget target; - private GLGeometryObject2D geometry; private GLGeometryObjectData geomData; - public GLWireframeShape2D(IGLTarget target, - GeneralGridGeometry gridGeometry, boolean mutable) { - this.target = target; + public GLWireframeShape2D(GeneralGridGeometry gridGeometry, boolean mutable) { geomData = new GLGeometryObjectData(GL.GL_LINE_STRIP, GL.GL_VERTEX_ARRAY); - geomData.setTarget(target); geomData.mutable = mutable; geomData.worldExtent = new PixelExtent(gridGeometry.getGridRange()); initialize(); } - public GLWireframeShape2D(IGLTarget target, IDescriptor descriptor, - boolean mutable) { - this(target, descriptor.getGridGeometry(), mutable); + public GLWireframeShape2D(IDescriptor descriptor, boolean mutable) { + this(descriptor.getGridGeometry(), mutable); this.descriptor = descriptor; } @@ -230,16 +224,16 @@ public class GLWireframeShape2D implements IWireframeShape { geometry.allocate(points); } - public synchronized void paint(IExtent viewExtent, Rectangle canvasSize, - RGB color, float lineWidth, LineStyle lineStyle, IFont font, - float alpha) throws VizException { + public synchronized void paint(IGLTarget target, IExtent viewExtent, + Rectangle canvasSize, RGB color, float lineWidth, + LineStyle lineStyle, IFont font, float alpha) throws VizException { if (isDrawable() == false) { return; } if (!geomData.mutable && !compiled) { compiled = true; - geometry.compile(); + geometry.compile(target.getGl()); } GL gl = target.getGl(); @@ -321,7 +315,7 @@ public class GLWireframeShape2D implements IWireframeShape { gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); } - geometry.paint(); + geometry.paint(target.getGl()); gl.glDisable(GL.GL_BLEND); diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/PreferenceBasedGLFont.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/PreferenceBasedGLFont.java index 70020f6edf..7c9ccf5767 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/PreferenceBasedGLFont.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/PreferenceBasedGLFont.java @@ -135,22 +135,10 @@ public class PreferenceBasedGLFont implements IGLFont, IPropertyChangeListener { public void propertyChange(PropertyChangeEvent event) { if (propertyName.equals(event.getProperty())) { preferenceFont.disposeInternal(); - preferenceFont = FontFactory.getInstance().getFont(propertyName, - preferenceFont.getTarget()); - preferenceFont.getTarget().setNeedsRefresh(true); + preferenceFont = FontFactory.getInstance().getFont(propertyName); } } - /* - * (non-Javadoc) - * - * @see com.raytheon.viz.core.gl.IGLFont#getTarget() - */ - @Override - public GLTarget getTarget() { - return preferenceFont.getTarget(); - } - /* * (non-Javadoc) * diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/TextRendererCache.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/TextRendererCache.java index b5ba4be74d..7b98400691 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/TextRendererCache.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/TextRendererCache.java @@ -25,6 +25,9 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; +import javax.media.opengl.GL; + +import com.raytheon.viz.core.gl.GLDisposalManager.GLDisposer; import com.sun.opengl.util.j2d.TextRenderer; /** @@ -60,7 +63,14 @@ public class TextRendererCache { @Override protected boolean removeEldestEntry(Entry eldest) { if (size() > UNUSED_RENDERER_SIZE) { - eldest.getValue().dispose(); + final TextRenderer renderer = eldest.getValue(); + new GLDisposer() { + @Override + protected void dispose(GL gl) { + renderer.dispose(); + + } + }.dispose(); return true; } return false; diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/UnmodifiableGLFont.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/UnmodifiableGLFont.java index 1159528209..971f7e2732 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/UnmodifiableGLFont.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/UnmodifiableGLFont.java @@ -23,8 +23,6 @@ import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.drawables.IFont; -import com.raytheon.uf.viz.core.status.StatusConstants; -import com.raytheon.viz.core.gl.Activator; import com.raytheon.viz.core.gl.IGLFont; import com.sun.opengl.util.j2d.TextRenderer; @@ -47,7 +45,8 @@ import com.sun.opengl.util.j2d.TextRenderer; */ public class UnmodifiableGLFont implements IGLFont { - private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(UnmodifiableGLFont.class); + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(UnmodifiableGLFont.class); private IGLFont unmodifiableFont; @@ -146,14 +145,4 @@ public class UnmodifiableGLFont implements IGLFont { return unmodifiableFont.toString(); } - /* - * (non-Javadoc) - * - * @see com.raytheon.viz.core.gl.IGLFont#getTarget() - */ - @Override - public GLTarget getTarget() { - return unmodifiableFont.getTarget(); - } - } diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/cache/ImageCache.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/cache/ImageCache.java index f55ec418db..f956533d01 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/cache/ImageCache.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/cache/ImageCache.java @@ -20,12 +20,12 @@ package com.raytheon.viz.core.gl.internal.cache; -import java.util.ArrayList; -import java.util.List; +import javax.media.opengl.GL; import com.raytheon.uf.common.util.cache.LRUCache; import com.raytheon.uf.viz.core.Activator; import com.raytheon.uf.viz.core.preferences.PreferenceConstants; +import com.raytheon.viz.core.gl.GLDisposalManager.GLDisposer; /** * Cache for GLImages, one for memory and one fore texture @@ -77,8 +77,6 @@ public class ImageCache extends LRUCache implements /** The instance of the memory cache */ private static ImageCache memoryCache; - private List waitingToDispose; - /** * Get Singletons * @@ -116,7 +114,6 @@ public class ImageCache extends LRUCache implements */ private ImageCache(long maxSz) { super(maxSz); - this.waitingToDispose = new ArrayList(); } public void put(IImageCacheable image) { @@ -126,13 +123,16 @@ public class ImageCache extends LRUCache implements @Override protected void removeItem(Item item) { super.removeItem(item); - waitingToDispose.add(item.value); - } - - public IImageCacheable[] getImagesWaitingToDispose() { - IImageCacheable[] arr = this.waitingToDispose - .toArray(new IImageCacheable[waitingToDispose.size()]); - this.waitingToDispose.clear(); - return arr; + final IImageCacheable i = item.value; + if (this == memoryCache) { + i.disposeTextureData(); + } else if (this == textureCache) { + new GLDisposer() { + @Override + protected void dispose(GL gl) { + i.disposeTexture(gl); + } + }.dispose(); + } } } diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/ext/GLColormapShadedShapeExtension.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/ext/GLColormapShadedShapeExtension.java index b15f789f78..972a2d5399 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/ext/GLColormapShadedShapeExtension.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/ext/GLColormapShadedShapeExtension.java @@ -97,7 +97,6 @@ public class GLColormapShadedShapeExtension extends throws VizException { if (shape instanceof GLColormapShadedShape) { GLColormapShadedShape glBaseShape = (GLColormapShadedShape) shape; - target.makeContextCurrent(); GL gl = target.getGl(); gl.glPolygonMode(GL.GL_BACK, GL.GL_FILL); gl.glEnableClientState(GL.GL_VERTEX_ARRAY); diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/ext/GLOffscreenRenderingExtension.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/ext/GLOffscreenRenderingExtension.java index 0a611fad52..2a54154aec 100644 --- a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/ext/GLOffscreenRenderingExtension.java +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/internal/ext/GLOffscreenRenderingExtension.java @@ -17,7 +17,6 @@ import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.viz.core.gl.IGLTarget; import com.raytheon.viz.core.gl.dataformat.AbstractGLColorMapDataFormat; import com.raytheon.viz.core.gl.dataformat.GLByteDataFormat; -import com.raytheon.viz.core.gl.dataformat.GLColorMapData; import com.raytheon.viz.core.gl.dataformat.IGLColorMapDataFormatProvider; import com.raytheon.viz.core.gl.images.AbstractGLImage; @@ -34,7 +33,6 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension throw new VizException( "Can only use GLImages as offscreen frameBuffer on GLTarget"); } - target.makeContextCurrent(); AbstractGLImage glImage = (AbstractGLImage) offscreenImage; if (glImage.getStatus() == IImage.Status.UNLOADED || glImage.getStatus() == IImage.Status.LOADING) { @@ -52,7 +50,6 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension @Override public void renderOnscreen() throws VizException { - target.makeContextCurrent(); Rectangle canvasSize = target.getBounds(); target.getGl().glViewport(0, 0, canvasSize.width, canvasSize.height); target.getGl().glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0); @@ -132,7 +129,8 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension // assume we don't support luminance supportsLuminance = false; // Reconstruct image - image = constructOffscreenImage(dataType, dimensions, parameters); + image = constructOffscreenImage(dataType, dimensions, + parameters); } } return image; diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLFrameBufferObject.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLFrameBufferObject.java new file mode 100644 index 0000000000..6470a385f0 --- /dev/null +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLFrameBufferObject.java @@ -0,0 +1,120 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.viz.core.gl.objects; + +import javax.media.opengl.GL; + +/** + * + * A simple wrapper around a GL frameBuffer id that manages creation and + * disposal of frameBuffer ids. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 17, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class GLFrameBufferObject extends GLIdWrapper { + + /** + * Create a new frameBuffer id in gl and register this frameBuffer to be + * disposed when parent is garbage collected. + * + * @param parent + * - the object that will be using the texture. + * @param gl + */ + public GLFrameBufferObject(Object parent) { + super(parent); + } + + /** + * Create a new frameBuffer id in gl + * + * @param gl + */ + public GLFrameBufferObject() { + super(); + } + + @Override + protected void genId(GL gl, int[] arr) { + gl.glGenFramebuffersEXT(1, arr, 0); + } + + @Override + protected void deleteId(GL gl, int[] arr) { + gl.glDeleteFramebuffersEXT(1, arr, 0); + + } + + public void bind(GL gl) { + gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, id); + } + + public String checkStatus(GL gl) { + String errorMessage = null; + + switch (gl.glCheckFramebufferStatusEXT(GL.GL_FRAMEBUFFER_EXT)) { + case GL.GL_FRAMEBUFFER_COMPLETE_EXT: { + // Everything is ok. + break; + } + case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: { + errorMessage = "Error: Framebuffer incomplete, fbo attachement is NOT complete"; + break; + } + case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: { + errorMessage = "Error: Framebuffer incomplete, no image is attached to FBO"; + break; + } + case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: { + errorMessage = "Error: Framebuffer incomplete, attached images have different dimensions"; + break; + } + case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: { + errorMessage = "Error: Framebuffer incomplete, color attached images have different internal formats"; + break; + } + case GL.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: { + errorMessage = "Error: Framebuffer incomplete, draw buffer"; + break; + } + case GL.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: { + errorMessage = "Error: Framebuffer incomplete, read buffer"; + break; + } + case GL.GL_FRAMEBUFFER_UNSUPPORTED_EXT: { + errorMessage = "Error: Framebuffer not supported by hardware/drivers"; + break; + } + } + return errorMessage; + } + +} diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLIdWrapper.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLIdWrapper.java new file mode 100644 index 0000000000..bd87d164ed --- /dev/null +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLIdWrapper.java @@ -0,0 +1,96 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.viz.core.gl.objects; + +import javax.media.opengl.GL; +import javax.media.opengl.glu.GLU; + +import com.raytheon.viz.core.gl.GLDisposalManager; +import com.raytheon.viz.core.gl.GLDisposalManager.GLDisposer; + +/** + * + * Most objects in GL are represented in Java as an integer id. This class + * provides some of the generic code needed to manage these and dispose of these + * GL Objects + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 17, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public abstract class GLIdWrapper extends GLDisposer { + + protected int id; + + public GLIdWrapper(Object parent) { + this(); + GLDisposalManager.autoDispose(this, parent); + } + + public GLIdWrapper() { + int[] arr = new int[1]; + genId(GLU.getCurrentGL(), arr); + this.id = arr[0]; + } + + public boolean isValid() { + return id != -1; + } + + public int getId() { + return id; + } + + @Override + protected void dispose(GL gl) { + if (id != -1) { + deleteId(gl, new int[] { id }); + } + this.id = -1; + } + + /** + * Generate an id for this object, arr is an array of length 1 and id should + * be set to the only element in the array + * + * @param gl + * @param arr + */ + protected abstract void genId(GL gl, int[] arr); + + /** + * Delete an id for this object, arr is an array of length 1 and will + * contain the id + * + * @param gl + * @param arr + */ + protected abstract void deleteId(GL gl, int[] arr); + +} diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLRenderBuffer.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLRenderBuffer.java new file mode 100644 index 0000000000..74d10d3191 --- /dev/null +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLRenderBuffer.java @@ -0,0 +1,84 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.viz.core.gl.objects; + +import javax.media.opengl.GL; + +/** + * + * A simple wrapper around a GL renderBuffer id that manages creation and + * disposal of renderBuffer ids. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 17, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class GLRenderBuffer extends GLIdWrapper { + + /** + * Create a new renderBuffer id in gl and register this renderBuffer to be + * disposed when parent is garbage collected. + * + * @param parent + * - the object that will be using the texture. + * @param gl + */ + public GLRenderBuffer(Object parent) { + super(parent); + } + + /** + * Create a new renderBuffer id in gl + * + * @param gl + */ + public GLRenderBuffer() { + super(); + } + + @Override + protected void genId(GL gl, int[] arr) { + gl.glGenRenderbuffersEXT(1, arr, 0); + } + + @Override + protected void deleteId(GL gl, int[] arr) { + gl.glDeleteRenderbuffersEXT(1, arr, 0); + } + + public void bind(GL gl) { + gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, id); + } + + public void createStorage(GL gl, int internalFormat, int width, int height) { + gl.glRenderbufferStorageEXT(GL.GL_RENDERBUFFER_EXT, internalFormat, + width, height); + } + +} diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLTextureObject.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLTextureObject.java new file mode 100644 index 0000000000..6655978fdd --- /dev/null +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLTextureObject.java @@ -0,0 +1,88 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.viz.core.gl.objects; + +import javax.media.opengl.GL; + +/** + * + * A simple wrapper around a GLTextureId that manages creation and disposal of + * texture ids. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 17, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class GLTextureObject extends GLIdWrapper { + + /** + * Create a new texture id in gl and register this texture to be disposed + * when parent is garbage collected. + * + * @param parent + * - the object that will be using the texture. + * @param gl + */ + public GLTextureObject(Object parent) { + super(parent); + } + + /** + * Create a new texture id in gl + * + * @param gl + */ + public GLTextureObject() { + super(); + } + + @Override + protected void genId(GL gl, int[] arr) { + gl.glGenTextures(1, arr, 0); + + } + + @Override + protected void deleteId(GL gl, int[] arr) { + gl.glDeleteTextures(1, arr, 0); + } + + /** + * + * @param gl + * @param target + * Specifies the target to which the texture is bound. Must be + * either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, or + * GL_TEXTURE_CUBE_MAP. + */ + public void bind(GL gl, int target) { + gl.glBindTexture(target, id); + } + +} diff --git a/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLVertexBufferObject.java b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLVertexBufferObject.java new file mode 100644 index 0000000000..da0c8a880e --- /dev/null +++ b/cave/com.raytheon.viz.core.gl/src/com/raytheon/viz/core/gl/objects/GLVertexBufferObject.java @@ -0,0 +1,88 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.viz.core.gl.objects; + +import javax.media.opengl.GL; + +/** + * + * A wrapper around a vbo id from gl. This object contains the logic to create + * and dispose vbo ids. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 17, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class GLVertexBufferObject extends GLIdWrapper { + + /** + * Create a new vboId in gl and register this vbo to be disposed when parent + * is garbage collected. + * + * @param parent + * - the object that will be using the vbo. + * @param gl + */ + public GLVertexBufferObject(Object parent) { + super(); + } + + /** + * Create a new vboId in gl + * + * @param gl + */ + public GLVertexBufferObject() { + super(); + } + + @Override + protected void genId(GL gl, int[] arr) { + gl.glGenBuffers(1, arr, 0); + } + + @Override + protected void deleteId(GL gl, int[] arr) { + gl.glDeleteBuffers(1, arr, 0); + } + + /** + * + * @param gl + * @param target + * Specifies the target to which the buffer object is bound. The + * symbolic constant must be GL_ARRAY_BUFFER, + * GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, or + * GL_PIXEL_UNPACK_BUFFER + */ + public void bind(GL gl, int target) { + gl.glBindBuffer(target, id); + } + +}