コード例 #1
0
/**
 * Returns a pixel format identifier that is suitable for Java 2D's needs
 * (must have a depth buffer, support for pbuffers, etc).  This method will
 * iterate through all pixel formats (if any) that match the requested
 * attributes and will attempt to find a pixel format with a minimal combined
 * depth+stencil buffer.  Note that we currently only need depth capabilities
 * (for shape clipping purposes), but wglChoosePixelFormatARB() will often
 * return a list of pixel formats 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 pixel format.  If no appropriate pixel
 * format can be found, this method returns 0.
 */
static int
WGLGC_GetPixelFormatForDC(HDC hdc)
{
    int attrs[] = {
        WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
        WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
        WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE,
        WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
        WGL_DEPTH_BITS_ARB, 16, // anything >= 16 will work for us
        0
    };
    int pixfmts[32];
    int chosenPixFmt = 0;
    int nfmts, i;

    // 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;

    J2dRlsTraceLn(J2D_TRACE_INFO, "WGLGC_GetPixelFormatForDC");

    // find all pixel formats (maximum of 32) with the provided attributes
    if (!j2d_wglChoosePixelFormatARB(hdc, attrs, NULL, 32, pixfmts, &nfmts)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGC_GetPixelFormatForDC: error choosing pixel format");
        return 0;
    }

    if (nfmts <= 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGC_GetPixelFormatForDC: no pixel formats found");
        return 0;
    }

    J2dRlsTraceLn(J2D_TRACE_VERBOSE, "  candidate pixel formats:");

    // iterate through the list of pixel formats, looking for the one that
    // meets our requirements while keeping the combined depth+stencil sizes
    // to a minimum
    for (i = 0; i < nfmts; i++) {
        int attrKeys[] = {
            WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB,
            WGL_DOUBLE_BUFFER_ARB, WGL_ALPHA_BITS_ARB
        };
        int attrVals[4];
        int pixfmt = pixfmts[i];
        int depth, stencil, db, alpha;

        j2d_wglGetPixelFormatAttribivARB(hdc, pixfmt, 0, 4,
                                         attrKeys, attrVals);

        depth   = attrVals[0];
        stencil = attrVals[1];
        db      = attrVals[2];
        alpha   = attrVals[3];

        J2dRlsTrace5(J2D_TRACE_VERBOSE,
            "[V]     pixfmt=%d db=%d alpha=%d depth=%d stencil=%d valid=",
                     pixfmt, db, alpha, depth, stencil);

        if ((depth + stencil) < minDepthPlusStencil) {
            J2dRlsTrace(J2D_TRACE_VERBOSE, "true\n");
            minDepthPlusStencil = depth + stencil;
            chosenPixFmt = pixfmt;
        } else {
            J2dRlsTrace(J2D_TRACE_VERBOSE, "false (large depth)\n");
        }
    }

    if (chosenPixFmt == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGC_GetPixelFormatForDC: could not find appropriate pixfmt");
        return 0;
    }

    J2dRlsTraceLn1(J2D_TRACE_INFO,
        "WGLGC_GetPixelFormatForDC: chose %d as the best pixel format",
                   chosenPixFmt);

    return chosenPixFmt;
}
コード例 #2
0
ファイル: GLXGraphicsConfig.c プロジェクト: wei-tang/JVM
/**
 * 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;
}