/* * 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); } }