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_MacGLContext.h" 35 36 extern void printAndReleaseResources(jlong pf, jlong ctx, const char *message); 37 38 /* 39 * Class: com_sun_prism_es2_MacGLContext 40 * Method: nInitialize 41 * Signature: (JJJ)J 42 */ 43 JNIEXPORT jlong JNICALL Java_com_sun_prism_es2_MacGLContext_nInitialize 44 (JNIEnv *env, jclass class, jlong nativeDInfo, jlong nativePFInfo, 45 jlong nativeShareCtxHandle, jboolean vSyncRequested) { 46 const char *glVersion; 47 const char *glVendor; 48 const char *glRenderer; 49 char *tmpVersionStr; 50 int versionNumbers[2]; 51 const char *glExtensions; 52 53 jlong pixelFormat = 0; 54 jlong win = 0; 55 jlong context = 0; 56 int viewNotReady; 57 jboolean result; 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 66 pixelFormat = pfInfo->pixelFormat; 67 win = dInfo->win; 68 69 context = (jlong) (intptr_t) createContext((void *) (intptr_t) nativeShareCtxHandle, 70 (void *) (intptr_t) win, 71 (void *) (intptr_t) pixelFormat, &viewNotReady); 72 73 if (context == 0) { 74 fprintf(stderr, "Fail in createContext"); 75 return 0; 76 } 77 78 result = makeCurrentContext((void *) (intptr_t) context); 79 if (!result) { 80 printAndReleaseResources(0, context, 81 "Fail in makeCurrentContext"); 82 return 0; 83 } 84 85 /* Get the OpenGL version */ 86 glVersion = (char *) glGetString(GL_VERSION); 87 if (glVersion == NULL) { 88 printAndReleaseResources(0, context, "glVersion == null"); 89 return 0; 90 } 91 92 /* find out the version, major and minor version number */ 93 tmpVersionStr = strdup(glVersion); 94 extractVersionInfo(tmpVersionStr, versionNumbers); 95 free(tmpVersionStr); 96 97 /* 98 fprintf(stderr, "GL_VERSION string = %s\n", glVersion); 99 fprintf(stderr, "GL_VERSION (major.minor) = %d.%d\n", 100 versionNumbers[0], versionNumbers[1]); 101 */ 102 103 /* 104 * Supported Cards: Intel HD Graphics, Intel HD Graphics 2000/3000, 105 * Radeon HD 2350, GeForce FX (with newer drivers), GeForce 6 series or higher 106 * 107 * Check for OpenGL 2.0 or later. 108 */ 109 if (versionNumbers[0] < 2) { 110 printAndReleaseResources(0, context, NULL); 111 fprintf(stderr, "Prism-ES2 Error : GL_VERSION (major.minor) = %d.%d\n", 112 versionNumbers[0], versionNumbers[1]); 113 return 0; 114 } 115 116 /* Get the OpenGL vendor and renderer */ 117 glVendor = (const char *) glGetString(GL_VENDOR); 118 if (glVendor == NULL) { 119 glVendor = "<UNKNOWN>"; 120 } 121 glRenderer = (const char *) glGetString(GL_RENDERER); 122 if (glRenderer == NULL) { 123 glRenderer = "<UNKNOWN>"; 124 } 125 126 glExtensions = (const char *) glGetString(GL_EXTENSIONS); 127 if (glExtensions == NULL) { 128 printAndReleaseResources(0, context, "glExtensions == null"); 129 return 0; 130 } 131 132 // We use GL 2.0 and GL_ARB_pixel_buffer_object as an guide to 133 // determine PS 3.0 capable. 134 if (!isExtensionSupported(glExtensions, "GL_ARB_pixel_buffer_object")) { 135 printAndReleaseResources(0, context, "GL profile isn't PS 3.0 capable"); 136 return 0; 137 } 138 139 /* allocate the structure */ 140 ctxInfo = (ContextInfo *) malloc(sizeof (ContextInfo)); 141 if (ctxInfo == NULL) { 142 fprintf(stderr, "nInitialize: Failed in malloc\n"); 143 return 0; 144 } 145 146 /* initialize the structure */ 147 initializeCtxInfo(ctxInfo); 148 ctxInfo->versionStr = strdup(glVersion); 149 ctxInfo->vendorStr = strdup(glVendor); 150 ctxInfo->rendererStr = strdup(glRenderer); 151 ctxInfo->glExtensionStr = strdup(glExtensions); 152 ctxInfo->versionNumbers[0] = versionNumbers[0]; 153 ctxInfo->versionNumbers[1] = versionNumbers[1]; 154 ctxInfo->context = context; 155 156 /* set function pointers */ 157 ctxInfo->glActiveTexture = (PFNGLACTIVETEXTUREPROC) 158 getProcAddress("glActiveTexture"); 159 ctxInfo->glAttachShader = (PFNGLATTACHSHADERPROC) 160 getProcAddress("glAttachShader"); 161 ctxInfo->glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) 162 getProcAddress("glBindAttribLocation"); 163 ctxInfo->glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) 164 getProcAddress("glBindFramebuffer"); 165 ctxInfo->glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) 166 getProcAddress("glBindRenderbuffer"); 167 ctxInfo->glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) 168 getProcAddress("glCheckFramebufferStatus"); 169 ctxInfo->glCreateProgram = (PFNGLCREATEPROGRAMPROC) 170 getProcAddress("glCreateProgram"); 171 ctxInfo->glCreateShader = (PFNGLCREATESHADERPROC) 172 getProcAddress("glCreateShader"); 173 ctxInfo->glCompileShader = (PFNGLCOMPILESHADERPROC) 174 getProcAddress("glCompileShader"); 175 ctxInfo->glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) 176 getProcAddress("glDeleteBuffers"); 177 ctxInfo->glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) 178 getProcAddress("glDeleteFramebuffers"); 179 ctxInfo->glDeleteProgram = (PFNGLDELETEPROGRAMPROC) 180 getProcAddress("glDeleteProgram"); 181 ctxInfo->glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) 182 getProcAddress("glDeleteRenderbuffers"); 183 ctxInfo->glDeleteShader = (PFNGLDELETESHADERPROC) 184 getProcAddress("glDeleteShader"); 185 ctxInfo->glDetachShader = (PFNGLDETACHSHADERPROC) 186 getProcAddress("glDetachShader"); 187 ctxInfo->glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) 188 getProcAddress("glDisableVertexAttribArray"); 189 ctxInfo->glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) 190 getProcAddress("glEnableVertexAttribArray"); 191 ctxInfo->glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) 192 getProcAddress("glFramebufferRenderbuffer"); 193 ctxInfo->glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) 194 getProcAddress("glFramebufferTexture2D"); 195 ctxInfo->glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) 196 getProcAddress("glGenFramebuffers"); 197 ctxInfo->glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) 198 getProcAddress("glGenRenderbuffers"); 199 ctxInfo->glGetProgramiv = (PFNGLGETPROGRAMIVPROC) 200 getProcAddress("glGetProgramiv"); 201 ctxInfo->glGetShaderiv = (PFNGLGETSHADERIVPROC) 202 getProcAddress("glGetShaderiv"); 203 ctxInfo->glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) 204 getProcAddress("glGetUniformLocation"); 205 ctxInfo->glLinkProgram = (PFNGLLINKPROGRAMPROC) 206 getProcAddress("glLinkProgram"); 207 ctxInfo->glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) 208 getProcAddress("glRenderbufferStorage"); 209 ctxInfo->glShaderSource = (PFNGLSHADERSOURCEPROC) 210 getProcAddress("glShaderSource"); 211 ctxInfo->glUniform1f = (PFNGLUNIFORM1FPROC) 212 getProcAddress("glUniform1f"); 213 ctxInfo->glUniform2f = (PFNGLUNIFORM2FPROC) 214 getProcAddress("glUniform2f"); 215 ctxInfo->glUniform3f = (PFNGLUNIFORM3FPROC) 216 getProcAddress("glUniform3f"); 217 ctxInfo->glUniform4f = (PFNGLUNIFORM4FPROC) 218 getProcAddress("glUniform4f"); 219 ctxInfo->glUniform4fv = (PFNGLUNIFORM4FVPROC) 220 getProcAddress("glUniform4fv"); 221 ctxInfo->glUniform1i = (PFNGLUNIFORM1IPROC) 222 getProcAddress("glUniform1i"); 223 ctxInfo->glUniform2i = (PFNGLUNIFORM2IPROC) 224 getProcAddress("glUniform2i"); 225 ctxInfo->glUniform3i = (PFNGLUNIFORM3IPROC) 226 getProcAddress("glUniform3i"); 227 ctxInfo->glUniform4i = (PFNGLUNIFORM4IPROC) 228 getProcAddress("glUniform4i"); 229 ctxInfo->glUniform4iv = (PFNGLUNIFORM4IVPROC) 230 getProcAddress("glUniform4iv"); 231 ctxInfo->glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) 232 getProcAddress("glUniformMatrix4fv"); 233 ctxInfo->glUseProgram = (PFNGLUSEPROGRAMPROC) 234 getProcAddress("glUseProgram"); 235 ctxInfo->glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) 236 getProcAddress("glValidateProgram"); 237 ctxInfo->glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) 238 getProcAddress("glVertexAttribPointer"); 239 ctxInfo->glGenBuffers = (PFNGLGENBUFFERSPROC) 240 getProcAddress("glGenBuffers"); 241 ctxInfo->glBindBuffer = (PFNGLBINDBUFFERPROC) 242 getProcAddress("glBindBuffer"); 243 ctxInfo->glBufferData = (PFNGLBUFFERDATAPROC) 244 getProcAddress("glBufferData"); 245 ctxInfo->glBufferSubData = (PFNGLBUFFERSUBDATAPROC) 246 getProcAddress("glBufferSubData"); 247 ctxInfo->glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) 248 getProcAddress("glGetShaderInfoLog"); 249 ctxInfo->glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) 250 getProcAddress("glGetProgramInfoLog"); 251 ctxInfo->glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) 252 getProcAddress("glTexImage2DMultisample"); 253 ctxInfo->glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) 254 getProcAddress("glRenderbufferStorageMultisample"); 255 ctxInfo->glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) 256 getProcAddress("glBlitFramebuffer"); 257 258 // initialize platform states and properties to match 259 // cached states and properties 260 setSwapInterval((void *) jlong_to_ptr(ctxInfo->context), 0); 261 ctxInfo->state.vSyncEnabled = JNI_FALSE; 262 ctxInfo->vSyncRequested = vSyncRequested; 263 264 initState(ctxInfo); 265 266 // Release context once we are all done 267 makeCurrentContext(NULL); 268 269 return ptr_to_jlong(ctxInfo); 270 } 271 272 /* 273 * Class: com_sun_prism_es2_MacGLContext 274 * Method: nGetNativeHandle 275 * Signature: (J)J 276 */ 277 JNIEXPORT jlong JNICALL Java_com_sun_prism_es2_MacGLContext_nGetNativeHandle 278 (JNIEnv *env, jclass class, jlong nativeCtxInfo) { 279 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 280 if (ctxInfo == NULL) { 281 return 0; 282 } 283 return ctxInfo->context; 284 } 285 286 /* 287 * Class: com_sun_prism_es2_MacGLContext 288 * Method: nMakeCurrent 289 * Signature: (JJ)V 290 */ 291 JNIEXPORT void JNICALL Java_com_sun_prism_es2_MacGLContext_nMakeCurrent 292 (JNIEnv *env, jclass class, jlong nativeCtxInfo, jlong nativeDInfo) { 293 ContextInfo *ctxInfo = (ContextInfo *) jlong_to_ptr(nativeCtxInfo); 294 DrawableInfo *dInfo = (DrawableInfo *) jlong_to_ptr(nativeDInfo); 295 int interval; 296 jboolean vSyncNeeded; 297 298 if ((ctxInfo == NULL) || (dInfo == NULL)) { 299 return; 300 } 301 302 if (!makeCurrentContext((void *) (intptr_t) ctxInfo->context)) { 303 fprintf(stderr, "Failed in makeCurrentContext\n"); 304 } 305 vSyncNeeded = ctxInfo->vSyncRequested && dInfo->onScreen; 306 if (vSyncNeeded == ctxInfo->state.vSyncEnabled) { 307 return; 308 } 309 interval = (vSyncNeeded) ? 1 : 0; 310 ctxInfo->state.vSyncEnabled = vSyncNeeded; 311 setSwapInterval((void *) jlong_to_ptr(ctxInfo->context), interval); 312 }