001: /*
002: * $RCSfile: GraphicsConfigTemplate3D.java,v $
003: *
004: * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.8 $
028: * $Date: 2008/02/28 20:17:22 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import java.awt.GraphicsDevice;
035: import java.awt.GraphicsConfiguration;
036: import java.awt.GraphicsConfigTemplate;
037:
038: /**
039: * This class is used to obtain a valid GraphicsConfiguration that can be used by Java 3D.
040: * A user instantiates one of these objects and then sets all
041: * non-default attributes as desired. The getBestConfiguration()
042: * method in the GraphicsDevice class is then called with this
043: * GraphicsConfigTemplate and the "best" GraphicsConfiguration is returned. The "best"
044: * GraphicsConfiguration means that this GraphicsConfiguration is supported and it
045: * meets or exceeds what was requested in the GraphicsConfigTemplate.
046: * Null is returned if no such "best" GraphicsConfiguration is found.
047: *
048: * @see GraphicsConfigTemplate
049: * @see GraphicsDevice
050: * @see GraphicsConfiguration
051: */
052: public class GraphicsConfigTemplate3D extends GraphicsConfigTemplate {
053:
054: int depthSize;
055: int doubleBuffer;
056: int blueSize;
057: int greenSize;
058: int redSize;
059: int sceneAntialiasing;
060: int stereo;
061: int stencilSize;
062:
063: // Temporary variables use for passing argument to/from Request Renderer
064: Object testCfg;
065:
066: static Object globalLock = new Object();
067: static Object monitorLock = new Object();
068: static volatile boolean threadWaiting = false;
069:
070: /**
071: * Constructs a GraphicsConfigTemplate3D object with default parameters.
072: * The default values are as follows:
073: * <ul>
074: * depthSize : 16<br>
075: * doubleBuffer : REQUIRED<br>
076: * sceneAntialiasing : UNNECESSARY<br>
077: * stereo : UNNECESSARY<br>
078: * redSize : 2<br>
079: * greenSize : 2<br>
080: * blueSize : 2<br>
081: * stencilSize : 0<br>
082: * </ul>
083: */
084: public GraphicsConfigTemplate3D() {
085: doubleBuffer = REQUIRED;
086: stereo = UNNECESSARY;
087: depthSize = 16;
088: stencilSize = 0;
089: redSize = greenSize = blueSize = 2;
090: sceneAntialiasing = UNNECESSARY;
091: }
092:
093: /**
094: * Sets the double buffering requirement. It should be
095: * GraphicsConfigTemplate.REQUIRED, GraphicsConfigTemplate.PREFERRED,
096: * or GraphicsConfigTemplate.UNNECESSARY.
097: * If an invalid value is passed in, it is ignored.
098: * If the value of double buffering is
099: * GraphicsConfigTemplate.REQUIRED, and no GraphicsConfiguration is found
100: * that meets this requirement, null will be returned in getBestConfiguration().
101: * @param value the value to set this field to
102: */
103: public void setDoubleBuffer(int value) {
104: if (value < REQUIRED && value > UNNECESSARY)
105: return;
106:
107: doubleBuffer = value;
108: }
109:
110: /**
111: * Retrieves the double buffering value.
112: * @return the current value of the doubleBuffer attribute
113: */
114: public int getDoubleBuffer() {
115: return doubleBuffer;
116: }
117:
118: /**
119: * Sets the stereo requirement. It should be
120: * GraphicsConfigTemplate.REQUIRED, GraphicsConfigTemplate.PREFERRED,
121: * or GraphicsConfigTemplate.UNNECESSARY. If an invalid value
122: * is passed in, it is ignored. If the value of stereo requirement is
123: * GraphicsConfigTemplate.REQUIRED, and no GraphicsConfiguration is found
124: * that meets this requirement, null will be returned in getBestConfiguration().
125: * @param value the value to set this field to
126: */
127: public void setStereo(int value) {
128: if (value < REQUIRED && value > UNNECESSARY)
129: return;
130:
131: stereo = value;
132: }
133:
134: /**
135: * Retrieves the stereo value.
136: * @return the current value of the stereo attribute.
137: */
138: public int getStereo() {
139: return stereo;
140: }
141:
142: /**
143: * Sets the scene antialiasing requirement. It should be
144: * GraphicsConfigTemplate.REQUIRED, GraphicsConfigTemplate.PREFERRED,
145: * or GraphicsConfigTemplate.UNNECESSARY. If an invalid value
146: * is passed in, it is ignored. If the value of scene antialiasing is
147: * GraphicsConfigTemplate.REQUIRED, and no GraphicsConfiguration is found
148: * that meets this requirement, null will be returned in getBestConfiguration().
149: * @param value the value to set this field to
150: */
151: public void setSceneAntialiasing(int value) {
152: if (value < REQUIRED && value > UNNECESSARY)
153: return;
154:
155: sceneAntialiasing = value;
156: }
157:
158: /**
159: * Retrieves the scene antialiasing value.
160: * @return the current value of the scene antialiasing attribute.
161: */
162: public int getSceneAntialiasing() {
163: return sceneAntialiasing;
164: }
165:
166: /**
167: * Sets the depth buffer size requirement. This is the minimum requirement.
168: * If no GraphicsConfiguration is found that meets or
169: * exceeds this minimum requirement, null will be returned in
170: * getBestConfiguration().
171: * @param value the value to set this field to
172: */
173: public void setDepthSize(int value) {
174: if (value < 0)
175: return;
176:
177: depthSize = value;
178: }
179:
180: /**
181: * Retrieves the size of the depth buffer.
182: * @return the current value of the depthSize attribute
183: */
184: public int getDepthSize() {
185: return depthSize;
186: }
187:
188: /**
189: * Sets the stencil buffer size requirement.
190: * This is the minimum requirement.
191: * If no GraphicsConfiguration is found that meets or
192: * exceeds this minimum requirement, null will be returned in
193: * getBestConfiguration().
194: *
195: * @param value the value to set this field to
196: *
197: * @since Java 3D 1.4
198: */
199: public void setStencilSize(int value) {
200: if (value < 0)
201: return;
202:
203: stencilSize = value;
204: }
205:
206: /**
207: * Retrieves the size of the stencil buffer.
208: *
209: * @return the current value of the stencilSize attribute
210: *
211: * @since Java 3D 1.4
212: */
213: public int getStencilSize() {
214: return stencilSize;
215: }
216:
217: /**
218: * Sets the number of red bits required. This is the minimum requirement.
219: * If no GraphicsConfiguration is found that meets or
220: * exceeds this minimum requirement, null will be returned in
221: * getBestConfiguration().
222: * @param value the value to set this field to
223: */
224: public void setRedSize(int value) {
225: if (value < 0)
226: return;
227:
228: redSize = value;
229: }
230:
231: /**
232: * Retrieves the number of red bits requested by this template.
233: * @return the current value of the redSize attribute.
234: */
235: public int getRedSize() {
236: return redSize;
237: }
238:
239: /**
240: * Sets the number of green bits required. This is the minimum requirement.
241: * If no GraphicsConfiguration is found that meets or
242: * exceeds this minimum requirement, null will be returned in
243: * getBestConfiguration().
244: * @param value the value to set this field to
245: */
246: public void setGreenSize(int value) {
247: if (value < 0)
248: return;
249:
250: greenSize = value;
251: }
252:
253: /**
254: * Retrieves the number of green bits requested by this template.
255: * @return the current value of the greenSize attribute.
256: */
257: public int getGreenSize() {
258: return greenSize;
259: }
260:
261: /**
262: * Sets the number of blue bits required. This is the minimum requirement.
263: * If no GraphicsConfiguration is found that meets or
264: * exceeds this minimum requirement, null will be returned in
265: * getBestConfiguration().
266: * @param value the value to set this field to
267: */
268: public void setBlueSize(int value) {
269: if (value < 0)
270: return;
271:
272: blueSize = value;
273: }
274:
275: /**
276: * Retrieves the number of blue bits requested by this template.
277: * @return the current value of the blueSize attribute.
278: */
279: public int getBlueSize() {
280: return blueSize;
281: }
282:
283: /**
284: * Implement the abstract function of getBestConfiguration() in GraphicsConfigTemplate.
285: * Usually this function is not directly called by the user. It is
286: * implicitly called by getBestConfiguration() in GraphicsDevice.
287: * The method getBestConfiguration() in GraphicsDevice will return whatever this function returns.
288: * This function will return the "best" GraphicsConfiguration. The "best" GraphicsConfiguration
289: * means that this GraphicsConfiguration is supported and it meets or exceeds what was requested in the
290: * GraphicsConfigTemplate. If no such "best" GraphicsConfiguration is found, null is returned.
291: * @param gc the array of GraphicsConfigurations to choose from
292: *
293: * @return the best GraphicsConfiguration
294: *
295: * @see GraphicsDevice
296: */
297: public GraphicsConfiguration getBestConfiguration(
298: GraphicsConfiguration[] gc) {
299: if ((gc == null) || (gc.length == 0) || (gc[0] == null)) {
300: return null;
301: }
302:
303: synchronized (globalLock) {
304: testCfg = gc;
305:
306: // It is possible that the followign postRequest will
307: // cause request renderer run immediately before
308: // runMonitor(WAIT). So we need to set
309: // threadWaiting to true.
310: threadWaiting = true;
311:
312: // Prevent deadlock if invoke from Behavior callback since
313: // this thread has to wait Renderer thread to finish but
314: // MC can only handle postRequest and put it in Renderer
315: // queue when free.
316: if (Thread.currentThread() instanceof BehaviorScheduler) {
317: VirtualUniverse.mc.sendRenderMessage(gc[0], this ,
318: MasterControl.GETBESTCONFIG);
319: } else {
320: VirtualUniverse.mc.postRequest(
321: MasterControl.GETBESTCONFIG, this );
322: }
323: runMonitor(J3dThread.WAIT);
324: return (GraphicsConfiguration) testCfg;
325: }
326: }
327:
328: /**
329: * Returns a boolean indicating whether or not the given
330: * GraphicsConfiguration can be used to create a drawing
331: * surface that can be rendered to.
332: *
333: * @param gc the GraphicsConfiguration object to test
334: *
335: * @return <code>true</code> if this GraphicsConfiguration object
336: * can be used to create surfaces that can be rendered to,
337: * <code>false</code> if the GraphicsConfiguration can not be used
338: * to create a drawing surface usable by this API.
339: */
340: public boolean isGraphicsConfigSupported(GraphicsConfiguration gc) {
341: if (gc == null) {
342: return false;
343: }
344:
345: synchronized (globalLock) {
346: testCfg = gc;
347: threadWaiting = true;
348: if (Thread.currentThread() instanceof BehaviorScheduler) {
349: VirtualUniverse.mc.sendRenderMessage(gc, this ,
350: MasterControl.ISCONFIGSUPPORT);
351: } else {
352: VirtualUniverse.mc.postRequest(
353: MasterControl.ISCONFIGSUPPORT, this );
354: }
355: runMonitor(J3dThread.WAIT);
356: return ((Boolean) testCfg).booleanValue();
357: }
358: }
359:
360: /**
361: * Set the stereo/doubleBuffer/sceneAntialiasingAccum
362: * and hasSceneAntialiasingMultiSamples flags in Canvas3D
363: */
364: static void getGraphicsConfigFeatures(Canvas3D c) {
365: synchronized (globalLock) {
366: threadWaiting = true;
367: if (Thread.currentThread() instanceof BehaviorScheduler) {
368: VirtualUniverse.mc.sendRenderMessage(
369: c.graphicsConfiguration, c,
370: MasterControl.SET_GRAPHICSCONFIG_FEATURES);
371: } else {
372: VirtualUniverse.mc.postRequest(
373: MasterControl.SET_GRAPHICSCONFIG_FEATURES, c);
374: }
375: runMonitor(J3dThread.WAIT);
376: }
377: }
378:
379: /**
380: * Set the queryProperties() map in Canvas3D
381: */
382: static void setQueryProps(Canvas3D c) {
383: synchronized (globalLock) {
384: threadWaiting = true;
385: if (Thread.currentThread() instanceof BehaviorScheduler) {
386: VirtualUniverse.mc.sendRenderMessage(
387: c.graphicsConfiguration, c,
388: MasterControl.SET_QUERYPROPERTIES);
389: } else {
390: VirtualUniverse.mc.postRequest(
391: MasterControl.SET_QUERYPROPERTIES, c);
392: }
393: runMonitor(J3dThread.WAIT);
394: }
395: }
396:
397: static void runMonitor(int action) {
398: // user thread will locked the globalLock when Renderer
399: // thread invoke this function so we can't use
400: // the same lock.
401: synchronized (monitorLock) {
402: switch (action) {
403: case J3dThread.WAIT:
404: // Issue 279 - loop until ready
405: while (threadWaiting) {
406: try {
407: monitorLock.wait();
408: } catch (InterruptedException e) {
409: System.err.println(e);
410: }
411: }
412: break;
413: case J3dThread.NOTIFY:
414: monitorLock.notify();
415: threadWaiting = false;
416: break;
417: }
418: }
419: }
420:
421: // Return a string representing the value, one of:
422: // REQUIRED, PREFERRED, or UNNECESSARY
423: private static final String enumStr(int val) {
424: switch (val) {
425: case REQUIRED:
426: return "REQUIRED";
427: case PREFERRED:
428: return "PREFERRED";
429: case UNNECESSARY:
430: return "UNNECESSARY";
431: }
432:
433: return "UNDEFINED";
434: }
435:
436: /**
437: * Returns a string representation of this object.
438: * @return a string representation of this object.
439: */
440: public String toString() {
441: return "redSize : " + redSize + ", " + "greenSize : "
442: + greenSize + ", " + "blueSize : " + blueSize + ", "
443: + "depthSize : " + depthSize + ", " + "doubleBuffer : "
444: + enumStr(doubleBuffer) + ", " + "sceneAntialiasing : "
445: + enumStr(sceneAntialiasing) + ", " + "stereo : "
446: + enumStr(stereo);
447: }
448: }
|