001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Oleg V. Khaschansky
019: * @version $Revision$
020: */package org.apache.harmony.awt.gl.opengl;
021:
022: import org.apache.harmony.awt.gl.GLVolatileImage;
023: import org.apache.harmony.awt.gl.Surface;
024: import org.apache.harmony.awt.gl.MultiRectArea;
025: import org.apache.harmony.awt.wtk.NativeWindow;
026:
027: import java.awt.*;
028: import java.awt.image.BufferedImage;
029: import java.awt.image.ImageObserver;
030: import java.lang.reflect.InvocationTargetException;
031:
032: public class OGLVolatileImage extends GLVolatileImage {
033: //private static final GL gl = GL.getInstance();
034: private static final ImageCapabilities ic = new ImageCapabilities(
035: true);
036:
037: private int w;
038: private int h;
039: private OGLOffscreenWindow win;
040: private OGLContextManager ctxmgr;
041: private OGLGraphics2D lastGraphics = null;
042:
043: private final Disposer disposer = new Disposer();
044:
045: /**
046: * Helps us use OGL graphics in the uniform way
047: */
048: public class OGLOffscreenWindow implements NativeWindow {
049: private Rectangle bounds;
050: private OGLContextManager.OffscreenBufferObject pbuffer;
051:
052: OGLOffscreenWindow(
053: OGLContextManager.OffscreenBufferObject pbuffer,
054: Rectangle bounds) {
055: this .pbuffer = pbuffer;
056: this .bounds = bounds;
057: }
058:
059: private OGLContextManager.OffscreenBufferObject getOffscreenBuffer() {
060: return pbuffer;
061: }
062:
063: public long getId() {
064: return pbuffer.id;
065: }
066:
067: public long getHdc() {
068: return pbuffer.hdc;
069: }
070:
071: public Rectangle getBounds() {
072: return bounds;
073: }
074:
075: // Following methods are placeholders - not used
076: public void setVisible(boolean v) {
077: }
078:
079: public void setBounds(int x, int y, int w, int h, int boundsMask) {
080: }
081:
082: public Insets getInsets() {
083: return null;
084: }
085:
086: public void setEnabled(boolean value) {
087: }
088:
089: public void setFocusable(boolean value) {
090: }
091:
092: public boolean isFocusable() {
093: return false;
094: }
095:
096: public boolean setFocus(boolean focus) {
097: return false;
098: }
099:
100: public void dispose() {
101: }
102:
103: public void placeAfter(NativeWindow w) {
104: }
105:
106: public void toFront() {
107: }
108:
109: public void toBack() {
110: }
111:
112: public void setResizable(boolean value) {
113: }
114:
115: public void setTitle(String title) {
116: }
117:
118: public void grabMouse() {
119: }
120:
121: public void ungrabMouse() {
122: }
123:
124: public void setState(int state) {
125: }
126:
127: public void setIconImage(Image image) {
128: }
129:
130: public void setAlwaysOnTop(boolean value) {
131: }
132:
133: public void setMaximizedBounds(Rectangle bounds) {
134: }
135:
136: public Point getScreenPos() {
137: return null;
138: }
139:
140: public void setPacked(boolean packed) {
141: }
142:
143: public Surface getSurface() {
144: return null;
145: }
146:
147: public MultiRectArea getObscuredRegion(Rectangle part) {
148: return null;
149: }
150:
151: public void setIMStyle() {
152: }
153: }
154:
155: public OGLVolatileImage(OGLContextManager ctxmgr, int w, int h) {
156: this .ctxmgr = ctxmgr;
157: this .w = w;
158: this .h = h;
159: this .win = new OGLOffscreenWindow(ctxmgr.createOffscreenBuffer(
160: w, h), new Rectangle(0, 0, w, h));
161: }
162:
163: @Override
164: public Surface getImageSurface() {
165: return lastGraphics.getSurface();
166: }
167:
168: @Override
169: public boolean contentsLost() {
170: return false;
171: }
172:
173: @Override
174: public Graphics2D createGraphics() {/*
175: boolean firstTime = false; // First time we need to clear buffer
176: if (lastGraphics == null) {
177: firstTime = true;
178: }*/
179:
180: lastGraphics = new OGLGraphics2D(win, 0, 0, w, h);
181: /*
182: if (firstTime) {
183: lastGraphics.makeCurrent();
184: gl.glClear(GLDefs.GL_COLOR_BUFFER_BIT);
185: }
186: */
187: return lastGraphics;
188: }
189:
190: @Override
191: public ImageCapabilities getCapabilities() {
192: return ic;
193: }
194:
195: @Override
196: public int getHeight() {
197: return h;
198: }
199:
200: @Override
201: public BufferedImage getSnapshot() {
202: Surface s = getImageSurface();
203: return new BufferedImage(s.getColorModel(), s.getRaster(),
204: true, null);
205: }
206:
207: @Override
208: public int getWidth() {
209: return w;
210: }
211:
212: @Override
213: public int validate(GraphicsConfiguration gc) {
214: if (gc.equals(ctxmgr)) {
215: return IMAGE_OK;
216: }
217: return IMAGE_INCOMPATIBLE;
218: }
219:
220: @Override
221: public Object getProperty(String name, ImageObserver observer) {
222: return UndefinedProperty;
223: }
224:
225: @Override
226: public int getWidth(ImageObserver observer) {
227: return w;
228: }
229:
230: @Override
231: public int getHeight(ImageObserver observer) {
232: return h;
233: }
234:
235: @Override
236: protected void finalize() throws Throwable {
237: super .finalize();
238: disposer.dispose();
239: }
240:
241: @Override
242: public void flush() {
243: super .flush();
244: disposer.dispose();
245: }
246:
247: private void disposeImpl() {
248: if (win != null) {
249: ctxmgr.freeOffscreenBuffer(win.getOffscreenBuffer());
250: win = null;
251: }
252: }
253:
254: private final class Disposer {
255: boolean createdInEventDispatchThread;
256: Thread creatorThread = null;
257: boolean objectDisposed = false;
258:
259: Disposer() {
260: createdInEventDispatchThread = EventQueue
261: .isDispatchThread();
262: creatorThread = Thread.currentThread();
263: }
264:
265: private final void dispose() {
266: if (!objectDisposed) {
267: Thread disposingThread = Thread.currentThread();
268: if (creatorThread == disposingThread) {
269: disposeImpl();
270: objectDisposed = true;
271: } else if (createdInEventDispatchThread) {
272: try {
273: EventQueue.invokeAndWait(new Runnable() {
274: public void run() {
275: disposeImpl();
276: }
277: });
278: } catch (InterruptedException e) {
279: e.printStackTrace();
280: } catch (InvocationTargetException e) {
281: e.printStackTrace();
282: }
283: objectDisposed = true;
284: }
285: }
286: // Don't set objectDisposed to true if can't dispose from the current thread.
287: // Threre's still a hope that dispose will be invoked from another thread.
288: }
289: }
290: }
|