Beispiel #1
0
/**
 * Attempts to create a new GLXFBConfig for the requested screen and visual.
 * If there are no valid GLXFBConfigs available, 0 is returned.
 */
static GLXFBConfig
GLXGC_InitFBConfig(JNIEnv *env, jint screennum, jint visnum)
{
    jboolean foundconfig = JNI_FALSE;
    GLXFBConfig *fbconfigs;
    GLXFBConfig fbc;
    int nconfs, i;
    int attrlist[] = {GLX_VISUAL_ID, 0,
                      GLX_DRAWABLE_TYPE,
                      GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT,
                      GLX_RENDER_TYPE, GLX_RGBA_BIT,
                      GLX_STENCIL_SIZE, 1,
                      0};

    J2dTraceLn2(J2D_TRACE_INFO, "in GLXGC_InitFBConfig (scn=%d vis=0x%x)",
                screennum, visnum);

    attrlist[1] = visnum;

    // find all fbconfigs for this screen with the provided attributes
    fbconfigs = j2d_glXChooseFBConfig(awt_display, screennum,
                                      attrlist, &nconfs);

    if ((fbconfigs == NULL) || (nconfs <= 0)) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not find any valid fbconfigs");
        return 0;
    }

    J2dTraceLn(J2D_TRACE_VERBOSE, "candidate fbconfigs:");

    // iterate through the list of fbconfigs, looking for the one that matches
    // the requested visual ID and supports RGBA rendering as well as the
    // creation of windows, pbuffers, and pixmaps
    for (i = 0; i < nconfs; i++) {
        XVisualInfo *xvi;
        int dtype, rtype, ssize, caveat;
        fbc = fbconfigs[i];

        xvi = j2d_glXGetVisualFromFBConfig(awt_display, fbc);
        j2d_glXGetFBConfigAttrib(awt_display, fbc, GLX_DRAWABLE_TYPE, &dtype);
        j2d_glXGetFBConfigAttrib(awt_display, fbc, GLX_RENDER_TYPE, &rtype);
        j2d_glXGetFBConfigAttrib(awt_display, fbc, GLX_STENCIL_SIZE, &ssize);
        j2d_glXGetFBConfigAttrib(awt_display, fbc, GLX_CONFIG_CAVEAT, &caveat);
        
        J2dTrace5(J2D_TRACE_VERBOSE,
                  "  id=0x%x dtype=0x%x rtype=0x%x ssize=%d caveat=%d valid=",
                  xvi->visualid, dtype, rtype, ssize, caveat);

        // REMIND: we may want to check caveat to avoid "GLX_SLOW" configs...
        if ((xvi->visualid == visnum) &&
            (dtype == attrlist[3]) &&
            (rtype & GLX_RGBA_BIT) &&
            (ssize > 0))
        {
            J2dTrace(J2D_TRACE_VERBOSE, "true\n");
            foundconfig = JNI_TRUE;
            break;
        }

        J2dTrace(J2D_TRACE_VERBOSE, "false\n");
    }

    // free the list of fbconfigs
    XFree(fbconfigs);

    if (!foundconfig) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not find an appropriate fbconfig");
        return 0;
    }

    return fbc;
}
Beispiel #2
0
/**
 * Attempts to create a new GLXFBConfig for the requested screen and visual.
 * If visualid is 0, this method will iterate through all GLXFBConfigs (if
 * any) that match the requested attributes and will attempt to find an
 * fbconfig with a minimal combined depth+stencil buffer.  Note that we
 * currently only need depth capabilities (for shape clipping purposes), but
 * glXChooseFBConfig() will often return a list of fbconfigs with the largest
 * depth buffer (and stencil) sizes at the top of the list.  Therefore, we
 * scan through the whole list to find the most VRAM-efficient fbconfig.
 * If visualid is non-zero, the GLXFBConfig associated with the given visual
 * is chosen (assuming it meets the requested attributes).  If there are no
 * valid GLXFBConfigs available, this method returns 0.
 */
