JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
Display.java
Go to the documentation of this file.
1/**
2 * Copyright 2010 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.newt;
30
31import java.io.IOException;
32import java.lang.ref.WeakReference;
33import java.util.ArrayList;
34import java.util.Collection;
35import java.util.Iterator;
36
37import com.jogamp.nativewindow.AbstractGraphicsDevice;
38import com.jogamp.nativewindow.NativeWindowException;
39import com.jogamp.nativewindow.util.PixelRectangle;
40import com.jogamp.nativewindow.util.PixelFormat;
41import com.jogamp.nativewindow.util.PointImmutable;
42
43import jogamp.newt.Debug;
44
45import com.jogamp.common.util.IOUtil;
46import com.jogamp.newt.util.EDTUtil;
47
48public abstract class Display {
49 public static final boolean DEBUG = Debug.debug("Display");
50 protected static final boolean DEBUG_POINTER_ICON = Debug.debug("Display.PointerIcon");
51
52 /** return precomputed hashCode from FQN {@link #getFQName()} */
53 @Override
54 public abstract int hashCode();
55
56 /** return true if obj is of type Display and both FQN {@link #getFQName()} equals */
57 @Override
58 public boolean equals(final Object obj) {
59 if (this == obj) { return true; }
60 if (obj instanceof Display) {
61 final Display d = (Display)obj;
62 return d.getFQName().equals(getFQName());
63 }
64 return false;
65 }
66
67 /**
68 * Native PointerIcon handle.
69 * <p>
70 * Instances can be created via {@link Display}'s
71 * {@link Display#createPointerIcon(com.jogamp.common.util.IOUtil.ClassResources, int, int) createPointerIcon(pngResource, ..)}
72 * or {@link Display#createPointerIcon(PixelRectangle, int, int) createPointerIcon(pixelrect, ..)}.
73 * </p>
74 * <p>
75 * Instance is {@link #destroy()}'ed automatically if it's {@link #getDisplay() associated Display} is destroyed.
76 * </p>
77 * <p>
78 * Instance can be re-validated after destruction via {@link #validate()}.
79 * </p>
80 * <p>
81 * {@link PointerIcon} must not be {@link #destroy() destroyed} while in use!
82 * </p>
83 * <p>
84 * {@link PointerIcon} may be {@link #destroy() destroyed} manually after use,
85 * i.e. when no {@link Window} {@link Window#setPointerIcon(PointerIcon) uses them} anymore.
86 * However, this is not required.
87 * </p>
88 * <p>
89 * PointerIcons can be used via {@link Window#setPointerIcon(PointerIcon)}.
90 * </p>
91 */
92 public static interface PointerIcon extends PixelRectangle {
93 /**
94 * Always neatly packed, i.e. width * bytes_per_pixel.
95 * <p>
96 * {@inheritDoc}
97 * </p>
98 */
99 @Override
101
102 /**
103 * Always false, i.e. origin is TOP-LEFT.
104 * <p>
105 * {@inheritDoc}
106 * </p>
107 */
108 @Override
109 boolean isGLOriented();
110
111 /**
112 * Computes a hash code over:
113 * <ul>
114 * <li>display</li>
115 * <li>pixelformat</li>
116 * <li>size</li>
117 * <li>stride</li>
118 * <li>isGLOriented</li>
119 * <li>pixels</li>
120 * <li>hotspot</li>
121 * </ul>
122 * Dismissing the native handle!
123 * <p>
124 * The hashCode shall be computed only once with first call
125 * and stored for later retrieval to enhance performance.
126 * </p>
127 * <p>
128 * {@inheritDoc}
129 * </p>
130 */
131 @Override
132 int hashCode();
133
134 /**
135 * @return the associated Display
136 */
138
139 /** Returns the hotspot. */
141
142 /**
143 * Returns true if valid, otherwise false.
144 * <p>
145 * A PointerIcon instance becomes invalid if it's {@link #getDisplay() associated Display} is destroyed.
146 * </p>
147 */
148 boolean isValid();
149
150 /**
151 * Destroys this instance.
152 * <p>
153 * Will be called automatically if it's {@link #getDisplay() associated Display} is destroyed.
154 * </p>
155 */
156 void destroy();
157 }
158
159 /**
160 * Returns the native platform's {@link PixelFormat} for pointer-icon pixel data.
161 * <p>
162 * Using this value will avoid conversion within {@link #createPointerIcon(PixelRectangle, int, int)}.
163 * </p>
164 * <p>
165 * Known native pixel formats are:
166 * <ul>
167 * <li>X11: {@link PixelFormat#BGRA8888}</li>
168 * <li>Windows: {@link PixelFormat#BGRA8888}</li>
169 * <li>OSX: {@link PixelFormat#RGBA8888}</li>
170 * </ul>
171 * </p>
172 */
174
175 /**
176 * Returns the native platform's direct NIO buffer requirement pointer-icon pixel data.
177 * <p>
178 * Using this value will avoid conversion within {@link #createPointerIcon(PixelRectangle, int, int)}.
179 * </p>
180 */
181 public abstract boolean getNativePointerIconForceDirectNIO();
182
183 /**
184 * Returns the newly created {@link PointerIcon} or <code>null</code> if not implemented on platform.
185 * <p>
186 * See {@link PointerIcon} for lifecycle semantics.
187 * </p>
188 *
189 * @param pngResource single PNG resource for the {@link PointerIcon}. Only the first entry of {@link IOUtil.ClassResources#resourcePaths} is used.
190 * @param hotX pointer hotspot x-coord, origin is upper-left corner
191 * @param hotY pointer hotspot y-coord, origin is upper-left corner
192 *
193 * @throws IllegalArgumentException if pngResource is null or invalid
194 * @throws IllegalStateException if this Display instance is not {@link #isNativeValid() valid yet}.
195 * @throws IOException if the <code>pngResource</code> could not be {@link IOUtil.ClassResources#resolve(int) resolved}
196 * or via the PNG parser processing the input stream.
197 *
198 * @see PointerIcon
199 * @see Window#setPointerIcon(PointerIcon)
200 */
201 public abstract PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY)
202 throws IllegalArgumentException, IllegalStateException, IOException;
203
204 /**
205 * Returns the newly created {@link PointerIcon} or <code>null</code> if not implemented on platform.
206 * <p>
207 * See {@link PointerIcon} for lifecycle semantics.
208 * </p>
209 * <p>
210 * In case {@link #getNativePointerIconPixelFormat()} or {@link #getNativePointerIconForceDirectNIO()}
211 * is not matched by the given <code>pixelrect</code>, the <code>pixelrect</code> is converted
212 * into the required {@link PixelFormat} and NIO type.
213 * </p>
214 *
215 * @param pixelrect {@link PixelRectangle} source for the {@link PointerIcon}
216 * @param hotX pointer hotspot x-coord, origin is upper-left corner
217 * @param hotY pointer hotspot y-coord, origin is upper-left corner
218 *
219 * @throws IllegalArgumentException if pixelrect is null.
220 * @throws IllegalStateException if this Display instance is not {@link #isNativeValid() valid yet}.
221 *
222 * @see PointerIcon
223 * @see Window#setPointerIcon(PointerIcon)
224 * @see #getNativePointerIconPixelFormat()
225 * @see #getNativePointerIconForceDirectNIO()
226 */
227 public abstract PointerIcon createPointerIcon(final PixelRectangle pixelrect, final int hotX, final int hotY) throws IllegalArgumentException, IllegalStateException;
228
229 /**
230 * Manual trigger the native creation, if it is not done yet.<br>
231 * This is useful to be able to request the {@link com.jogamp.nativewindow.AbstractGraphicsDevice}, via
232 * {@link #getGraphicsDevice()}.<br>
233 * Otherwise the abstract device won't be available before the dependent components (Screen and Window) are realized.
234 * <p>
235 * This method is usually invoke by {@link #addReference()}
236 * </p>
237 * @throws NativeWindowException if the native creation failed.
238 */
239 public abstract void createNative() throws NativeWindowException;
240
241 /**
242 * Manually trigger the destruction, incl. native destruction.<br>
243 * <p>
244 * This method is usually invoke by {@link #removeReference()}
245 * </p>
246 */
247 public abstract void destroy();
248
249 /**
250 * Validate EDT running state.<br>
251 * Stop the running EDT in case this display is destroyed already.<br>
252 * @return true if EDT has been stopped (destroyed but running), otherwise false.
253 */
254 public abstract boolean validateEDTStopped();
255
256 /**
257 * @return true if the native display handle is valid and ready to operate,
258 * otherwise false.
259 *
260 * @see #destroy()
261 */
262 public abstract boolean isNativeValid();
263
264 /**
265 * @return number of references
266 */
267 public abstract int getReferenceCount();
268
269 /**
270 * The 1st call will initiate native creation,
271 * since we follow the lazy creation pattern.
272 *
273 * @return number of references post operation
274 * @throws NativeWindowException if the native creation failed.
275 * @see #removeReference()
276 */
277 public abstract int addReference() throws NativeWindowException ;
278
279 /**
280 * The last call may destroy this instance,
281 * if {@link #getDestroyWhenUnused()} returns <code>true</code>.
282 *
283 * @return number of references post operation
284 * @see #addReference()
285 * @see #getDestroyWhenUnused()
286 * @see #setDestroyWhenUnused(boolean)
287 */
288 public abstract int removeReference();
289
290 /**
291 * Return the {@link AbstractGraphicsDevice} used for depending resources lifecycle,
292 * i.e. {@link Screen} and {@link Window}, as well as the event dispatching (EDT). */
294
295 /**
296 * Return the handle of the {@link AbstractGraphicsDevice} as returned by {@link #getGraphicsDevice()}.
297 */
298 public abstract long getHandle();
299
300 /**
301 * @return The fully qualified Display name,
302 * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()}.
303 */
304 public abstract String getFQName();
305
306 /**
307 * @return this display internal serial id
308 */
309 public abstract int getId();
310
311 /**
312 * @return This display connection name as defined at creation time.
313 * The display connection name is a technical platform specific detail, see {@link AbstractGraphicsDevice#getConnection()}.
314 *
315 * @see AbstractGraphicsDevice#getConnection()
316 */
317 public abstract String getName();
318
319 /**
320 * @return the native display type, ie {@link com.jogamp.nativewindow.NativeWindowFactory#getNativeWindowType(boolean)}
321 */
322 public abstract String getType();
323
324 /** Return true if this instance is exclusive, i.e. will not be shared. */
325 public abstract boolean isExclusive();
326
327 /**
328 * Sets a new {@link EDTUtil} and returns the previous one.
329 * <p>
330 * If <code>usrEDTUtil</code> is <code>null</code>,
331 * the device's default EDTUtil is created and used.
332 * </p>
333 * <p>
334 * If a previous one exists and it differs from <code>usrEDTUtil</code>,
335 * it's being stopped, wait-until-idle.
336 * </p>
337 * <p>
338 * If <code>usrEDTUtil</code> is not null and equals the previous one,
339 * no change is being made.
340 * </p>
341 */
342 public abstract EDTUtil setEDTUtil(EDTUtil usrEDTUtil);
343
344 public abstract EDTUtil getEDTUtil();
345
346 /**
347 * @return true if EDT is running and not subject to be stopped, otherwise false.
348 */
349 public abstract boolean isEDTRunning();
350
351 public abstract void dispatchMessages();
352
353 // Global Displays
354 protected static final ArrayList<WeakReference<Display>> displayList = new ArrayList<WeakReference<Display>>();
355 protected static int displaysActive = 0;
356
357 public static void dumpDisplayList(final String prefix) {
358 synchronized(displayList) {
359 System.err.println(prefix+" DisplayList[] entries: "+displayList.size()+" - "+getThreadName());
360 final Iterator<WeakReference<Display>> ri = displayList.iterator();
361 for(int j=0; ri.hasNext(); j++) {
362 final Display d = ri.next().get();
363 System.err.println(" ["+j+"] : "+d+", GC'ed "+(null==d));
364 }
365 }
366 }
367
368 /**
369 *
370 * @param type
371 * @param name
372 * @param fromIndex start index, then increasing until found or end of list
373 * @paran shared if true, only shared instances are found, otherwise also exclusive
374 * @return
375 */
376 public static Display getFirstDisplayOf(final String type, final String name, final int fromIndex, final boolean shared) {
377 return getDisplayOfImpl(type, name, fromIndex, 1, shared);
378 }
379
380 /**
381 *
382 * @param type
383 * @param name
384 * @param fromIndex start index, then decreasing until found or end of list. -1 is interpreted as size - 1.
385 * @param shared if true, only shared instances are found, otherwise also exclusive
386 * @return
387 */
388 public static Display getLastDisplayOf(final String type, final String name, final int fromIndex, final boolean shared) {
389 return getDisplayOfImpl(type, name, fromIndex, -1, shared);
390 }
391
392 private static Display getDisplayOfImpl(final String type, final String name, final int fromIndex, final int incr, final boolean shared) {
393 synchronized(displayList) {
394 int i = fromIndex >= 0 ? fromIndex : displayList.size() - 1 ;
395 while( ( incr > 0 ) ? i < displayList.size() : i >= 0 ) {
396 final Display display = displayList.get(i).get();
397 if( null == display ) {
398 // Clear GC'ed dead reference entry!
399 displayList.remove(i);
400 if( incr < 0 ) {
401 // decrease
402 i+=incr;
403 } // else nop - remove shifted subsequent elements to the left
404 } else {
405 if( display.getType().equals(type) &&
406 display.getName().equals(name) &&
407 ( !shared || shared && !display.isExclusive() )
408 ) {
409 return display;
410 }
411 i+=incr;
412 }
413 }
414 }
415 return null;
416 }
417
418 protected static void addDisplay2List(final Display display) {
419 synchronized(displayList) {
420 // GC before add
421 int i=0;
422 while( i < displayList.size() ) {
423 if( null == displayList.get(i).get() ) {
424 displayList.remove(i);
425 } else {
426 i++;
427 }
428 }
429 displayList.add(new WeakReference<Display>(display));
430 }
431 }
432
433 /** Returns the global display collection */
434 public static Collection<Display> getAllDisplays() {
435 ArrayList<Display> list;
436 synchronized(displayList) {
437 list = new ArrayList<Display>();
438 int i = 0;
439 while( i < displayList.size() ) {
440 final Display d = displayList.get(i).get();
441 if( null == d ) {
442 displayList.remove(i);
443 } else {
444 list.add( displayList.get(i).get() );
445 i++;
446 }
447 }
448 }
449 return list;
450 }
451
452 public static int getActiveDisplayNumber() {
453 synchronized(displayList) {
454 return displaysActive;
455 }
456 }
457
458 public static String getThreadName() {
459 final Thread ct = Thread.currentThread();
460 return "Thread["+toHexString(ct.hashCode()) + ", " + ct.getName()+"]";
461 }
462
463 public static String toHexString(final int hex) {
464 return "0x" + Integer.toHexString(hex);
465 }
466
467 public static String toHexString(final long hex) {
468 return "0x" + Long.toHexString(hex);
469 }
470
471 public static int hashCodeNullSafe(final Object o) {
472 return ( null != o ) ? o.hashCode() : 0;
473 }
474}
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
static int hashCodeNullSafe(final Object o)
Definition: Display.java:471
static Display getLastDisplayOf(final String type, final String name, final int fromIndex, final boolean shared)
Definition: Display.java:388
static Display getFirstDisplayOf(final String type, final String name, final int fromIndex, final boolean shared)
Definition: Display.java:376
abstract boolean getNativePointerIconForceDirectNIO()
Returns the native platform's direct NIO buffer requirement pointer-icon pixel data.
static final boolean DEBUG
Definition: Display.java:49
static final ArrayList< WeakReference< Display > > displayList
Definition: Display.java:354
static String toHexString(final long hex)
Definition: Display.java:467
abstract void dispatchMessages()
abstract int hashCode()
return precomputed hashCode from FQN getFQName()
boolean equals(final Object obj)
return true if obj is of type Display and both FQN getFQName() equals
Definition: Display.java:58
abstract int addReference()
The 1st call will initiate native creation, since we follow the lazy creation pattern.
abstract AbstractGraphicsDevice getGraphicsDevice()
Return the AbstractGraphicsDevice used for depending resources lifecycle, i.e.
abstract int getReferenceCount()
abstract String getName()
static int displaysActive
Definition: Display.java:355
static int getActiveDisplayNumber()
Definition: Display.java:452
abstract int removeReference()
The last call may destroy this instance, if getDestroyWhenUnused() returns true.
abstract PixelFormat getNativePointerIconPixelFormat()
Returns the native platform's PixelFormat for pointer-icon pixel data.
abstract boolean validateEDTStopped()
Validate EDT running state.
abstract EDTUtil getEDTUtil()
static String getThreadName()
Definition: Display.java:458
abstract String getType()
abstract String getFQName()
abstract int getId()
static String toHexString(final int hex)
Definition: Display.java:463
static Collection< Display > getAllDisplays()
Returns the global display collection.
Definition: Display.java:434
abstract void destroy()
Manually trigger the destruction, incl.
abstract boolean isExclusive()
Return true if this instance is exclusive, i.e.
abstract boolean isEDTRunning()
abstract void createNative()
Manual trigger the native creation, if it is not done yet.
static final boolean DEBUG_POINTER_ICON
Definition: Display.java:50
abstract boolean isNativeValid()
abstract PointerIcon createPointerIcon(final IOUtil.ClassResources pngResource, final int hotX, final int hotY)
Returns the newly created PointerIcon or null if not implemented on platform.
static void addDisplay2List(final Display display)
Definition: Display.java:418
abstract EDTUtil setEDTUtil(EDTUtil usrEDTUtil)
Sets a new EDTUtil and returns the previous one.
static void dumpDisplayList(final String prefix)
Definition: Display.java:357
abstract long getHandle()
Return the handle of the AbstractGraphicsDevice as returned by getGraphicsDevice().
abstract PointerIcon createPointerIcon(final PixelRectangle pixelrect, final int hotX, final int hotY)
Returns the newly created PointerIcon or null if not implemented on platform.
A interface describing a graphics device in a toolkit-independent manner.
Pixel Rectangle identified by it's hashCode().
Native PointerIcon handle.
Definition: Display.java:92
PointImmutable getHotspot()
Returns the hotspot.
boolean isValid()
Returns true if valid, otherwise false.
boolean isGLOriented()
Always false, i.e.
int hashCode()
Computes a hash code over:
void destroy()
Destroys this instance.
int getStride()
Always neatly packed, i.e.
EDT stands for Event Dispatch Thread.
Definition: EDTUtil.java:53