Пример #1
0
/*
 * Class:     sun_java2d_d3d_D3DGraphicsDevice
 * Method:    getAvailableAcceleratedMemoryNative
 * Signature: (I)J
 */
JNIEXPORT jlong JNICALL
Java_sun_java2d_d3d_D3DGraphicsDevice_getAvailableAcceleratedMemoryNative
  (JNIEnv *env, jclass gdc, jint gdiScreen)
{
    // REMIND: looks like Direct3D provides information about texture memory
    // only via IDirect3DDevice9::GetAvailableTextureMem, however, it
    // seems to report the same amount as direct draw used to.
    HRESULT res;
    D3DPipelineManager *pMgr;
    D3DContext *pCtx;
    IDirect3DDevice9 *pd3dDevice;
    UINT adapter;

    J2dTraceLn(J2D_TRACE_INFO, "D3DGD_getAvailableAcceleratedMemoryNative");

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

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

    UINT mem = pd3dDevice->GetAvailableTextureMem();
    J2dTraceLn1(J2D_TRACE_VERBOSE, "  available memory=%d", mem);
    return mem;
}
Пример #2
0
/*
 * Class:     sun_java2d_d3d_D3DSurfaceData
 * Method:    dbGetPixelNative
 * Signature: (JII)I
 */
JNIEXPORT jint JNICALL Java_sun_java2d_d3d_D3DSurfaceData_dbGetPixelNative
  (JNIEnv *env, jclass clazz, jlong pData, jint x, jint y)
{
    HRESULT res;
    D3DSDOps *d3dsdo;
    D3DContext *pCtx;
    D3DPipelineManager *pMgr;
    D3DResource *pLockableRes;
    jint pixel = 0;

    J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_dbGetPixelNative");

    RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData), pixel);
    RETURN_STATUS_IF_NULL(d3dsdo->pResource, pixel);
    RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), pixel);

    if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
        D3DRQ_MarkLostIfNeeded(res, d3dsdo);
        return pixel;
    }
    RETURN_STATUS_IF_NULL(pCtx->GetResourceManager(), 0);

    IDirect3DDevice9 *pd3dDevice = pCtx->Get3DDevice();
    IDirect3DSurface9 *pSrc = d3dsdo->pResource->GetSurface();
    D3DFORMAT srcFmt = d3dsdo->pResource->GetDesc()->Format;

    pCtx->UpdateState(STATE_OTHEROP);

    res = pCtx->GetResourceManager()->
            GetLockableRTSurface(1, 1, srcFmt, &pLockableRes);
    if (SUCCEEDED(res)) {
        IDirect3DSurface9 *pTmpSurface;
        RECT srcRect = { x, y, x+1, y+1};
        RECT dstRect = { 0l, 0l, 1, 1 };

        pTmpSurface = pLockableRes->GetSurface();
        res = pd3dDevice->StretchRect(pSrc, &srcRect, pTmpSurface, &dstRect,
                                      D3DTEXF_NONE);
        if (SUCCEEDED(res)) {
            D3DLOCKED_RECT lRect;

            res = pTmpSurface->LockRect(&lRect, &dstRect, D3DLOCK_NOSYSLOCK);
            if (SUCCEEDED(res)) {
                if (srcFmt == D3DFMT_X8R8G8B8) {
                    pixel = *(jint*)lRect.pBits;
                } else {
                    pixel = *(unsigned short*)lRect.pBits;
                }
                pTmpSurface->UnlockRect();
            }
        }
    }
    D3DRQ_MarkLostIfNeeded(res, d3dsdo);

    return pixel;
}
Пример #3
0
/*
 * Class:     sun_java2d_d3d_D3DGraphicsDevice
 * Method:    enterFullScreenExclusiveNative
 * Signature: (IJ)V
 */
