JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
EGLGraphicsDevice.java
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2023 JogAmp Community. All rights reserved.
3 * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * - Redistribution of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * - Redistribution in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of Sun Microsystems, Inc. or the names of
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * This software is provided "AS IS," without a warranty of any kind. ALL
21 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
22 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
23 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
24 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
25 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
26 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
27 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
28 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
29 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
30 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
31 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32 */
33
34package com.jogamp.nativewindow.egl;
35
36import com.jogamp.common.util.VersionNumber;
37import com.jogamp.nativewindow.AbstractGraphicsDevice;
38import com.jogamp.nativewindow.DefaultGraphicsDevice;
39import com.jogamp.nativewindow.NativeWindowException;
40import com.jogamp.nativewindow.NativeWindowFactory;
41
42/**
43 * Encapsulates a graphics device on EGL platforms.
44 */
45public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
46 /** EGL default native display ID */
47 public static final int EGL_DEFAULT_DISPLAY = 0;
48 /** EGL no display handle */
49 public static final int EGL_NO_DISPLAY = 0;
50
51 private final long[] nativeDisplayID = new long[1];
52 private VersionNumber eglVersion = VersionNumber.zeroVersion;
53
54 /**
55 * Hack to allow inject a EGL termination call.
56 * <p>
57 * FIXME: This shall be removed when relocated EGL to the nativewindow package,
58 * since then it can be utilized directly.
59 * </p>
60 */
61 public interface EGLDisplayLifecycleCallback {
62 /**
63 * Implementation should issue an <code>EGL.eglGetDisplay(nativeDisplayID)</code>
64 * inclusive <code>EGL.eglInitialize(eglDisplayHandle, ..)</code> call.
65 * @param nativeDisplayID in/out array of size 1, passing the requested nativeVisualID, may return a different revised nativeVisualID handle
66 * @param major out array for EGL major version
67 * @param minor out array for EGL minor version
68 * @return the initialized EGL display ID, or <code>0</code> if not successful
69 */
70 public long eglGetAndInitDisplay(final long[] nativeDisplayID, final int[] major, final int[] minor);
71
72 /**
73 * Implementation should issue an <code>EGL.eglTerminate(eglDisplayHandle)</code> call.
74 * @param eglDisplayHandle
75 */
76 void eglTerminate(long eglDisplayHandle);
77 }
78
79 /**
80 * Returns the native display ID of the given abstract device,
81 * i.e. either {@link EGLGraphicsDevice#getNativeDisplayID()} or {@link AbstractGraphicsDevice#getHandle()}.
82 */
83 public static long getNativeDisplayID(final AbstractGraphicsDevice aDevice) {
84 if( aDevice instanceof EGLGraphicsDevice ) {
85 return ((EGLGraphicsDevice)aDevice).getNativeDisplayID();
86 } else {
87 return aDevice.getHandle();
88 }
89 }
90
91 /**
92 * Generic EGLGraphicsDevice constructor.
93 * @param nativeDisplayID the existing native display ID
94 * @param connection the existing underlying native connection name
95 * @param unitID the unit ID
96 * @param handle the handle, maybe 0
97 * @param eglLifecycleCallback
98 */
99 private EGLGraphicsDevice(final long nativeDisplayID, final String connection, final int unitID, final long handle,
100 final EGLDisplayLifecycleCallback eglLifecycleCallback)
101 {
103 this.nativeDisplayID[0] = nativeDisplayID;
104 setHandleOwnership(eglLifecycleCallback);
105 }
106
107 /**
108 * Constructs a dummy {@link EGLGraphicsDevice} with default connection settings.
109 * <p>
110 * The constructed instance will never create a valid EGL display handle.
111 * </p>
112 */
115 }
116
117 /**
118 * Constructs a new dummy {@link EGLGraphicsDevice} reusing the given native display connection
119 * with a {@link EGL#EGL_NO_DISPLAY} EGL display handle.
120 * <p>
121 * The constructed instance will never create a valid EGL display handle.
122 * </p>
123 * @param nativeDisplayID the existing native display ID
124 * @param eglDisplay the existing EGL handle to this nativeDisplayID
125 * @param connection the existing underlying native connection name
126 * @param unitID the unit ID
127 */
128 public EGLGraphicsDevice(final long nativeDisplayID, final String connection, final int unitID) {
129 this(nativeDisplayID, connection, unitID, EGL_NO_DISPLAY, null);
130 }
131
132 /**
133 * Constructs a new {@link EGLGraphicsDevice} reusing the given native display connection and handle
134 * <p>
135 * The constructed instance will not take ownership of given EGL display handle.
136 * </p>
137 * @param nativeDisplayID the existing native display ID
138 * @param eglDisplay the existing EGL handle to this nativeDisplayID
139 * @param connection the existing underlying native connection name
140 * @param unitID the unit ID
141 */
142 public EGLGraphicsDevice(final long nativeDisplayID, final long eglDisplay, final String connection, final int unitID) {
143 this(nativeDisplayID, connection, unitID, eglDisplay, null);
144 if (EGL_NO_DISPLAY == this.nativeDisplayID[0]) {
145 throw new NativeWindowException("Invalid EGL_NO_DISPLAY display handle");
146 }
147 }
148
149 /**
150 * Constructs a new {@link EGLGraphicsDevice} using {@link AbstractGraphicsDevice}'s native display ID and connection,
151 * using the {@link EGLDisplayLifecycleCallback} to handle this instance's native EGL lifecycle.
152 * <p>
153 * The constructed instance will take ownership of the created EGL display handle.
154 * </p>
155 * @param aDevice valid {@link AbstractGraphicsDevice}'s native display ID, connection and unitID
156 * @param eglLifecycleCallback valid {@link EGLDisplayLifecycleCallback} to handle this instance's native EGL lifecycle.
157 */
158 public EGLGraphicsDevice(final AbstractGraphicsDevice aDevice, final EGLDisplayLifecycleCallback eglLifecycleCallback) {
159 this(getNativeDisplayID(aDevice), aDevice.getConnection(), aDevice.getUnitID(), EGL_NO_DISPLAY, eglLifecycleCallback);
160 if (null == eglLifecycleCallback) {
161 throw new NativeWindowException("Null EGLDisplayLifecycleCallback");
162 }
163 }
164
165 /**
166 * Constructs a new {@link EGLGraphicsDevice} using {@link AbstractGraphicsDevice}'s native display ID and connection,
167 * using the {@link EGLDisplayLifecycleCallback} to handle this instance's native EGL lifecycle.
168 * <p>
169 * The constructed instance will take ownership of the created EGL display handle.
170 * </p>
171 * @param nativeDisplayID the existing native display ID
172 * @param connection the existing underlying native connection name
173 * @param unitID the unit ID
174 * @param eglLifecycleCallback valid {@link EGLDisplayLifecycleCallback} to handle this instance's native EGL lifecycle.
175 */
176 public EGLGraphicsDevice(final long nativeDisplayID, final String connection, final int unitID, final EGLDisplayLifecycleCallback eglLifecycleCallback) {
177 this(nativeDisplayID, connection, unitID, EGL_NO_DISPLAY, eglLifecycleCallback);
178 if (null == eglLifecycleCallback) {
179 throw new NativeWindowException("Null EGLDisplayLifecycleCallback");
180 }
181 }
182
183 /** EGL server version as returned by {@code eglInitialize(..)}. Only valid after {@link #open()}. */
184 public VersionNumber getEGLVersion() { return eglVersion; }
185
186 /**
187 * Return the native display ID of this instance.
188 * <p>
189 * Since EGL 1.4, sharing resources requires e.g. a GLContext to use the same native display ID
190 * for the so called shared context list and the to be created context.
191 * </p>
192 * @see #getNativeDisplayID(AbstractGraphicsDevice)
193 */
194 public long getNativeDisplayID() { return nativeDisplayID[0]; }
195
196 /**
197 * Returns true if given {@link AbstractGraphicsDevice} uses the same {@link #getNativeDisplayID()} of this instance.
198 * <p>
199 * In case given {@link AbstractGraphicsDevice} is not a {@link EGLGraphicsDevice}, its {@link AbstractGraphicsDevice#getHandle()}
200 * is being used as the native display id for a matching {@link EGLGraphicsDevice} instance.
201 * </p>
202 * @see #getNativeDisplayID(AbstractGraphicsDevice)
203 */
204 public boolean sameNativeDisplayID(final AbstractGraphicsDevice aDevice) {
205 return getNativeDisplayID(aDevice) == getNativeDisplayID();
206 }
207
208 @Override
209 public Object clone() {
210 return super.clone();
211 }
212
213 /**
214 * Opens the EGL device if handle is null and it's {@link EGLDisplayLifecycleCallback} is valid.
215 * <p>
216 * {@inheritDoc}
217 * </p>
218 */
219 @Override
220 public boolean open() {
221 if(isHandleOwner() && 0 == handle) {
222 if(DEBUG) {
223 System.err.println(Thread.currentThread().getName() + " - EGLGraphicsDevice.open(): "+this);
224 }
225 final int[] major = { 0 };
226 final int[] minor = { 0 };
227 handle = getEGLLifecycleCallback().eglGetAndInitDisplay(nativeDisplayID, major, minor);
228 if(0 == handle) {
229 eglVersion = VersionNumber.zeroVersion;
230 throw new NativeWindowException("EGLGraphicsDevice.open() failed: "+this);
231 } else {
232 eglVersion = new VersionNumber(major[0], minor[0], 0);
233 return true;
234 }
235 }
236 return false;
237 }
238
239 /**
240 * Closes the EGL device if handle is not null and it's {@link EGLDisplayLifecycleCallback} is valid.
241 * <p>
242 * {@inheritDoc}
243 * </p>
244 */
245 @Override
246 public boolean close() {
247 if(isHandleOwner() && 0 != handle) {
248 if(DEBUG) {
249 System.err.println(Thread.currentThread().getName() + " - EGLGraphicsDevice.close(): "+this);
250 }
251 getEGLLifecycleCallback().eglTerminate(handle);
252 }
253 return super.close();
254 }
255
256 private EGLDisplayLifecycleCallback getEGLLifecycleCallback() {
257 return (EGLDisplayLifecycleCallback) getHandleOwnership();
258 }
259
260 @Override
261 public String toString() {
262 return getClass().getSimpleName()+"[type "+getType()+", v"+eglVersion+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID[0])+", connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", owner "+isHandleOwner()+", "+toolkitLock+"]";
263 }
264}
265
final String getType()
Returns the type of the underlying subsystem, ie NativeWindowFactory.TYPE_KD, NativeWindowFactory....
final int getUnitID()
Returns the graphics device unit ID.
final String getConnection()
Returns the semantic GraphicsDevice connection.
final long getHandle()
Returns the native handle of the underlying native device, if such thing exist.
static String getDefaultDisplayConnection()
Return the default display connection for the given windowing toolkit type gathered via NativeWindowF...
final Object setHandleOwnership(final Object newOwnership)
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Provides a pluggable mechanism for arbitrary window toolkits to adapt their components to the NativeW...
static final String TYPE_EGL
OpenKODE/EGL type, as retrieved with getNativeWindowType(boolean).
Encapsulates a graphics device on EGL platforms.
EGLGraphicsDevice()
Constructs a dummy EGLGraphicsDevice with default connection settings.
static final int EGL_DEFAULT_DISPLAY
EGL default native display ID.
EGLGraphicsDevice(final long nativeDisplayID, final long eglDisplay, final String connection, final int unitID)
Constructs a new EGLGraphicsDevice reusing the given native display connection and handle.
boolean sameNativeDisplayID(final AbstractGraphicsDevice aDevice)
Returns true if given AbstractGraphicsDevice uses the same getNativeDisplayID() of this instance.
VersionNumber getEGLVersion()
EGL server version as returned by eglInitialize(..).
boolean open()
Opens the EGL device if handle is null and it's EGLDisplayLifecycleCallback is valid.
long getNativeDisplayID()
Return the native display ID of this instance.
EGLGraphicsDevice(final long nativeDisplayID, final String connection, final int unitID)
Constructs a new dummy EGLGraphicsDevice reusing the given native display connection with a EGL#EGL_N...
static final int EGL_NO_DISPLAY
EGL no display handle.
static long getNativeDisplayID(final AbstractGraphicsDevice aDevice)
Returns the native display ID of the given abstract device, i.e.
boolean close()
Closes the EGL device if handle is not null and it's EGLDisplayLifecycleCallback is valid.
EGLGraphicsDevice(final long nativeDisplayID, final String connection, final int unitID, final EGLDisplayLifecycleCallback eglLifecycleCallback)
Constructs a new EGLGraphicsDevice using AbstractGraphicsDevice's native display ID and connection,...
EGLGraphicsDevice(final AbstractGraphicsDevice aDevice, final EGLDisplayLifecycleCallback eglLifecycleCallback)
Constructs a new EGLGraphicsDevice using AbstractGraphicsDevice's native display ID and connection,...
A interface describing a graphics device in a toolkit-independent manner.
long getHandle()
Returns the native handle of the underlying native device, if such thing exist.
int getUnitID()
Returns the graphics device unit ID.
static int DEFAULT_UNIT
Default unit id for the 1st device: 0.
String getConnection()
Returns the semantic GraphicsDevice connection.
long eglGetAndInitDisplay(final long[] nativeDisplayID, final int[] major, final int[] minor)
Implementation should issue an EGL.eglGetDisplay(nativeDisplayID) inclusive EGL.eglInitialize(eglDisp...
void eglTerminate(long eglDisplayHandle)
Implementation should issue an EGL.eglTerminate(eglDisplayHandle) call.