void D3DInitializer::D3DAdapterInitializer::InitImpl()
{
    J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) started", adapter);

    D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
    if (pMgr == NULL) {
        return;
    }

    D3DContext *pd3dContext;
    pMgr->GetD3DContext(adapter, &pd3dContext);

    J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) finished", adapter);
}
Exemple #2
0
D3DPipelineManager * D3DPipelineManager::CreateInstance(void)
{
    if (!IsD3DEnabled() ||
        FAILED((D3DPipelineManager::CheckOSVersion())) ||
        FAILED((D3DPipelineManager::GDICheckForBadHardware())))
    {
        return NULL;
    }

    if (pMgr == NULL) {
        pMgr = new D3DPipelineManager();
        if (FAILED(pMgr->InitD3D())) {
            SAFE_DELETE(pMgr);
        }
    } else {
        // this should never happen so to be on the safe side do not
        // use this unexpected pointer, do not try to release it, just null
        // it out and fail safely
        J2dRlsTraceLn1(J2D_TRACE_ERROR,
                       "D3DPPLM::CreateInstance: unexpected instance: 0x%x,"\
                       " abort.", pMgr);
        pMgr = NULL;
    }
    return pMgr;
}
Exemple #3
0
HRESULT D3DPipelineManager::GetD3DContext(UINT adapterOrdinal,
                                          D3DContext **ppd3dContext)
{
    J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GetD3DContext");

    HRESULT res = S_OK;
    if (adapterOrdinal < 0 || adapterOrdinal >= adapterCount ||
        pAdapters == NULL ||
        pAdapters[adapterOrdinal].state == CONTEXT_INIT_FAILED)
    {
        J2dRlsTraceLn1(J2D_TRACE_ERROR,
            "D3DPPLM::GetD3DContext: invalid parameters or "\
            "failed init for adapter %d", adapterOrdinal);
        *ppd3dContext = NULL;
        return E_FAIL;
    }

    if (pAdapters[adapterOrdinal].state == CONTEXT_NOT_INITED) {
        D3DContext *pCtx = NULL;

        if (pAdapters[adapterOrdinal].pd3dContext != NULL) {
            J2dTraceLn1(J2D_TRACE_ERROR, "  non-null context in "\
                        "uninitialized adapter %d", adapterOrdinal);
            res = E_FAIL;
        } else {
            J2dTraceLn1(J2D_TRACE_VERBOSE,
                        "  initializing context for adapter %d",adapterOrdinal);

            if (SUCCEEDED(res = D3DEnabledOnAdapter(adapterOrdinal))) {
                res = D3DContext::CreateInstance(pd3d9, adapterOrdinal, &pCtx);
                if (FAILED(res)) {
                    J2dRlsTraceLn1(J2D_TRACE_ERROR,
                        "D3DPPLM::GetD3DContext: failed to create context "\
                        "for adapter=%d", adapterOrdinal);
                }
            } else {
                J2dRlsTraceLn1(J2D_TRACE_ERROR,
                    "D3DPPLM::GetContext: no d3d on adapter %d",adapterOrdinal);
            }
        }
        pAdapters[adapterOrdinal].state =
            SUCCEEDED(res) ? CONTEXT_CREATED : CONTEXT_INIT_FAILED;
        pAdapters[adapterOrdinal].pd3dContext = pCtx;
    }
    *ppd3dContext = pAdapters[adapterOrdinal].pd3dContext;
    return res;
}
void D3DInitializer::CleanImpl(bool reInit)
{
    J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DInitializer::CleanImpl (%s)",
                                    reInit ? "RELAUNCH" : "normal");
    D3DPipelineManager::DeleteInstance();
    if (bComInitialized) {
        CoUninitialize();
    }
}
Exemple #5
0
HWND D3DPipelineManager::CreateDefaultFocusWindow()
{
    UINT adapterOrdinal = D3DADAPTER_DEFAULT;

    J2dTraceLn1(J2D_TRACE_INFO,
                "D3DPPLM::CreateDefaultFocusWindow: adapter=%d",
                adapterOrdinal);

    if (defaultFocusWindow != 0) {
        J2dRlsTraceLn(J2D_TRACE_WARNING,
                      "D3DPPLM::CreateDefaultFocusWindow: "\
                      "existing default focus window!");
        return defaultFocusWindow;
    }

    WNDCLASS wc;
    ZeroMemory(&wc, sizeof(WNDCLASS));
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpfnWndProc = DefWindowProc;
    wc.lpszClassName = L"D3DFocusWindow";
    if (RegisterClass(&wc) == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "D3DPPLM::CreateDefaultFocusWindow: "\
                      "error registering window class");
        return 0;
    }

    MONITORINFO mi;
    ZeroMemory(&mi, sizeof(MONITORINFO));
    mi.cbSize = sizeof(MONITORINFO);
    HMONITOR hMon = pd3d9->GetAdapterMonitor(adapterOrdinal);
    if (hMon == 0 || !GetMonitorInfo(hMon, (LPMONITORINFO)&mi)) {
        J2dRlsTraceLn1(J2D_TRACE_ERROR,
            "D3DPPLM::CreateDefaultFocusWindow: "\
            "error getting monitor info for adapter=%d", adapterOrdinal);
        return 0;
    }

    HWND hWnd = CreateWindow(L"D3DFocusWindow", L"D3DFocusWindow", 0,
        mi.rcMonitor.left, mi.rcMonitor.top, 1, 1,
        NULL, NULL, GetModuleHandle(NULL), NULL);
    if (hWnd == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "D3DPPLM::CreateDefaultFocusWindow: CreateWindow failed");
    } else {
        J2dTraceLn2(J2D_TRACE_INFO,
            "  Created default focus window %x for adapter %d",
            hWnd, adapterOrdinal);
        defaultFocusWindow = hWnd;
    }
    return hWnd;
}
Exemple #6
0
/*
 * Class:     sun_java2d_cmm_lcms_LCMS
 * Method:    freeProfile
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfile
  (JNIEnv *env, jobject obj, jlong id)
{
    storeID_t sProf;

    sProf.j = id;
    if (cmsCloseProfile(sProf.pf) == 0) {
        J2dRlsTraceLn1(J2D_TRACE_ERROR, "LCMS_freeProfile: cmsCloseProfile(%d)"
                       "== 0", id);
        JNU_ThrowByName(env, "java/awt/color/CMMException",
                        "Cannot close profile");
    }

}
int TestTextureFormats(D3DContext *d3dContext)
{
    int testRes = J2D_D3D_FAILURE;

    D3DTextureTable &table = d3dContext->GetTextureTable();
    int pfExists;
    // Check that there's at least one valid pixel format
    // for each transparency type (opaque, bitmask, translucent)
    for (int t = TR_OPAQUE_IDX; t < TR_MAX_IDX; t++) {
        pfExists = FALSE;
        for (int d = DEPTH16_IDX; d < DEPTH_MAX_IDX; d++) {
            if (table[t][d].pfType != PF_INVALID) {
                pfExists = TRUE;
                break;
            }
        }
        if (pfExists == FALSE) {
            // couldn't find a pixel formap for this transparency type
            J2dRlsTraceLn1(J2D_TRACE_ERROR,
                           "D3DTest::TestTextureFormats no texture formats"\
                           " for %d transparency", t);
            break;
        }
    }

    // we must have ARGB texture format (may be used for text rendering)
    if (pfExists == TRUE &&
        table[TR_TRANSLUCENT_IDX][DEPTH32_IDX].pfType == PF_INT_ARGB)
    {
        testRes |= J2D_D3D_PIXEL_FORMATS_OK;
    } else {
        J2dRlsTraceLn1(J2D_TRACE_ERROR,
                       "D3DTest::TestTextureFormats: FAILED pfType=%d",
                       table[TR_TRANSLUCENT_IDX][DEPTH32_IDX].pfType);
    }
    return testRes;
}
Exemple #8
0
/**
 * Attempts to initialize GLX and the core OpenGL library.  For this method
 * to return JNI_TRUE, the following must be true:
 *     - libGL must be loaded successfully (via dlopen)
 *     - all function symbols from libGL must be available and loaded properly
 *     - the GLX extension must be available through X11
 *     - client GLX version must be >= 1.3
 * If any of these requirements are not met, this method will return
 * JNI_FALSE, indicating there is no hope of using GLX/OpenGL for any
 * GraphicsConfig in the environment.
 */
