alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (D3DPipelineManager.cpp)

This example Java source code file (D3DPipelineManager.cpp) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

d3dpipelinemanager, e_fail, failed, hmonitor, hresult, hwnd, j2drlstraceln, j2drlstraceln1, j2dtraceln, j2dtraceln1, null, s_ok, true, uint

The D3DPipelineManager.cpp Java example source code

/*
 * Copyright (c) 2007, 2011, 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 "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 = JDK_LoadSystemLibrary("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;

    // fix for 6946559: if d3d preloading fails jmv may be NULL
    if (jvm == NULL) {
        return;
    }

    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    RETURN_IF_NULL(env);

    pMgr = D3DPipelineManager::GetInstance();
    RETURN_IF_NULL(pMgr);
    hMon = pMgr->pd3d9->GetAdapterMonitor(adapter);

    /*
     * If we don't have devices initialized yet, no sense to clear them.
     */
    if (!Devices::GetInstance()){
         return;
    }

    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_2008R2|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\n");
                    currentOS = OS_VISTA;
                } else {
                    J2dRlsTrace(J2D_TRACE_INFO, "OS_WINSERV_2008\n");
                    currentOS = OS_WINSERV_2008;
                }
            } else if (osvi.dwMajorVersion >= 6 && osvi.dwMinorVersion >= 1) {
                if (osvi.wProductType == VER_NT_WORKSTATION) {
                    J2dRlsTrace(J2D_TRACE_INFO, "OS_WINDOWS7 or newer\n");
                    currentOS = OS_WINDOWS7;
                } else {
                    J2dRlsTrace(J2D_TRACE_INFO, "OS_WINSERV_2008R2 or newer\n");
                    currentOS = OS_WINSERV_2008R2;
                }
            } 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;
}


//==============================================================
// D3DInitializer
//==============================================================

D3DInitializer D3DInitializer::theInstance;

D3DInitializer::D3DInitializer()
    : bComInitialized(false), pAdapterIniters(NULL)
{
}

D3DInitializer::~D3DInitializer()
{
    if (pAdapterIniters) {
        delete[] pAdapterIniters;
    }
}

void D3DInitializer::InitImpl()
{
    J2dRlsTraceLn(J2D_TRACE_INFO, "D3DInitializer::InitImpl");
    if (SUCCEEDED(::CoInitialize(NULL))) {
        bComInitialized = true;
    }
    D3DPipelineManager *pMgr = D3DPipelineManager::CreateInstance();
    if (pMgr != NULL) {
        // init adapters if we are preloading
        if (AwtToolkit::GetInstance().GetPreloadThread().OnPreloadThread()) {
            UINT adapterCount = pMgr->adapterCount;

            pAdapterIniters = new D3DAdapterInitializer[adapterCount];
            for (UINT i=0; i<adapterCount; i++) {
                pAdapterIniters[i].setAdapter(i);
                AwtToolkit::GetInstance().GetPreloadThread().AddAction(&pAdapterIniters[i]);
            }
        }
    }
}

void D3DInitializer::CleanImpl(bool reInit)
{
    J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DInitializer::CleanImpl (%s)",
                                    reInit ? "RELAUNCH" : "normal");
    D3DPipelineManager::DeleteInstance();
    if (bComInitialized) {
        CoUninitialize();
    }
}


void D3DInitializer::D3DAdapterInitializer::InitImpl()
{
    J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) started", adapter);

    D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
    if (pMgr == NULL) {
        return;
    }

    D3DContext *pd3dContext;
    pMgr->GetD3DContext(adapter, &pd3dContext);

    J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) finished", adapter);
}

void D3DInitializer::D3DAdapterInitializer::CleanImpl(bool reInit)
{
    // nothing to do - D3DPipelineManager cleans adapters
}


extern "C" {
/*
 * Export function to start D3D preloading
 * (called from java/javaw - see src/windows/bin/java-md.c)
 */
__declspec(dllexport) int preloadD3D()
{
    J2dRlsTraceLn(J2D_TRACE_INFO, "AWT warmup: preloadD3D");
    AwtToolkit::GetInstance().GetPreloadThread().AddAction(&D3DInitializer::GetInstance());
    return 1;
}

}

Other Java examples (source code examples)

Here is a short list of links related to this Java D3DPipelineManager.cpp source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.