| /* |
| * Copyright (c) 2007, 2008, 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 "D3DResourceManager.h" |
| #include "awt.h" |
| #include "D3DPaints.h" |
| #include "D3DTextRenderer.h" |
| |
| void |
| D3DResource::Init(IDirect3DResource9 *pRes, IDirect3DSwapChain9 *pSC) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DResource::Init"); |
| |
| pResource = NULL; |
| pSwapChain = pSC; |
| pSurface = NULL; |
| pTexture = NULL; |
| pOps = NULL; |
| ZeroMemory(&desc, sizeof(desc)); |
| desc.Format = D3DFMT_UNKNOWN; |
| |
| if (pRes != NULL) { |
| pResource = pRes; |
| |
| D3DRESOURCETYPE type = pResource->GetType(); |
| switch (type) { |
| case D3DRTYPE_TEXTURE: |
| // addRef is needed because both pResource and pTexture will be |
| // Release()d, and they point to the same object |
| pResource->AddRef(); |
| pTexture = (IDirect3DTexture9*)pResource; |
| pTexture->GetSurfaceLevel(0, &pSurface); |
| break; |
| case D3DRTYPE_SURFACE: |
| pResource->AddRef(); |
| pSurface = (IDirect3DSurface9*)pResource; |
| break; |
| case D3DRTYPE_CUBETEXTURE: |
| ((IDirect3DCubeTexture9*)pResource)->GetLevelDesc(0, &desc); |
| break; |
| default: |
| J2dTraceLn1(J2D_TRACE_VERBOSE, " resource type=%d", type); |
| } |
| } else if (pSwapChain != NULL) { |
| pSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface); |
| } else { |
| J2dTraceLn(J2D_TRACE_VERBOSE, " pResource == pSwapChain == NULL"); |
| } |
| |
| if (pSurface != NULL) { |
| pSurface->GetDesc(&desc); |
| } |
| |
| SAFE_PRINTLN(pResource); |
| SAFE_PRINTLN(pSurface); |
| SAFE_PRINTLN(pTexture); |
| SAFE_PRINTLN(pSwapChain); |
| } |
| |
| D3DResource::~D3DResource() |
| { |
| Release(); |
| } |
| |
| void |
| D3DResource::SetSDOps(D3DSDOps *pOps) |
| { |
| if (pOps != NULL && this->pOps != NULL) { |
| // something's wrong, we're overwriting |
| // a non-null field (setting it to null is allowed) |
| J2dTraceLn2(J2D_TRACE_WARNING, |
| "D3DResource::SetSDOps: overwriting "\ |
| "this->pOps=0x%x with pOps=0x%x", this->pOps, pOps); |
| } |
| this->pOps = pOps; |
| } |
| |
| BOOL |
| D3DResource::IsDefaultPool() |
| { |
| if (desc.Format != D3DFMT_UNKNOWN) { |
| return (desc.Pool == D3DPOOL_DEFAULT); |
| } |
| return TRUE; |
| } |
| |
| void |
| D3DResource::Release() |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DResource::Release"); |
| |
| SAFE_PRINTLN(pResource); |
| SAFE_PRINTLN(pSurface); |
| SAFE_PRINTLN(pTexture); |
| SAFE_PRINTLN(pSwapChain); |
| |
| SAFE_RELEASE(pSurface); |
| SAFE_RELEASE(pTexture); |
| SAFE_RELEASE(pResource); |
| SAFE_RELEASE(pSwapChain); |
| |
| if (pOps != NULL) { |
| // if sdOps is not NULL it means that the release was initiated |
| // from the native level, and is caused by a surface loss |
| D3DSD_MarkLost(pOps); |
| pOps->pResource = NULL; |
| pOps = NULL; |
| } |
| } |
| |
| HRESULT |
| D3DResourceManager::CreateInstance(D3DContext *pCtx, |
| D3DResourceManager** ppResourceMgr) |
| { |
| HRESULT res; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::CreateInstance"); |
| |
| *ppResourceMgr = new D3DResourceManager(); |
| if (FAILED(res = (*ppResourceMgr)->Init(pCtx))) { |
| delete *ppResourceMgr; |
| *ppResourceMgr = NULL; |
| } |
| return res; |
| } |
| |
| D3DResourceManager::D3DResourceManager() |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::D3DRM"); |
| |
| this->pCtx = NULL; |
| this->pHead = NULL; |
| } |
| |
| HRESULT |
| D3DResourceManager::Init(D3DContext *pCtx) |
| { |
| J2dTraceLn1(J2D_TRACE_INFO, "D3DRM::Init pCtx=%x", pCtx); |
| if (this->pCtx != pCtx || |
| (this->pCtx != NULL && |
| this->pCtx->Get3DDevice() != pCtx->Get3DDevice())) |
| { |
| ReleaseAll(); |
| } |
| this->pCtx = pCtx; |
| return S_OK; |
| } |
| |
| D3DResourceManager::~D3DResourceManager() |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::~D3DRM"); |
| ReleaseAll(); |
| pCtx = NULL; |
| pHead = NULL; |
| } |
| |
| void |
| D3DResourceManager::ReleaseAll() |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::ReleaseAll"); |
| IManagedResource* pCurrent; |
| while (pHead != NULL) { |
| pCurrent = pHead; |
| pHead = pHead->pNext; |
| delete pCurrent; |
| } |
| pCachedDestTexture = NULL; |
| pBlitTexture = NULL; |
| pBlitRTTexture = NULL; |
| pBlitOSPSurface = NULL; |
| pGradientTexture = NULL; |
| pLookupOpLutTexture = NULL; |
| pMaskTexture = NULL; |
| pMultiGradientTexture = NULL; |
| pLockableRTSurface = NULL; |
| } |
| |
| void |
| D3DResourceManager::ReleaseDefPoolResources() |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::ReleaseDefPoolResources"); |
| // REMIND: for now, release all resources |
| ReleaseAll(); |
| } |
| |
| HRESULT |
| D3DResourceManager::ReleaseResource(IManagedResource* pResource) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::ReleaseResource"); |
| |
| if (pResource != NULL) { |
| J2dTraceLn1(J2D_TRACE_VERBOSE, " releasing pResource=%x", pResource); |
| if (pResource->pPrev != NULL) { |
| pResource->pPrev->pNext = pResource->pNext; |
| } else { |
| // it's the head |
| pHead = pResource->pNext; |
| if (pHead != NULL) { |
| pHead->pPrev = NULL; |
| } |
| } |
| if (pResource->pNext != NULL) { |
| pResource->pNext->pPrev = pResource->pPrev; |
| } |
| delete pResource; |
| } |
| return S_OK; |
| } |
| |
| HRESULT |
| D3DResourceManager::AddResource(IManagedResource* pResource) |
| { |
| HRESULT res = S_OK; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::AddResource"); |
| |
| if (pResource != NULL) { |
| J2dTraceLn1(J2D_TRACE_VERBOSE, " pResource=%x", pResource); |
| pResource->pPrev = NULL; |
| pResource->pNext = pHead; |
| if (pHead != NULL) { |
| pHead->pPrev = pResource; |
| } |
| pHead = pResource; |
| } |
| |
| return S_OK; |
| } |
| |
| HRESULT |
| D3DResourceManager::CreateTexture(UINT width, UINT height, |
| BOOL isRTT, BOOL isOpaque, |
| D3DFORMAT *pFormat, DWORD dwUsage, |
| D3DResource **ppTextureResource) |
| { |
| D3DPOOL pool; |
| D3DFORMAT format; |
| HRESULT res; |
| IDirect3DDevice9 *pd3dDevice; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::CreateTexture"); |
| J2dTraceLn4(J2D_TRACE_VERBOSE, " w=%d h=%d isRTT=%d isOpaque=%d", |
| width, height, isRTT, isOpaque); |
| |
| if (ppTextureResource == NULL || pCtx == NULL || |
| (pd3dDevice = pCtx->Get3DDevice()) == NULL) |
| { |
| return E_FAIL; |
| } |
| if (FAILED(res = pd3dDevice->TestCooperativeLevel())) { |
| return res; |
| } |
| |
| if (pFormat != NULL && *pFormat != D3DFMT_UNKNOWN) { |
| format = *pFormat; |
| } else { |
| if (isOpaque) { |
| format = D3DFMT_X8R8G8B8; |
| } else { |
| format = D3DFMT_A8R8G8B8; |
| } |
| } |
| |
| if (isRTT) { |
| dwUsage = D3DUSAGE_RENDERTARGET; |
| pool = D3DPOOL_DEFAULT; |
| } else { |
| if (dwUsage == D3DUSAGE_DYNAMIC && !pCtx->IsDynamicTextureSupported()) { |
| dwUsage = 0; |
| } |
| if (dwUsage == D3DUSAGE_DYNAMIC) { |
| pool = D3DPOOL_DEFAULT; |
| } else { |
| pool = pCtx->IsHWRasterizer() ? |
| D3DPOOL_MANAGED : D3DPOOL_SYSTEMMEM; |
| } |
| } |
| |
| if (pCtx->IsPow2TexturesOnly()) { |
| UINT w, h; |
| for (w = 1; width > w; w <<= 1); |
| for (h = 1; height > h; h <<= 1); |
| width = w; |
| height = h; |
| } |
| if (pCtx->IsSquareTexturesOnly()) { |
| if (width > height) { |
| height = width; |
| } else { |
| width = height; |
| } |
| } |
| |
| IDirect3DTexture9 *pTexture = NULL; |
| res = pd3dDevice->CreateTexture(width, height, 1/*levels*/, dwUsage, |
| format, pool, &pTexture, 0); |
| if (SUCCEEDED(res)) { |
| J2dTraceLn1(J2D_TRACE_VERBOSE, " created texture: 0x%x", pTexture); |
| *ppTextureResource = new D3DResource((IDirect3DResource9*)pTexture); |
| res = AddResource(*ppTextureResource); |
| } else { |
| DebugPrintD3DError(res, "D3DRM::CreateTexture failed"); |
| *ppTextureResource = NULL; |
| format = D3DFMT_UNKNOWN; |
| } |
| |
| if (pFormat != NULL) { |
| *pFormat = format; |
| } |
| |
| return res; |
| } |
| |
| HRESULT D3DResourceManager::CreateRTSurface(UINT width, UINT height, |
| BOOL isOpaque, BOOL isLockable, |
| D3DFORMAT *pFormat/*out*/, |
| D3DResource** ppSurfaceResource/*out*/) |
| { |
| HRESULT res; |
| IDirect3DDevice9 *pd3dDevice; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::CreateRTSurface"); |
| J2dTraceLn3(J2D_TRACE_VERBOSE, " w=%d h=%d isOpaque=%d", |
| width, height, isOpaque); |
| |
| if (pCtx == NULL || ppSurfaceResource == NULL || |
| (pd3dDevice = pCtx->Get3DDevice()) == NULL) |
| { |
| return E_FAIL; |
| } |
| if (FAILED(res = pd3dDevice->TestCooperativeLevel())) { |
| return res; |
| } |
| |
| D3DPRESENT_PARAMETERS *curParams = pCtx->GetPresentationParams(); |
| D3DFORMAT format = isOpaque ? curParams->BackBufferFormat : D3DFMT_A8R8G8B8; |
| IDirect3DSurface9 *pSurface = NULL; |
| |
| res = pd3dDevice->CreateRenderTarget(width, height, format, |
| D3DMULTISAMPLE_NONE, 0, |
| isLockable, |
| &pSurface, NULL); |
| if (SUCCEEDED(res)) { |
| J2dTraceLn1(J2D_TRACE_VERBOSE, " created RT Surface: 0x%x ", pSurface); |
| if (pFormat != NULL) { |
| *pFormat = format; |
| } |
| *ppSurfaceResource = new D3DResource((IDirect3DResource9*)pSurface); |
| res = AddResource(*ppSurfaceResource); |
| } else { |
| DebugPrintD3DError(res, "D3DRM::CreateRTSurface failed"); |
| ppSurfaceResource = NULL; |
| } |
| return res; |
| } |
| |
| // REMIND: this method is currently unused; consider removing it later... |
| HRESULT D3DResourceManager::CreateOSPSurface(UINT width, UINT height, |
| D3DFORMAT fmt, |
| D3DResource** ppSurfaceResource/*out*/) |
| { |
| HRESULT res; |
| IDirect3DDevice9 *pd3dDevice; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::CreateOSPSurface"); |
| J2dTraceLn2(J2D_TRACE_VERBOSE, " w=%d h=%d", width, height); |
| |
| if (pCtx == NULL || ppSurfaceResource == NULL || |
| (pd3dDevice = pCtx->Get3DDevice()) == NULL) |
| { |
| return E_FAIL; |
| } |
| if (FAILED(res = pd3dDevice->TestCooperativeLevel())) { |
| return res; |
| } |
| |
| // since the off-screen plain surface is intended to be used with |
| // the UpdateSurface() method, it is essential that it be created |
| // in the same format as the destination and allocated in the |
| // SYSTEMMEM pool (otherwise UpdateSurface() will fail) |
| D3DFORMAT format; |
| if (fmt == D3DFMT_UNKNOWN) { |
| format = pCtx->GetPresentationParams()->BackBufferFormat; |
| } else { |
| format = fmt; |
| } |
| D3DPOOL pool = D3DPOOL_SYSTEMMEM; |
| IDirect3DSurface9 *pSurface = NULL; |
| |
| res = pd3dDevice->CreateOffscreenPlainSurface(width, height, |
| format, pool, |
| &pSurface, NULL); |
| if (SUCCEEDED(res)) { |
| J2dTraceLn1(J2D_TRACE_VERBOSE, " created OSP Surface: 0x%x ",pSurface); |
| *ppSurfaceResource = new D3DResource((IDirect3DResource9*)pSurface); |
| res = AddResource(*ppSurfaceResource); |
| } else { |
| DebugPrintD3DError(res, "D3DRM::CreateOSPSurface failed"); |
| ppSurfaceResource = NULL; |
| } |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::CreateSwapChain(HWND hWnd, UINT numBuffers, |
| UINT width, UINT height, |
| D3DSWAPEFFECT swapEffect, |
| UINT presentationInterval, |
| D3DResource ** ppSwapChainResource) |
| { |
| HRESULT res; |
| IDirect3DDevice9 *pd3dDevice; |
| IDirect3DSwapChain9 *pSwapChain = NULL; |
| D3DPRESENT_PARAMETERS newParams, *curParams; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::CreateSwapChain"); |
| J2dTraceLn4(J2D_TRACE_VERBOSE, " w=%d h=%d hwnd=%x numBuffers=%d", |
| width, height, hWnd, numBuffers); |
| |
| if (pCtx == NULL || ppSwapChainResource == NULL || |
| (pd3dDevice = pCtx->Get3DDevice()) == NULL) |
| { |
| return E_FAIL; |
| } |
| RETURN_STATUS_IF_FAILED(res = pd3dDevice->TestCooperativeLevel()); |
| |
| curParams = pCtx->GetPresentationParams(); |
| |
| if (curParams->Windowed == FALSE) { |
| // there's a single swap chain in full-screen mode, use it if |
| // it fits our parameters, reset the device otherwise |
| if (curParams->BackBufferCount != numBuffers || |
| curParams->SwapEffect != swapEffect || |
| curParams->PresentationInterval != presentationInterval) |
| { |
| newParams = *curParams; |
| newParams.BackBufferCount = numBuffers; |
| newParams.SwapEffect = swapEffect; |
| newParams.PresentationInterval = presentationInterval; |
| |
| res = pCtx->ConfigureContext(&newParams); |
| RETURN_STATUS_IF_FAILED(res); |
| // this reset will not have released the device, so our pd3dDevice |
| // is still valid, but to be on a safe side, reset it |
| pd3dDevice = pCtx->Get3DDevice(); |
| } |
| res = pd3dDevice->GetSwapChain(0, &pSwapChain); |
| } else { |
| ZeroMemory(&newParams, sizeof(D3DPRESENT_PARAMETERS)); |
| newParams.BackBufferWidth = width; |
| newParams.BackBufferHeight = height; |
| newParams.hDeviceWindow = hWnd; |
| newParams.Windowed = TRUE; |
| newParams.BackBufferCount = numBuffers; |
| newParams.SwapEffect = swapEffect; |
| newParams.PresentationInterval = presentationInterval; |
| |
| res = pd3dDevice->CreateAdditionalSwapChain(&newParams, &pSwapChain); |
| } |
| |
| if (SUCCEEDED(res)) { |
| J2dTraceLn1(J2D_TRACE_VERBOSE," created swap chain: 0x%x ",pSwapChain); |
| *ppSwapChainResource = new D3DResource(pSwapChain); |
| res = AddResource(*ppSwapChainResource); |
| } else { |
| DebugPrintD3DError(res, "D3DRM::CreateSwapChain failed"); |
| *ppSwapChainResource = NULL; |
| } |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::GetMaskTexture(D3DResource **ppTextureResource) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::GetMaskTexture"); |
| |
| RETURN_STATUS_IF_NULL(pCtx, E_FAIL); |
| RETURN_STATUS_IF_NULL(ppTextureResource, E_FAIL); |
| |
| D3DFORMAT format = pCtx->IsTextureFormatSupported(D3DFMT_A8) ? |
| D3DFMT_A8 : D3DFMT_A8R8G8B8; |
| |
| jboolean needsInit = (pMaskTexture == NULL); |
| HRESULT res; |
| if (FAILED(res = |
| GetStockTextureResource(D3D_MASK_CACHE_WIDTH_IN_TEXELS, |
| D3D_MASK_CACHE_HEIGHT_IN_TEXELS, |
| FALSE/*isRTT*/, FALSE/*isOpaque*/, &format, 0, |
| &pMaskTexture))) |
| { |
| return res; |
| } |
| |
| if (needsInit) { |
| // init special fully opaque tile in the upper-right corner of |
| // the mask cache texture |
| jubyte allOnes[D3D_MASK_CACHE_TILE_SIZE]; |
| memset(allOnes, 0xff, D3D_MASK_CACHE_TILE_SIZE); |
| if (FAILED(res = pCtx->UploadTileToTexture( |
| pMaskTexture, |
| allOnes, |
| D3D_MASK_CACHE_SPECIAL_TILE_X, |
| D3D_MASK_CACHE_SPECIAL_TILE_Y, |
| 0, 0, |
| D3D_MASK_CACHE_TILE_WIDTH, |
| D3D_MASK_CACHE_TILE_HEIGHT, |
| D3D_MASK_CACHE_TILE_WIDTH, |
| TILEFMT_1BYTE_ALPHA))) |
| { |
| return res; |
| } |
| } |
| |
| *ppTextureResource = pMaskTexture; |
| |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::GetBlitTexture(D3DResource **ppTextureResource) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::GetBlitTexture"); |
| |
| RETURN_STATUS_IF_NULL(pCtx, E_FAIL); |
| RETURN_STATUS_IF_NULL(ppTextureResource, E_FAIL); |
| |
| HRESULT res = |
| GetStockTextureResource(D3DC_BLIT_TILE_SIZE, D3DC_BLIT_TILE_SIZE, |
| FALSE/*isRTT*/, FALSE/*isOpaque*/, NULL, |
| D3DUSAGE_DYNAMIC, |
| &pBlitTexture); |
| *ppTextureResource = pBlitTexture; |
| |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::GetGradientTexture(D3DResource **ppTextureResource) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::GetGradientTexture"); |
| |
| RETURN_STATUS_IF_NULL(pCtx, E_FAIL); |
| RETURN_STATUS_IF_NULL(ppTextureResource, E_FAIL); |
| |
| HRESULT res = |
| GetStockTextureResource(2, 1, |
| FALSE/*isRTT*/, FALSE/*isOpaque*/, NULL, 0, |
| &pGradientTexture); |
| *ppTextureResource = pGradientTexture; |
| |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::GetMultiGradientTexture(D3DResource **ppTextureResource) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::GetMultiGradientTexture"); |
| |
| RETURN_STATUS_IF_NULL(pCtx, E_FAIL); |
| RETURN_STATUS_IF_NULL(ppTextureResource, E_FAIL); |
| |
| HRESULT res = |
| GetStockTextureResource(MAX_MULTI_GRADIENT_COLORS, 1, |
| FALSE/*isRTT*/, FALSE/*isOpaque*/, NULL, 0, |
| &pMultiGradientTexture); |
| *ppTextureResource = pMultiGradientTexture; |
| |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::GetLookupOpLutTexture(D3DResource **ppTextureResource) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::GetLookupOpTexture"); |
| |
| RETURN_STATUS_IF_NULL(pCtx, E_FAIL); |
| RETURN_STATUS_IF_NULL(ppTextureResource, E_FAIL); |
| |
| D3DFORMAT format = D3DFMT_L16; |
| HRESULT res = |
| GetStockTextureResource(256, 4, |
| FALSE/*isRTT*/, FALSE/*isOpaque*/, &format, 0, |
| &pLookupOpLutTexture); |
| *ppTextureResource = pLookupOpLutTexture; |
| |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::GetBlitRTTexture(UINT width, UINT height, D3DFORMAT format, |
| D3DResource **ppTextureResource) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::GetBlitRTTexture"); |
| RETURN_STATUS_IF_NULL(pCtx, E_FAIL); |
| RETURN_STATUS_IF_NULL(ppTextureResource, E_FAIL); |
| |
| HRESULT res = GetStockTextureResource(width, height, |
| TRUE/*isRTT*/, FALSE/*isOpaque*/, |
| &format, 0, |
| &pBlitRTTexture); |
| if (SUCCEEDED(res)) { |
| D3DSURFACE_DESC *pDesc = pBlitRTTexture->GetDesc(); |
| D3DCAPS9 *pDevCaps = pCtx->GetDeviceCaps(); |
| if ((width <= pDesc->Width && height <= pDesc->Height) && |
| (format == pDesc->Format || |
| SUCCEEDED(pCtx->Get3DObject()->CheckDeviceFormatConversion( |
| pDevCaps->AdapterOrdinal, |
| pDevCaps->DeviceType, format, pDesc->Format)))) |
| { |
| *ppTextureResource = pBlitRTTexture; |
| return res; |
| } |
| // current texture doesn't fit, release and allocate a new one |
| ReleaseResource(pBlitRTTexture); |
| pBlitRTTexture = NULL; |
| } |
| if (width < D3DC_BLIT_TILE_SIZE) width = D3DC_BLIT_TILE_SIZE; |
| if (height < D3DC_BLIT_TILE_SIZE) height = D3DC_BLIT_TILE_SIZE; |
| |
| res = CreateTexture(width, height, TRUE, FALSE, &format, 0,&pBlitRTTexture); |
| *ppTextureResource = pBlitRTTexture; |
| |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::GetBlitOSPSurface(UINT width, UINT height, D3DFORMAT fmt, |
| D3DResource **ppSurfaceResource) |
| { |
| HRESULT res = S_OK; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::GetBlitOSPSurface"); |
| RETURN_STATUS_IF_NULL(pCtx, E_FAIL); |
| RETURN_STATUS_IF_NULL(ppSurfaceResource, E_FAIL); |
| |
| if (pBlitOSPSurface != NULL) { |
| D3DSURFACE_DESC *pDesc = pBlitOSPSurface->GetDesc(); |
| if (width == pDesc->Width && height == pDesc->Height && |
| (fmt == pDesc->Format || fmt == D3DFMT_UNKNOWN)) |
| { |
| *ppSurfaceResource = pBlitOSPSurface; |
| return res; |
| } |
| // current surface doesn't fit, release and allocate a new one |
| ReleaseResource(pBlitOSPSurface); |
| pBlitOSPSurface = NULL; |
| } |
| |
| res = CreateOSPSurface(width, height, fmt, &pBlitOSPSurface); |
| *ppSurfaceResource = pBlitOSPSurface; |
| |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::GetLockableRTSurface(UINT width, UINT height, |
| D3DFORMAT format, |
| D3DResource **ppSurfaceResource) |
| { |
| HRESULT res = S_OK; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::GetLockableRTSurface"); |
| RETURN_STATUS_IF_NULL(pCtx, E_FAIL); |
| RETURN_STATUS_IF_NULL(ppSurfaceResource, E_FAIL); |
| |
| if (pLockableRTSurface != NULL) { |
| D3DSURFACE_DESC *pDesc = pLockableRTSurface->GetDesc(); |
| if (width <= pDesc->Width && height <= pDesc->Height && |
| format == pDesc->Format) |
| { |
| *ppSurfaceResource = pLockableRTSurface; |
| return res; |
| } |
| // current surface doesn't fit, release and allocate a new one |
| ReleaseResource(pLockableRTSurface); |
| pLockableRTSurface = NULL; |
| } |
| if (width < D3DC_BLIT_TILE_SIZE) width = D3DC_BLIT_TILE_SIZE; |
| if (height < D3DC_BLIT_TILE_SIZE) height = D3DC_BLIT_TILE_SIZE; |
| |
| res = CreateRTSurface(width,height, |
| (format != D3DFMT_A8R8G8B8), TRUE /*lockable*/, |
| &format, &pLockableRTSurface); |
| *ppSurfaceResource = pLockableRTSurface; |
| |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::GetCachedDestTexture(D3DFORMAT format, |
| D3DResource **ppTextureResource) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "D3DRM::GetCachedDestTexture"); |
| |
| RETURN_STATUS_IF_NULL(pCtx, E_FAIL); |
| RETURN_STATUS_IF_NULL(ppTextureResource, E_FAIL); |
| |
| HRESULT res = |
| GetStockTextureResource(D3DTR_CACHED_DEST_WIDTH, |
| D3DTR_CACHED_DEST_HEIGHT, |
| TRUE/*isRTT*/, FALSE/*isOpaque*/, |
| &format, 0, &pCachedDestTexture); |
| if (SUCCEEDED(res)) { |
| D3DSURFACE_DESC *pDesc = pCachedDestTexture->GetDesc(); |
| D3DCAPS9 *pDevCaps = pCtx->GetDeviceCaps(); |
| if ((format == pDesc->Format || |
| SUCCEEDED(pCtx->Get3DObject()->CheckDeviceFormatConversion( |
| pDevCaps->AdapterOrdinal, |
| pDevCaps->DeviceType, format, pDesc->Format)))) |
| { |
| *ppTextureResource = pCachedDestTexture; |
| return res; |
| } |
| // current texture doesn't fit, release and allocate a new one |
| ReleaseResource(pCachedDestTexture); |
| pCachedDestTexture = NULL; |
| } |
| res = CreateTexture(D3DTR_CACHED_DEST_WIDTH, D3DTR_CACHED_DEST_HEIGHT, |
| TRUE, FALSE, &format, 0, |
| &pCachedDestTexture); |
| *ppTextureResource = pCachedDestTexture; |
| return res; |
| } |
| |
| HRESULT |
| D3DResourceManager::GetStockTextureResource(UINT width, UINT height, |
| BOOL isRTT, BOOL isOpaque, |
| D3DFORMAT *pFormat/*in/out*/, |
| DWORD dwUsage, |
| D3DResource **ppTextureResource) |
| { |
| D3DResource *pResource = *ppTextureResource; |
| if (pResource != NULL) { |
| if (pResource->GetTexture() != NULL) { |
| return S_OK; |
| } |
| ReleaseResource(pResource); |
| *ppTextureResource = NULL; |
| } |
| |
| return CreateTexture(width, height, isRTT, isOpaque, pFormat, dwUsage, |
| ppTextureResource); |
| } |