/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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()); }