void
PlaybackManager::ForceCompletion()
{
#ifdef WIN32
  if (mBaseDT->GetType() == BackendType::DIRECT2D) {
    ID3D10Device1 *device = Factory::GetDirect3D10Device();
    RefPtr<ID3D10Query> query;
    D3D10_QUERY_DESC desc;
    desc.Query = D3D10_QUERY_EVENT;
    desc.MiscFlags = 0;
    device->CreateQuery(&desc, byRef(query));
    query->End();
    while (query->GetData(nullptr, 0, 0) == S_FALSE) {}
  }
#endif
}
void
gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce)
{
#ifdef CAIRO_HAS_D2D_SURFACE
    if (mD2DDevice) {
        ID3D10Device1 *device = cairo_d2d_device_get_device(mD2DDevice);

        if (SUCCEEDED(device->GetDeviceRemovedReason())) {
            return;
        }
        mD2DDevice = nullptr;
    }

    mozilla::ScopedGfxFeatureReporter reporter("D2D", aAttemptForce);

    HMODULE d3d10module = LoadLibraryA("d3d10_1.dll");
    D3D10CreateDevice1Func createD3DDevice = (D3D10CreateDevice1Func)
        GetProcAddress(d3d10module, "D3D10CreateDevice1");
    nsRefPtr<ID3D10Device1> device;

    if (createD3DDevice) {
        HMODULE dxgiModule = LoadLibraryA("dxgi.dll");
        CreateDXGIFactory1Func createDXGIFactory1 = (CreateDXGIFactory1Func)
            GetProcAddress(dxgiModule, "CreateDXGIFactory1");

        // Try to use a DXGI 1.1 adapter in order to share resources
        // across processes.
        nsRefPtr<IDXGIAdapter1> adapter1;
        if (createDXGIFactory1) {
            nsRefPtr<IDXGIFactory1> factory1;
            HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1),
                                            getter_AddRefs(factory1));

            if (FAILED(hr) || !factory1) {
              // This seems to happen with some people running the iZ3D driver.
              // They won't get acceleration.
              return;
            }
    
            hr = factory1->EnumAdapters1(0, getter_AddRefs(adapter1));

            if (SUCCEEDED(hr) && adapter1) {
                hr = adapter1->CheckInterfaceSupport(__uuidof(ID3D10Device),
                                                     nullptr);
                if (FAILED(hr)) {
                    // We should return and not accelerate if we don't have
                    // D3D 10.0 support.
                    return;
                }
            }
        }

        // It takes a lot of time (5-10% of startup time or ~100ms) to do both
        // a createD3DDevice on D3D10_FEATURE_LEVEL_10_0 and 
        // D3D10_FEATURE_LEVEL_10_1.  Therefore we set a pref if we ever get
        // 10.1 to work and we use that first if the pref is set.
        // Going direct to a 10.1 check only takes 20-30ms.
        // The initialization of hr doesn't matter here because it will get
        // overwritten whether or not the preference is set.
        //   - If the preferD3D10_1 pref is set it gets overwritten immediately.
        //   - If the preferD3D10_1 pref is not set, the if condition after
        //     the one that follows us immediately will short circuit before 
        //     checking FAILED(hr) and will again get overwritten immediately.
        // We initialize it here just so it does not appear to be an
        // uninitialized value.
        HRESULT hr = E_FAIL;
        bool preferD3D10_1 = 
          Preferences::GetBool("gfx.direct3d.prefer_10_1", false);
        if (preferD3D10_1) {
            hr = createD3DDevice(
                  adapter1, 
                  D3D10_DRIVER_TYPE_HARDWARE,
                  NULL,
                  D3D10_CREATE_DEVICE_BGRA_SUPPORT |
                  D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
                  D3D10_FEATURE_LEVEL_10_1,
                  D3D10_1_SDK_VERSION,
                  getter_AddRefs(device));

            // If we fail here, the DirectX version or video card probably
            // changed.  We previously could use 10.1 but now we can't
            // anymore.  Revert back to doing a 10.0 check first before
            // the 10.1 check.
            if (FAILED(hr)) {
                Preferences::SetBool("gfx.direct3d.prefer_10_1", false);
            } else {
                mD2DDevice = cairo_d2d_create_device_from_d3d10device(device);
            }
        }

        if (!preferD3D10_1 || FAILED(hr)) {
            // If preferD3D10_1 is set and 10.1 failed, fall back to 10.0.
            // if preferD3D10_1 is not yet set, then first try to create
            // a 10.0 D3D device, then try to see if 10.1 works.
            nsRefPtr<ID3D10Device1> device1;
            hr = createD3DDevice(
                  adapter1, 
                  D3D10_DRIVER_TYPE_HARDWARE,
                  NULL,
                  D3D10_CREATE_DEVICE_BGRA_SUPPORT |
                  D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
                  D3D10_FEATURE_LEVEL_10_0,
                  D3D10_1_SDK_VERSION,
                  getter_AddRefs(device1));

            if (SUCCEEDED(hr)) {
                device = device1;
                if (preferD3D10_1) {
                  mD2DDevice = 
                    cairo_d2d_create_device_from_d3d10device(device);
                }
            }
        }

        // If preferD3D10_1 is not yet set and 10.0 succeeded
        if (!preferD3D10_1 && SUCCEEDED(hr)) {
            // We have 10.0, let's try 10.1.  This second check will only
            // ever be done once if it succeeds.  After that an option
            // will be set to prefer using 10.1 before trying 10.0.
            // In the case that 10.1 fails, it won't be a long operation
            // like it is when 10.1 succeeds, so we don't need to optimize
            // the case where 10.1 is not supported, but 10.0 is supported.
            nsRefPtr<ID3D10Device1> device1;
            hr = createD3DDevice(
                  adapter1, 
                  D3D10_DRIVER_TYPE_HARDWARE,
                  NULL,
                  D3D10_CREATE_DEVICE_BGRA_SUPPORT |
                  D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
                  D3D10_FEATURE_LEVEL_10_1,
                  D3D10_1_SDK_VERSION,
                  getter_AddRefs(device1));

            if (SUCCEEDED(hr)) {
                device = device1;
                Preferences::SetBool("gfx.direct3d.prefer_10_1", true);
            }
            mD2DDevice = cairo_d2d_create_device_from_d3d10device(device);
        }
    }

    if (!mD2DDevice && aAttemptForce) {
        mD2DDevice = cairo_d2d_create_device();
    }

    if (mD2DDevice) {
        reporter.SetSuccessful();
        mozilla::gfx::Factory::SetDirect3D10Device(cairo_d2d_device_get_device(mD2DDevice));
    }