static jboolean
GLXGC_InitGLX()
{
    int errorbase, eventbase;
    const char *version;

    J2dRlsTraceLn(J2D_TRACE_INFO, "GLXGC_InitGLX");

    if (!OGLFuncs_OpenLibrary()) {
        return JNI_FALSE;
    }

    if (!OGLFuncs_InitPlatformFuncs() ||
        !OGLFuncs_InitBaseFuncs() ||
        !OGLFuncs_InitExtFuncs())
    {
        OGLFuncs_CloseLibrary();
        return JNI_FALSE;
    }

    if (!j2d_glXQueryExtension(awt_display, &errorbase, &eventbase)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "GLXGC_InitGLX: GLX extension is not present");
        OGLFuncs_CloseLibrary();
        return JNI_FALSE;
    }

    version = j2d_glXGetClientString(awt_display, GLX_VERSION);
    if (version == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "GLXGC_InitGLX: could not query GLX version");
        OGLFuncs_CloseLibrary();
        return JNI_FALSE;
    }

    // we now only verify that the client GLX version is >= 1.3 (if the
    // server does not support GLX 1.3, then we will find that out later
    // when we attempt to create a GLXFBConfig)
    J2dRlsTraceLn1(J2D_TRACE_INFO,
                   "GLXGC_InitGLX: client GLX version=%s", version);
    if (!((version[0] == '1' && version[2] >= '3') || (version[0] > '1'))) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "GLXGC_InitGLX: invalid GLX version; 1.3 is required");
        OGLFuncs_CloseLibrary();
        return JNI_FALSE;
    }

    return JNI_TRUE;
}
Exemple #9
0
HRESULT D3DPipelineManager::D3DEnabledOnAdapter(UINT adapter)
{
    HRESULT res;
    D3DDISPLAYMODE dm;

    res = pd3d9->GetAdapterDisplayMode(adapter, &dm);
    RETURN_STATUS_IF_FAILED(res);

    res = pd3d9->CheckDeviceType(adapter, devType, dm.Format, dm.Format, TRUE);
    if (FAILED(res)) {
        J2dRlsTraceLn1(J2D_TRACE_ERROR,
                "D3DPPLM::D3DEnabledOnAdapter: no " \
                "suitable d3d device on adapter %d", adapter);
    }

    return res;
}
Exemple #10
0
/*
 * Class:     sun_java2d_d3d_D3DGraphicsDevice
 * Method:    getDeviceCapsNative
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL
Java_sun_java2d_d3d_D3DGraphicsDevice_getDeviceCapsNative
  (JNIEnv *env, jclass d3dsdc, jint gdiScreen)
{
    D3DPipelineManager *pMgr;
    D3DContext *pCtx;
    UINT adapter;

    J2dRlsTraceLn(J2D_TRACE_INFO, "D3DGD_getDeviceCapsNative");

    pMgr = D3DPipelineManager::GetInstance();
    RETURN_STATUS_IF_NULL(pMgr, CAPS_EMPTY);
    adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);

    if (FAILED(pMgr->GetD3DContext(adapter, &pCtx))) {
        J2dRlsTraceLn1(J2D_TRACE_ERROR,
                      "D3DGD_getDeviceCapsNative: device %d disabled", adapter);
        return CAPS_EMPTY;
    }
    return pCtx->GetContextCaps();
}
/**
 * Returns JNI_TRUE only if all of the following conditions are met:
 *   - the GL_ARB_fragment_shader extension is available
 *   - the LCD text shader codepath has been enabled via the system property
 *   - the hardware supports the minimum number of texture units
 */
static jboolean
OGLContext_IsLCDShaderSupportAvailable(JNIEnv *env,
                                       jboolean fragShaderAvailable)
{
    jboolean isLCDShaderEnabled = JNI_FALSE;
    GLint maxTexUnits;

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_IsLCDShaderSupportAvailable");

    // first see if the fragment shader extension is available
    if (!fragShaderAvailable) {
        return JNI_FALSE;
    }

    // next see if the lcdshader system property has been enabled
    isLCDShaderEnabled =
        JNU_GetStaticFieldByName(env, NULL,
                                 "sun/java2d/opengl/OGLSurfaceData",
                                 "isLCDShaderEnabled", "Z").z;
    if (!isLCDShaderEnabled) {
        J2dRlsTraceLn(J2D_TRACE_INFO,
                      "OGLContext_IsLCDShaderSupportAvailable: disabled via flag");
        return JNI_FALSE;
    }

    // finally, check to see if the hardware supports the required number
    // of texture units
    j2d_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &maxTexUnits);
    if (maxTexUnits < 2) {
        J2dRlsTraceLn1(J2D_TRACE_INFO,
                       "OGLContext_IsLCDShaderSupportAvailable: not enough tex units (%d)",
                       maxTexUnits);
    }

    J2dRlsTraceLn(J2D_TRACE_INFO,
                  "OGLContext_IsLCDShaderSupportAvailable: LCD text shader supported");

    return JNI_TRUE;
}
Exemple #12
0
/**
 * Returns the X11 VisualID that corresponds to the best GLXFBConfig for the
 * given screen.  If no valid visual could be found, this method returns zero.
 * Note that this method will attempt to initialize GLX (and all the
 * necessary function symbols) if it has not been already.  The AWT_LOCK
 * must be acquired before calling this method.
 */
VisualID
GLXGC_FindBestVisual(JNIEnv *env, jint screen)
{
    GLXFBConfig fbc;
    XVisualInfo *xvi;
    VisualID visualid;

    J2dRlsTraceLn1(J2D_TRACE_INFO, "GLXGC_FindBestVisual: scn=%d", screen);

    if (!GLXGC_IsGLXAvailable()) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGC_FindBestVisual: could not initialize GLX");
        return 0;
    }

    fbc = GLXGC_InitFBConfig(env, screen, 0);
    if (fbc == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGC_FindBestVisual: could not find best visual");
        return 0;
    }

    xvi = j2d_glXGetVisualFromFBConfig(awt_display, fbc);
    if (xvi == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "GLXGC_FindBestVisual: could not get visual for fbconfig");
        return 0;
    }

    visualid = xvi->visualid;
    XFree(xvi);

    J2dRlsTraceLn2(J2D_TRACE_INFO,
        "GLXGC_FindBestVisual: chose 0x%x as the best visual for screen %d",
                   visualid, screen);

    return visualid;
}
Exemple #13
0
int TestForBadHardware(DxCapabilities *dxCaps)
{
    // Check this device against a list of bad d3d devices and
    // disable as necessary
    static WCHAR *badDeviceStrings[] = {
        L"Trident Video Accelerator",
        L"RAGE PRO",
        L"RAGE XL",
        L"Rage Fury",
    };
    static int numBadDevices = 4;
    WCHAR *dxDeviceName = dxCaps->GetDeviceName();
    for (int i = 0; i < numBadDevices; ++i) {
        if (wcsstr(dxDeviceName, badDeviceStrings[i]) != NULL) {
            // REMIND: For now, we disable d3d for all operations because
            // of one bad d3d device in the system.  This is because we
            // should avoid registering the d3d rendering loops at the
            // Java level since we cannot use d3d at the native level.
            // A real fix would instead understand the difference between
            // a surface that could handle d3d native rendering and one
            // that could not and would use the appropriate rendering loop
            // so that disabling d3d on simply one device would be
            // sufficient.
            // Note that this disable-all approach is okay for now because
            // the single bad device (Trident) that triggers this error
            // is generally found on laptops, where multiple graphics
            // devices are not even possible, so disabling d3d for all
            // devices is equivalent to disabling d3d for this single
            // device.
            J2dRlsTraceLn1(J2D_TRACE_ERROR,
                           "TestForBadHardware: Found match: %S. Test FAILED",
                           badDeviceStrings[i]);
            return J2D_D3D_FAILURE;
        }
    }
    return J2D_D3D_HW_OK;
}
Exemple #14
0
/**
 * Determines whether the WGL pipeline can be used for a given GraphicsConfig
 * provided its screen number and visual ID.  If the minimum requirements are
 * met, the native WGLGraphicsConfigInfo structure is initialized for this
 * GraphicsConfig with the necessary information (pixel format, etc.)
 * and a pointer to this structure is returned as a jlong.  If
 * initialization fails at any point, zero is returned, indicating that WGL
 * cannot be used for this GraphicsConfig (we should fallback on the existing
 * DX pipeline).
 */
