Example #1
0
/**
 * Disposes all memory and resources allocated for the given OGLContext.
 */
static void
GLXGC_DestroyOGLContext(OGLContext *oglc)
{
    GLXCtxInfo *ctxinfo;

    J2dTraceLn(J2D_TRACE_INFO, "GLXGC_DestroyOGLContext");

    if (oglc == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "GLXGC_DestroyOGLContext: context is null");
        return;
    }

    // at this point, this context will be current to its scratch surface
    // so the following GL/GLX operations should be safe...

    OGLContext_DestroyContextResources(oglc);

    ctxinfo = (GLXCtxInfo *)oglc->ctxInfo;
    if (ctxinfo != NULL) {
        // release the current context before we continue
        j2d_glXMakeContextCurrent(awt_display, None, None, NULL);

        if (ctxinfo->context != 0) {
            j2d_glXDestroyContext(awt_display, ctxinfo->context);
        }
        if (ctxinfo->scratchSurface != 0) {
            j2d_glXDestroyPbuffer(awt_display, ctxinfo->scratchSurface);
        }

        free(ctxinfo);
    }

    free(oglc);
}
/**
 * This function disposes of any native windowing system resources associated
 * with this surface.  For instance, if the given OGLSDOps is of type
 * OGLSD_PBUFFER, this method implementation will destroy the actual pbuffer
 * surface.
 */
void
OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo)
{
    GLXSDOps *glxsdo = (GLXSDOps *)oglsdo->privOps;

    J2dTraceLn(J2D_TRACE_INFO, "OGLSD_DestroyOGLSurface");

    if (oglsdo->drawableType == OGLSD_PBUFFER) {
        if (glxsdo->drawable != 0) {
            j2d_glXDestroyPbuffer(awt_display, glxsdo->drawable);
            glxsdo->drawable = 0;
        }
    } else if (oglsdo->drawableType == OGLSD_WINDOW) {
        // X Window is free'd later by AWT code...
    }
}
Example #3
0
/**
 * This function disposes of any native windowing system resources associated
 * with this surface.  For instance, if the given OGLSDOps is of type
 * OGLSD_PBUFFER, this method implementation will destroy the actual pbuffer
 * surface (with GLX, the glXDestroyPbuffer() method would be invoked).
 * Returns SD_SUCCESS if the operation was successful; SD_FAILURE otherwise.
 */
jint
OGLSD_DisposeOGLSurface(JNIEnv *env, OGLSDOps *oglsdo)
{
    GLXSDOps *glxsdo = (GLXSDOps *)oglsdo->privOps;

    J2dTraceLn(J2D_TRACE_INFO, "in OGLSD_DisposeOGLSurface");

    if (oglsdo->drawableType == OGLSD_PIXMAP) {
        if (glxsdo->drawable != 0) {
            j2d_glXDestroyPixmap(awt_display, glxsdo->drawable);
        }
        if (glxsdo->xdrawable != 0) {
            XFreePixmap(awt_display, glxsdo->xdrawable);
        }
    } else if (oglsdo->drawableType == OGLSD_PBUFFER) {
        if (glxsdo->drawable != 0) {
            j2d_glXDestroyPbuffer(awt_display, glxsdo->drawable);
        }
    } else if (oglsdo->drawableType == OGLSD_WINDOW) {
        // X Window is free'd later by AWT code...
    }

    return SD_SUCCESS;
}
Example #4
0
/**
 * Determines whether the GLX pipeline can be used for a given GraphicsConfig
 * provided its screen number and visual ID.  If the minimum requirements are
 * met, the native GLXGraphicsConfigInfo structure is initialized for this
 * GraphicsConfig with the necessary information (pthread key, GLXFBConfig,
 * etc.) and a pointer to this structure is returned as a jlong.  If
 * initialization fails at any point, zero is returned, indicating that GLX
 * cannot be used for this GraphicsConfig (we should fallback on the existing
 * X11 pipeline).
 */