#endif
}
void
gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce)
{
#ifdef CAIRO_HAS_D2D_SURFACE
    if (mD2DDevice) {
        ID3D10Device1 *device = cairo_d2d_device_get_device(mD2DDevice);

        if (SUCCEEDED(device->GetDeviceRemovedReason())) {
            return;
        }
        mD2DDevice = nullptr;
    }

    mozilla::ScopedGfxFeatureReporter reporter("D2D", aAttemptForce);

    nsRefPtr<ID3D10Device1> device;

    int supportedFeatureLevelsCount = ArrayLength(kSupportedFeatureLevels);
    // If we're not running in Metro don't allow DX9.3
    if (!IsRunningInWindowsMetro()) {
      supportedFeatureLevelsCount--;
    }

    nsRefPtr<IDXGIAdapter1> adapter1 = GetDXGIAdapter();

    if (!adapter1) {
      // Unable to create adapter, abort acceleration.
      return;
    }

    // It takes a lot of time (5-10% of startup time or ~100ms) to do both
    // a createD3DDevice on D3D10_FEATURE_LEVEL_10_0.  We therefore store
    // the last used feature level to go direct to that.
    int featureLevelIndex = Preferences::GetInt(kFeatureLevelPref, 0);
    if (featureLevelIndex >= supportedFeatureLevelsCount || featureLevelIndex < 0)
      featureLevelIndex = 0;

    // Start with the last used feature level, and move to lower DX versions
    // until we find one that works.
    HRESULT hr = E_FAIL;
    for (int i = featureLevelIndex; i < supportedFeatureLevelsCount; i++) {
      hr = CreateDevice(adapter1, i);
      // If it succeeded we found the first available feature level
      if (SUCCEEDED(hr))
        break;
    }

    // If we succeeded in creating a device, try for a newer device
    // that we haven't tried yet.
    if (SUCCEEDED(hr)) {
      for (int i = featureLevelIndex - 1; i >= 0; i--) {
        hr = CreateDevice(adapter1, i);
        // If it failed then we don't have new hardware
        if (FAILED(hr)) {
          break;
        }
      }
    }

    if (!mD2DDevice && aAttemptForce) {
        mD2DDevice = cairo_d2d_create_device();
    }

    if (mD2DDevice) {
        reporter.SetSuccessful();
        mozilla::gfx::Factory::SetDirect3D10Device(cairo_d2d_device_get_device(mD2DDevice));
    }
#endif
}
Example #4
0
HRESULT touchmind::Context::CreateDeviceResources() {
#ifdef TOUCHMIND_CONTEXT_DEBUG
  LOG_ENTER;
#endif
  HRESULT hr = S_OK;
  RECT rcClient;
  ID3D10Device1 *pDevice = nullptr;
  IDXGIDevice *pDXGIDevice = nullptr;
  IDXGIAdapter *pAdapter = nullptr;
  IDXGIFactory *pDXGIFactory = nullptr;
  IDXGISurface *pSurface = nullptr;

  if (m_hwnd == nullptr) {
    LOG(SEVERITY_LEVEL_WARN) << L"HWND has not been set.";
    return S_FALSE;
  }

  GetClientRect(m_hwnd, &rcClient);

  UINT nWidth = std::abs(rcClient.right - rcClient.left);
  UINT nHeight = std::abs(rcClient.bottom - rcClient.top);

  if (!m_pDevice) {
#ifdef TOUCHMIND_CONTEXT_DEBUG
    LOG(SEVERITY_LEVEL_DEBUG) << L"Creating D3D Device.";
#endif
#ifdef _DEBUG
    // GMA950 doesn't work with D3D10_CREATE_DEVICE_DEBUG
    UINT nDeviceFlags = D3D10_CREATE_DEVICE_BGRA_SUPPORT | D3D10_CREATE_DEVICE_DEBUG;
// UINT nDeviceFlags = D3D10_CREATE_DEVICE_BGRA_SUPPORT;
#else
    UINT nDeviceFlags = D3D10_CREATE_DEVICE_BGRA_SUPPORT;
#endif
    hr = _CreateD3DDevice(nullptr, D3D10_DRIVER_TYPE_HARDWARE, nDeviceFlags, &pDevice);

    if (FAILED(hr)) {
      LOG(SEVERITY_LEVEL_INFO) << L"Creating hardware support D3D10 device was failed. Try D3D10_DRIVER_TYPE_WARP.";
      hr = _CreateD3DDevice(nullptr, D3D10_DRIVER_TYPE_WARP, nDeviceFlags, &pDevice);
      if (FAILED(hr)) {
        LOG(SEVERITY_LEVEL_FATAL) << L"Creating D3D10 device was failed.";
        return hr;
      }
    }

    if (SUCCEEDED(hr)) {
      hr = pDevice->QueryInterface(&m_pDevice);
    }
    if (SUCCEEDED(hr)) {
      hr = pDevice->QueryInterface(&pDXGIDevice);
    }
    if (SUCCEEDED(hr)) {
      hr = pDXGIDevice->GetAdapter(&pAdapter);
    }
    if (SUCCEEDED(hr)) {
      hr = pAdapter->GetParent(IID_PPV_ARGS(&pDXGIFactory));
    }
    if (SUCCEEDED(hr)) {
      DXGI_SWAP_CHAIN_DESC swapDesc;
      ::ZeroMemory(&swapDesc, sizeof(swapDesc));

      swapDesc.BufferDesc.Width = nWidth;
      swapDesc.BufferDesc.Height = nHeight;
      swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
      swapDesc.BufferDesc.RefreshRate.Numerator = 60;
      swapDesc.BufferDesc.RefreshRate.Denominator = 1;
      swapDesc.SampleDesc.Count = m_msaaSampleCount;
      swapDesc.SampleDesc.Quality = m_msaaQuality;
      swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
      swapDesc.BufferCount = 1;
      swapDesc.OutputWindow = m_hwnd;
      swapDesc.Windowed = TRUE;

      hr = pDXGIFactory->CreateSwapChain(m_pDevice, &swapDesc, &m_pSwapChain);
#ifdef DEBUG_GPU_RESOURCE
      LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] IDXGISwapChain = [" << std::hex << m_pSwapChain << L"]" << std::dec;
#endif
      if (FAILED(hr)) {
        LOG(SEVERITY_LEVEL_FATAL) << L"Creating swap chain was failed.";
        return hr;
      }
    }

    if (SUCCEEDED(hr)) {
      hr = _CreateD3DDeviceResources();
    }
    if (SUCCEEDED(hr)) {
      hr = _RecreateSizedResources(nWidth, nHeight);
    }
    if (SUCCEEDED(hr)) {
      if (m_pRenderEventListener != nullptr) {
        m_pRenderEventListener->CreateD2DResources(this, m_pD2DFactory, m_pD2DTexture2DRenderTarget);
      }
    }
  }

  SafeRelease(&pDevice);
  SafeRelease(&pDXGIDevice);
  SafeRelease(&pAdapter);
  SafeRelease(&pDXGIFactory);
  SafeRelease(&pSurface);