JNIEXPORT jboolean JNICALL
Java_sun_java2d_d3d_D3DGraphicsDevice_enterFullScreenExclusiveNative
  (JNIEnv *env, jclass gdc, jint gdiScreen, jlong window)
{
    HRESULT res;
    D3DPipelineManager *pMgr;
    D3DContext *pCtx;
    HWND hWnd;
    AwtWindow *w;
    D3DPRESENT_PARAMETERS newParams, *pCurParams;
    D3DDISPLAYMODE dm;
    UINT adapter;

    J2dTraceLn(J2D_TRACE_INFO, "D3DGD_enterFullScreenExclusiveNative");

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

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

    w = (AwtWindow *)AwtComponent::GetComponent((HWND)window);
    if (w == NULL || !::IsWindow(hWnd = w->GetTopLevelHWnd())) {
        J2dTraceLn(J2D_TRACE_WARNING,
                   "D3DGD_enterFullScreenExclusiveNative: disposed window");
        return JNI_FALSE;
    }

    // REMIND: should we also move the non-topleve window from
    // being on top here (it's moved to front in GraphicsDevice.setFSW())?

    pCtx->Get3DObject()->GetAdapterDisplayMode(adapter, &dm);
    pCurParams = pCtx->GetPresentationParams();

    // let the mananger know that we're entering the fs mode, it will
    // set the proper current focus window for us, which ConfigureContext will
    // use when creating the device
    pMgr->SetFSFocusWindow(adapter, hWnd);

    newParams = *pCurParams;
    newParams.hDeviceWindow = hWnd;
    newParams.Windowed = FALSE;
    newParams.BackBufferCount = 1;
    newParams.BackBufferFormat = dm.Format;
    newParams.FullScreen_RefreshRateInHz = dm.RefreshRate;
    newParams.BackBufferWidth = dm.Width;
    newParams.BackBufferHeight = dm.Height;
    newParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
    newParams.SwapEffect = D3DSWAPEFFECT_DISCARD;

    res = pCtx->ConfigureContext(&newParams);
    D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
    return SUCCEEDED(res);
}
Пример #4
0
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);
}
Пример #5
0
/*
 * Class:     sun_java2d_d3d_D3DSurfaceData
 * Method:    initTexture
 * Signature: (JZZ)Z
 */
JNIEXPORT jboolean
JNICALL Java_sun_java2d_d3d_D3DSurfaceData_initTexture
  (JNIEnv *env, jobject d3dsd,
  jlong pData, jboolean isRTT, jboolean isOpaque)
{
    HRESULT res;
    D3DSDOps *d3dsdo;
    D3DContext *pCtx;
    D3DPipelineManager *pMgr;
    D3DFORMAT format;

    J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initTexture");

    RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData), JNI_FALSE);
    RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);

    if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
        D3DRQ_MarkLostIfNeeded(res, d3dsdo);
        return JNI_FALSE;
    }
    RETURN_STATUS_IF_NULL(pCtx->GetResourceManager(), JNI_FALSE);

    pCtx->GetResourceManager()->ReleaseResource(d3dsdo->pResource);
    d3dsdo->pResource = NULL;

    if (isRTT && isOpaque) {
        format = pCtx->GetPresentationParams()->BackBufferFormat;
    } else {
        format = D3DFMT_UNKNOWN;
    }

    res = pCtx->GetResourceManager()->
        CreateTexture(d3dsdo->width, d3dsdo->height,
                      isRTT, isOpaque,
                      &format, 0/*usage*/, &d3dsdo->pResource);
    if (SUCCEEDED(res)) {
        J2dTraceLn1(J2D_TRACE_VERBOSE,
                    "  created texture pResource=%x", d3dsdo->pResource);
        d3dsdo->pResource->SetSDOps(d3dsdo);
    } else {
        D3DRQ_MarkLostIfNeeded(res, d3dsdo);
    }
    D3DSD_SetNativeDimensions(env, d3dsdo);

    return SUCCEEDED(res);
}
Пример #6
0
/*
 * Class:     sun_java2d_d3d_D3DGraphicsDevice
 * Method:    exitFullScreenExclusiveNative
 * Signature: (I)V
 */
JNIEXPORT jboolean JNICALL
Java_sun_java2d_d3d_D3DGraphicsDevice_exitFullScreenExclusiveNative
  (JNIEnv *env, jclass gdc, jint gdiScreen)
{
    HRESULT res;
    D3DPipelineManager *pMgr;
    D3DContext *pCtx;
    D3DPRESENT_PARAMETERS newParams, *pCurParams;
    UINT adapter;

    J2dTraceLn(J2D_TRACE_INFO, "D3DGD_exitFullScreenExclusiveNative");

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

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

    pCurParams = pCtx->GetPresentationParams();

    newParams = *pCurParams;
    // we're exiting fs, the device window can be 0
    newParams.hDeviceWindow = 0;
    newParams.Windowed = TRUE;
    newParams.BackBufferFormat = D3DFMT_UNKNOWN;
    newParams.BackBufferCount = 1;
    newParams.FullScreen_RefreshRateInHz = 0;
    newParams.BackBufferWidth = 0;
    newParams.BackBufferHeight = 0;
    newParams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    newParams.SwapEffect = D3DSWAPEFFECT_COPY;

    res = pCtx->ConfigureContext(&newParams);
    D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());

    // exited fs, update current focus window
    // note that we call this after this adapter exited fs mode so that
    // the rest of the adapters can be reset
    pMgr->SetFSFocusWindow(adapter, 0);

    return SUCCEEDED(res);
}
Пример #7
0
/*
 * Class:     sun_java2d_d3d_D3DGraphicsDevice
 * Method:    isD3DAvailableOnDeviceNative
 * Signature: (I)Z
 */