static jlong
GLXGC_GetGLXConfigInfo(JNIEnv *env, jint screennum, jint visnum)
{
    GLXFBConfig fbconfig;
    GLXContext context;
    GLXPbuffer glxpbuffer;
    int pbattrlist[] = {GLX_PBUFFER_WIDTH, 1,
                        GLX_PBUFFER_HEIGHT, 1,
                        GLX_PRESERVED_CONTENTS, GL_FALSE,
                        0};
    GLXGraphicsConfigInfo *glxinfo;
    int db;
    const unsigned char *versionstr;

    J2dTraceLn(J2D_TRACE_INFO, "in GLXGC_GetGLXConfigInfo");

    fbconfig = GLXGC_InitFBConfig(env, screennum, visnum);
    if (fbconfig == 0) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not create fbconfig");
        return 0;
    }

    glxinfo = (GLXGraphicsConfigInfo *)malloc(sizeof(GLXGraphicsConfigInfo));
    if (glxinfo == NULL) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not allocate memory for glxinfo");
        return 0;
    }

    // create a temporary context, used for querying OpenGL version and
    // extensions
    context = j2d_glXCreateNewContext(awt_display, fbconfig,
                                      GLX_RGBA_TYPE, NULL, GL_TRUE);
    if (context == 0) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not create temp GLX context");
        free(glxinfo);
        return 0;
    }

    // this is pretty sketchy, but it seems to be the easiest way to create
    // some form of GLXDrawable using only the display and a GLXFBConfig
    // (in order to make the context current for checking the version,
    // extensions, etc)...
    glxpbuffer = j2d_glXCreatePbuffer(awt_display, fbconfig, pbattrlist);
    if (glxpbuffer == 0) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not create scratch pbuffer");
        j2d_glXDestroyContext(awt_display, context);
        free(glxinfo);
        return 0;
    }

    // the temporary context must be made current before we can query the
    // version and extension strings
    j2d_glXMakeContextCurrent(awt_display, glxpbuffer, glxpbuffer, context);

    versionstr = j2d_glGetString(GL_VERSION);
    OGLContext_GetExtensionInfo(&glxinfo->extInfo);

    // destroy the temporary resources
    j2d_glXMakeContextCurrent(awt_display, None, None, NULL);
    j2d_glXDestroyPbuffer(awt_display, glxpbuffer);
    j2d_glXDestroyContext(awt_display, context);

    // invalidate the current context
    OGLContext_InvalidateCurrentContext(env);

    J2dTraceLn(J2D_TRACE_VERBOSE, "finished with temporary pbuffer/context");

    J2dTraceLn1(J2D_TRACE_INFO, "OpenGL version: %s", versionstr);
    if (!OGLContext_IsVersionSupported(versionstr)) {
        J2dTraceLn(J2D_TRACE_ERROR, "invalid OpenGL version; 1.2 is required");
        free(glxinfo);
        return 0;
    }

    J2dTraceLn(J2D_TRACE_VERBOSE,
               "successfully finished checking dependencies");

    j2d_glXGetFBConfigAttrib(awt_display, fbconfig, GLX_DOUBLEBUFFER, &db);

    glxinfo->screen = screennum;
    glxinfo->visual = visnum;
    glxinfo->fbconfig = fbconfig;
    glxinfo->isDoubleBuffered = db;

    // create the single shared context (if it hasn't been created already)
    if (sharedContext == NULL) {
        if (GLXGC_InitSharedContext(env, glxinfo) == SD_FAILURE) {
            J2dTraceLn(J2D_TRACE_ERROR, "could not init shared context");
            free(glxinfo);
            return 0;
        }
    }

    return ptr_to_jlong(glxinfo);
}
Example #5
0
/**
 * Determines whether the GLX pipeline can be used for a given GraphicsConfig
 * provided its screen number and visual ID.  If the minimum requirements are
 * met, the native GLXGraphicsConfigInfo structure is initialized for this
 * GraphicsConfig with the necessary information (GLXFBConfig, etc.)
 * and a pointer to this structure is returned as a jlong.  If
 * initialization fails at any point, zero is returned, indicating that GLX
 * cannot be used for this GraphicsConfig (we should fallback on the existing
 * X11 pipeline).
 */