JNIEXPORT jlong JNICALL
Java_sun_java2d_opengl_WGLGraphicsConfig_getWGLConfigInfo(JNIEnv *env,
                                                          jclass wglgc,
                                                          jint screennum,
                                                          jint pixfmt)
{
    OGLContext *oglc;
    PIXELFORMATDESCRIPTOR pfd;
    HWND hwnd;
    HDC hdc;
    HGLRC context;
    HPBUFFERARB scratch;
    HDC scratchDC;
    WGLGraphicsConfigInfo *wglinfo;
    const unsigned char *versionstr;
    const char *extstr;
    jint caps = CAPS_EMPTY;
    int attrKeys[] = { WGL_DOUBLE_BUFFER_ARB, WGL_ALPHA_BITS_ARB };
    int attrVals[2];

    J2dRlsTraceLn(J2D_TRACE_INFO, "WGLGraphicsConfig_getWGLConfigInfo");

    // initialize GL/WGL extension functions
    if (!WGLGC_InitExtFuncs(screennum)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsConfig_getWGLConfigInfo: could not init ext funcs");
        return 0L;
    }

    // create a scratch window
    hwnd = WGLGC_CreateScratchWindow(screennum);
    if (hwnd == 0) {
        return 0L;
    }

    // get the HDC for the scratch window
    hdc = GetDC(hwnd);
    if (hdc == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsConfig_getWGLConfigInfo: could not get dc for scratch window");
        DestroyWindow(hwnd);
        return 0L;
    }

    if (pixfmt == 0) {
        // find an appropriate pixel format
        pixfmt = WGLGC_GetPixelFormatForDC(hdc);
        if (pixfmt == 0) {
            J2dRlsTraceLn(J2D_TRACE_ERROR,
                "WGLGraphicsConfig_getWGLConfigInfo: could not find appropriate pixfmt");
            ReleaseDC(hwnd, hdc);
            DestroyWindow(hwnd);
            return 0L;
        }
    }

    if (sharedContext == 0) {
        // create the one shared context
        sharedContext = WGLGC_CreateContext(screennum, pixfmt);
        if (sharedContext == 0) {
            J2dRlsTraceLn(J2D_TRACE_ERROR,
                "WGLGraphicsConfig_getWGLConfigInfo: could not create shared context");
            ReleaseDC(hwnd, hdc);
            DestroyWindow(hwnd);
            return 0L;
        }
    }

    // set the pixel format for the scratch window
    if (!SetPixelFormat(hdc, pixfmt, &pfd)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsconfig_getWGLConfigInfo: error setting pixel format");
        ReleaseDC(hwnd, hdc);
        DestroyWindow(hwnd);
        return 0L;
    }

    // create the HGLRC (context) for this WGLGraphicsConfig
    context = j2d_wglCreateContext(hdc);
    if (context == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsConfig_getWGLConfigInfo: could not create WGL context");
        ReleaseDC(hwnd, hdc);
        DestroyWindow(hwnd);
        return 0L;
    }

    // REMIND: when using wglShareLists, the two contexts must use an
    //         identical pixel format...
    if (!j2d_wglShareLists(sharedContext, context)) {
        J2dRlsTraceLn(J2D_TRACE_WARNING,
            "WGLGraphicsConfig_getWGLConfigInfo: unable to share lists");
    }

    // make the context current so that we can query the OpenGL version
    // and extension strings
    if (!j2d_wglMakeCurrent(hdc, context)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsConfig_getWGLConfigInfo: could not make temp context current");
        j2d_wglDeleteContext(context);
        ReleaseDC(hwnd, hdc);
        DestroyWindow(hwnd);
        return 0L;
    }

    // get version and extension strings
    versionstr = j2d_glGetString(GL_VERSION);
    extstr = j2d_wglGetExtensionsStringARB(hdc);
    OGLContext_GetExtensionInfo(env, &caps);

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

    if (!OGLContext_IsVersionSupported(versionstr)) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsConfig_getWGLConfigInfo: OpenGL 1.2 is required");
        j2d_wglMakeCurrent(NULL, NULL);
        j2d_wglDeleteContext(context);
        ReleaseDC(hwnd, hdc);
        DestroyWindow(hwnd);
        return 0L;
    }

    // check for required WGL extensions
    if (!OGLContext_IsExtensionAvailable(extstr, "WGL_ARB_pbuffer") ||
        !OGLContext_IsExtensionAvailable(extstr, "WGL_ARB_make_current_read")||
        !OGLContext_IsExtensionAvailable(extstr, "WGL_ARB_pixel_format"))
    {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsConfig_getWGLConfigInfo: required ext(s) unavailable");
        j2d_wglMakeCurrent(NULL, NULL);
        j2d_wglDeleteContext(context);
        ReleaseDC(hwnd, hdc);
        DestroyWindow(hwnd);
        return 0L;
    }

    // get config-specific capabilities
    j2d_wglGetPixelFormatAttribivARB(hdc, pixfmt, 0, 2, attrKeys, attrVals);
    if (attrVals[0]) {
        caps |= CAPS_DOUBLEBUFFERED;
    }
    if (attrVals[1] > 0) {
        caps |= CAPS_STORED_ALPHA;
    }

    // create the scratch pbuffer
    scratch = j2d_wglCreatePbufferARB(hdc, pixfmt, 1, 1, NULL);

    // destroy the temporary resources
    j2d_wglMakeCurrent(NULL, NULL);
    ReleaseDC(hwnd, hdc);
    DestroyWindow(hwnd);

    if (scratch == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsConfig_getWGLConfigInfo: could not create scratch surface");
        j2d_wglDeleteContext(context);
        return 0L;
    }

    // get the HDC for the scratch pbuffer
    scratchDC = j2d_wglGetPbufferDCARB(scratch);
    if (scratchDC == 0) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsConfig_getWGLConfigInfo: could not get hdc for scratch surface");
        j2d_wglDeleteContext(context);
        j2d_wglDestroyPbufferARB(scratch);
        return 0L;
    }

    // initialize the OGLContext, which wraps the pixfmt and HGLRC (context)
    oglc = WGLGC_InitOGLContext(pixfmt, context, scratch, scratchDC, caps);
    if (oglc == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsConfig_getWGLConfigInfo: could not create oglc");
        j2d_wglDeleteContext(context);
        j2d_wglReleasePbufferDCARB(scratch, scratchDC);
        j2d_wglDestroyPbufferARB(scratch);
        return 0L;
    }    

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

    // create the WGLGraphicsConfigInfo record for this config
    wglinfo = (WGLGraphicsConfigInfo *)malloc(sizeof(WGLGraphicsConfigInfo));
    if (wglinfo == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "WGLGraphicsConfig_getWGLConfigInfo: could not allocate memory for wglinfo");
        WGLGC_DestroyOGLContext(oglc);
        return 0L;
    }

    wglinfo->screen = screennum;
    wglinfo->pixfmt = pixfmt;
    wglinfo->context = oglc;

    return ptr_to_jlong(wglinfo);
}
Exemple #15
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;
}
/*
 * Class:     sun_java2d_d3d_D3DSurfaceData
 * Method:    initOffScreenSurface
 * Signature: (JJJIIII)I
 */