JNIEXPORT jboolean JNICALL
Java_sun_java2d_d3d_D3DGraphicsDevice_isD3DAvailableOnDeviceNative
  (JNIEnv *env, jclass gdc, jint gdiScreen)
{
    HRESULT res;
    D3DPipelineManager *pMgr;
    D3DContext *pCtx;
    UINT adapter;

    J2dTraceLn(J2D_TRACE_INFO, "D3DGD_isD3DAvailableOnDeviceNative");

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

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

    return JNI_TRUE;
}
Пример #8
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();
}
Пример #9
0
void D3DSD_Flush(void *pData)
{
    J2dTraceLn(J2D_TRACE_INFO, "D3DSD_Flush");
    RETURN_IF_NULL(pData);

    D3DSDOps *d3dsdo = (D3DSDOps*)pData;
    if (d3dsdo->pResource != NULL) {
        D3DContext *pCtx;
        D3DPipelineManager *pMgr;

        d3dsdo->pResource->SetSDOps(NULL);

        if ((pMgr = D3DPipelineManager::GetInstance()) != NULL &&
            SUCCEEDED(pMgr->GetD3DContext(d3dsdo->adapter, &pCtx)))
        {
            if (pCtx->GetResourceManager()) {
                pCtx->GetResourceManager()->ReleaseResource(d3dsdo->pResource);
            }
        }
        d3dsdo->pResource = NULL;
    }
}
Пример #10
0
/*
 * Class:     sun_java2d_d3d_D3DSurfaceData
 * Method:    getNativeResourceNative
 * Signature: (JI)J
 */
JNIEXPORT jlong JNICALL
    Java_sun_java2d_d3d_D3DSurfaceData_getNativeResourceNative
        (JNIEnv *env, jclass d3sdc, jlong pData, jint resType)
{
    D3DSDOps *d3dsdo;

    J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_getNativeResourceNative")

    RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData), 0L);

    if (resType == D3D_DEVICE_RESOURCE) {
        HRESULT res;
        D3DPipelineManager *pMgr;
        D3DContext *pCtx;

        RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), 0L);
        if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
            D3DRQ_MarkLostIfNeeded(res, d3dsdo);
            return 0L;
        }
        return ptr_to_jlong(pCtx->Get3DDevice());
    }

    RETURN_STATUS_IF_NULL(d3dsdo->pResource, 0L);

    if (resType == RT_PLAIN || resType == RT_TEXTURE) {
        return ptr_to_jlong(d3dsdo->pResource->GetSurface());
    }
    if (resType == TEXTURE) {
        return ptr_to_jlong(d3dsdo->pResource->GetTexture());
    }
    if (resType == FLIP_BACKBUFFER) {
        return ptr_to_jlong(d3dsdo->pResource->GetSwapChain());
    }

    return 0L;
}
Пример #11
0
/*
 * Class:     sun_java2d_d3d_D3DSurfaceData
 * Method:    updateWindowAccelImpl
 * Signature: (JJII)Z
 */
JNIEXPORT jboolean
JNICALL Java_sun_java2d_d3d_D3DSurfaceData_updateWindowAccelImpl
  (JNIEnv *env, jclass clazz, jlong pd3dsd, jlong pData, jint w, jint h)
{
    HRESULT res;
    AwtWindow *window;
    HBITMAP hBitmap = NULL;
    D3DSDOps *d3dsdo;
    D3DResource *pSrcRes;
    D3DContext *pCtx;
    D3DPipelineManager *pMgr;
    D3DResource *pLockableRes = NULL;
    IDirect3DSurface9 *pTmpSurface = NULL;
    IDirect3DDevice9 *pd3dDevice = NULL;
    D3DLOCKED_RECT lockedRect;

    J2dTraceLn(J2D_TRACE_ERROR, "D3DSurfaceData_updateWindowAccelImpl");

    if (w <= 0 || h <= 0) {
        return JNI_TRUE;
    }

    RETURN_STATUS_IF_NULL(window = (AwtWindow *)jlong_to_ptr(pData), JNI_FALSE);
    RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pd3dsd), JNI_FALSE);
    RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);
    RETURN_STATUS_IF_NULL(pSrcRes = d3dsdo->pResource, JNI_FALSE);

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

    RETURN_STATUS_IF_NULL(pd3dDevice = pCtx->Get3DDevice(), JNI_FALSE);
    pCtx->UpdateState(STATE_OTHEROP);

    res = pCtx->GetResourceManager()->
            GetBlitOSPSurface(pSrcRes->GetDesc()->Width,
                              pSrcRes->GetDesc()->Height,
                              pSrcRes->GetDesc()->Format,
                              &pLockableRes);
    if (FAILED(res)) {
        D3DRQ_MarkLostIfNeeded(res, d3dsdo);
        return JNI_FALSE;
    }
    pTmpSurface = pLockableRes->GetSurface();

    res = pd3dDevice->GetRenderTargetData(pSrcRes->GetSurface(), pTmpSurface);
    if (FAILED(res)) {
        D3DRQ_MarkLostIfNeeded(res, d3dsdo);
        return JNI_FALSE;
    }

    res = pTmpSurface->LockRect(&lockedRect, NULL, D3DLOCK_NOSYSLOCK);
    if (SUCCEEDED(res)) {
        hBitmap =
            BitmapUtil::CreateBitmapFromARGBPre(w, h,
                                                lockedRect.Pitch,
                                                (int*)lockedRect.pBits);
        pTmpSurface->UnlockRect();
    }
    RETURN_STATUS_IF_NULL(hBitmap, JNI_FALSE);

    window->UpdateWindow(env, NULL, w, h, hBitmap);

    // hBitmap is released in UpdateWindow

    return JNI_TRUE;
}
Пример #12
0
/*
 * Class:     sun_java2d_d3d_D3DSurfaceData
 * Method:    initFlipBackbuffer
 * Signature: (JJIZ)Z
 */
