/* * Class: sun_java2d_d3d_D3DSurfaceData * Method: initPlain * Signature: (JZ)Z */ JNIEXPORT jboolean JNICALL Java_sun_java2d_d3d_D3DSurfaceData_initRTSurface (JNIEnv *env, jobject d3dsd, jlong pData, jboolean isOpaque) { HRESULT res; D3DSDOps *d3dsdo; D3DContext *pCtx; D3DPipelineManager *pMgr; D3DFORMAT format = D3DFMT_UNKNOWN; J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initRTSurface"); 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; res = pCtx->GetResourceManager()-> CreateRTSurface(d3dsdo->width, d3dsdo->height, isOpaque, FALSE /*lockable*/, &format, &d3dsdo->pResource); if (SUCCEEDED(res)) { J2dTraceLn1(J2D_TRACE_VERBOSE, " created RT surface 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: 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; }
/* * 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; }
/* * 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; }
/* * 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()); }