lwjgl/src/java/org/lwjgl/opengles/EGL.java

922 lines
33 KiB
Java

/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengles;
import org.lwjgl.BufferChecks;
import org.lwjgl.LWJGLException;
import org.lwjgl.MemoryUtil;
import org.lwjgl.PointerBuffer;
import java.nio.IntBuffer;
/** EGL wrapper class. */
public final class EGL {
/** EGL aliases */
public static final int
EGL_FALSE = 0,
EGL_TRUE = 1;
/** Out-of-band handle values */
public static final int
EGL_DEFAULT_DISPLAY = 0,
EGL_NO_CONTEXT = 0,
EGL_NO_DISPLAY = 0,
EGL_NO_SURFACE = 0;
/** Out-of-band attribute value */
public static final int EGL_DONT_CARE = -1;
/** Errors / GetError return values */
public static final int
EGL_SUCCESS = 0x3000,
EGL_NOT_INITIALIZED = 0x3001,
EGL_BAD_ACCESS = 0x3002,
EGL_BAD_ALLOC = 0x3003,
EGL_BAD_ATTRIBUTE = 0x3004,
EGL_BAD_CONFIG = 0x3005,
EGL_BAD_CONTEXT = 0x3006,
EGL_BAD_CURRENT_SURFACE = 0x3007,
EGL_BAD_DISPLAY = 0x3008,
EGL_BAD_MATCH = 0x3009,
EGL_BAD_NATIVE_PIXMAP = 0x300A,
EGL_BAD_NATIVE_WINDOW = 0x300B,
EGL_BAD_PARAMETER = 0x300C,
EGL_BAD_SURFACE = 0x300D,
EGL_CONTEXT_LOST = 0x300E; // EGL 1.1 - IMG_power_management
/** Reserved =0x300F;-=0x301F; for additional errors */
/** Config attributes */
public static final int
EGL_BUFFER_SIZE = 0x3020,
EGL_ALPHA_SIZE = 0x3021,
EGL_BLUE_SIZE = 0x3022,
EGL_GREEN_SIZE = 0x3023,
EGL_RED_SIZE = 0x3024,
EGL_DEPTH_SIZE = 0x3025,
EGL_STENCIL_SIZE = 0x3026,
EGL_CONFIG_CAVEAT = 0x3027,
EGL_CONFIG_ID = 0x3028,
EGL_LEVEL = 0x3029,
EGL_MAX_PBUFFER_HEIGHT = 0x302A,
EGL_MAX_PBUFFER_PIXELS = 0x302B,
EGL_MAX_PBUFFER_WIDTH = 0x302C,
EGL_NATIVE_RENDERABLE = 0x302D,
EGL_NATIVE_VISUAL_ID = 0x302E,
EGL_NATIVE_VISUAL_TYPE = 0x302F,
EGL_SAMPLES = 0x3031,
EGL_SAMPLE_BUFFERS = 0x3032,
EGL_SURFACE_TYPE = 0x3033,
EGL_TRANSPARENT_TYPE = 0x3034,
EGL_TRANSPARENT_BLUE_VALUE = 0x3035,
EGL_TRANSPARENT_GREEN_VALUE = 0x3036,
EGL_TRANSPARENT_RED_VALUE = 0x3037,
EGL_NONE = 0x3038, // Attrib list terminator
EGL_BIND_TO_TEXTURE_RGB = 0x3039,
EGL_BIND_TO_TEXTURE_RGBA = 0x303A,
EGL_MIN_SWAP_INTERVAL = 0x303B,
EGL_MAX_SWAP_INTERVAL = 0x303C,
EGL_LUMINANCE_SIZE = 0x303D,
EGL_ALPHA_MASK_SIZE = 0x303E,
EGL_COLOR_BUFFER_TYPE = 0x303F,
EGL_RENDERABLE_TYPE = 0x3040,
EGL_MATCH_NATIVE_PIXMAP = 0x3041, // Pseudo-attribute (not queryable)
EGL_CONFORMANT = 0x3042;
/** Reserved =0x3041;-=0x304F; for additional config attributes */
/** Config attribute values */
public static final int
EGL_SLOW_CONFIG = 0x3050, // EGL_CONFIG_CAVEAT value
EGL_NON_CONFORMANT_CONFIG = 0x3051, // EGL_CONFIG_CAVEAT value
EGL_TRANSPARENT_RGB = 0x3052, // EGL_TRANSPARENT_TYPE value
EGL_RGB_BUFFER = 0x308E, // EGL_COLOR_BUFFER_TYPE value
EGL_LUMINANCE_BUFFER = 0x308F; // EGL_COLOR_BUFFER_TYPE value
/** More config attribute values, for EGL_TEXTURE_FORMAT */
public static final int
EGL_NO_TEXTURE = 0x305C,
EGL_TEXTURE_RGB = 0x305D,
EGL_TEXTURE_RGBA = 0x305E,
EGL_TEXTURE_2D = 0x305F;
/** EGL_SURFACE_TYPE mask bits */
public static final int
EGL_PBUFFER_BIT = 0x0001,
EGL_PIXMAP_BIT = 0x0002,
EGL_WINDOW_BIT = 0x0004,
EGL_VG_COLORSPACE_LINEAR_BIT = 0x0020,
EGL_VG_ALPHA_FORMAT_PRE_BIT = 0x0040,
EGL_MULTISAMPLE_RESOLVE_BOX_BIT = 0x0200,
EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400;
/** EGL_RENDERABLE_TYPE mask bits */
public static final int
EGL_OPENGL_ES_BIT = 0x0001,
EGL_OPENVG_BIT = 0x0002,
EGL_OPENGL_ES2_BIT = 0x0004,
EGL_OPENGL_BIT = 0x0008;
/** QueryString targets */
public static final int
EGL_VENDOR = 0x3053,
EGL_VERSION = 0x3054,
EGL_EXTENSIONS = 0x3055,
EGL_CLIENT_APIS = 0x308D;
/** QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
public static final int
EGL_HEIGHT = 0x3056,
EGL_WIDTH = 0x3057,
EGL_LARGEST_PBUFFER = 0x3058,
EGL_TEXTURE_FORMAT = 0x3080,
EGL_TEXTURE_TARGET = 0x3081,
EGL_MIPMAP_TEXTURE = 0x3082,
EGL_MIPMAP_LEVEL = 0x3083,
EGL_RENDER_BUFFER = 0x3086,
EGL_VG_COLORSPACE = 0x3087,
EGL_VG_ALPHA_FORMAT = 0x3088,
EGL_HORIZONTAL_RESOLUTION = 0x3090,
EGL_VERTICAL_RESOLUTION = 0x3091,
EGL_PIXEL_ASPECT_RATIO = 0x3092,
EGL_SWAP_BEHAVIOR = 0x3093,
EGL_MULTISAMPLE_RESOLVE = 0x3099;
/** EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
public static final int
EGL_BACK_BUFFER = 0x3084,
EGL_SINGLE_BUFFER = 0x3085;
/** OpenVG color spaces */
public static final int
EGL_VG_COLORSPACE_sRGB = 0x3089, // EGL_VG_COLORSPACE value
EGL_VG_COLORSPACE_LINEAR = 0x308A; // EGL_VG_COLORSPACE value
/** OpenVG alpha formats */
public static final int
EGL_VG_ALPHA_FORMAT_NONPRE = 0x308B, // EGL_ALPHA_FORMAT value
EGL_VG_ALPHA_FORMAT_PRE = 0x308C; // EGL_ALPHA_FORMAT
/**
* Constant scale factor by which fractional display resolutions &
* aspect ratio are scaled when queried as integer values.
*/
public static final int EGL_DISPLAY_SCALING = 10000;
/** Unknown display resolution/aspect ratio */
public static final int EGL_UNKNOWN = -1;
/** Back buffer swap behaviors */
public static final int
EGL_BUFFER_PRESERVED = 0x3094, // EGL_SWAP_BEHAVIOR value
EGL_BUFFER_DESTROYED = 0x3095; // EGL_SWAP_BEHAVIOR value
/** CreatePbufferFromClientBuffer buffer types */
static final int EGL_OPENVG_IMAGE = 0x3096;
/** QueryContext targets */
public static final int EGL_CONTEXT_CLIENT_TYPE = 0x3097;
/** CreateContext attributes */
public static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
/** Multisample resolution behaviors */
public static final int
EGL_MULTISAMPLE_RESOLVE_DEFAULT = 0x309A, // EGL_MULTISAMPLE_RESOLVE value
EGL_MULTISAMPLE_RESOLVE_BOX = 0x309B; // EGL_MULTISAMPLE_RESOLVE value
/** BindAPI/QueryAPI targets */
public static final int
EGL_OPENGL_ES_API = 0x30A0,
EGL_OPENVG_API = 0x30A1,
EGL_OPENGL_API = 0x30A2;
/** GetCurrentSurface targets */
public static final int
EGL_DRAW = 0x3059,
EGL_READ = 0x305A;
/** WaitNative engines */
static final int EGL_CORE_NATIVE_ENGINE = 0x305B;
private EGL() {
}
public static native int eglGetError();
/**
* Obtains an EGL display from the specified native display and initializes it.
*
* @param display_id the handle to the native display.
*
* @return the EGL Display
*
* @throws org.lwjgl.LWJGLException if no display is available or an EGL error occurs
*/
public static EGLDisplay eglGetDisplay(long display_id) throws LWJGLException {
//LWJGLUtil.log("eglGetDisplay");
final long pointer = neglGetDisplay(display_id);
if ( pointer == EGL_NO_DISPLAY ) // No error is generated when this happens
throw new LWJGLException("Failed to get EGL display from native display handle: " + display_id);
return new EGLDisplay(pointer);
}
private static native long neglGetDisplay(long display_id);
/**
* Initializes the specified EGL display.
*
* @param dpy the EGL display to initialize
* @param version the EGL major and minor version will be returned in this buffer.
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static void eglInitialize(EGLDisplay dpy, IntBuffer version) throws LWJGLException {
//LWJGLUtil.log("eglInitialize");
BufferChecks.checkBuffer(version, 2);
if ( !neglInitialize(dpy.getPointer(), MemoryUtil.getAddress(version)) )
throwEGLError("Failed to initialize EGL display.");
}
private static native boolean neglInitialize(long dpy_ptr, long version);
/**
* Release the resources associated with the specified EGL display.
*
* @param dpy the EGL display to terminate
*/
static void eglTerminate(EGLDisplay dpy) throws LWJGLException {
//LWJGLUtil.log("eglTerminate");
if ( !neglTerminate(dpy.getPointer()) )
throwEGLError("Failed to terminate EGL display.");
}
private static native boolean neglTerminate(long dpy_ptr);
/**
* Returns a string describing some aspect of the EGL implementation running on the specified display.
*
* @param dpy the EGL display to query
* @param name the value to query
*
* @return the description
*/
public static String eglQueryString(EGLDisplay dpy, int name) {
//LWJGLUtil.log("eglQueryString");
return neglQueryString(dpy.getPointer(), name);
}
private static native String neglQueryString(long dpy, int name);
/**
* Returns the number of EGLConfigs that are available on the specified display.
*
* @param dpy the EGLDisplay
*
* @return the number of EGLConfigs available
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
* @see #eglGetConfigs(EGLDisplay, EGLConfig[], IntBuffer)
*/
static int eglGetConfigsNum(EGLDisplay dpy) throws LWJGLException {
//LWJGLUtil.log("eglGetConfigsNum");
IntBuffer num_config = APIUtil.getBufferInt();
if ( !neglGetConfigs(dpy.getPointer(), 0L, 0, MemoryUtil.getAddress0(num_config)) )
throwEGLError("Failed to get EGL configs.");
return num_config.get(0);
}
/**
* Returns the available EGLConfigs on the speficied display. The number of available EGLConfigs
* is returned in the num_config parameter. The configs array may be null. If it is null, a new
* array will be allocated, with size equal to the result of {@link #eglGetConfigsNum(EGLDisplay)} eglGetConfigsNum}.
* If it is not null, no more than {@code configs.length} EGLConfigs will be returned. If the array is bigger
* than the number of available EGLConfigs, the remaining array elements will not be affected.
*
* @param dpy the EGLDisplay
* @param configs the EGLConfigs array
* @param num_config the number of available EGLConfigs returned
*
* @return the available EGLConfigs
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static EGLConfig[] eglGetConfigs(EGLDisplay dpy, EGLConfig[] configs, IntBuffer num_config) throws LWJGLException {
//LWJGLUtil.log("eglGetConfigs");
BufferChecks.checkBuffer(num_config, 1);
if ( configs == null ) {
if ( !neglGetConfigs(dpy.getPointer(), 0L, 0, MemoryUtil.getAddress(num_config)) )
throwEGLError("Failed to get number of available EGL configs.");
configs = new EGLConfig[num_config.get(num_config.position())];
}
final PointerBuffer configs_buffer = APIUtil.getBufferPointer(configs.length);
if ( !neglGetConfigs(dpy.getPointer(), MemoryUtil.getAddress0(configs_buffer), configs.length, MemoryUtil.getAddress(num_config)) )
throwEGLError("Failed to get EGL configs.");
final int config_size = num_config.get(num_config.position());
for ( int i = 0; i < config_size; i++ )
configs[i] = new EGLConfig(dpy, configs_buffer.get(i));
return configs;
}
private static native boolean neglGetConfigs(long dpy_ptr, long configs, int config_size, long num_config);
/**
* Returns the number of EGLConfigs that are available on the specified display and
* match the speficied list of attributes.
*
* @param dpy the EGLDisplay
* @param attrib_list the attribute list (may be null)
*
* @return the number of EGLConfigs available that satisft the attribute list
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
* @see #eglChooseConfig(EGLDisplay, IntBuffer, EGLConfig[], IntBuffer)
*/
static int eglChooseConfigNum(EGLDisplay dpy, IntBuffer attrib_list) throws LWJGLException {
//LWJGLUtil.log("eglChooseConfigNum");
checkAttribList(attrib_list);
IntBuffer num_config = APIUtil.getBufferInt();
if ( !neglChooseConfig(dpy.getPointer(), MemoryUtil.getAddressSafe(attrib_list), 0L, 0, MemoryUtil.getAddress0(num_config)) )
throwEGLError("Failed to get EGL configs.");
return num_config.get(0);
}
/**
* Returns the available EGLConfigs on the speficied display that satisfy the specified list of attributes.
* The number of available EGLConfigs is returned in the num_config parameter. The configs array may be null.
* If it is null, a new array will be allocated, with size equal to the result of {@link #eglGetConfigsNum(EGLDisplay)} eglGetConfigsNum}.
* If it is not null, no more than {@code configs.length} EGLConfigs will be returned. If the array is bigger
* than the number of available EGLConfigs, the remaining array elements will not be affected.
*
* @param dpy the EGLDisplay
* @param attrib_list the attribute list (may be null)
* @param configs the EGLConfigs array
* @param num_config the number of available EGLConfigs returned
*
* @return the available EGLConfigs that satisfy the attribute list
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static EGLConfig[] eglChooseConfig(EGLDisplay dpy, IntBuffer attrib_list, EGLConfig[] configs, IntBuffer num_config) throws LWJGLException {
//LWJGLUtil.log("eglChooseConfig");
checkAttribList(attrib_list);
BufferChecks.checkBuffer(num_config, 1);
int config_size;
if ( configs == null ) {
if ( !neglChooseConfig(dpy.getPointer(), MemoryUtil.getAddressSafe(attrib_list), 0L, 0, MemoryUtil.getAddress(num_config)) )
throwEGLError("Failed to get number of available EGL configs.");
config_size = num_config.get(num_config.position());
} else
config_size = configs.length;
//LWJGLUtil.log("config_size = " + config_size);
PointerBuffer configs_buffer = APIUtil.getBufferPointer(config_size);
if ( !neglChooseConfig(dpy.getPointer(), MemoryUtil.getAddressSafe(attrib_list), MemoryUtil.getAddress0(configs_buffer), config_size, MemoryUtil.getAddress(num_config)) )
throwEGLError("Failed to choose EGL config.");
// Get the true number of configurations (the first neglChooseConfig call may return more than the second)
config_size = num_config.get(num_config.position());
if ( configs == null )
configs = new EGLConfig[config_size];
for ( int i = 0; i < config_size; i++ )
configs[i] = new EGLConfig(dpy, configs_buffer.get(i));
return configs;
}
private static native boolean neglChooseConfig(long dpy_ptr, long attrib_list, long configs, int config_size, long num_config);
/**
* Returns the value of an EGL config attribute.
*
* @param dpy the EGL display
* @param config the EGL config
* @param attribute the attribute
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static int eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, int attribute) throws LWJGLException {
//LWJGLUtil.log("eglGetConfigAttrib");
final IntBuffer value = APIUtil.getBufferInt();
if ( !neglGetConfigAttrib(dpy.getPointer(), config.getPointer(), attribute, MemoryUtil.getAddress(value)) )
throwEGLError("Failed to get EGL config attribute.");
return value.get(0);
}
private static native boolean neglGetConfigAttrib(long dpy_ptr, long config_ptr, int attribute, long value);
/**
* Creates an on-screen rendering surface on the specified EGL display.
*
* @param dpy the EGL display
* @param config the EGL config
* @param win the native window handle
* @param attrib_list an attribute list (may be null)
*
* @return the created EGL surface
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, long win, IntBuffer attrib_list) throws LWJGLException {
//LWJGLUtil.log("eglCreateWindowSurface");
checkAttribList(attrib_list);
final long pointer = neglCreateWindowSurface(dpy.getPointer(), config.getPointer(), win, MemoryUtil.getAddressSafe(attrib_list));
if ( pointer == EGL_NO_SURFACE )
throwEGLError("Failed to create EGL window surface.");
return new EGLSurface(dpy, config, pointer);
}
private static native long neglCreateWindowSurface(long dpy_ptr, long config_ptr, long win, long attrib_list);
/**
* Creates an off-screen rendering surface on the specified EGL display.
*
* @param dpy the EGL display
* @param config the EGL config
* @param attrib_list an attribute list (may be null)
*
* @return the created EGL surface
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, IntBuffer attrib_list) throws LWJGLException {
//LWJGLUtil.log("eglCreatePbufferSurface");
checkAttribList(attrib_list);
final long pointer = neglCreatePbufferSurface(dpy.getPointer(), config.getPointer(), MemoryUtil.getAddressSafe(attrib_list));
if ( pointer == EGL_NO_SURFACE )
throwEGLError("Failed to create EGL pbuffer surface.");
return new EGLSurface(dpy, config, pointer);
}
private static native long neglCreatePbufferSurface(long dpy_ptr, long config_ptr, long attrib_list);
/*
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
*/
/**
* Sets the specified EGL surface attribute to the specified value.
*
* @param dpy the EGL display
* @param surface the EGL surface
* @param attribute the attribute
* @param value the attribute value
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static void eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, int attribute, int value) throws LWJGLException {
//LWJGLUtil.log("eglSurfaceAttrib");
if ( !neglSurfaceAttrib(dpy.getPointer(), surface.getPointer(), attribute, value) )
throwEGLError("Failed to set surface attribute.");
}
private static native boolean neglSurfaceAttrib(long dpy_ptr, long surface_ptr, int attribute, int value);
/**
* Destroys the specified EGL surface.
*
* @param dpy the EGL display
* @param surface the EGL surface to destroy
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static void eglDestroySurface(EGLDisplay dpy, EGLSurface surface) throws LWJGLException {
//LWJGLUtil.log("eglDestroySurface");
if ( !neglDestroySurface(dpy.getPointer(), surface.getPointer()) )
throwEGLError("Failed to destroy EGL surface.");
}
private static native boolean neglDestroySurface(long dpy_ptr, long surface_ptr);
/**
* Returns the value of the specified EGL surface attribute in the value parameter.
*
* @param dpy the EGL display
* @param surface the EGL surface
* @param attribute the surface attribute
* @param value the attribute value will be returned here
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
public static void eglQuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, IntBuffer value) throws LWJGLException {
//LWJGLUtil.log("eglQuerySurface");
BufferChecks.checkBuffer(value, 1);
if ( !neglQuerySurface(dpy.getPointer(), surface.getPointer(), attribute, MemoryUtil.getAddress(value)) )
throwEGLError("Failed to query surface attribute.");
}
private static native boolean neglQuerySurface(long dpy_ptr, long surface_ptr, int attribute, long value);
/**
* Binds the specified rendering API to the current thread.
*
* @param api the API to bind
*
* @return true if the bind was successful, false if an EGL error occurs
*/
public static native boolean eglBindAPI(int api);
/**
* Returns the current rendering API.
*
* @return the rendering API bound to the current thread
*/
public static native int eglQueryAPI();
/**
* Returns EGL to its state at thread initialization. This includes the following:<br>
* <p>
* For each client API supported by EGL, if there is a currently bound context,
* that context is released. This is equivalent to calling eglMakeCurrent
* with ctx set to EGL_NO_CONTEXT and both draw and read set to EGL_NO_SURFACE
* </p><br>
* <p>The current rendering API is reset to its value at thread initialization</p><br>
* <p>Any additional implementation-dependent per-thread state maintained by EGL
* is marked for deletion as soon as possible.</p>
*
* @return true if thread state was released successfully, false is an EGL error occurs
*/
static native boolean eglReleaseThread();
/*
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
*/
/**
* Specifies the minimum number of video frame periods per buffer swap for
* the window associated with the current context.
*
* @param dpy the EGL display
* @param interval the frame interval
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static void eglSwapInterval(EGLDisplay dpy, int interval) throws LWJGLException {
//LWJGLUtil.log("eglSwapInterval");
if ( !neglSwapInterval(dpy.getPointer(), interval) )
throwEGLError("Failed to set swap interval.");
}
private static native boolean neglSwapInterval(long dpy_ptr, int interval);
/**
* Creates a new EGL context for the current rendering API.
*
* @param dpy the EGL display
* @param config the EGL config
* @param share_context the EGL context to share data with
* @param attrib_list the attribute list (may be null)
*
* @return the created EGL context
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, IntBuffer attrib_list) throws LWJGLException {
//LWJGLUtil.log("eglCreateContext");
checkAttribList(attrib_list);
final long pointer = neglCreateContext(dpy.getPointer(), config.getPointer(),
share_context == null ? EGL_NO_CONTEXT : share_context.getPointer(),
MemoryUtil.getAddressSafe(attrib_list));
if ( pointer == EGL_NO_CONTEXT )
throwEGLError("Failed to create EGL context.");
return new EGLContext(dpy, config, pointer);
}
private static native long neglCreateContext(long dpy_ptr, long config_ptr, long share_context_ptr, long attrib_list);
/**
* Destroys a rendering context.
*
* @param dpy the EGL display
* @param ctx the EGL context
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
static void eglDestroyContext(EGLDisplay dpy, EGLContext ctx) throws LWJGLException {
//LWJGLUtil.log("eglDestroyContext");
if ( !neglDestroyContext(dpy.getPointer(), ctx.getPointer()) )
throwEGLError("Failed to destroy context.");
}
private static native boolean neglDestroyContext(long dpy_ptr, long ctx_ptr);
/**
* Binds the specified context to the current thread and to the draw and read surfaces.
*
* @param dpy the EGL display
* @param draw the draw EGL surface
* @param read the read EGL surface
* @param ctx the EGL context to make current
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
* @throws PowerManagementEventException if an EGL power management event occurs
*/
static void eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) throws LWJGLException, PowerManagementEventException {
//LWJGLUtil.log("eglMakeCurrent");
if ( !neglMakeCurrent(dpy.getPointer(),
draw == null ? EGL_NO_SURFACE : draw.getPointer(),
read == null ? EGL_NO_SURFACE : read.getPointer(),
ctx == null ? EGL_NO_CONTEXT : ctx.getPointer()) ) {
final int error = eglGetError();
if ( error == EGL_CONTEXT_LOST )
throw new PowerManagementEventException();
else
throwEGLError("Failed to change the current context.", error);
}
}
/**
* Releases the current context without assigning a new one.
*
* @param dpy the EGL display
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
* @throws PowerManagementEventException if an EGL power management event occurs
* @see #eglMakeCurrent(EGLDisplay, EGLSurface, EGLSurface, EGLContext)
*/
public static void eglReleaseCurrent(EGLDisplay dpy) throws LWJGLException, PowerManagementEventException {
//LWJGLUtil.log("eglReleaseCurrent");
eglMakeCurrent(dpy, null, null, null);
}
private static native boolean neglMakeCurrent(long dpy_ptr, long draw_ptr, long read_ptr, long ctx_ptr);
/**
* Returns the current EGL context for the current rendering API.
* If there is no context current, null is returned.
*
* @return the current context
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
public static EGLContext eglGetCurrentContext() throws LWJGLException {
//LWJGLUtil.log("eglGetCurrentContext");
// Get current context
final long ctx = neglGetCurrentContext();
if ( ctx == EGL_NO_CONTEXT )
return null;
// Get current display
final EGLDisplay display = eglGetCurrentDisplay();
// Query context's CONFIG_ID
final IntBuffer attrib_list = APIUtil.getBufferInt();
neglQueryContext(display.getPointer(), ctx, EGL_CONFIG_ID, MemoryUtil.getAddress0(attrib_list));
final EGLConfig config = getEGLConfig(display, attrib_list);
// Create the context handle
return new EGLContext(display, config, ctx);
}
/**
* Returns true if the specified EGL context is the current context.
* This method is faster than using {@code #eglGetCurrentContext}
* and comparing the two EGLContext objects.
*
* @param context the EGL context
*
* @return true if the EGL context is current
*
* @see #eglGetCurrentContext()
*/
public static boolean eglIsCurrentContext(EGLContext context) {
//LWJGLUtil.log("eglIsCurrentContext");
return neglGetCurrentContext() == context.getPointer();
}
private static native long neglGetCurrentContext();
/**
* Returns the EGL surfaces used for rendering by the current context.
* If there is no context current, null is returned.
*
* @param readdraw the read or draw surface
*
* @return the current surface
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
public static EGLSurface eglGetCurrentSurface(int readdraw) throws LWJGLException {
//LWJGLUtil.log("eglGetCurrentSurface");
final long surface = neglGetCurrentSurface(readdraw);
if ( surface == EGL_NO_SURFACE )
return null;
// Get current display
EGLDisplay display = eglGetCurrentDisplay();
// Query context's CONFIG_ID
final IntBuffer attrib_list = APIUtil.getBufferInt();
if ( !neglQuerySurface(display.getPointer(), surface, EGL_CONFIG_ID, MemoryUtil.getAddress0(attrib_list)) )
throwEGLError("Failed to query surface EGL config ID.");
final EGLConfig config = getEGLConfig(display, attrib_list);
// Create the surface handle
return new EGLSurface(display, config, surface);
}
private static native long neglGetCurrentSurface(int readdraw);
/**
* Returns the EGL display associated with the current context.
*
* @return the current display
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
public static EGLDisplay eglGetCurrentDisplay() throws LWJGLException {
//LWJGLUtil.log("eglGetCurrentDisplay");
return new EGLDisplay(neglGetCurrentDisplay());
}
private static native long neglGetCurrentDisplay();
/**
* Returns the value of the specified EGL context attribute in the value parameter.
*
* @param dpy the EGL display
* @param ctx the EGL context
* @param attribute the context attribute
* @param value the attribute value will be returned here
*
* @throws org.lwjgl.LWJGLException if an EGL error occurs
*/
public static void eglQueryContext(EGLDisplay dpy, EGLContext ctx, int attribute, IntBuffer value) throws LWJGLException {
//LWJGLUtil.log("eglQueryContext");
BufferChecks.checkBuffer(value, 1);
if ( !neglQueryContext(dpy.getPointer(), ctx.getPointer(), attribute, MemoryUtil.getAddress(value)) )
throwEGLError("Failed to query context attribute.");
}
private static native boolean neglQueryContext(long dpy_ptr, long ctx_ptr, int attribute, long value);
/**
* Prevents native rendering API functions from executing until any
* outstanding client API rendering affecting the same surface is complete.
*
* @return true if the wait was successful, false is an EGL error occurs
*/
public static native boolean eglWaitClient();
/**
* This method does the equivalent of:<br>
* <code>
* EGLenum api = eglQueryAPI();
* eglBindAPI(EGL_OPENGL_ES_API);
* eglWaitClient();
* eglBindAPI(api);
* </code>
*
* @return true if the wait was successful, false if an EGL error occurs
*/
public static native boolean eglWaitGL();
/**
* Prevents a client API command sequence from executing until any outstanding
* native rendering affecting the same surface is complete.
*
* @param engine the native rendering engine
*
* @return true if the wait was successful, false if an EGL error occurs
*/
public static native boolean eglWaitNative(int engine);
/**
* Posts the color buffer to the window.
*
* @param dpy the EGL display
* @param surface the EGL back-buffered window surface
*
* @throws org.lwjgl.LWJGLException if an EGL occurs
* @throws PowerManagementEventException if an EGL power management event occurs
*/
static void eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) throws LWJGLException, PowerManagementEventException {
//LWJGLUtil.log("eglSwapBuffers");
if ( !neglSwapBuffers(dpy.getPointer(), surface.getPointer()) ) {
final int error = eglGetError();
if ( error == EGL_CONTEXT_LOST )
throw new PowerManagementEventException();
else
throwEGLError("Failed to swap buffers.", error);
}
}
private static native boolean neglSwapBuffers(long dpy_ptr, long surface_ptr);
//EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
/* --------------------------------
HELPER METHODS
-------------------------------- */
static void checkAttribList(IntBuffer attrib_list) {
if ( attrib_list == null )
return;
//BufferChecks.checkDirect(attrib_list);
if ( attrib_list.remaining() % 2 != 1 )
throw new IllegalArgumentException("Invalid number of values in attribute list.");
if ( attrib_list.get(attrib_list.limit() - 1) != EGL_NONE )
throw new IllegalArgumentException("The attribute list is not terminated with EGL_NONE.");
}
private static EGLConfig getEGLConfig(final EGLDisplay dpy, final IntBuffer attrib_list) throws LWJGLException {
final int configID = attrib_list.get(0);
// -- This fails on the emulator
// Get EGL config used by the context
attrib_list.put(0, EGL_CONFIG_ID).put(1, configID).put(2, EGL_NONE);
final PointerBuffer configs_buffer = APIUtil.getBufferPointer(1);
if ( !neglChooseConfig(dpy.getPointer(), MemoryUtil.getAddress(attrib_list), MemoryUtil.getAddress0(configs_buffer), 1, MemoryUtil.getAddress(attrib_list, 3)) )
throwEGLError("Failed to choose EGL config.");
return new EGLConfig(dpy, configs_buffer.get(0));
// -- Emulator workaround
/*
EGLConfig config = null;
final EGLConfig[] configs = eglGetConfigs(dpy, null, attrib_list);
final int config_size = attrib_list.get(0);
for ( int i = 0; i < config_size; i++ ) {
if ( configs[i].getConfigID() == configID ) {
config = configs[i];
break;
}
}
if ( config == null )
throwEGLError("Failed to retrieve EGL config for current context.");
return config;
//*/
}
static void throwEGLError(final String msg) throws LWJGLException {
throwEGLError(msg, eglGetError());
}
static void throwEGLError(String msg, final int error) throws LWJGLException {
if ( error != EGL_SUCCESS )
msg += " EGL error: " + Util.translateEGLErrorString(error);
throw new LWJGLException(msg);
}
}