1 /* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <jni.h> 27 #include <stdlib.h> 28 #include <assert.h> 29 #include <stdio.h> 30 #include <string.h> 31 #include <math.h> 32 33 #include "../PrismES2Defs.h" 34 #include "com_sun_prism_es2_X11GLContext.h" 35 36 /* 37 * Class: com_sun_prism_es2_X11GLContext 38 * Method: nInitialize 39 * Signature: (JJZ)J 40 */ 41 JNIEXPORT jlong JNICALL Java_com_sun_prism_es2_X11GLContext_nInitialize 42 (JNIEnv *env, jclass class, jlong nativeDInfo, jlong nativePFInfo, 43 jboolean vSyncRequested) { 44 const char *glVersion; 45 const char *glVendor; 46 const char *glRenderer; 47 char *tmpVersionStr; 48 int versionNumbers[2]; 49 const char *glExtensions; 50 const char *glxExtensions; 51 52 Window win = None; 53 GLXFBConfig fbConfig = NULL; 54 GLXContext ctx = NULL; 55 XVisualInfo *visualInfo = NULL; 56 int numFBConfigs, index, visualID; 57 Display *display = NULL; 58 ContextInfo *ctxInfo = NULL; 59 DrawableInfo *dInfo = (DrawableInfo *) jlong_to_ptr(nativeDInfo); 60 PixelFormatInfo *pfInfo = (PixelFormatInfo *) jlong_to_ptr(nativePFInfo); 61 62 if ((dInfo == NULL) || (pfInfo == NULL)) { 63 return 0; 64 } 65 display = pfInfo->display; 66 fbConfig = pfInfo->fbConfig; 67 win = dInfo->win; 68 69 ctx = glXCreateNewContext(display, fbConfig, GLX_RGBA_TYPE, NULL, True); 70 71 if (ctx == NULL) { 72 fprintf(stderr, "Failed in glXCreateNewContext"); 73 return 0; 74 } 75 76 if (!glXMakeCurrent(display, win, ctx)) { 77 glXDestroyContext(display, ctx); 78 fprintf(stderr, "Failed in glXMakeCurrent"); 79 return 0; 80 } 81 82 /* Get the OpenGL version */ 83 glVersion = (char *) glGetString(GL_VERSION); 84 if (glVersion == NULL) { 85 glXDestroyContext(display, ctx); 86 fprintf(stderr, "glVersion == null"); 87 return 0; 88 } 89 90 /* find out the version, major and minor version number */ 91 tmpVersionStr = strdup(glVersion); 92 extractVersionInfo(tmpVersionStr, versionNumbers); 93 free(tmpVersionStr); 94 95 /* 96 fprintf(stderr, "GL_VERSION string = %s\n", glVersion); 97 fprintf(stderr, "GL_VERSION (major.minor) = %d.%d\n", 98 versionNumbers[0], versionNumbers[1]); 99 */ 100 101 /* 102 * Targeted Cards: Intel HD Graphics, Intel HD Graphics 2000/3000, 103 * Radeon HD 2350, GeForce FX (with newer drivers), GeForce 7 series or higher 104 * 105 * Check for OpenGL 2.1 or later. 106 */ 107 if ((versionNumbers[0] < 2) || ((versionNumbers[0] == 2) && (versionNumbers[1] < 1))) { 108 glXDestroyContext(display, ctx); 109 fprintf(stderr, "Prism-ES2 Error : GL_VERSION (major.minor) = %d.%d\n", 110 versionNumbers[0], versionNumbers[1]); 111 return 0; 112 } 113 114 /* Get the OpenGL vendor and renderer */ 115 glVendor = (const char *) glGetString(GL_VENDOR); 116 if (glVendor == NULL) { 117 glVendor = "<UNKNOWN>"; 118 } 119 glRenderer = (const char *) glGetString(GL_RENDERER); 120 if (glRenderer == NULL) { 121 glRenderer = "<UNKNOWN>"; 122 } 123 124 glExtensions = (const char *) glGetString(GL_EXTENSIONS); 125 if (glExtensions == NULL) { 126 glXDestroyContext(display, ctx); 127 fprintf(stderr, "glExtensions == null"); 128 return 0; 129 } 130 131 // We use GL_ARB_pixel_buffer_object as an guide to 132 // determine PS 3.0 capable. 133 if (!isExtensionSupported(glExtensions, "GL_ARB_pixel_buffer_object")) { 134 glXDestroyContext(display, ctx); 135 fprintf(stderr, "GL profile isn't PS 3.0 capable"); 136 return 0; 137 } 138 139 glxExtensions = (const char *) glXGetClientString(display, GLX_EXTENSIONS); 140 if (glxExtensions == NULL) { 141 glXDestroyContext(display, ctx); 142 fprintf(stderr, "glxExtensions == null"); 143 return 0; 144 } 145 146 /* 147 fprintf(stderr, "glExtensions: %s\n", glExtensions); 148 fprintf(stderr, "glxExtensions: %s\n", glxExtensions); 149 */ 150 151 /* allocate the structure */ 152 ctxInfo = (ContextInfo *) malloc(sizeof (ContextInfo)); 153 if (ctxInfo == NULL) { 154 fprintf(stderr, "nInitialize: Failed in malloc\n"); 155 return 0; 156 } 157 158 /* initialize the structure */ 159 initializeCtxInfo(ctxInfo); 160 ctxInfo->versionStr = strdup(glVersion); 161 ctxInfo->vendorStr = strdup(glVendor); 162 ctxInfo->rendererStr = strdup(glRenderer); 163 ctxInfo->glExtensionStr = strdup(glExtensions); 164 ctxInfo->glxExtensionStr = strdup(glxExtensions); 165 ctxInfo->versionNumbers[0] = versionNumbers[0]; 166 ctxInfo->versionNumbers[1] = versionNumbers[1]; 167 ctxInfo->display = display; 168 ctxInfo->context = ctx; 169 170 /* set function pointers */ 171 ctxInfo->glActiveTexture = (PFNGLACTIVETEXTUREPROC) 172 dlsym(RTLD_DEFAULT, "glActiveTexture"); 173 ctxInfo->glAttachShader = (PFNGLATTACHSHADERPROC) 174 dlsym(RTLD_DEFAULT, "glAttachShader"); 175 ctxInfo->glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) 176 dlsym(RTLD_DEFAULT, "glBindAttribLocation"); 177 ctxInfo->glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) 178 dlsym(RTLD_DEFAULT, "glBindFramebuffer"); 179 ctxInfo->glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) 180 dlsym(RTLD_DEFAULT, "glBindRenderbuffer"); 181 ctxInfo->glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) 182 dlsym(RTLD_DEFAULT, "glCheckFramebufferStatus"); 183 ctxInfo->glCreateProgram = (PFNGLCREATEPROGRAMPROC) 184 dlsym(RTLD_DEFAULT, "glCreateProgram"); 185 ctxInfo->glCreateShader = (PFNGLCREATESHADERPROC) 186 dlsym(RTLD_DEFAULT, "glCreateShader"); 187 ctxInfo->glCompileShader = (PFNGLCOMPILESHADERPROC) 188 dlsym(RTLD_DEFAULT, "glCompileShader"); 189 ctxInfo->glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) 190 dlsym(RTLD_DEFAULT, "glDeleteBuffers"); 191 ctxInfo->glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) 192 dlsym(RTLD_DEFAULT, "glDeleteFramebuffers"); 193 ctxInfo->glDeleteProgram = (PFNGLDELETEPROGRAMPROC) 194 dlsym(RTLD_DEFAULT, "glDeleteProgram"); 195 ctxInfo->glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) 196 dlsym(RTLD_DEFAULT, "glDeleteRenderbuffers"); 197 ctxInfo->glDeleteShader = (PFNGLDELETESHADERPROC) 198 dlsym(RTLD_DEFAULT, "glDeleteShader"); 199 ctxInfo->glDetachShader = (PFNGLDETACHSHADERPROC) 200 dlsym(RTLD_DEFAULT, "glDetachShader"); 201 ctxInfo->glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) 202 dlsym(RTLD_DEFAULT, "glDisableVertexAttribArray"); 203 ctxInfo->glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) 204 dlsym(RTLD_DEFAULT, "glEnableVertexAttribArray"); 205 ctxInfo->glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) 206 dlsym(RTLD_DEFAULT, "glFramebufferRenderbuffer"); 207 ctxInfo->glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) 208 dlsym(RTLD_DEFAULT, "glFramebufferTexture2D"); 209 ctxInfo->glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) 210 dlsym(RTLD_DEFAULT, "glGenFramebuffers"); 211 ctxInfo->glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) 212 dlsym(RTLD_DEFAULT, "glGenRenderbuffers"); 213 ctxInfo->glGetProgramiv = (PFNGLGETPROGRAMIVPROC) 214 dlsym(RTLD_DEFAULT, "glGetProgramiv"); 215 ctxInfo->glGetShaderiv = (PFNGLGETSHADERIVPROC) 216 dlsym(RTLD_DEFAULT, "glGetShaderiv"); 217 ctxInfo->glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) 218 dlsym(RTLD_DEFAULT, "glGetUniformLocation"); 219 ctxInfo->glLinkProgram = (PFNGLLINKPROGRAMPROC) 220 dlsym(RTLD_DEFAULT, "glLinkProgram"); 221 ctxInfo->glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) 222 dlsym(RTLD_DEFAULT, "glRenderbufferStorage"); 223 ctxInfo->glShaderSource = (PFNGLSHADERSOURCEPROC) 224 dlsym(RTLD_DEFAULT, "glShaderSource"); 225 ctxInfo->glUniform1f = (PFNGLUNIFORM1FPROC) 226 dlsym(RTLD_DEFAULT, "glUniform1f"); 227 ctxInfo->glUniform2f = (PFNGLUNIFORM2FPROC) 228 dlsym(RTLD_DEFAULT, "glUniform2f"); 229 ctxInfo->glUniform3f = (PFNGLUNIFORM3FPROC) 230 dlsym(RTLD_DEFAULT, "glUniform3f"); 231 ctxInfo->glUniform4f = (PFNGLUNIFORM4FPROC) 232 dlsym(RTLD_DEFAULT, "glUniform4f"); 233 ctxInfo->glUniform4fv = (PFNGLUNIFORM4FVPROC) 234 dlsym(RTLD_DEFAULT, "glUniform4fv"); 235 ctxInfo->glUniform1i = (PFNGLUNIFORM1IPROC) 236 dlsym(RTLD_DEFAULT, "glUniform1i"); 237 ctxInfo->glUniform2i = (PFNGLUNIFORM2IPROC) 238 dlsym(RTLD_DEFAULT, "glUniform2i"); 239 ctxInfo->glUniform3i = (PFNGLUNIFORM3IPROC) 240 dlsym(RTLD_DEFAULT, "glUniform3i"); 241 ctxInfo->glUniform4i = (PFNGLUNIFORM4IPROC) 242 dlsym(RTLD_DEFAULT, "glUniform4i"); 243 ctxInfo->glUniform4iv = (PFNGLUNIFORM4IVPROC) 244 dlsym(RTLD_DEFAULT, "glUniform4iv"); 245 ctxInfo->glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) 246 dlsym(RTLD_DEFAULT, "glUniformMatrix4fv"); 247 ctxInfo->glUseProgram = (PFNGLUSEPROGRAMPROC) 248 dlsym(RTLD_DEFAULT, "glUseProgram"); 249 ctxInfo->glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) 250 dlsym(RTLD_DEFAULT, "glValidateProgram"); 251 ctxInfo->glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) 252 dlsym(RTLD_DEFAULT, "glVertexAttribPointer"); 253 ctxInfo->glGenBuffers = (PFNGLGENBUFFERSPROC) 254 dlsym(RTLD_DEFAULT, "glGenBuffers"); 255 ctxInfo->glBindBuffer = (PFNGLBINDBUFFERPROC) 256 dlsym(RTLD_DEFAULT, "glBindBuffer"); 257 ctxInfo->glBufferData = (PFNGLBUFFERDATAPROC) 258 dlsym(RTLD_DEFAULT, "glBufferData"); 259 ctxInfo->glBufferSubData = (PFNGLBUFFERSUBDATAPROC) 260 dlsym(RTLD_DEFAULT, "glBufferSubData"); 261 ctxInfo->glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) 262 dlsym(RTLD_DEFAULT, "glGetShaderInfoLog"); 263 ctxInfo->glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) 264 dlsym(RTLD_DEFAULT,"glTexImage2DMultisample"); 265 ctxInfo->glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) 266 dlsym(RTLD_DEFAULT,"glRenderbufferStorageMultisample"); 267 ctxInfo->glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) 268 dlsym(RTLD_DEFAULT,"glBlitFramebuffer"); 269 270 if (isExtensionSupported(ctxInfo->glxExtensionStr, 271 "GLX_SGI_swap_control")) { 272 ctxInfo->glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) 273 dlsym(RTLD_DEFAULT, "glXSwapIntervalSGI"); 274 275 if (ctxInfo->glXSwapIntervalSGI == NULL) { 276 ctxInfo->glXSwapIntervalSGI = glXGetProcAddress("glXSwapIntervalSGI"); 277 } 278 279 } 280 281 // initialize platform states and properties to match 282 // cached states and properties 283 if (ctxInfo->glXSwapIntervalSGI != NULL) { 284 ctxInfo->glXSwapIntervalSGI(0); 285 } 286 ctxInfo->state.vSyncEnabled = JNI_FALSE; 287 ctxInfo->vSyncRequested = vSyncRequested; 288 289 initState(ctxInfo); 290 291 // Release context once we are all done 292 glXMakeCurrent(display, None, NULL); 293 294 return ptr_to_jlong(ctxInfo); 295 } 296 297 /* 298 * Class: com_sun_prism_es2_X11GLContext 299 * Method: nGetNativeHandle 300 * Signature: (J)J 301 */ 302 JNIEXPORT jlong JNICALL Java_com_sun_prism_es2_X11GLContext_nGetNativeHandle 303 (JNIEnv *env, jclass class, jlong nativeCtxInfo) { 304 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 305 if (ctxInfo == NULL) { 306 return 0; 307 } 308 return ptr_to_jlong(ctxInfo->context); 309 } 310 311 /* 312 * Class: com_sun_prism_es2_X11GLContext 313 * Method: nMakeCurrent 314 * Signature: (JJ)V 315 */ 316 JNIEXPORT void JNICALL Java_com_sun_prism_es2_X11GLContext_nMakeCurrent 317 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeDInfo) { 318 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 319 DrawableInfo *dInfo = (DrawableInfo *) jlong_to_ptr(nativeDInfo); 320 int interval; 321 jboolean vSyncNeeded; 322 323 if (!glXMakeCurrent(ctxInfo->display, dInfo->win, ctxInfo->context)) { 324 fprintf(stderr, "Failed in glXMakeCurrent"); 325 } 326 327 vSyncNeeded = ctxInfo->vSyncRequested && dInfo->onScreen; 328 if (vSyncNeeded == ctxInfo->state.vSyncEnabled) { 329 return; 330 } 331 interval = (vSyncNeeded) ? 1 : 0; 332 ctxInfo->state.vSyncEnabled = vSyncNeeded; 333 if (ctxInfo->glXSwapIntervalSGI != NULL) { 334 ctxInfo->glXSwapIntervalSGI(interval); 335 } 336 }