JNIEXPORT jboolean
JNICALL Java_sun_java2d_d3d_D3DSurfaceData_initFlipBackbuffer
  (JNIEnv *env, jobject d3dsd, jlong pData, jlong pPeerData,
  jint numBuffers, jint swapEffect,
  jint vSyncType)
{
    HRESULT res;
    D3DSDOps *d3dsdo;
    D3DContext *pCtx;
    D3DPipelineManager *pMgr;
    HWND hWnd;
    UINT presentationInterval;
    AwtComponent *pPeer;
    RECT r = { 0, 0, 0, 0 };

    J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initFlipBackbuffer");

    RETURN_STATUS_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData), JNI_FALSE);
    RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);
    RETURN_STATUS_IF_NULL(pPeer = (AwtComponent *)jlong_to_ptr(pPeerData),
                          JNI_FALSE);

    hWnd = pPeer->GetHWnd();
    if (!IsWindow(hWnd)) {
        J2dTraceLn(J2D_TRACE_WARNING,
                   "D3DSurfaceData_initFlipBackbuffer: disposed component");
        return JNI_FALSE;
    }

    pPeer->GetInsets(&r);
    d3dsdo->xoff = -r.left;
    d3dsdo->yoff = -r.top;

    if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) {
        D3DRQ_MarkLostIfNeeded(res, d3dsdo);
        return JNI_FALSE;
    }
    RETURN_STATUS_IF_NULL(pCtx->GetResourceManager(), JNI_FALSE);

    pCtx->GetResourceManager()->ReleaseResource(d3dsdo->pResource);
    d3dsdo->pResource = NULL;

    d3dsdo->swapEffect = (D3DSWAPEFFECT)swapEffect;

    // in full-screen mode we should v-sync
    if (pCtx->GetPresentationParams()->Windowed) {
        if (vSyncType == VSYNC_ON) {
            presentationInterval = D3DPRESENT_INTERVAL_ONE;
            J2dTraceLn(J2D_TRACE_VERBOSE,
                       "  windowed, forced interval: ONE");
        } else {
            presentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
            J2dTraceLn(J2D_TRACE_VERBOSE,
                       "  windowed, default interval: IMMEDIATE");
        }

        // REMIND: this is a workaround for the current issue
        // we have with non-copy flip chains: since we can not specify
        // the dest rectangle for Present for these modes, the result of
        // Present(NULL, NULL) is scaled to the client area.
        if (d3dsdo->xoff != 0 || d3dsdo->yoff != 0) {
            d3dsdo->swapEffect = D3DSWAPEFFECT_COPY;
        }
    } else {
        if (vSyncType == VSYNC_OFF) {
            presentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
            J2dTraceLn(J2D_TRACE_VERBOSE,
                       "  full-screen, forced interval: IMMEDIATE");
        } else {
            presentationInterval = D3DPRESENT_INTERVAL_ONE;
            J2dTraceLn(J2D_TRACE_VERBOSE,
                       "  full-screen, default interval: ONE");
        }
    }

    res = pCtx->GetResourceManager()->
        CreateSwapChain(hWnd, numBuffers,
                        d3dsdo->width, d3dsdo->height,
                        d3dsdo->swapEffect, presentationInterval,
                        &d3dsdo->pResource);
    if (SUCCEEDED(res)) {
        J2dTraceLn1(J2D_TRACE_VERBOSE, "  created swap chain pResource=0x%x",
                    d3dsdo->pResource);
        d3dsdo->pResource->SetSDOps(d3dsdo);
    } else {
        D3DRQ_MarkLostIfNeeded(res, d3dsdo);
    }
    D3DSD_SetNativeDimensions(env, d3dsdo);

    return SUCCEEDED(res);
}
Пример #13
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());
}