mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-14 08:58:46 +00:00
6733976: VS2008 errors compiling AWT files - explicit casts need to be added 6728735: VS2008 errors compiling UnicowsLoader.h and fatal error in awtmsg.h Unicows-related and Win95/98/Me-related code is removed Reviewed-by: uta, tdv
937 lines
33 KiB
C++
937 lines
33 KiB
C++
/*
|
|
* Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
* have any questions.
|
|
*/
|
|
|
|
#include "D3DBadHardware.h"
|
|
#include "D3DPipelineManager.h"
|
|
#include "D3DRenderQueue.h"
|
|
#include "WindowsFlags.h"
|
|
#include "awt_Win32GraphicsDevice.h"
|
|
|
|
// state of the adapter prior to initialization
|
|
#define CONTEXT_NOT_INITED 0
|
|
// this state is set if adapter initialization had failed
|
|
#define CONTEXT_INIT_FAILED (-1)
|
|
// this state is set if adapter was successfully created
|
|
#define CONTEXT_CREATED 1
|
|
|
|
static BOOL bNoHwCheck = (getenv("J2D_D3D_NO_HWCHECK") != NULL);
|
|
|
|
D3DPipelineManager *D3DPipelineManager::pMgr = NULL;
|
|
|
|
D3DPipelineManager * D3DPipelineManager::CreateInstance(void)
|
|
{
|
|
if (!IsD3DEnabled() ||
|
|
FAILED((D3DPipelineManager::CheckOSVersion())) ||
|
|
FAILED((D3DPipelineManager::GDICheckForBadHardware())))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (pMgr == NULL) {
|
|
pMgr = new D3DPipelineManager();
|
|
if (FAILED(pMgr->InitD3D())) {
|
|
SAFE_DELETE(pMgr);
|
|
}
|
|
} else {
|
|
// this should never happen so to be on the safe side do not
|
|
// use this unexpected pointer, do not try to release it, just null
|
|
// it out and fail safely
|
|
J2dRlsTraceLn1(J2D_TRACE_ERROR,
|
|
"D3DPPLM::CreateInstance: unexpected instance: 0x%x,"\
|
|
" abort.", pMgr);
|
|
pMgr = NULL;
|
|
}
|
|
return pMgr;
|
|
}
|
|
|
|
void D3DPipelineManager::DeleteInstance()
|
|
{
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::DeleteInstance()");
|
|
SAFE_DELETE(pMgr);
|
|
}
|
|
|
|
D3DPipelineManager * D3DPipelineManager::GetInstance(void)
|
|
{
|
|
return pMgr;
|
|
}
|
|
|
|
D3DPipelineManager::D3DPipelineManager(void)
|
|
{
|
|
pd3d9 = NULL;
|
|
hLibD3D9 = NULL;
|
|
pAdapters = NULL;
|
|
adapterCount = 0;
|
|
currentFSFocusAdapter = -1;
|
|
defaultFocusWindow = 0;
|
|
devType = SelectDeviceType();
|
|
}
|
|
|
|
D3DPipelineManager::~D3DPipelineManager(void)
|
|
{
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::~D3DPipelineManager()");
|
|
ReleaseD3D();
|
|
}
|
|
|
|
HRESULT D3DPipelineManager::ReleaseD3D(void)
|
|
{
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::ReleaseD3D()");
|
|
|
|
ReleaseAdapters();
|
|
|
|
SAFE_RELEASE(pd3d9);
|
|
|
|
if (hLibD3D9 != NULL) {
|
|
::FreeLibrary(hLibD3D9);
|
|
hLibD3D9 = NULL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// Creates a Direct3D9 object and initializes adapters.
|
|
// If succeeded, returns S_OK, otherwise returns the error code.
|
|
HRESULT D3DPipelineManager::InitD3D(void)
|
|
{
|
|
typedef IDirect3D9 * WINAPI FnDirect3DCreate9(UINT SDKVersion);
|
|
|
|
hLibD3D9 = ::LoadLibrary(TEXT("d3d9.dll"));
|
|
if (hLibD3D9 == NULL) {
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: no d3d9.dll");
|
|
return E_FAIL;
|
|
}
|
|
|
|
FnDirect3DCreate9 *d3dcreate9 = NULL;
|
|
d3dcreate9 = (FnDirect3DCreate9*)
|
|
::GetProcAddress(hLibD3D9, "Direct3DCreate9");
|
|
if (d3dcreate9 == NULL) {
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: no Direct3DCreate9");
|
|
::FreeLibrary(hLibD3D9);
|
|
return E_FAIL;
|
|
}
|
|
|
|
pd3d9 = d3dcreate9(D3D_SDK_VERSION);
|
|
if (pd3d9 == NULL) {
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
|
"InitD3D: unable to create IDirect3D9 object");
|
|
::FreeLibrary(hLibD3D9);
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT res;
|
|
if (FAILED(res = InitAdapters())) {
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: failed to init adapters");
|
|
ReleaseD3D();
|
|
return res;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT D3DPipelineManager::ReleaseAdapters()
|
|
{
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::ReleaseAdapters()");
|
|
|
|
D3DRQ_ResetCurrentContextAndDestination();
|
|
if (pAdapters != NULL) {
|
|
for (UINT i = 0; i < adapterCount; i++) {
|
|
if (pAdapters[i].pd3dContext != NULL) {
|
|
delete pAdapters[i].pd3dContext;
|
|
}
|
|
}
|
|
delete[] pAdapters;
|
|
pAdapters = NULL;
|
|
}
|
|
if (defaultFocusWindow != 0) {
|
|
DestroyWindow(defaultFocusWindow);
|
|
UnregisterClass(L"D3DFocusWindow", GetModuleHandle(NULL));
|
|
defaultFocusWindow = 0;
|
|
}
|
|
currentFSFocusAdapter = -1;
|
|
return S_OK;
|
|
}
|
|
|
|
// static
|
|
void D3DPipelineManager::NotifyAdapterEventListeners(UINT adapter,
|
|
jint eventType)
|
|
{
|
|
HMONITOR hMon;
|
|
int gdiScreen;
|
|
D3DPipelineManager *pMgr;
|
|
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
|
|
|
pMgr = D3DPipelineManager::GetInstance();
|
|
RETURN_IF_NULL(pMgr);
|
|
hMon = pMgr->pd3d9->GetAdapterMonitor(adapter);
|
|
gdiScreen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hMon);
|
|
|
|
JNU_CallStaticMethodByName(env, NULL,
|
|
"sun/java2d/pipe/hw/AccelDeviceEventNotifier",
|
|
"eventOccured", "(II)V",
|
|
gdiScreen, eventType);
|
|
}
|
|
|
|
UINT D3DPipelineManager::GetAdapterOrdinalForScreen(jint gdiScreen)
|
|
{
|
|
HMONITOR mHnd = AwtWin32GraphicsDevice::GetMonitor(gdiScreen);
|
|
if (mHnd == (HMONITOR)0) {
|
|
return D3DADAPTER_DEFAULT;
|
|
}
|
|
return GetAdapterOrdinalByHmon((HMONITOR)mHnd);
|
|
}
|
|
|
|
// static
|
|
HRESULT D3DPipelineManager::HandleAdaptersChange(HMONITOR *pHMONITORs, UINT monNum)
|
|
{
|
|
HRESULT res = S_OK;
|
|
BOOL bResetD3D = FALSE, bFound;
|
|
|
|
D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
|
|
RETURN_STATUS_IF_NULL(pHMONITORs, E_FAIL);
|
|
if (pMgr == NULL) {
|
|
// NULL pMgr is valid when the pipeline is not enabled or if it hasn't
|
|
// been created yet
|
|
return S_OK;
|
|
}
|
|
RETURN_STATUS_IF_NULL(pMgr->pAdapters, E_FAIL);
|
|
RETURN_STATUS_IF_NULL(pMgr->pd3d9, E_FAIL);
|
|
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::HandleAdaptersChange");
|
|
|
|
if (monNum != pMgr->adapterCount) {
|
|
J2dTraceLn2(J2D_TRACE_VERBOSE,
|
|
" number of adapters changed (old=%d, new=%d)",
|
|
pMgr->adapterCount, monNum);
|
|
bResetD3D = TRUE;
|
|
} else {
|
|
for (UINT i = 0; i < pMgr->adapterCount; i++) {
|
|
HMONITOR hMon = pMgr->pd3d9->GetAdapterMonitor(i);
|
|
if (hMon == (HMONITOR)0x0) {
|
|
J2dTraceLn1(J2D_TRACE_VERBOSE, " adapter %d: removed", i);
|
|
bResetD3D = TRUE;
|
|
break;
|
|
}
|
|
bFound = FALSE;
|
|
for (UINT mon = 0; mon < monNum; mon++) {
|
|
if (pHMONITORs[mon] == hMon) {
|
|
J2dTraceLn3(J2D_TRACE_VERBOSE,
|
|
" adapter %d: found hmnd[%d]=0x%x", i, mon, hMon);
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (!bFound) {
|
|
J2dTraceLn2(J2D_TRACE_VERBOSE,
|
|
" adapter %d: could not find hmnd=0x%x "\
|
|
"in the list of new hmnds", i, hMon);
|
|
bResetD3D = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bResetD3D) {
|
|
J2dTraceLn(J2D_TRACE_VERBOSE, " adapters changed: resetting d3d");
|
|
pMgr->ReleaseD3D();
|
|
res = pMgr->InitD3D();
|
|
}
|
|
return res;
|
|
}
|
|
|
|
HRESULT D3DPipelineManager::HandleLostDevices()
|
|
{
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::HandleLostDevices()");
|
|
BOOL bAllClear = TRUE;
|
|
|
|
HWND hwnd = GetCurrentFocusWindow();
|
|
if (hwnd != defaultFocusWindow) {
|
|
// we're in full-screen mode
|
|
WINDOWPLACEMENT wp;
|
|
::ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
|
|
wp.length = sizeof(WINDOWPLACEMENT);
|
|
::GetWindowPlacement(hwnd, &wp);
|
|
|
|
// Only attempt to restore the devices if we're in full-screen mode
|
|
// and the fs window is active; sleep otherwise.
|
|
// Restoring a window while minimized causes problems on Vista:
|
|
// sometimes we restore the window too quickly and it pops up back from
|
|
// minimized state when the device is restored.
|
|
//
|
|
// WARNING: this is a sleep on the Toolkit thread! We may reconsider
|
|
// this if we find any issues later.
|
|
if ((wp.showCmd & SW_SHOWMINNOACTIVE) && !(wp.showCmd & SW_SHOWNORMAL)){
|
|
static DWORD prevCallTime = 0;
|
|
J2dTraceLn(J2D_TRACE_VERBOSE, " fs focus window is minimized");
|
|
DWORD currentTime = ::GetTickCount();
|
|
if ((currentTime - prevCallTime) < 100) {
|
|
J2dTraceLn(J2D_TRACE_VERBOSE, " tight loop detected, sleep");
|
|
::Sleep(100);
|
|
}
|
|
prevCallTime = currentTime;
|
|
return D3DERR_DEVICELOST;
|
|
}
|
|
}
|
|
if (pAdapters != NULL) {
|
|
for (UINT i = 0; i < adapterCount; i++) {
|
|
if (pAdapters[i].pd3dContext != NULL) {
|
|
J2dTraceLn1(J2D_TRACE_VERBOSE,
|
|
" HandleLostDevices: checking adapter %d", i);
|
|
D3DContext *d3dc = pAdapters[i].pd3dContext;
|
|
if (FAILED(d3dc->CheckAndResetDevice())) {
|
|
bAllClear = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return bAllClear ? S_OK : D3DERR_DEVICELOST;
|
|
}
|
|
|
|
HRESULT D3DPipelineManager::InitAdapters()
|
|
{
|
|
HRESULT res = E_FAIL;
|
|
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::InitAdapters()");
|
|
if (pAdapters != NULL) {
|
|
ReleaseAdapters();
|
|
}
|
|
|
|
adapterCount = pd3d9->GetAdapterCount();
|
|
pAdapters = new D3DAdapter[adapterCount];
|
|
if (pAdapters == NULL) {
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR, "InitAdapters: out of memory");
|
|
adapterCount = 0;
|
|
return E_FAIL;
|
|
}
|
|
ZeroMemory(pAdapters, adapterCount * sizeof(D3DAdapter));
|
|
|
|
res = CheckAdaptersInfo();
|
|
RETURN_STATUS_IF_FAILED(res);
|
|
|
|
currentFSFocusAdapter = -1;
|
|
if (CreateDefaultFocusWindow() == 0) {
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// static
|
|
HRESULT
|
|
D3DPipelineManager::CheckOSVersion()
|
|
{
|
|
// require Windows XP or newer client-class OS
|
|
if (IS_WINVER_ATLEAST(5, 1) &&
|
|
!D3DPPLM_OsVersionMatches(OS_WINSERV_2008|OS_WINSERV_2003))
|
|
{
|
|
J2dTraceLn(J2D_TRACE_INFO,
|
|
"D3DPPLM::CheckOSVersion: Windows XP or newer client-classs"\
|
|
" OS detected, passed");
|
|
return S_OK;
|
|
}
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
|
"D3DPPLM::CheckOSVersion: Windows 2000 or earlier (or a "\
|
|
"server) OS detected, failed");
|
|
if (bNoHwCheck) {
|
|
J2dRlsTraceLn(J2D_TRACE_WARNING,
|
|
" OS check overridden via J2D_D3D_NO_HWCHECK");
|
|
return S_OK;
|
|
}
|
|
return E_FAIL;
|
|
}
|
|
|
|
// static
|
|
HRESULT
|
|
D3DPipelineManager::GDICheckForBadHardware()
|
|
{
|
|
DISPLAY_DEVICE dd;
|
|
dd.cb = sizeof(DISPLAY_DEVICE);
|
|
|
|
int failedDevices = 0;
|
|
int attachedDevices = 0;
|
|
int i = 0;
|
|
WCHAR *id;
|
|
WCHAR vendorId[5];
|
|
WCHAR deviceId[5];
|
|
DWORD dwDId, dwVId;
|
|
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GDICheckForBadHardware");
|
|
|
|
// i<20 is to guard against buggy drivers
|
|
while (EnumDisplayDevices(NULL, i, &dd, 0) && i < 20) {
|
|
if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) {
|
|
attachedDevices++;
|
|
id = dd.DeviceID;
|
|
if (wcslen(id) > 21) {
|
|
// get vendor ID
|
|
wcsncpy(vendorId, id+8, 4);
|
|
int args1 = swscanf(vendorId, L"%X", &dwVId);
|
|
|
|
// get device ID
|
|
wcsncpy(deviceId, id+17, 4);
|
|
int args2 = swscanf(deviceId, L"%X", &dwDId);
|
|
|
|
if (args1 == 1 && args2 == 1) {
|
|
J2dTraceLn2(J2D_TRACE_VERBOSE,
|
|
" device: vendorID=0x%04x, deviceId=0x%04x",
|
|
dwVId, dwDId);
|
|
// since we don't have a driver version here we will
|
|
// just ask to ignore the version for now; bad hw
|
|
// entries with specific drivers information will be
|
|
// processed later when d3d is initialized and we can
|
|
// obtain a driver version
|
|
if (FAILED(CheckForBadHardware(dwVId, dwDId, MAX_VERSION))){
|
|
failedDevices++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
if (failedDevices == attachedDevices) {
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
|
"D3DPPLM::GDICheckForBadHardware: no suitable devices found");
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
BOOL D3DPPLM_OsVersionMatches(USHORT osInfo) {
|
|
static USHORT currentOS = OS_UNDEFINED;
|
|
|
|
if (currentOS == OS_UNDEFINED) {
|
|
BOOL bVersOk;
|
|
OSVERSIONINFOEX osvi;
|
|
|
|
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
|
|
bVersOk = GetVersionEx((OSVERSIONINFO *) &osvi);
|
|
|
|
J2dRlsTrace(J2D_TRACE_INFO, "[I] OS Version = ");
|
|
if (bVersOk && osvi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
|
|
osvi.dwMajorVersion > 4)
|
|
{
|
|
if (osvi.dwMajorVersion >= 6 && osvi.dwMinorVersion >= 0) {
|
|
if (osvi.wProductType == VER_NT_WORKSTATION) {
|
|
J2dRlsTrace(J2D_TRACE_INFO, "OS_VISTA or newer\n");
|
|
currentOS = OS_VISTA;
|
|
} else {
|
|
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINSERV_2008 or newer\n");
|
|
currentOS = OS_WINSERV_2008;
|
|
}
|
|
} else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {
|
|
if (osvi.wProductType == VER_NT_WORKSTATION) {
|
|
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINXP_64\n");
|
|
currentOS = OS_WINXP_64;
|
|
} else {
|
|
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINSERV_2003\n");
|
|
currentOS = OS_WINSERV_2003;
|
|
}
|
|
} else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {
|
|
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINXP ");
|
|
currentOS = OS_WINXP;
|
|
if (osvi.wSuiteMask & VER_SUITE_PERSONAL) {
|
|
J2dRlsTrace(J2D_TRACE_INFO, "Home\n");
|
|
} else {
|
|
J2dRlsTrace(J2D_TRACE_INFO, "Pro\n");
|
|
}
|
|
} else {
|
|
J2dRlsTrace2(J2D_TRACE_INFO,
|
|
"OS_UNKNOWN: dwMajorVersion=%d dwMinorVersion=%d\n",
|
|
osvi.dwMajorVersion, osvi.dwMinorVersion);
|
|
currentOS = OS_UNKNOWN;
|
|
}
|
|
} else {
|
|
if (bVersOk) {
|
|
J2dRlsTrace2(J2D_TRACE_INFO,
|
|
"OS_UNKNOWN: dwPlatformId=%d dwMajorVersion=%d\n",
|
|
osvi.dwPlatformId, osvi.dwMajorVersion);
|
|
} else {
|
|
J2dRlsTrace(J2D_TRACE_INFO,"OS_UNKNOWN: GetVersionEx failed\n");
|
|
}
|
|
currentOS = OS_UNKNOWN;
|
|
}
|
|
}
|
|
return (currentOS & osInfo);
|
|
}
|
|
|
|
// static
|
|
HRESULT
|
|
D3DPipelineManager::CheckForBadHardware(DWORD vId, DWORD dId, LONGLONG version)
|
|
{
|
|
DWORD vendorId, deviceId;
|
|
UINT adapterInfo = 0;
|
|
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::CheckForBadHardware");
|
|
|
|
while ((vendorId = badHardware[adapterInfo].VendorId) != 0x0000 &&
|
|
(deviceId = badHardware[adapterInfo].DeviceId) != 0x0000)
|
|
{
|
|
if (vendorId == vId && (deviceId == dId || deviceId == ALL_DEVICEIDS)) {
|
|
LONGLONG goodVersion = badHardware[adapterInfo].DriverVersion;
|
|
USHORT osInfo = badHardware[adapterInfo].OsInfo;
|
|
// the hardware check fails if:
|
|
// - we have an entry for this OS and
|
|
// - hardware is bad for all driver versions (NO_VERSION), or
|
|
// we have a driver version which is older than the
|
|
// minimum required for this OS
|
|
if (D3DPPLM_OsVersionMatches(osInfo) &&
|
|
(goodVersion == NO_VERSION || version < goodVersion))
|
|
{
|
|
J2dRlsTraceLn2(J2D_TRACE_ERROR,
|
|
"D3DPPLM::CheckForBadHardware: found matching "\
|
|
"hardware: VendorId=0x%04x DeviceId=0x%04x",
|
|
vendorId, deviceId);
|
|
if (goodVersion != NO_VERSION) {
|
|
// this was a match by the driver version
|
|
LARGE_INTEGER li;
|
|
li.QuadPart = goodVersion;
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
|
" bad driver found, device disabled");
|
|
J2dRlsTraceLn4(J2D_TRACE_ERROR,
|
|
" update your driver to at "\
|
|
"least version %d.%d.%d.%d",
|
|
HIWORD(li.HighPart), LOWORD(li.HighPart),
|
|
HIWORD(li.LowPart), LOWORD(li.LowPart));
|
|
} else {
|
|
// this was a match by the device (no good driver for this
|
|
// device)
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
|
"D3DPPLM::CheckForBadHardware: bad hardware "\
|
|
"found, device disabled");
|
|
}
|
|
if (!bNoHwCheck) {
|
|
return D3DERR_INVALIDDEVICE;
|
|
}
|
|
J2dRlsTraceLn(J2D_TRACE_WARNING, " Warning: hw/driver match "\
|
|
"overridden (via J2D_D3D_NO_HWCHECK)");
|
|
}
|
|
}
|
|
adapterInfo++;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT D3DPipelineManager::CheckAdaptersInfo()
|
|
{
|
|
D3DADAPTER_IDENTIFIER9 aid;
|
|
UINT failedAdaptersCount = 0;
|
|
|
|
J2dRlsTraceLn(J2D_TRACE_INFO, "CheckAdaptersInfo");
|
|
J2dRlsTraceLn(J2D_TRACE_INFO, "------------------");
|
|
for (UINT Adapter = 0; Adapter < adapterCount; Adapter++) {
|
|
|
|
if (FAILED(pd3d9->GetAdapterIdentifier(Adapter, 0, &aid))) {
|
|
pAdapters[Adapter].state = CONTEXT_INIT_FAILED;
|
|
failedAdaptersCount++;
|
|
continue;
|
|
}
|
|
|
|
J2dRlsTraceLn1(J2D_TRACE_INFO, "Adapter Ordinal : %d", Adapter);
|
|
J2dRlsTraceLn1(J2D_TRACE_INFO, "Adapter Handle : 0x%x",
|
|
pd3d9->GetAdapterMonitor(Adapter));
|
|
J2dRlsTraceLn1(J2D_TRACE_INFO, "Description : %s",
|
|
aid.Description);
|
|
J2dRlsTraceLn2(J2D_TRACE_INFO, "GDI Name, Driver : %s, %s",
|
|
aid.DeviceName, aid.Driver);
|
|
J2dRlsTraceLn1(J2D_TRACE_INFO, "Vendor Id : 0x%04x",
|
|
aid.VendorId);
|
|
J2dRlsTraceLn1(J2D_TRACE_INFO, "Device Id : 0x%04x",
|
|
aid.DeviceId);
|
|
J2dRlsTraceLn1(J2D_TRACE_INFO, "SubSys Id : 0x%x",
|
|
aid.SubSysId);
|
|
J2dRlsTraceLn4(J2D_TRACE_INFO, "Driver Version : %d.%d.%d.%d",
|
|
HIWORD(aid.DriverVersion.HighPart),
|
|
LOWORD(aid.DriverVersion.HighPart),
|
|
HIWORD(aid.DriverVersion.LowPart),
|
|
LOWORD(aid.DriverVersion.LowPart));
|
|
J2dRlsTrace3(J2D_TRACE_INFO,
|
|
"[I] GUID : {%08X-%04X-%04X-",
|
|
aid.DeviceIdentifier.Data1,
|
|
aid.DeviceIdentifier.Data2,
|
|
aid.DeviceIdentifier.Data3);
|
|
J2dRlsTrace4(J2D_TRACE_INFO, "%02X%02X-%02X%02X",
|
|
aid.DeviceIdentifier.Data4[0],
|
|
aid.DeviceIdentifier.Data4[1],
|
|
aid.DeviceIdentifier.Data4[2],
|
|
aid.DeviceIdentifier.Data4[3]);
|
|
J2dRlsTrace4(J2D_TRACE_INFO, "%02X%02X%02X%02X}\n",
|
|
aid.DeviceIdentifier.Data4[4],
|
|
aid.DeviceIdentifier.Data4[5],
|
|
aid.DeviceIdentifier.Data4[6],
|
|
aid.DeviceIdentifier.Data4[7]);
|
|
|
|
if (FAILED(CheckForBadHardware(aid.VendorId, aid.DeviceId,
|
|
aid.DriverVersion.QuadPart)) ||
|
|
FAILED(CheckDeviceCaps(Adapter)) ||
|
|
FAILED(D3DEnabledOnAdapter(Adapter)))
|
|
{
|
|
pAdapters[Adapter].state = CONTEXT_INIT_FAILED;
|
|
failedAdaptersCount++;
|
|
}
|
|
J2dRlsTraceLn(J2D_TRACE_INFO, "------------------");
|
|
}
|
|
|
|
if (failedAdaptersCount == adapterCount) {
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
|
"D3DPPLM::CheckAdaptersInfo: no suitable adapters found");
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
D3DDEVTYPE D3DPipelineManager::SelectDeviceType()
|
|
{
|
|
char *pRas = getenv("J2D_D3D_RASTERIZER");
|
|
D3DDEVTYPE dtype = D3DDEVTYPE_HAL;
|
|
if (pRas != NULL) {
|
|
J2dRlsTrace(J2D_TRACE_WARNING, "[W] D3DPPLM::SelectDeviceType: ");
|
|
if (strncmp(pRas, "ref", 3) == 0 || strncmp(pRas, "rgb", 3) == 0) {
|
|
J2dRlsTrace(J2D_TRACE_WARNING, "ref rasterizer selected");
|
|
dtype = D3DDEVTYPE_REF;
|
|
} else if (strncmp(pRas, "hal",3) == 0 || strncmp(pRas, "tnl",3) == 0) {
|
|
J2dRlsTrace(J2D_TRACE_WARNING, "hal rasterizer selected");
|
|
dtype = D3DDEVTYPE_HAL;
|
|
} else if (strncmp(pRas, "nul", 3) == 0) {
|
|
J2dRlsTrace(J2D_TRACE_WARNING, "nullref rasterizer selected");
|
|
dtype = D3DDEVTYPE_NULLREF;
|
|
} else {
|
|
J2dRlsTrace1(J2D_TRACE_WARNING,
|
|
"unknown rasterizer: %s, only (ref|hal|nul) "\
|
|
"supported, hal selected instead", pRas);
|
|
}
|
|
J2dRlsTrace(J2D_TRACE_WARNING, "\n");
|
|
}
|
|
return dtype;
|
|
}
|
|
|
|
#define CHECK_CAP(FLAG, CAP) \
|
|
do { \
|
|
if (!((FLAG)&CAP)) { \
|
|
J2dRlsTraceLn2(J2D_TRACE_ERROR, \
|
|
"D3DPPLM::CheckDeviceCaps: adapter %d: Failed "\
|
|
"(cap %s not supported)", \
|
|
adapter, #CAP); \
|
|
return E_FAIL; \
|
|
} \
|
|
} while (0)
|
|
|
|
HRESULT D3DPipelineManager::CheckDeviceCaps(UINT adapter)
|
|
{
|
|
HRESULT res;
|
|
D3DCAPS9 d3dCaps;
|
|
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::CheckDeviceCaps");
|
|
|
|
res = pd3d9->GetDeviceCaps(adapter, devType, &d3dCaps);
|
|
RETURN_STATUS_IF_FAILED(res);
|
|
|
|
CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_DRAWPRIMTLVERTEX);
|
|
|
|
// by requiring hardware tnl we are hoping for better drivers quality
|
|
if (!IsD3DForced()) {
|
|
// fail if not hw tnl unless d3d was forced
|
|
CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_HWTRANSFORMANDLIGHT);
|
|
}
|
|
if (d3dCaps.DeviceType == D3DDEVTYPE_HAL) {
|
|
CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_HWRASTERIZATION);
|
|
}
|
|
|
|
CHECK_CAP(d3dCaps.RasterCaps, D3DPRASTERCAPS_SCISSORTEST);
|
|
|
|
CHECK_CAP(d3dCaps.Caps3, D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD);
|
|
|
|
CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_CULLNONE);
|
|
CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_BLENDOP);
|
|
CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_MASKZ);
|
|
|
|
CHECK_CAP(d3dCaps.ZCmpCaps, D3DPCMPCAPS_ALWAYS);
|
|
CHECK_CAP(d3dCaps.ZCmpCaps, D3DPCMPCAPS_LESS);
|
|
|
|
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_ZERO);
|
|
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_ONE);
|
|
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_SRCALPHA);
|
|
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_DESTALPHA);
|
|
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_INVSRCALPHA);
|
|
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_INVDESTALPHA);
|
|
|
|
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_ZERO);
|
|
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_ONE);
|
|
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_SRCALPHA);
|
|
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_DESTALPHA);
|
|
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_INVSRCALPHA);
|
|
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_INVDESTALPHA);
|
|
|
|
CHECK_CAP(d3dCaps.TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP);
|
|
CHECK_CAP(d3dCaps.TextureAddressCaps, D3DPTADDRESSCAPS_WRAP);
|
|
|
|
CHECK_CAP(d3dCaps.TextureOpCaps, D3DTEXOPCAPS_MODULATE);
|
|
|
|
if (d3dCaps.PixelShaderVersion < D3DPS_VERSION(2,0) && !IsD3DForced()) {
|
|
J2dRlsTraceLn1(J2D_TRACE_ERROR,
|
|
"D3DPPLM::CheckDeviceCaps: adapter %d: Failed "\
|
|
"(pixel shaders 2.0 required)", adapter);
|
|
return E_FAIL;
|
|
}
|
|
|
|
J2dRlsTraceLn1(J2D_TRACE_INFO,
|
|
"D3DPPLM::CheckDeviceCaps: adapter %d: Passed", adapter);
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT D3DPipelineManager::D3DEnabledOnAdapter(UINT adapter)
|
|
{
|
|
HRESULT res;
|
|
D3DDISPLAYMODE dm;
|
|
|
|
res = pd3d9->GetAdapterDisplayMode(adapter, &dm);
|
|
RETURN_STATUS_IF_FAILED(res);
|
|
|
|
res = pd3d9->CheckDeviceType(adapter, devType, dm.Format, dm.Format, TRUE);
|
|
if (FAILED(res)) {
|
|
J2dRlsTraceLn1(J2D_TRACE_ERROR,
|
|
"D3DPPLM::D3DEnabledOnAdapter: no " \
|
|
"suitable d3d device on adapter %d", adapter);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
UINT D3DPipelineManager::GetAdapterOrdinalByHmon(HMONITOR hMon)
|
|
{
|
|
UINT ret = D3DADAPTER_DEFAULT;
|
|
|
|
if (pd3d9 != NULL) {
|
|
UINT adapterCount = pd3d9->GetAdapterCount();
|
|
for (UINT adapter = 0; adapter < adapterCount; adapter++) {
|
|
HMONITOR hm = pd3d9->GetAdapterMonitor(adapter);
|
|
if (hm == hMon) {
|
|
ret = adapter;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
D3DFORMAT
|
|
D3DPipelineManager::GetMatchingDepthStencilFormat(UINT adapterOrdinal,
|
|
D3DFORMAT adapterFormat,
|
|
D3DFORMAT renderTargetFormat)
|
|
{
|
|
static D3DFORMAT formats[] =
|
|
{ D3DFMT_D16, D3DFMT_D32, D3DFMT_D24S8, D3DFMT_D24X8 };
|
|
D3DFORMAT newFormat = D3DFMT_UNKNOWN;
|
|
HRESULT res;
|
|
for (int i = 0; i < 4; i++) {
|
|
res = pd3d9->CheckDeviceFormat(adapterOrdinal,
|
|
devType, adapterFormat, D3DUSAGE_DEPTHSTENCIL,
|
|
D3DRTYPE_SURFACE, formats[i]);
|
|
if (FAILED(res)) continue;
|
|
|
|
res = pd3d9->CheckDepthStencilMatch(adapterOrdinal,
|
|
devType, adapterFormat, renderTargetFormat, formats[i]);
|
|
if (FAILED(res)) continue;
|
|
newFormat = formats[i];
|
|
break;
|
|
}
|
|
return newFormat;
|
|
}
|
|
|
|
HWND D3DPipelineManager::CreateDefaultFocusWindow()
|
|
{
|
|
UINT adapterOrdinal = D3DADAPTER_DEFAULT;
|
|
|
|
J2dTraceLn1(J2D_TRACE_INFO,
|
|
"D3DPPLM::CreateDefaultFocusWindow: adapter=%d",
|
|
adapterOrdinal);
|
|
|
|
if (defaultFocusWindow != 0) {
|
|
J2dRlsTraceLn(J2D_TRACE_WARNING,
|
|
"D3DPPLM::CreateDefaultFocusWindow: "\
|
|
"existing default focus window!");
|
|
return defaultFocusWindow;
|
|
}
|
|
|
|
WNDCLASS wc;
|
|
ZeroMemory(&wc, sizeof(WNDCLASS));
|
|
wc.hInstance = GetModuleHandle(NULL);
|
|
wc.lpfnWndProc = DefWindowProc;
|
|
wc.lpszClassName = L"D3DFocusWindow";
|
|
if (RegisterClass(&wc) == 0) {
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
|
"D3DPPLM::CreateDefaultFocusWindow: "\
|
|
"error registering window class");
|
|
return 0;
|
|
}
|
|
|
|
MONITORINFO mi;
|
|
ZeroMemory(&mi, sizeof(MONITORINFO));
|
|
mi.cbSize = sizeof(MONITORINFO);
|
|
HMONITOR hMon = pd3d9->GetAdapterMonitor(adapterOrdinal);
|
|
if (hMon == 0 || !GetMonitorInfo(hMon, (LPMONITORINFO)&mi)) {
|
|
J2dRlsTraceLn1(J2D_TRACE_ERROR,
|
|
"D3DPPLM::CreateDefaultFocusWindow: "\
|
|
"error getting monitor info for adapter=%d", adapterOrdinal);
|
|
return 0;
|
|
}
|
|
|
|
HWND hWnd = CreateWindow(L"D3DFocusWindow", L"D3DFocusWindow", 0,
|
|
mi.rcMonitor.left, mi.rcMonitor.top, 1, 1,
|
|
NULL, NULL, GetModuleHandle(NULL), NULL);
|
|
if (hWnd == 0) {
|
|
J2dRlsTraceLn(J2D_TRACE_ERROR,
|
|
"D3DPPLM::CreateDefaultFocusWindow: CreateWindow failed");
|
|
} else {
|
|
J2dTraceLn2(J2D_TRACE_INFO,
|
|
" Created default focus window %x for adapter %d",
|
|
hWnd, adapterOrdinal);
|
|
defaultFocusWindow = hWnd;
|
|
}
|
|
return hWnd;
|
|
}
|
|
|
|
HWND D3DPipelineManager::GetCurrentFocusWindow()
|
|
{
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GetCurrentFocusWindow");
|
|
if (currentFSFocusAdapter < 0) {
|
|
J2dTraceLn1(J2D_TRACE_VERBOSE,
|
|
" no fs windows, using default focus window=0x%x",
|
|
defaultFocusWindow);
|
|
return defaultFocusWindow;
|
|
}
|
|
J2dTraceLn1(J2D_TRACE_VERBOSE, " using fs window=0x%x",
|
|
pAdapters[currentFSFocusAdapter].fsFocusWindow);
|
|
return pAdapters[currentFSFocusAdapter].fsFocusWindow;
|
|
}
|
|
|
|
HWND D3DPipelineManager::SetFSFocusWindow(UINT adapterOrdinal, HWND hWnd)
|
|
{
|
|
J2dTraceLn2(J2D_TRACE_INFO,"D3DPPLM::SetFSFocusWindow hwnd=0x%x adapter=%d",
|
|
hWnd, adapterOrdinal);
|
|
|
|
HWND prev = pAdapters[adapterOrdinal].fsFocusWindow;
|
|
pAdapters[adapterOrdinal].fsFocusWindow = hWnd;
|
|
if (currentFSFocusAdapter < 0) {
|
|
J2dTraceLn(J2D_TRACE_VERBOSE, " first full-screen window");
|
|
// first fs window
|
|
currentFSFocusAdapter = adapterOrdinal;
|
|
// REMIND: we might want to reset the rest of the context here as well
|
|
// like we do when the an adapter exits fs mode; currently they will
|
|
// be reset sometime later
|
|
} else {
|
|
// there's already a fs window
|
|
if (currentFSFocusAdapter == adapterOrdinal) {
|
|
// it's current fs window => we're exiting fs mode on this adapter;
|
|
// look for a new fs focus window
|
|
if (hWnd == 0) {
|
|
UINT i;
|
|
currentFSFocusAdapter = -1;
|
|
for (i = 0; i < adapterCount; i++) {
|
|
if (pAdapters[i].fsFocusWindow != 0) {
|
|
J2dTraceLn1(J2D_TRACE_VERBOSE,
|
|
" adapter %d is still in fs mode", i);
|
|
currentFSFocusAdapter = i;
|
|
break;
|
|
}
|
|
}
|
|
// we have to reset all devices any time current focus device
|
|
// exits fs mode, and also to prevent some of them being left in
|
|
// a lost state when the last device exits fs - when non-last
|
|
// adapters exit fs mode they would not be able to create the
|
|
// device and will be put in a lost state forever
|
|
HRESULT res;
|
|
J2dTraceLn(J2D_TRACE_VERBOSE,
|
|
" adapter exited full-screen, reset all adapters");
|
|
for (i = 0; i < adapterCount; i++) {
|
|
if (pAdapters[i].pd3dContext != NULL) {
|
|
res = pAdapters[i].pd3dContext->ResetContext();
|
|
D3DRQ_MarkLostIfNeeded(res,
|
|
D3DRQ_GetCurrentDestination());
|
|
}
|
|
}
|
|
} else {
|
|
J2dTraceLn1(J2D_TRACE_WARNING,
|
|
"D3DPM::SetFSFocusWindow: setting the fs "\
|
|
"window again for adapter %d", adapterOrdinal);
|
|
}
|
|
}
|
|
}
|
|
return prev;
|
|
}
|
|
|
|
HRESULT D3DPipelineManager::GetD3DContext(UINT adapterOrdinal,
|
|
D3DContext **ppd3dContext)
|
|
{
|
|
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GetD3DContext");
|
|
|
|
HRESULT res = S_OK;
|
|
if (adapterOrdinal < 0 || adapterOrdinal >= adapterCount ||
|
|
pAdapters == NULL ||
|
|
pAdapters[adapterOrdinal].state == CONTEXT_INIT_FAILED)
|
|
{
|
|
J2dRlsTraceLn1(J2D_TRACE_ERROR,
|
|
"D3DPPLM::GetD3DContext: invalid parameters or "\
|
|
"failed init for adapter %d", adapterOrdinal);
|
|
*ppd3dContext = NULL;
|
|
return E_FAIL;
|
|
}
|
|
|
|
if (pAdapters[adapterOrdinal].state == CONTEXT_NOT_INITED) {
|
|
D3DContext *pCtx = NULL;
|
|
|
|
if (pAdapters[adapterOrdinal].pd3dContext != NULL) {
|
|
J2dTraceLn1(J2D_TRACE_ERROR, " non-null context in "\
|
|
"uninitialized adapter %d", adapterOrdinal);
|
|
res = E_FAIL;
|
|
} else {
|
|
J2dTraceLn1(J2D_TRACE_VERBOSE,
|
|
" initializing context for adapter %d",adapterOrdinal);
|
|
|
|
if (SUCCEEDED(res = D3DEnabledOnAdapter(adapterOrdinal))) {
|
|
res = D3DContext::CreateInstance(pd3d9, adapterOrdinal, &pCtx);
|
|
if (FAILED(res)) {
|
|
J2dRlsTraceLn1(J2D_TRACE_ERROR,
|
|
"D3DPPLM::GetD3DContext: failed to create context "\
|
|
"for adapter=%d", adapterOrdinal);
|
|
}
|
|
} else {
|
|
J2dRlsTraceLn1(J2D_TRACE_ERROR,
|
|
"D3DPPLM::GetContext: no d3d on adapter %d",adapterOrdinal);
|
|
}
|
|
}
|
|
pAdapters[adapterOrdinal].state =
|
|
SUCCEEDED(res) ? CONTEXT_CREATED : CONTEXT_INIT_FAILED;
|
|
pAdapters[adapterOrdinal].pd3dContext = pCtx;
|
|
}
|
|
*ppd3dContext = pAdapters[adapterOrdinal].pd3dContext;
|
|
return res;
|
|
}
|