123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ui/gl/gl_fence_win.h"
- #include "base/logging.h"
- #include "base/notreached.h"
- #include "ui/gl/gl_angle_util_win.h"
- #include <d3d11_4.h>
- namespace gl {
- bool GLFenceWin::IsSupported() {
- Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
- gl::QueryD3D11DeviceObjectFromANGLE();
- if (!d3d11_device)
- return false;
- // Support for ID3D11Device5 implies support for ID3D11DeviceContext4.
- // No point in letting you create fences if you can't signal or wait on them.
- Microsoft::WRL::ComPtr<ID3D11Device5> d3d11_device5;
- HRESULT hr = d3d11_device.As(&d3d11_device5);
- if (FAILED(hr)) {
- return false;
- }
- return true;
- }
- std::unique_ptr<GLFenceWin> GLFenceWin::CreateForGpuFence() {
- Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
- gl::QueryD3D11DeviceObjectFromANGLE();
- if (!d3d11_device) {
- DLOG(ERROR) << "Unable to retrieve ID3D11Device from ANGLE";
- return nullptr;
- }
- return CreateForGpuFence(d3d11_device.Get());
- }
- std::unique_ptr<GLFenceWin> GLFenceWin::CreateForGpuFence(
- ID3D11Device* d3d11_device) {
- Microsoft::WRL::ComPtr<ID3D11Device5> d3d11_device5;
- HRESULT hr = d3d11_device->QueryInterface(IID_PPV_ARGS(&d3d11_device5));
- if (FAILED(hr)) {
- DLOG(ERROR) << "Unable to retrieve ID3D11Device5 interface "
- << logging::SystemErrorCodeToString(hr);
- return nullptr;
- }
- Microsoft::WRL::ComPtr<ID3D11Fence> d3d11_fence;
- hr = d3d11_device5->CreateFence(0, D3D11_FENCE_FLAG_SHARED,
- IID_PPV_ARGS(&d3d11_fence));
- if (FAILED(hr)) {
- DLOG(ERROR) << "Unable to create ID3D11Fence "
- << logging::SystemErrorCodeToString(hr);
- return nullptr;
- }
- HANDLE shared_handle;
- hr = d3d11_fence->CreateSharedHandle(
- nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, nullptr,
- &shared_handle);
- if (FAILED(hr)) {
- DLOG(ERROR) << "Unable to create shared handle for DXGIResource "
- << logging::SystemErrorCodeToString(hr);
- return nullptr;
- }
- // Put the shared handle into an RAII object as quickly as possible to
- // ensure we do not leak it.
- base::win::ScopedHandle scoped_handle(shared_handle);
- Microsoft::WRL::ComPtr<ID3D11DeviceContext> d3d11_device_context;
- d3d11_device5->GetImmediateContext(&d3d11_device_context);
- Microsoft::WRL::ComPtr<ID3D11DeviceContext4> d3d11_device_context4;
- hr = d3d11_device_context.As(&d3d11_device_context4);
- if (FAILED(hr)) {
- DLOG(ERROR) << "Unable to retrieve ID3D11DeviceContext4 interface "
- << logging::SystemErrorCodeToString(hr);
- return nullptr;
- }
- hr = d3d11_device_context4->Signal(d3d11_fence.Get(), 1);
- if (FAILED(hr)) {
- DLOG(ERROR) << "Unable to Signal D3D11 fence "
- << logging::SystemErrorCodeToString(hr);
- return nullptr;
- }
- gfx::GpuFenceHandle gpu_fence_handle;
- gpu_fence_handle.owned_handle = std::move(scoped_handle);
- return std::make_unique<GLFenceWin>(std::move(d3d11_fence),
- std::move(gpu_fence_handle));
- }
- std::unique_ptr<GLFenceWin> GLFenceWin::CreateFromGpuFence(
- const gfx::GpuFence& gpu_fence) {
- Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
- gl::QueryD3D11DeviceObjectFromANGLE();
- return CreateFromGpuFence(d3d11_device.Get(), gpu_fence);
- }
- std::unique_ptr<GLFenceWin> GLFenceWin::CreateFromGpuFence(
- ID3D11Device* d3d11_device,
- const gfx::GpuFence& gpu_fence) {
- Microsoft::WRL::ComPtr<ID3D11Device5> d3d11_device5;
- HRESULT hr = d3d11_device->QueryInterface(IID_PPV_ARGS(&d3d11_device5));
- if (FAILED(hr)) {
- DLOG(ERROR) << "Unable to retrieve ID3D11Device5 interface "
- << logging::SystemErrorCodeToString(hr);
- return nullptr;
- }
- gfx::GpuFenceHandle gpu_fence_handle = gpu_fence.GetGpuFenceHandle().Clone();
- Microsoft::WRL::ComPtr<ID3D11Fence> d3d11_fence;
- hr = d3d11_device5->OpenSharedFence(gpu_fence_handle.owned_handle.Get(),
- IID_PPV_ARGS(&d3d11_fence));
- if (FAILED(hr)) {
- DLOG(ERROR) << "Unable to open a shared fence "
- << logging::SystemErrorCodeToString(hr);
- return nullptr;
- }
- return std::make_unique<GLFenceWin>(std::move(d3d11_fence),
- std::move(gpu_fence_handle));
- }
- GLFenceWin::GLFenceWin(Microsoft::WRL::ComPtr<ID3D11Fence> d3d11_fence,
- gfx::GpuFenceHandle gpu_fence_handle)
- : d3d11_fence_(std::move(d3d11_fence)),
- gpu_fence_handle_(std::move(gpu_fence_handle)) {}
- GLFenceWin::~GLFenceWin() = default;
- bool GLFenceWin::HasCompleted() {
- NOTREACHED();
- return false;
- }
- void GLFenceWin::ClientWait() {
- NOTREACHED();
- }
- void GLFenceWin::ServerWait() {
- Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device;
- d3d11_fence_->GetDevice(&d3d11_device);
- Microsoft::WRL::ComPtr<ID3D11DeviceContext> d3d11_device_context;
- d3d11_device->GetImmediateContext(&d3d11_device_context);
- Microsoft::WRL::ComPtr<ID3D11DeviceContext4> d3d11_device_context4;
- HRESULT hr = d3d11_device_context.As(&d3d11_device_context4);
- if (FAILED(hr)) {
- DLOG(ERROR) << "Unable to retrieve ID3D11DeviceContext4 interface "
- << logging::SystemErrorCodeToString(hr);
- return;
- }
- hr = d3d11_device_context4->Wait(d3d11_fence_.Get(), 1);
- if (FAILED(hr)) {
- DLOG(ERROR) << "Unable to Wait on D3D11 fence "
- << logging::SystemErrorCodeToString(hr);
- return;
- }
- }
- std::unique_ptr<gfx::GpuFence> GLFenceWin::GetGpuFence() {
- return std::make_unique<gfx::GpuFence>(gpu_fence_handle_.Clone());
- }
- } // namespace gl
|