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