JNIEXPORT jint JNICALL
Java_sun_java2d_d3d_D3DSurfaceData_initOffScreenSurface
    (JNIEnv *env, jobject sData,
     jlong pCtx,
     jlong pData, jlong parentPdata,
     jint width, jint height,
     jint d3dSurfaceType, jint screen)
{
    Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData);
    D3DContext *pd3dc = (D3DContext *)jlong_to_ptr(pCtx);

    J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initOffScreenSurface");
    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  width=%-4d height=%-4d type=%-3d scr=%-3d",
                width, height, d3dSurfaceType, screen);

    // REMIND: ideally this should be done in initOps
    if (d3dSurfaceType == D3D_ATTACHED_SURFACE) {
        wsdo->sdOps.Dispose = Win32BBSD_Dispose;
    }

    if (init_D3DSDO(env, wsdo, width, height,
                    d3dSurfaceType, screen) == JNI_FALSE)
    {
        SurfaceData_ThrowInvalidPipeException(env,
            "Can't create offscreen surface");
        return PF_INVALID;
    }

    HMONITOR hMon = (HMONITOR)wsdo->device->GetMonitor();
    DDrawObjectStruct *ddInstance = GetDDInstanceForDevice(hMon);
    if (!ddInstance || !ddInstance->valid || !pd3dc) {
        return PF_INVALID;
    }

    if (d3dSurfaceType == D3D_ATTACHED_SURFACE) {
        // REMIND: still using the old path. ideally the creation of attached
        // surface shoudld be done in the same way as other types of surfaces,
        // that is, in D3DContext::CreateSurface, but we really don't use
        // anything from D3DContext to get an attached surface, so this
        // was left here.

        Win32SDOps *wsdo_parent = (Win32SDOps *)jlong_to_ptr(parentPdata);
        // we're being explicit here: requesting backbuffer, and render target
        DDrawSurface* pNew = wsdo_parent->lpSurface == NULL ?
            NULL :
            wsdo_parent->lpSurface->
                GetDDAttachedSurface(DDSCAPS_BACKBUFFER|DDSCAPS_3DDEVICE);
        if (pNew == NULL ||
            FAILED(pd3dc->AttachDepthBuffer(pNew->GetDXSurface())))
        {
            J2dRlsTraceLn1(J2D_TRACE_ERROR,
                           "D3DSD_initSurface: GetAttachedSurface for parent"\
                           " wsdo_parent->lpSurface=0x%x failed",
                           wsdo_parent->lpSurface);
            if (pNew != NULL) {
                delete pNew;
            }
            SurfaceData_ThrowInvalidPipeException(env,
                "Can't create attached offscreen surface");
            return PF_INVALID;
        }

        wsdo->lpSurface = pNew;
        wsdo->ddInstance = ddInstance;
        J2dTraceLn2(J2D_TRACE_VERBOSE,
                    "D3DSD_initSurface: created attached surface: "\
                    "wsdo->lpSurface=0x%x for parent "\
                    "wsdo_parent->lpSurface=0x%x",
                    wsdo->lpSurface, wsdo_parent->lpSurface);
        // we don't care about pixel format for non-texture surfaces
        return PF_INVALID;
    }

    DXSurface *dxSurface = NULL;
    jint pf = PF_INVALID;
    HRESULT res;
    if (SUCCEEDED(res = pd3dc->CreateSurface(env, wsdo->w, wsdo->h,
                                             wsdo->depth, wsdo->transparency,
                                             d3dSurfaceType,
                                             &dxSurface, &pf)))
    {
        // REMIND: put all the error-handling stuff here from
        // DDCreateOffScreenSurface
        wsdo->lpSurface = new DDrawSurface(ddInstance->ddObject, dxSurface);
        wsdo->surfacePuntData.lpSurfaceVram = wsdo->lpSurface;
        wsdo->ddInstance = ddInstance;
        // the dimensions of the surface may be adjusted in case of
        // textures
        wsdo->w = dxSurface->GetWidth();
        wsdo->h = dxSurface->GetHeight();
        J2dTraceLn1(J2D_TRACE_VERBOSE,
                    "D3DSurfaceData_initSurface: created surface: "\
                    "wsdo->lpSurface=0x%x", wsdo->lpSurface);
    } else {
        DebugPrintDirectDrawError(res,
                                  "D3DSurfaceData_initSurface: "\
                                  "CreateSurface failed");
        // REMIND: should use some other way to signal that
        // surface creation was unsuccessful
        SurfaceData_ThrowInvalidPipeException(env,
                                              "Can't create offscreen surf");
    }
    return pf;
}
Exemple #17
0
LCMSBOOL _cmsModifyTagData(cmsHPROFILE hProfile, icTagSignature sig,
                       void *data, size_t size)
{
    LCMSBOOL isNew;
    int i, idx, delta, count;
    LPBYTE padChars[3] = {0, 0, 0};
    LPBYTE beforeBuf, afterBuf, ptr;
    size_t beforeSize, afterSize;
    icUInt32Number profileSize, temp;
    LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile;

    isNew = FALSE;
    idx = _cmsSearchTag(Icc, sig, FALSE);
    if (idx < 0) {
        isNew = TRUE;
        idx = Icc->TagCount++;
        if (Icc->TagCount >= MAX_TABLE_TAG) {
            J2dRlsTraceLn1(J2D_TRACE_ERROR, "_cmsModifyTagData: Too many tags "
                           "(%d)\n", Icc->TagCount);
            Icc->TagCount = MAX_TABLE_TAG-1;
            return FALSE;
        }
    }

    /* Read in size from header */
    Icc->Seek(Icc, 0);
    Icc->Read(&profileSize, sizeof(icUInt32Number), 1, Icc);
    AdjustEndianess32((LPBYTE) &profileSize);

    /* Compute the change in profile size */
    if (isNew) {
        delta = sizeof(icTag) + ALIGNLONG(size);
    } else {
        delta = ALIGNLONG(size) - ALIGNLONG(Icc->TagSizes[idx]);
    }
    /* Add tag to internal structures */
    ptr = malloc(size);
    if (ptr == NULL) {
        if(isNew) {
            Icc->TagCount--;
        }
        J2dRlsTraceLn(J2D_TRACE_ERROR, "_cmsModifyTagData: ptr == NULL");
        return FALSE;
    }

    /* We change the size of Icc here only if we know it'll actually
     * grow: if Icc is about to shrink we must wait until we've read
     * the previous data.  */
    if (delta > 0) {
	if (!Icc->Grow(Icc, delta)) {
	    free(ptr);
	    if(isNew) {
		Icc->TagCount--;
	    }
	    J2dRlsTraceLn(J2D_TRACE_ERROR,
			  "_cmsModifyTagData: Icc->Grow() == FALSE");
	    return FALSE;
	}
    }

    /* Compute size of tag data before/after the modified tag */
    beforeSize = ((isNew)?profileSize:Icc->TagOffsets[idx]) -
                 Icc->TagOffsets[0];
    if (Icc->TagCount == (idx + 1)) {
        afterSize = 0;
    } else {
        afterSize = profileSize - Icc->TagOffsets[idx+1];
    }
    /* Make copies of the data before/after the modified tag */
    if (beforeSize > 0) {
        beforeBuf = malloc(beforeSize);
        if (!beforeBuf) {
            if(isNew) {
                Icc->TagCount--;
            }
            free(ptr);
            J2dRlsTraceLn(J2D_TRACE_ERROR,
                          "_cmsModifyTagData: beforeBuf == NULL");
            return FALSE;
        }
        Icc->Seek(Icc, Icc->TagOffsets[0]);
        Icc->Read(beforeBuf, beforeSize, 1, Icc);
    }

    if (afterSize > 0) {
        afterBuf = malloc(afterSize);
        if (!afterBuf) {
            free(ptr);
            if(isNew) {
                Icc->TagCount--;
            }
            if (beforeSize > 0) {
                free(beforeBuf);
            }
            J2dRlsTraceLn(J2D_TRACE_ERROR,
                          "_cmsModifyTagData: afterBuf == NULL");
            return FALSE;
        }
        Icc->Seek(Icc, Icc->TagOffsets[idx+1]);
        Icc->Read(afterBuf, afterSize, 1, Icc);
    }

    CopyMemory(ptr, data, size);
    Icc->TagSizes[idx] = size;
    Icc->TagNames[idx] = sig;
    if (Icc->TagPtrs[idx]) {
        free(Icc->TagPtrs[idx]);
    }
    Icc->TagPtrs[idx] = ptr;
    if (isNew) {
        Icc->TagOffsets[idx] = profileSize;
    }


    /* Update the profile size in the header */
    profileSize += delta;
    Icc->Seek(Icc, 0);
    temp = TransportValue32(profileSize);
    Icc->Write(Icc, sizeof(icUInt32Number), &temp);

    /* Shrink Icc, if needed.  */
    if (delta < 0) {
	if (!Icc->Grow(Icc, delta)) {
	    free(ptr);
	    if(isNew) {
		Icc->TagCount--;
	    }
	    J2dRlsTraceLn(J2D_TRACE_ERROR,
			  "_cmsModifyTagData: Icc->Grow() == FALSE");
	    return FALSE;
	}
    }

    /* Adjust tag offsets: if the tag is new, we must account
       for the new tag table entry; otherwise, only those tags after
       the modified tag are changed (by delta) */
    if (isNew) {
        for (i = 0; i < Icc->TagCount; ++i) {
            Icc->TagOffsets[i] += sizeof(icTag);
        }
    } else {
        for (i = idx+1; i < Icc->TagCount; ++i) {
            Icc->TagOffsets[i] += delta;
        }
    }

    /* Write out a new tag table */
    count = 0;
    for (i = 0; i < Icc->TagCount; ++i) {
        if (Icc->TagNames[i] != 0) {
            ++count;
        }
    }
    Icc->Seek(Icc, sizeof(icHeader));
    temp = TransportValue32(count);
    Icc->Write(Icc, sizeof(icUInt32Number), &temp);

    for (i = 0; i < Icc->TagCount; ++i) {
        if (Icc->TagNames[i] != 0) {
            icTag tag;
            tag.sig = TransportValue32(Icc->TagNames[i]);
            tag.offset = TransportValue32((icInt32Number) Icc->TagOffsets[i]);
            tag.size = TransportValue32((icInt32Number) Icc->TagSizes[i]);
            Icc->Write(Icc, sizeof(icTag), &tag);
        }
    }

    /* Write unchanged data before the modified tag */
    if (beforeSize > 0) {
        Icc->Write(Icc, beforeSize, beforeBuf);
        free(beforeBuf);
    }

    /* Write modified tag data */
    Icc->Write(Icc, size, data);
    if (size % 4) {
        Icc->Write(Icc, 4 - (size % 4), padChars);
    }

    /* Write unchanged data after the modified tag */
    if (afterSize > 0) {
        Icc->Write(Icc, afterSize, afterBuf);
        free(afterBuf);
    }

    return TRUE;
}
Exemple #18
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 */
}
Exemple #19
0
JNIEXPORT void JNICALL
Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer
    (JNIEnv *env, jobject oglrq,
     jlong buf, jint limit)
{
    jboolean sync = JNI_FALSE;
    unsigned char *b, *end;

    J2dTraceLn1(J2D_TRACE_INFO,
                "OGLRenderQueue_flushBuffer: limit=%d", limit);

    b = (unsigned char *)jlong_to_ptr(buf);
    if (b == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLRenderQueue_flushBuffer: cannot get direct buffer address");
        return;
    }

    INIT_PREVIOUS_OP();
    end = b + limit;

    while (b < end) {
        jint opcode = NEXT_INT(b);

        J2dTraceLn2(J2D_TRACE_VERBOSE,
                    "OGLRenderQueue_flushBuffer: opcode=%d, rem=%d",
                    opcode, (end-b));

        switch (opcode) {

        // draw ops
        case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE:
            {
                jint x1 = NEXT_INT(b);
                jint y1 = NEXT_INT(b);
                jint x2 = NEXT_INT(b);
                jint y2 = NEXT_INT(b);
                OGLRenderer_DrawLine(oglc, x1, y1, x2, y2);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT:
            {
                jint x = NEXT_INT(b);
                jint y = NEXT_INT(b);
                jint w = NEXT_INT(b);
                jint h = NEXT_INT(b);
                OGLRenderer_DrawRect(oglc, x, y, w, h);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY:
            {
                jint nPoints      = NEXT_INT(b);
                jboolean isClosed = NEXT_BOOLEAN(b);
                jint transX       = NEXT_INT(b);
                jint transY       = NEXT_INT(b);
                jint *xPoints = (jint *)b;
                jint *yPoints = ((jint *)b) + nPoints;
                OGLRenderer_DrawPoly(oglc, nPoints, isClosed,
                                     transX, transY,
                                     xPoints, yPoints);
                SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL:
            {
                jint x = NEXT_INT(b);
                jint y = NEXT_INT(b);
                // Note that we could use GL_POINTS here, but the common
                // use case for DRAW_PIXEL is when rendering a Path2D,
                // which will consist of a mix of DRAW_PIXEL and DRAW_LINE
                // calls.  So to improve batching we use GL_LINES here,
                // even though it requires an extra vertex per pixel.
                CONTINUE_IF_NULL(oglc);
                CHECK_PREVIOUS_OP(GL_LINES);
                j2d_glVertex2i(x, y);
                j2d_glVertex2i(x+1, y+1);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES:
            {
                jint count = NEXT_INT(b);
                OGLRenderer_DrawScanlines(oglc, count, (jint *)b);
                SKIP_BYTES(b, count * BYTES_PER_SCANLINE);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM:
            {
                jfloat x11 = NEXT_FLOAT(b);
                jfloat y11 = NEXT_FLOAT(b);
                jfloat dx21 = NEXT_FLOAT(b);
                jfloat dy21 = NEXT_FLOAT(b);
                jfloat dx12 = NEXT_FLOAT(b);
                jfloat dy12 = NEXT_FLOAT(b);
                jfloat lwr21 = NEXT_FLOAT(b);
                jfloat lwr12 = NEXT_FLOAT(b);
                OGLRenderer_DrawParallelogram(oglc,
                                              x11, y11,
                                              dx21, dy21,
                                              dx12, dy12,
                                              lwr21, lwr12);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM:
            {
                jfloat x11 = NEXT_FLOAT(b);
                jfloat y11 = NEXT_FLOAT(b);
                jfloat dx21 = NEXT_FLOAT(b);
                jfloat dy21 = NEXT_FLOAT(b);
                jfloat dx12 = NEXT_FLOAT(b);
                jfloat dy12 = NEXT_FLOAT(b);
                jfloat lwr21 = NEXT_FLOAT(b);
                jfloat lwr12 = NEXT_FLOAT(b);
                OGLRenderer_DrawAAParallelogram(oglc, dstOps,
                                                x11, y11,
                                                dx21, dy21,
                                                dx12, dy12,
                                                lwr21, lwr12);
            }
            break;

        // fill ops
        case sun_java2d_pipe_BufferedOpCodes_FILL_RECT:
            {
                jint x = NEXT_INT(b);
                jint y = NEXT_INT(b);
                jint w = NEXT_INT(b);
                jint h = NEXT_INT(b);
                OGLRenderer_FillRect(oglc, x, y, w, h);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS:
            {
                jint count = NEXT_INT(b);
                OGLRenderer_FillSpans(oglc, count, (jint *)b);
                SKIP_BYTES(b, count * BYTES_PER_SPAN);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM:
            {
                jfloat x11 = NEXT_FLOAT(b);
                jfloat y11 = NEXT_FLOAT(b);
                jfloat dx21 = NEXT_FLOAT(b);
                jfloat dy21 = NEXT_FLOAT(b);
                jfloat dx12 = NEXT_FLOAT(b);
                jfloat dy12 = NEXT_FLOAT(b);
                OGLRenderer_FillParallelogram(oglc,
                                              x11, y11,
                                              dx21, dy21,
                                              dx12, dy12);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM:
            {
                jfloat x11 = NEXT_FLOAT(b);
                jfloat y11 = NEXT_FLOAT(b);
                jfloat dx21 = NEXT_FLOAT(b);
                jfloat dy21 = NEXT_FLOAT(b);
                jfloat dx12 = NEXT_FLOAT(b);
                jfloat dy12 = NEXT_FLOAT(b);
                OGLRenderer_FillAAParallelogram(oglc, dstOps,
                                                x11, y11,
                                                dx21, dy21,
                                                dx12, dy12);
            }
            break;

        // text-related ops
        case sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST:
            {
                jint numGlyphs        = NEXT_INT(b);
                jint packedParams     = NEXT_INT(b);
                jfloat glyphListOrigX = NEXT_FLOAT(b);
                jfloat glyphListOrigY = NEXT_FLOAT(b);
                jboolean usePositions = EXTRACT_BOOLEAN(packedParams,
                                                        OFFSET_POSITIONS);
                jboolean subPixPos    = EXTRACT_BOOLEAN(packedParams,
                                                        OFFSET_SUBPIXPOS);
                jboolean rgbOrder     = EXTRACT_BOOLEAN(packedParams,
                                                        OFFSET_RGBORDER);
                jint lcdContrast      = EXTRACT_BYTE(packedParams,
                                                     OFFSET_CONTRAST);
                unsigned char *images = b;
                unsigned char *positions;
                jint bytesPerGlyph;
                if (usePositions) {
                    positions = (b + numGlyphs * BYTES_PER_GLYPH_IMAGE);
                    bytesPerGlyph = BYTES_PER_POSITIONED_GLYPH;
                } else {
                    positions = NULL;
                    bytesPerGlyph = BYTES_PER_GLYPH_IMAGE;
                }
                OGLTR_DrawGlyphList(env, oglc, dstOps,
                                    numGlyphs, usePositions,
                                    subPixPos, rgbOrder, lcdContrast,
                                    glyphListOrigX, glyphListOrigY,
                                    images, positions);
                SKIP_BYTES(b, numGlyphs * bytesPerGlyph);
            }
            break;

        // copy-related ops
        case sun_java2d_pipe_BufferedOpCodes_COPY_AREA:
            {
                jint x  = NEXT_INT(b);
                jint y  = NEXT_INT(b);
                jint w  = NEXT_INT(b);
                jint h  = NEXT_INT(b);
                jint dx = NEXT_INT(b);
                jint dy = NEXT_INT(b);
                OGLBlitLoops_CopyArea(env, oglc, dstOps,
                                      x, y, w, h, dx, dy);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_BLIT:
            {
                jint packedParams = NEXT_INT(b);
                jint sx1          = NEXT_INT(b);
                jint sy1          = NEXT_INT(b);
                jint sx2          = NEXT_INT(b);
                jint sy2          = NEXT_INT(b);
                jdouble dx1       = NEXT_DOUBLE(b);
                jdouble dy1       = NEXT_DOUBLE(b);
                jdouble dx2       = NEXT_DOUBLE(b);
                jdouble dy2       = NEXT_DOUBLE(b);
                jlong pSrc        = NEXT_LONG(b);
                jlong pDst        = NEXT_LONG(b);
                jint hint         = EXTRACT_BYTE(packedParams, OFFSET_HINT);
                jboolean texture  = EXTRACT_BOOLEAN(packedParams,
                                                    OFFSET_TEXTURE);
                jboolean rtt      = EXTRACT_BOOLEAN(packedParams,
                                                    OFFSET_RTT);
                jboolean xform    = EXTRACT_BOOLEAN(packedParams,
                                                    OFFSET_XFORM);
                jboolean isoblit  = EXTRACT_BOOLEAN(packedParams,
                                                    OFFSET_ISOBLIT);
                if (isoblit) {
                    OGLBlitLoops_IsoBlit(env, oglc, pSrc, pDst,
                                         xform, hint, texture, rtt,
                                         sx1, sy1, sx2, sy2,
                                         dx1, dy1, dx2, dy2);
                } else {
                    jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE);
                    OGLBlitLoops_Blit(env, oglc, pSrc, pDst,
                                      xform, hint, srctype, texture,
                                      sx1, sy1, sx2, sy2,
                                      dx1, dy1, dx2, dy2);
                }
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT:
            {
                jint sx      = NEXT_INT(b);
                jint sy      = NEXT_INT(b);
                jint dx      = NEXT_INT(b);
                jint dy      = NEXT_INT(b);
                jint w       = NEXT_INT(b);
                jint h       = NEXT_INT(b);
                jint dsttype = NEXT_INT(b);
                jlong pSrc   = NEXT_LONG(b);
                jlong pDst   = NEXT_LONG(b);
                OGLBlitLoops_SurfaceToSwBlit(env, oglc,
                                             pSrc, pDst, dsttype,
                                             sx, sy, dx, dy, w, h);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_MASK_FILL:
            {
                jint x        = NEXT_INT(b);
                jint y        = NEXT_INT(b);
                jint w        = NEXT_INT(b);
                jint h        = NEXT_INT(b);
                jint maskoff  = NEXT_INT(b);
                jint maskscan = NEXT_INT(b);
                jint masklen  = NEXT_INT(b);
                unsigned char *pMask = (masklen > 0) ? b : NULL;
                OGLMaskFill_MaskFill(oglc, x, y, w, h,
                                     maskoff, maskscan, masklen, pMask);
                SKIP_BYTES(b, masklen);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT:
            {
                jint dstx     = NEXT_INT(b);
                jint dsty     = NEXT_INT(b);
                jint width    = NEXT_INT(b);
                jint height   = NEXT_INT(b);
                jint masklen  = width * height * sizeof(jint);
                OGLMaskBlit_MaskBlit(env, oglc,
                                     dstx, dsty, width, height, b);
                SKIP_BYTES(b, masklen);
            }
            break;

        // state-related ops
        case sun_java2d_pipe_BufferedOpCodes_SET_RECT_CLIP:
            {
                jint x1 = NEXT_INT(b);
                jint y1 = NEXT_INT(b);
                jint x2 = NEXT_INT(b);
                jint y2 = NEXT_INT(b);
                OGLContext_SetRectClip(oglc, dstOps, x1, y1, x2, y2);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP:
            {
                OGLContext_BeginShapeClip(oglc);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS:
            {
                jint count = NEXT_INT(b);
                OGLRenderer_FillSpans(oglc, count, (jint *)b);
                SKIP_BYTES(b, count * BYTES_PER_SPAN);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP:
            {
                OGLContext_EndShapeClip(oglc, dstOps);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP:
            {
                OGLContext_ResetClip(oglc);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE:
            {
                jint rule         = NEXT_INT(b);
                jfloat extraAlpha = NEXT_FLOAT(b);
                jint flags        = NEXT_INT(b);
                OGLContext_SetAlphaComposite(oglc, rule, extraAlpha, flags);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE:
            {
                jint xorPixel = NEXT_INT(b);
                OGLContext_SetXorComposite(oglc, xorPixel);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE:
            {
                OGLContext_ResetComposite(oglc);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM:
            {
                jdouble m00 = NEXT_DOUBLE(b);
                jdouble m10 = NEXT_DOUBLE(b);
                jdouble m01 = NEXT_DOUBLE(b);
                jdouble m11 = NEXT_DOUBLE(b);
                jdouble m02 = NEXT_DOUBLE(b);
                jdouble m12 = NEXT_DOUBLE(b);
                OGLContext_SetTransform(oglc, m00, m10, m01, m11, m02, m12);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM:
            {
                OGLContext_ResetTransform(oglc);
            }
            break;

        // context-related ops
        case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES:
            {
                jlong pSrc = NEXT_LONG(b);
                jlong pDst = NEXT_LONG(b);
                if (oglc != NULL) {
                    RESET_PREVIOUS_OP();
                }
                oglc = OGLContext_SetSurfaces(env, pSrc, pDst);
                dstOps = (OGLSDOps *)jlong_to_ptr(pDst);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE:
            {
                jlong pConfigInfo = NEXT_LONG(b);
                if (oglc != NULL) {
                    RESET_PREVIOUS_OP();
                }
                oglc = OGLSD_SetScratchSurface(env, pConfigInfo);
                dstOps = NULL;
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE:
            {
                jlong pData = NEXT_LONG(b);
                OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
                if (oglsdo != NULL) {
                    CONTINUE_IF_NULL(oglc);
                    RESET_PREVIOUS_OP();
                    OGLSD_Delete(env, oglsdo);
                }
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE:
            {
                jlong pData = NEXT_LONG(b);
                OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData);
                if (oglsdo != NULL) {
                    CONTINUE_IF_NULL(oglc);
                    RESET_PREVIOUS_OP();
                    OGLSD_Delete(env, oglsdo);
                    if (oglsdo->privOps != NULL) {
                        free(oglsdo->privOps);
                    }
                }
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG:
            {
                jlong pConfigInfo = NEXT_LONG(b);
                CONTINUE_IF_NULL(oglc);
                RESET_PREVIOUS_OP();
                OGLGC_DestroyOGLGraphicsConfig(pConfigInfo);

                // the previous method will call glX/wglMakeCurrent(None),
                // so we should nullify the current oglc and dstOps to avoid
                // calling glFlush() (or similar) while no context is current
                oglc = NULL;
                dstOps = NULL;
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT:
            {
                // flush just in case there are any pending operations in
                // the hardware pipe
                if (oglc != NULL) {
                    RESET_PREVIOUS_OP();
                    j2d_glFlush();
                }

                // invalidate the references to the current context and
                // destination surface that are maintained at the native level
                oglc = NULL;
                dstOps = NULL;
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SAVE_STATE:
            {
                j2d_glPushAttrib(GL_ALL_ATTRIB_BITS);
                j2d_glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
                j2d_glMatrixMode(GL_MODELVIEW);
                j2d_glPushMatrix();
                j2d_glMatrixMode(GL_PROJECTION);
                j2d_glPushMatrix();
                j2d_glMatrixMode(GL_TEXTURE);
                j2d_glPushMatrix();
            }
            break;

        case sun_java2d_pipe_BufferedOpCodes_RESTORE_STATE:
            {
                j2d_glPopAttrib();
                j2d_glPopClientAttrib();
                j2d_glMatrixMode(GL_MODELVIEW);
                j2d_glPopMatrix();
                j2d_glMatrixMode(GL_PROJECTION);
                j2d_glPopMatrix();
                j2d_glMatrixMode(GL_TEXTURE);
                j2d_glPopMatrix();
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SYNC:
            {
                sync = JNI_TRUE;
            }
            break;

        // multibuffering ops
        case sun_java2d_pipe_BufferedOpCodes_SWAP_BUFFERS:
            {
                jlong window = NEXT_LONG(b);
                if (oglc != NULL) {
                    RESET_PREVIOUS_OP();
                }
                OGLSD_SwapBuffers(env, window);
            }
            break;

        // special no-op (mainly used for achieving 8-byte alignment)
        case sun_java2d_pipe_BufferedOpCodes_NOOP:
            break;

        // paint-related ops
        case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT:
            {
                OGLPaints_ResetPaint(oglc);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SET_COLOR:
            {
                jint pixel = NEXT_INT(b);
                OGLPaints_SetColor(oglc, pixel);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT:
            {
                jboolean useMask= NEXT_BOOLEAN(b);
                jboolean cyclic = NEXT_BOOLEAN(b);
                jdouble p0      = NEXT_DOUBLE(b);
                jdouble p1      = NEXT_DOUBLE(b);
                jdouble p3      = NEXT_DOUBLE(b);
                jint pixel1     = NEXT_INT(b);
                jint pixel2     = NEXT_INT(b);
                OGLPaints_SetGradientPaint(oglc, useMask, cyclic,
                                           p0, p1, p3,
                                           pixel1, pixel2);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT:
            {
                jboolean useMask = NEXT_BOOLEAN(b);
                jboolean linear  = NEXT_BOOLEAN(b);
                jint cycleMethod = NEXT_INT(b);
                jint numStops    = NEXT_INT(b);
                jfloat p0        = NEXT_FLOAT(b);
                jfloat p1        = NEXT_FLOAT(b);
                jfloat p3        = NEXT_FLOAT(b);
                void *fractions, *pixels;
                fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));
                pixels    = b; SKIP_BYTES(b, numStops * sizeof(jint));
                OGLPaints_SetLinearGradientPaint(oglc, dstOps,
                                                 useMask, linear,
                                                 cycleMethod, numStops,
                                                 p0, p1, p3,
                                                 fractions, pixels);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT:
            {
                jboolean useMask = NEXT_BOOLEAN(b);
                jboolean linear  = NEXT_BOOLEAN(b);
                jint numStops    = NEXT_INT(b);
                jint cycleMethod = NEXT_INT(b);
                jfloat m00       = NEXT_FLOAT(b);
                jfloat m01       = NEXT_FLOAT(b);
                jfloat m02       = NEXT_FLOAT(b);
                jfloat m10       = NEXT_FLOAT(b);
                jfloat m11       = NEXT_FLOAT(b);
                jfloat m12       = NEXT_FLOAT(b);
                jfloat focusX    = NEXT_FLOAT(b);
                void *fractions, *pixels;
                fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat));
                pixels    = b; SKIP_BYTES(b, numStops * sizeof(jint));
                OGLPaints_SetRadialGradientPaint(oglc, dstOps,
                                                 useMask, linear,
                                                 cycleMethod, numStops,
                                                 m00, m01, m02,
                                                 m10, m11, m12,
                                                 focusX,
                                                 fractions, pixels);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT:
            {
                jboolean useMask= NEXT_BOOLEAN(b);
                jboolean filter = NEXT_BOOLEAN(b);
                jlong pSrc      = NEXT_LONG(b);
                jdouble xp0     = NEXT_DOUBLE(b);
                jdouble xp1     = NEXT_DOUBLE(b);
                jdouble xp3     = NEXT_DOUBLE(b);
                jdouble yp0     = NEXT_DOUBLE(b);
                jdouble yp1     = NEXT_DOUBLE(b);
                jdouble yp3     = NEXT_DOUBLE(b);
                OGLPaints_SetTexturePaint(oglc, useMask, pSrc, filter,
                                          xp0, xp1, xp3,
                                          yp0, yp1, yp3);
            }
            break;

        // BufferedImageOp-related ops
        case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP:
            {
                jlong pSrc        = NEXT_LONG(b);
                jboolean edgeZero = NEXT_BOOLEAN(b);
                jint kernelWidth  = NEXT_INT(b);
                jint kernelHeight = NEXT_INT(b);
                OGLBufImgOps_EnableConvolveOp(oglc, pSrc, edgeZero,
                                              kernelWidth, kernelHeight, b);
                SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat));
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP:
            {
                OGLBufImgOps_DisableConvolveOp(oglc);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP:
            {
                jlong pSrc          = NEXT_LONG(b);
                jboolean nonPremult = NEXT_BOOLEAN(b);
                jint numFactors     = 4;
                unsigned char *scaleFactors = b;
                unsigned char *offsets = (b + numFactors * sizeof(jfloat));
                OGLBufImgOps_EnableRescaleOp(oglc, pSrc, nonPremult,
                                             scaleFactors, offsets);
                SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP:
            {
                OGLBufImgOps_DisableRescaleOp(oglc);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP:
            {
                jlong pSrc          = NEXT_LONG(b);
                jboolean nonPremult = NEXT_BOOLEAN(b);
                jboolean shortData  = NEXT_BOOLEAN(b);
                jint numBands       = NEXT_INT(b);
                jint bandLength     = NEXT_INT(b);
                jint offset         = NEXT_INT(b);
                jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte);
                void *tableValues = b;
                OGLBufImgOps_EnableLookupOp(oglc, pSrc, nonPremult, shortData,
                                            numBands, bandLength, offset,
                                            tableValues);
                SKIP_BYTES(b, numBands * bandLength * bytesPerElem);
            }
            break;
        case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP:
            {
                OGLBufImgOps_DisableLookupOp(oglc);
            }
            break;

        default:
            J2dRlsTraceLn1(J2D_TRACE_ERROR,
                "OGLRenderQueue_flushBuffer: invalid opcode=%d", opcode);
            if (oglc != NULL) {
                RESET_PREVIOUS_OP();
            }
            return;
        }
    }

    if (oglc != NULL) {
        RESET_PREVIOUS_OP();
        if (sync) {
            j2d_glFinish();
        } else {
            j2d_glFlush();
        }
        OGLSD_Flush(env);
    }
}
Exemple #20
0
HRESULT D3DPipelineManager::CheckAdaptersInfo()
{
    D3DADAPTER_IDENTIFIER9 aid;
    UINT failedAdaptersCount = 0;

    J2dRlsTraceLn(J2D_TRACE_INFO, "CheckAdaptersInfo");
    J2dRlsTraceLn(J2D_TRACE_INFO, "------------------");
    for (UINT Adapter = 0; Adapter < adapterCount; Adapter++) {

        if (FAILED(pd3d9->GetAdapterIdentifier(Adapter, 0, &aid))) {
            pAdapters[Adapter].state = CONTEXT_INIT_FAILED;
            failedAdaptersCount++;
            continue;
        }

        J2dRlsTraceLn1(J2D_TRACE_INFO, "Adapter Ordinal  : %d", Adapter);
        J2dRlsTraceLn1(J2D_TRACE_INFO, "Adapter Handle   : 0x%x",
                       pd3d9->GetAdapterMonitor(Adapter));
        J2dRlsTraceLn1(J2D_TRACE_INFO, "Description      : %s",
                       aid.Description);
        J2dRlsTraceLn2(J2D_TRACE_INFO, "GDI Name, Driver : %s, %s",
                       aid.DeviceName, aid.Driver);
        J2dRlsTraceLn1(J2D_TRACE_INFO, "Vendor Id        : 0x%04x",
                       aid.VendorId);
        J2dRlsTraceLn1(J2D_TRACE_INFO, "Device Id        : 0x%04x",
                       aid.DeviceId);
        J2dRlsTraceLn1(J2D_TRACE_INFO, "SubSys Id        : 0x%x",
                       aid.SubSysId);
        J2dRlsTraceLn4(J2D_TRACE_INFO, "Driver Version   : %d.%d.%d.%d",
                       HIWORD(aid.DriverVersion.HighPart),
                       LOWORD(aid.DriverVersion.HighPart),
                       HIWORD(aid.DriverVersion.LowPart),
                       LOWORD(aid.DriverVersion.LowPart));
        J2dRlsTrace3(J2D_TRACE_INFO,
                     "[I] GUID             : {%08X-%04X-%04X-",
                       aid.DeviceIdentifier.Data1,
                       aid.DeviceIdentifier.Data2,
                       aid.DeviceIdentifier.Data3);
        J2dRlsTrace4(J2D_TRACE_INFO, "%02X%02X-%02X%02X",
                       aid.DeviceIdentifier.Data4[0],
                       aid.DeviceIdentifier.Data4[1],
                       aid.DeviceIdentifier.Data4[2],
                       aid.DeviceIdentifier.Data4[3]);
        J2dRlsTrace4(J2D_TRACE_INFO, "%02X%02X%02X%02X}\n",
                       aid.DeviceIdentifier.Data4[4],
                       aid.DeviceIdentifier.Data4[5],
                       aid.DeviceIdentifier.Data4[6],
                       aid.DeviceIdentifier.Data4[7]);

        if (FAILED(CheckForBadHardware(aid.VendorId, aid.DeviceId,
                                       aid.DriverVersion.QuadPart)) ||
            FAILED(CheckDeviceCaps(Adapter))  ||
            FAILED(D3DEnabledOnAdapter(Adapter)))
        {
            pAdapters[Adapter].state = CONTEXT_INIT_FAILED;
            failedAdaptersCount++;
        }
        J2dRlsTraceLn(J2D_TRACE_INFO, "------------------");
    }

    if (failedAdaptersCount == adapterCount) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
                      "D3DPPLM::CheckAdaptersInfo: no suitable adapters found");
        return E_FAIL;
    }

    return S_OK;
}
Exemple #21
0
/*
 * Class:     sun_java2d_d3d_D3DGraphicsDevice
 * Method:    configDisplayModeNative
 * Signature: (IJIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_d3d_D3DGraphicsDevice_configDisplayModeNative
  (JNIEnv *env, jclass gdc, jint gdiScreen, jlong window,
   jint width, jint height, jint bitDepth, jint refreshRate)
{
    HRESULT res;
    D3DPipelineManager *pMgr;
    D3DContext *pCtx;
    D3DPRESENT_PARAMETERS newParams, *pCurParams;
    UINT adapter;

    J2dTraceLn(J2D_TRACE_INFO, "D3DGD_configDisplayModeNative");

    RETURN_IF_NULL(pMgr = D3DPipelineManager::GetInstance());
    adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);

    if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {
        D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
        return;
    }

    pCurParams = pCtx->GetPresentationParams();

    newParams = *pCurParams;
    newParams.BackBufferWidth = width;
    newParams.BackBufferHeight = height;
    newParams.FullScreen_RefreshRateInHz = refreshRate;
    newParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
    // we leave the swap effect so that it's more likely
    // to be the one user selected initially
//    newParams.SwapEffect = D3DSWAPEFFECT_DISCARD;

    if (bitDepth == 32) {
        newParams.BackBufferFormat = D3DFMT_X8R8G8B8;
    } else if (bitDepth == 16) {
        UINT modeNum;
        D3DDISPLAYMODE mode;
        IDirect3D9 *pd3d9;
        UINT modesCount;

        RETURN_IF_NULL(pd3d9 = pMgr->GetD3DObject());

        modesCount = pd3d9->GetAdapterModeCount(adapter, D3DFMT_R5G6B5);
        if (modesCount == 0) {
            modesCount = pd3d9->GetAdapterModeCount(adapter, D3DFMT_X1R5G5B5);
        }

        newParams.BackBufferFormat = D3DFMT_UNKNOWN;
        for (modeNum = 0; modeNum < modesCount; modeNum++) {
            if (SUCCEEDED(pd3d9->EnumAdapterModes(adapter, D3DFMT_R5G6B5,
                                                  modeNum, &mode)))
            {
                if (mode.Width == width && mode.Height == height &&
                    mode.RefreshRate == refreshRate)
                {
                    // prefer 565 over 555
                    if (mode.Format == D3DFMT_R5G6B5) {
                        newParams.BackBufferFormat = D3DFMT_R5G6B5;
                        break;
                    } else if (mode.Format == D3DFMT_X1R5G5B5) {
                        newParams.BackBufferFormat = D3DFMT_X1R5G5B5;
                    }
                }
            }
        }
        if (newParams.BackBufferFormat == D3DFMT_UNKNOWN) {
            J2dRlsTraceLn(J2D_TRACE_ERROR,
                          "D3DGD_configDisplayModeNative: no 16-bit formats");
            return;
        }
    } else {
        J2dRlsTraceLn1(J2D_TRACE_ERROR,
                       "D3DGD_configDisplayModeNative: unsupported depth: %d",
                       bitDepth);
        return;
    }

    J2dTraceLn4(J2D_TRACE_VERBOSE, "  changing to dm: %dx%dx%d@%d",
                newParams.BackBufferWidth, newParams.BackBufferHeight,
                bitDepth, refreshRate);
    J2dTraceLn1(J2D_TRACE_VERBOSE, "  selected backbuffer format: %d",
                newParams.BackBufferFormat);

    res = pCtx->ConfigureContext(&newParams);
    if (SUCCEEDED(res)) {
        // the full screen window doesn't receive WM_SIZE event when
        // the display mode changes (it does get resized though) so we need to
        // generate the event ourselves
        ::SendMessage(newParams.hDeviceWindow, WM_SIZE, width, height);
    }
    D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
}
Exemple #22
0
HRESULT D3DPipelineManager::CheckDeviceCaps(UINT adapter)
{
    HRESULT res;
    D3DCAPS9 d3dCaps;

    J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::CheckDeviceCaps");

    res = pd3d9->GetDeviceCaps(adapter, devType, &d3dCaps);
    RETURN_STATUS_IF_FAILED(res);

    CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_DRAWPRIMTLVERTEX);

    // by requiring hardware tnl we are hoping for better drivers quality
    if (!IsD3DForced()) {
        // fail if not hw tnl unless d3d was forced
        CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_HWTRANSFORMANDLIGHT);
    }
    if (d3dCaps.DeviceType == D3DDEVTYPE_HAL) {
        CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_HWRASTERIZATION);
    }

    CHECK_CAP(d3dCaps.RasterCaps, D3DPRASTERCAPS_SCISSORTEST);

    CHECK_CAP(d3dCaps.Caps3, D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD);

    CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_CULLNONE);
    CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_BLENDOP);
    CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_MASKZ);

    CHECK_CAP(d3dCaps.ZCmpCaps, D3DPCMPCAPS_ALWAYS);
    CHECK_CAP(d3dCaps.ZCmpCaps, D3DPCMPCAPS_LESS);

    CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_ZERO);
    CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_ONE);
    CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_SRCALPHA);
    CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_DESTALPHA);
    CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_INVSRCALPHA);
    CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_INVDESTALPHA);

    CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_ZERO);
    CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_ONE);
    CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_SRCALPHA);
    CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_DESTALPHA);
    CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_INVSRCALPHA);
    CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_INVDESTALPHA);

    CHECK_CAP(d3dCaps.TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP);
    CHECK_CAP(d3dCaps.TextureAddressCaps, D3DPTADDRESSCAPS_WRAP);

    CHECK_CAP(d3dCaps.TextureOpCaps, D3DTEXOPCAPS_MODULATE);

    if (d3dCaps.PixelShaderVersion < D3DPS_VERSION(2,0) && !IsD3DForced()) {
        J2dRlsTraceLn1(J2D_TRACE_ERROR,
                       "D3DPPLM::CheckDeviceCaps: adapter %d: Failed "\
                       "(pixel shaders 2.0 required)", adapter);
        return E_FAIL;
    }

    J2dRlsTraceLn1(J2D_TRACE_INFO,
                   "D3DPPLM::CheckDeviceCaps: adapter %d: Passed", adapter);
    return S_OK;
}