Exemplo n.º 1
0
FeatureStatus
DeviceManagerDx::CreateContentDevice()
{
  RefPtr<IDXGIAdapter1> adapter;
  if (!mDeviceStatus->isWARP()) {
    adapter = GetDXGIAdapter();
    if (!adapter) {
      gfxCriticalNote << "Could not get a DXGI adapter";
      return FeatureStatus::Unavailable;
    }
  }

  HRESULT hr;
  RefPtr<ID3D11Device> device;

  UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
  D3D_DRIVER_TYPE type = mDeviceStatus->isWARP()
                         ? D3D_DRIVER_TYPE_WARP
                         : D3D_DRIVER_TYPE_UNKNOWN;
  if (!CreateDevice(adapter, type, flags, hr, device)) {
    gfxCriticalNote << "Recovered from crash while creating a D3D11 content device";
    gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Content);
    return FeatureStatus::CrashedInHandler;
  }

  if (FAILED(hr) || !device) {
    gfxCriticalNote << "Failed to create a D3D11 content device: " << hexa(hr);
    gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Content);
    return FeatureStatus::Failed;
  }

  // InitializeD2D() will abort early if the compositor device did not support
  // texture sharing. If we're in the content process, we can't rely on the
  // parent device alone: some systems have dual GPUs that are capable of
  // binding the parent and child processes to different GPUs. As a safety net,
  // we re-check texture sharing against the newly created D3D11 content device.
  // If it fails, we won't use Direct2D.
  if (XRE_IsContentProcess()) {
    if (!D3D11Checks::DoesTextureSharingWork(device)) {
      return FeatureStatus::Failed;
    }

    DebugOnly<bool> ok = ContentAdapterIsParentAdapter(device);
    MOZ_ASSERT(ok);
  }

  {
    MutexAutoLock lock(mDeviceLock);
    mContentDevice = device;
  }
  mContentDevice->SetExceptionMode(0);

  RefPtr<ID3D10Multithread> multi;
  hr = mContentDevice->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
  if (SUCCEEDED(hr) && multi) {
    multi->SetMultithreadProtected(TRUE);
  }
  return FeatureStatus::Available;
}
Exemplo n.º 2
0
bool
DeviceManagerDx::CheckRemotePresentSupport()
{
  MOZ_ASSERT(XRE_IsParentProcess());

  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
  if (!adapter) {
    return false;
  }
  if (!D3D11Checks::DoesRemotePresentWork(adapter)) {
    return false;
  }
  return true;
}
Exemplo n.º 3
0
void
DeviceManagerDx::CreateCompositorDevice(FeatureState& d3d11)
{
  if (gfxPrefs::LayersD3D11ForceWARP()) {
    CreateWARPCompositorDevice();
    return;
  }

  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
  if (!adapter) {
    d3d11.SetFailed(FeatureStatus::Unavailable, "Failed to acquire a DXGI adapter",
                    NS_LITERAL_CSTRING("FEATURE_FAILURE_D3D11_DXGI"));
    return;
  }

  RefPtr<ID3D11Device> device;
  if (!CreateCompositorDeviceHelper(d3d11, adapter, true, device)) {
    // Try again without video support and record that it failed.
    mCompositorDeviceSupportsVideo = false;
    if (!CreateCompositorDeviceHelper(d3d11, adapter, false, device)) {
      return;
    }
  } else {
    mCompositorDeviceSupportsVideo = true;
  }

  // Only test this when not using WARP since it can fail and cause
  // GetDeviceRemovedReason to return weird values.
  bool textureSharingWorks = D3D11Checks::DoesTextureSharingWork(device);

  DXGI_ADAPTER_DESC desc;
  PodZero(&desc);
  adapter->GetDesc(&desc);

  if (!textureSharingWorks) {
    gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
                         FeatureStatus::Broken,
                         "Texture sharing doesn't work");
  }
  if (D3D11Checks::DoesRenderTargetViewNeedRecreating(device)) {
    gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
                         FeatureStatus::Broken,
                         "RenderTargetViews need recreating");
  }
  if (XRE_IsParentProcess()) {
    // It seems like this may only happen when we're using the NVIDIA gpu
    D3D11Checks::WarnOnAdapterMismatch(device);
  }

  int featureLevel = device->GetFeatureLevel();
  {
    MutexAutoLock lock(mDeviceLock);
    mCompositorDevice = device;
    mDeviceStatus = Some(D3D11DeviceStatus(
      false,
      textureSharingWorks,
      featureLevel,
      DxgiAdapterDesc::From(desc)));
  }
  mCompositorDevice->SetExceptionMode(0);
}
Exemplo n.º 4
0
RefPtr<ID3D11Device>
DeviceManagerDx::CreateDecoderDevice()
{
  bool isAMD = false;
  {
    MutexAutoLock lock(mDeviceLock);
    if (!mDeviceStatus) {
      return nullptr;
    }
    isAMD = mDeviceStatus->adapter().VendorId == 0x1002;
  }

  bool reuseDevice = false;
  if (gfxPrefs::Direct3D11ReuseDecoderDevice() < 0) {
    // Use the default logic, which is to allow reuse of devices on AMD, but create
    // separate devices everywhere else.
    if (isAMD) {
      reuseDevice = true;
    }
  } else if (gfxPrefs::Direct3D11ReuseDecoderDevice() > 0) {
    reuseDevice = true;
  }

  if (reuseDevice) {
    if (mCompositorDevice && mCompositorDeviceSupportsVideo && !mDecoderDevice) {
      mDecoderDevice = mCompositorDevice;

      RefPtr<ID3D10Multithread> multi;
      mDecoderDevice->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));
      if (multi) {
        multi->SetMultithreadProtected(TRUE);
      }
    }

    if (mDecoderDevice) {
      RefPtr<ID3D11Device> dev = mDecoderDevice;
      return dev.forget();
    }
  }

   if (!sD3D11CreateDeviceFn) {
    // We should just be on Windows Vista or XP in this case.
    return nullptr;
  }

  RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
  if (!adapter) {
    return nullptr;
  }

  HRESULT hr;
  RefPtr<ID3D11Device> device;

  UINT flags = D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS |
               D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
  if (!CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, flags, hr, device)) {
    return nullptr;
  }
  if (FAILED(hr) || !device || !D3D11Checks::DoesDeviceWork()) {
    return nullptr;
  }

  RefPtr<ID3D10Multithread> multi;
  device->QueryInterface(__uuidof(ID3D10Multithread), getter_AddRefs(multi));

  multi->SetMultithreadProtected(TRUE);

  if (reuseDevice) {
    mDecoderDevice = device;
  }
  return device;
}