| /* |
| * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| #include "D3DPipeline.h" |
| #include <jlong.h> |
| #include "D3DSurfaceData.h" |
| #include "D3DPipelineManager.h" |
| #include "Trace.h" |
| #include "awt_Toolkit.h" |
| #include "awt_Window.h" |
| #include "awt_BitmapUtil.h" |
| #include "D3DRenderQueue.h" |
| |
| |
| // REMIND: move to awt_Component.h |
| extern "C" HWND AwtComponent_GetHWnd(JNIEnv *env, jlong pData); |
| |
| /* This looks weird. but since some AWT headers need to be included, |
| * we end up with AWT's alloc.h macro definition of ExceptionOccurred. |
| * The reasons for that re-defintion do not apply to this code, so undef it. |
| */ |
| #undef ExceptionOccurred |
| |
| /** |
| * Initializes nativeWidth/Height fields of the SurfaceData object with |
| * dimensions on the native surface. |
| */ |
| void D3DSD_SetNativeDimensions(JNIEnv *env, D3DSDOps *d3dsdo) { |
| jobject sdObject; |
| jint width, height; |
| |
| RETURN_IF_NULL(sdObject = env->NewLocalRef(d3dsdo->sdOps.sdObject)); |
| |
| if (d3dsdo->pResource != NULL) { |
| width = d3dsdo->pResource->GetDesc()->Width; |
| height = d3dsdo->pResource->GetDesc()->Height; |
| } else { |
| width = d3dsdo->width; |
| height = d3dsdo->height; |
| } |
| |
| JNU_SetFieldByName(env, NULL, sdObject, "nativeWidth", "I", width); |
| if (!(env->ExceptionOccurred())) { |
| JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height); |
| } |
| |
| env->DeleteLocalRef(sdObject); |
| } |
| |
| 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; |
| } |
| } |
| |
| void |
| D3DSD_MarkLost(void *pData) |
| { |
| D3DSDOps *d3dsdo; |
| jobject sdObject; |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DSD_MarkLost"); |
| |
| RETURN_IF_NULL(pData); |
| |
| d3dsdo = (D3DSDOps*)pData; |
| RETURN_IF_NULL(sdObject = env->NewLocalRef(d3dsdo->sdOps.sdObject)); |
| |
| JNU_CallMethodByName(env, NULL, sdObject, |
| "setSurfaceLost", "(Z)V", JNI_TRUE); |
| |
| env->DeleteLocalRef(sdObject); |
| } |
| |
| // ------------ generic SurfaceData.h functions ---------------- |
| |
| void |
| D3DSD_Dispose(JNIEnv *env, SurfaceDataOps *ops) |
| { |
| D3DSDOps *d3dsdo = (D3DSDOps *)ops; |
| RETURN_IF_NULL(d3dsdo); |
| |
| JNU_CallStaticMethodByName(env, NULL, "sun/java2d/d3d/D3DSurfaceData", |
| "dispose", "(J)V", |
| ptr_to_jlong(ops)); |
| } |
| |
| /** |
| * This is the implementation of the general surface LockFunc defined in |
| * SurfaceData.h. |
| */ |
| jint |
| D3DSD_Lock(JNIEnv *env, |
| SurfaceDataOps *ops, |
| SurfaceDataRasInfo *pRasInfo, |
| jint lockflags) |
| { |
| JNU_ThrowInternalError(env, "D3DSD_Lock not implemented!"); |
| return SD_FAILURE; |
| } |
| |
| /** |
| * This is the implementation of the general GetRasInfoFunc defined in |
| * SurfaceData.h. |
| */ |
| void |
| D3DSD_GetRasInfo(JNIEnv *env, |
| SurfaceDataOps *ops, |
| SurfaceDataRasInfo *pRasInfo) |
| { |
| JNU_ThrowInternalError(env, "D3DSD_GetRasInfo not implemented!"); |
| } |
| |
| /** |
| * This is the implementation of the general surface UnlockFunc defined in |
| * SurfaceData.h. |
| */ |
| void |
| D3DSD_Unlock(JNIEnv *env, |
| SurfaceDataOps *ops, |
| SurfaceDataRasInfo *pRasInfo) |
| { |
| JNU_ThrowInternalError(env, "D3DSD_Unlock not implemented!"); |
| } |
| |
| // ------------ D3DSurfaceData's JNI methods ---------------- |
| |
| |
| extern "C" { |
| |
| /* |
| * Class: sun_java2d_d3d_D3DSurfaceData |
| * Method: initOps |
| * Signature: (III)V |
| */ |
| JNIEXPORT void |
| JNICALL Java_sun_java2d_d3d_D3DSurfaceData_initOps |
| (JNIEnv *env, jobject d3dsd, jint gdiScreen, jint width, jint height) |
| { |
| D3DPipelineManager *pMgr; |
| D3DSDOps *d3dsdo = (D3DSDOps *)SurfaceData_InitOps(env, d3dsd, |
| sizeof(D3DSDOps)); |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initOps"); |
| |
| if (d3dsdo == NULL) { |
| JNU_ThrowOutOfMemoryError(env, "creating native d3d ops"); |
| return; |
| } |
| |
| d3dsdo->sdOps.Lock = D3DSD_Lock; |
| d3dsdo->sdOps.GetRasInfo = D3DSD_GetRasInfo; |
| d3dsdo->sdOps.Unlock = D3DSD_Unlock; |
| d3dsdo->sdOps.Dispose = D3DSD_Dispose; |
| |
| d3dsdo->xoff = 0; |
| d3dsdo->yoff = 0; |
| d3dsdo->width = width; |
| d3dsdo->height = height; |
| |
| d3dsdo->pResource = NULL; |
| |
| d3dsdo->adapter = |
| (pMgr = D3DPipelineManager::GetInstance()) == NULL ? |
| D3DADAPTER_DEFAULT : |
| pMgr->GetAdapterOrdinalForScreen(gdiScreen); |
| } |
| |
| |
| /* |
| * 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_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_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_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_D3DSurfaceData |
| * Method: dbSetPixelNative |
| * Signature: (JIII)V |
| */ |
| JNIEXPORT void JNICALL Java_sun_java2d_d3d_D3DSurfaceData_dbSetPixelNative |
| (JNIEnv *env, jclass clazz, jlong pData, jint x, jint y, jint pixel) |
| { |
| HRESULT res; |
| D3DSDOps *d3dsdo; |
| D3DResource *pLockableRes; |
| D3DContext *pCtx; |
| D3DPipelineManager *pMgr; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_dbSetPixelNative"); |
| |
| RETURN_IF_NULL(d3dsdo = (D3DSDOps *)jlong_to_ptr(pData)); |
| RETURN_IF_NULL(d3dsdo->pResource); |
| RETURN_IF_NULL(pMgr = D3DPipelineManager::GetInstance()); |
| |
| if (FAILED(res = pMgr->GetD3DContext(d3dsdo->adapter, &pCtx))) { |
| D3DRQ_MarkLostIfNeeded(res, d3dsdo); |
| return; |
| } |
| RETURN_IF_NULL(pCtx->GetResourceManager()); |
| |
| 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; |
| D3DLOCKED_RECT lRect; |
| RECT srcRect = { 0l, 0l, 1, 1 }; |
| RECT dstRect = { x, y, x+1, y+1}; |
| |
| pTmpSurface = pLockableRes->GetSurface(); |
| res = pTmpSurface->LockRect(&lRect, &srcRect, D3DLOCK_NOSYSLOCK); |
| if (SUCCEEDED(res)) { |
| if (srcFmt == D3DFMT_X8R8G8B8) { |
| *(jint*)lRect.pBits = pixel; |
| } else { |
| *(unsigned short*)lRect.pBits = (unsigned short)pixel; |
| } |
| pTmpSurface->UnlockRect(); |
| |
| res = pd3dDevice->StretchRect(pTmpSurface, &srcRect, pSrc, &dstRect, |
| D3DTEXF_NONE); |
| } |
| } |
| D3DRQ_MarkLostIfNeeded(res, d3dsdo); |
| } |
| |
| /* |
| * 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; |
| } |
| } |