JNIEXPORT jlong JNICALL
Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo(JNIEnv *env,
                                                          jclass glxgc,
                                                          jint screennum,
                                                          jint visnum)
{
#ifndef HEADLESS
    OGLContext *oglc;
    GLXFBConfig fbconfig;
    GLXContext context;
    GLXPbuffer scratch;
    GLXGraphicsConfigInfo *glxinfo;
    jint caps = CAPS_EMPTY;
    int db, alpha;
    const unsigned char *versionstr;

    J2dRlsTraceLn(J2D_TRACE_INFO, "GLXGraphicsConfig_getGLXConfigInfo");

    if (usingXinerama) {
        // when Xinerama is enabled, the screen ID needs to be 0
        screennum = 0;
    }

    fbconfig = GLXGC_InitFBConfig(env, screennum, (VisualID)visnum);
    if (fbconfig == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGraphicsConfig_getGLXConfigInfo: could not create fbconfig");
        return 0L;
    }

    if (sharedContext == 0) {
        // create the one shared context
        sharedContext = j2d_glXCreateNewContext(awt_display, fbconfig,
                                                GLX_RGBA_TYPE, 0, GL_TRUE);
        if (sharedContext == 0) {
            J2dRlsTraceLn(J2D_TRACE_ERROR,
                "GLXGraphicsConfig_getGLXConfigInfo: could not create shared context");
            return 0L;
        }
    }

    // create the GLXContext for this GLXGraphicsConfig
    context = j2d_glXCreateNewContext(awt_display, fbconfig,
                                      GLX_RGBA_TYPE, sharedContext,
                                      GL_TRUE);
    if (context == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGraphicsConfig_getGLXConfigInfo: could not create GLX context");
        return 0L;
    }

    // this is pretty sketchy, but it seems to be the easiest way to create
    // some form of GLXDrawable using only the display and a GLXFBConfig
    // (in order to make the context current for checking the version,
    // extensions, etc)...
    scratch = GLXGC_InitScratchPbuffer(fbconfig);
    if (scratch == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGraphicsConfig_getGLXConfigInfo: could not create scratch pbuffer");
        j2d_glXDestroyContext(awt_display, context);
        return 0L;
    }

    // the context must be made current before we can query the
    // version and extension strings
    j2d_glXMakeContextCurrent(awt_display, scratch, scratch, context);

#ifdef __sparc
    /*
     * 6438225: The software rasterizer used by Sun's OpenGL libraries
     * for certain boards has quality issues, and besides, performance
     * of these boards is not high enough to justify the use of the
     * OpenGL-based Java 2D pipeline.  If we detect one of the following
     * boards via the GL_RENDERER string, just give up:
     *   - FFB[2[+]] ("Creator[3D]")
     *   - PGX-series ("m64")
     *   - AFB ("Elite3D")
     */
    {
        const char *renderer = (const char *)j2d_glGetString(GL_RENDERER);

        J2dRlsTraceLn1(J2D_TRACE_VERBOSE,
            "GLXGraphicsConfig_getGLXConfigInfo: detected renderer (%s)",
            (renderer == NULL) ? "null" : renderer);

        if (renderer == NULL ||
            strncmp(renderer, "Creator", 7) == 0 ||
            strncmp(renderer, "SUNWm64", 7) == 0 ||
            strncmp(renderer, "Elite", 5) == 0)
        {
            J2dRlsTraceLn1(J2D_TRACE_ERROR,
                "GLXGraphicsConfig_getGLXConfigInfo: unsupported board (%s)",
                (renderer == NULL) ? "null" : renderer);
            j2d_glXMakeContextCurrent(awt_display, None, None, NULL);
            j2d_glXDestroyPbuffer(awt_display, scratch);
            j2d_glXDestroyContext(awt_display, context);
            return 0L;
        }
    }
#endif /* __sparc */

    versionstr = j2d_glGetString(GL_VERSION);
    OGLContext_GetExtensionInfo(env, &caps);

    // destroy the temporary resources
    j2d_glXMakeContextCurrent(awt_display, None, None, NULL);

    J2dRlsTraceLn1(J2D_TRACE_INFO,
        "GLXGraphicsConfig_getGLXConfigInfo: OpenGL version=%s",
                   (versionstr == NULL) ? "null" : (char *)versionstr);

    if (!OGLContext_IsVersionSupported(versionstr)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGraphicsConfig_getGLXConfigInfo: OpenGL 1.2 is required");
        j2d_glXDestroyPbuffer(awt_display, scratch);
        j2d_glXDestroyContext(awt_display, context);
        return 0L;
    }

    // get config-specific capabilities
    j2d_glXGetFBConfigAttrib(awt_display, fbconfig, GLX_DOUBLEBUFFER, &db);
    if (db) {
        caps |= CAPS_DOUBLEBUFFERED;
    }
    j2d_glXGetFBConfigAttrib(awt_display, fbconfig, GLX_ALPHA_SIZE, &alpha);
    if (alpha > 0) {
        caps |= CAPS_STORED_ALPHA;
    }

    // initialize the OGLContext, which wraps the GLXFBConfig and GLXContext
    oglc = GLXGC_InitOGLContext(fbconfig, context, scratch, caps);
    if (oglc == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGraphicsConfig_getGLXConfigInfo: could not create oglc");
        j2d_glXDestroyPbuffer(awt_display, scratch);
        j2d_glXDestroyContext(awt_display, context);
        return 0L;
    }

    J2dTraceLn(J2D_TRACE_VERBOSE,
        "GLXGraphicsConfig_getGLXConfigInfo: finished checking dependencies");

    // create the GLXGraphicsConfigInfo record for this config
    glxinfo = (GLXGraphicsConfigInfo *)malloc(sizeof(GLXGraphicsConfigInfo));
    if (glxinfo == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGraphicsConfig_getGLXConfigInfo: could not allocate memory for glxinfo");
        GLXGC_DestroyOGLContext(oglc);
        return 0L;
    }

    glxinfo->screen = screennum;
    glxinfo->visual = visnum;
    glxinfo->context = oglc;
    glxinfo->fbconfig = fbconfig;

    return ptr_to_jlong(glxinfo);
#else
    return 0L;
#endif /* !HEADLESS */
}