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 }