static GLXFBConfig
GLXGC_InitFBConfig(JNIEnv *env, jint screennum, VisualID visualid)
{
    GLXFBConfig *fbconfigs;
    GLXFBConfig chosenConfig = 0;
    int nconfs, i;
    int attrlist[] = {GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_PBUFFER_BIT,
                      GLX_RENDER_TYPE, GLX_RGBA_BIT,
                      GLX_CONFIG_CAVEAT, GLX_NONE, // avoid "slow" configs
                      GLX_DEPTH_SIZE, 16, // anything >= 16 will work for us
                      0};

    // this is the initial minimum value for the combined depth+stencil size
    // (we initialize it to some absurdly high value; realistic values will
    // be much less than this number)
    int minDepthPlusStencil = 512;

    J2dRlsTraceLn2(J2D_TRACE_INFO, "GLXGC_InitFBConfig: scn=%d vis=0x%x",
                   screennum, visualid);

    // find all fbconfigs for this screen with the provided attributes
    fbconfigs = j2d_glXChooseFBConfig(awt_display, screennum,
                                      attrlist, &nconfs);

    if ((fbconfigs == NULL) || (nconfs <= 0)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGC_InitFBConfig: could not find any valid fbconfigs");
        return 0;
    }

    J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  candidate fbconfigs:");

    // iterate through the list of fbconfigs, looking for the one that matches
    // the requested VisualID and supports RGBA rendering as well as the
    // creation of windows and pbuffers
    for (i = 0; i < nconfs; i++) {
        XVisualInfo *xvi;
        VisualID fbvisualid;
        GLXFBConfig fbc = fbconfigs[i];

        // get VisualID from GLXFBConfig
        xvi = j2d_glXGetVisualFromFBConfig(awt_display, fbc);
        if (xvi == NULL) {
            continue;
        }
        fbvisualid = xvi->visualid;
        XFree(xvi);

        if (visualid == 0 || visualid == fbvisualid) {
            int dtype, rtype, depth, stencil, db, alpha, gamma;

            // get GLX-specific attributes from GLXFBConfig
            j2d_glXGetFBConfigAttrib(awt_display, fbc,
                                     GLX_DRAWABLE_TYPE, &dtype);
            j2d_glXGetFBConfigAttrib(awt_display, fbc,
                                     GLX_RENDER_TYPE, &rtype);
            j2d_glXGetFBConfigAttrib(awt_display, fbc,
                                     GLX_DEPTH_SIZE, &depth);
            j2d_glXGetFBConfigAttrib(awt_display, fbc,
                                     GLX_STENCIL_SIZE, &stencil);

            // these attributes don't affect our decision, but they are
            // interesting for trace logs, so we will query them anyway
            j2d_glXGetFBConfigAttrib(awt_display, fbc,
                                     GLX_DOUBLEBUFFER, &db);
            j2d_glXGetFBConfigAttrib(awt_display, fbc,
                                     GLX_ALPHA_SIZE, &alpha);

            J2dRlsTrace5(J2D_TRACE_VERBOSE,
                "[V]     id=0x%x db=%d alpha=%d depth=%d stencil=%d valid=",
                         fbvisualid, db, alpha, depth, stencil);

#ifdef __sparc
            /*
             * Sun's OpenGL implementation will always
             * return at least two GLXFBConfigs (visuals) from
             * glXChooseFBConfig().  The first will be a linear (gamma
             * corrected) visual; the second will have the same capabilities
             * as the first, except it will be a non-linear (non-gamma
             * corrected) visual, which is the one we want, otherwise
             * everything will look "washed out".  So we will reject any
             * visuals that have gamma values other than 1.0 (the value
             * returned by glXGetFBConfigAttrib() will be scaled
             * by 100, so 100 corresponds to a gamma value of 1.0, 220
             * corresponds to 2.2, and so on).
             */
            j2d_glXGetFBConfigAttrib(awt_display, fbc,
                                     GLX_GAMMA_VALUE_SUN, &gamma);
            if (gamma != 100) {
                J2dRlsTrace(J2D_TRACE_VERBOSE, "false (linear visual)\n");
                continue;
            }
#endif /* __sparc */

            if ((dtype & GLX_WINDOW_BIT) &&
                (dtype & GLX_PBUFFER_BIT) &&
                (rtype & GLX_RGBA_BIT) &&
                (depth >= 16))
            {
                if (visualid == 0) {
                    // when visualid == 0, we loop through all configs
                    // looking for an fbconfig that has the smallest combined
                    // depth+stencil size (this keeps VRAM usage to a minimum)
                    if ((depth + stencil) < minDepthPlusStencil) {
                        J2dRlsTrace(J2D_TRACE_VERBOSE, "true\n");
                        minDepthPlusStencil = depth + stencil;
                        chosenConfig = fbc;
                    } else {
                        J2dRlsTrace(J2D_TRACE_VERBOSE,
                                    "false (large depth)\n");
                    }
                    continue;
                } else {
                    // in this case, visualid == fbvisualid, which means
                    // we've found a valid fbconfig corresponding to the
                    // requested VisualID, so break out of the loop
                    J2dRlsTrace(J2D_TRACE_VERBOSE, "true\n");
                    chosenConfig = fbc;
                    break;
                }
            } else {
                J2dRlsTrace(J2D_TRACE_VERBOSE, "false (bad match)\n");
            }
        }
    }

    // free the list of fbconfigs
    XFree(fbconfigs);

    if (chosenConfig == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGC_InitFBConfig: could not find an appropriate fbconfig");
        return 0;
    }

    return chosenConfig;
}