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