#ifdef TOUCHMIND_CONTEXT_DEBUG
  LOG_LEAVE_HRESULT(hr);
#endif
  return hr;
}
void
gfxWindowsPlatform::VerifyD2DDevice(bool aAttemptForce)
{
#ifdef CAIRO_HAS_D2D_SURFACE
    if (mD2DDevice) {
        ID3D10Device1 *device = cairo_d2d_device_get_device(mD2DDevice);

        if (SUCCEEDED(device->GetDeviceRemovedReason())) {
            return;
        }
        mD2DDevice = nullptr;
    }

    mozilla::ScopedGfxFeatureReporter reporter("D2D", aAttemptForce);

    nsRefPtr<ID3D10Device1> device;

    nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll"));
    CreateDXGIFactory1Func createDXGIFactory1 = (CreateDXGIFactory1Func)
        GetProcAddress(dxgiModule, "CreateDXGIFactory1");

    int supportedFeatureLevelsCount = ArrayLength(kSupportedFeatureLevels);
    // If we're not running in Metro don't allow DX9.3
    if (!IsRunningInWindowsMetro()) {
      supportedFeatureLevelsCount--;
    }

    // It takes a lot of time (5-10% of startup time or ~100ms) to do both
    // a createD3DDevice on D3D10_FEATURE_LEVEL_10_0.  We therefore store
    // the last used feature level to go direct to that.
    int featureLevelIndex = Preferences::GetInt(kFeatureLevelPref, 0);
    if (featureLevelIndex >= supportedFeatureLevelsCount || featureLevelIndex < 0)
      featureLevelIndex = 0;

    // Try to use a DXGI 1.1 adapter in order to share resources
    // across processes.
    nsRefPtr<IDXGIAdapter1> adapter1;
    if (createDXGIFactory1) {
        nsRefPtr<IDXGIFactory1> factory1;
        HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1),
                                        getter_AddRefs(factory1));

        if (FAILED(hr) || !factory1) {
          // This seems to happen with some people running the iZ3D driver.
          // They won't get acceleration.
          return;
        }

        hr = factory1->EnumAdapters1(0, getter_AddRefs(adapter1));
        if (FAILED(hr) || !adapter1) {
          // We should return and not accelerate if we can't obtain
          // an adapter.
          return;
        }
    }

    // Start with the last used feature level, and move to lower DX versions
    // until we find one that works.
    HRESULT hr = E_FAIL;
    for (int i = featureLevelIndex; i < supportedFeatureLevelsCount; i++) {
      hr = CreateDevice(adapter1, i);
      // If it succeeded we found the first available feature level
      if (SUCCEEDED(hr))
        break;
    }

    // If we succeeded in creating a device, try for a newer device
    // that we haven't tried yet.
    if (SUCCEEDED(hr)) {
      for (int i = featureLevelIndex - 1; i >= 0; i--) {
        hr = CreateDevice(adapter1, i);
        // If it failed then we don't have new hardware
        if (FAILED(hr)) {
          break;
        }
      }
    }

    if (!mD2DDevice && aAttemptForce) {
        mD2DDevice = cairo_d2d_create_device();
    }

    if (mD2DDevice) {
        reporter.SetSuccessful();
        mozilla::gfx::Factory::SetDirect3D10Device(cairo_d2d_device_get_device(mD2DDevice));
    }
#endif
}