#ifndef GPU_COMMAND_BUFFER_SERVICE_DXGI_SHARED_HANDLE_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_DXGI_SHARED_HANDLE_MANAGER_H_
#include <d3d11.h>
#include <wrl/client.h>
#include <webgpu/webgpu_cpp.h>
#include "base/containers/flat_map.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/types/pass_key.h"
#include "base/win/scoped_handle.h"
#include "gpu/gpu_gles2_export.h"
#include "ui/gfx/gpu_memory_buffer_handle.h"
#include "ui/gl/buildflags.h"
namespace gpu {
class DXGISharedHandleManager;
class GPU_GLES2_EXPORT DXGISharedHandleState
: public base::subtle::RefCountedThreadSafeBase {
public:
REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
DXGISharedHandleState(base::PassKey<DXGISharedHandleManager>,
scoped_refptr<DXGISharedHandleManager> manager,
gfx::DXGIHandleToken token,
base::win::ScopedHandle shared_handle,
Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture);
DXGISharedHandleState(const DXGISharedHandleState&) = delete;
DXGISharedHandleState& operator=(const DXGISharedHandleState&) = delete;
void AddRef() const;
void Release() const;
HANDLE GetSharedHandle() const { return shared_handle_.Get(); }
bool has_keyed_mutex() const { return has_keyed_mutex_; }
Microsoft::WRL::ComPtr<ID3D11Texture2D> GetOrCreateD3D11Texture(
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device);
bool AcquireKeyedMutex(Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device);
void ReleaseKeyedMutex(Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device);
wgpu::SharedTextureMemory GetSharedTextureMemory(const wgpu::Device& device);
void MaybeCacheSharedTextureMemory(const wgpu::Device& device,
wgpu::SharedTextureMemory memory);
void EraseDawnSharedTextureMemory(const wgpu::Device& device);
private:
struct D3D11TextureState {
D3D11TextureState(Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture);
~D3D11TextureState();
D3D11TextureState(D3D11TextureState&&);
D3D11TextureState& operator=(D3D11TextureState&&);
Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture;
Microsoft::WRL::ComPtr<IDXGIKeyedMutex> dxgi_keyed_mutex;
int keyed_mutex_acquired_count = 0;
};
~DXGISharedHandleState();
mutable base::Lock lock_;
const scoped_refptr<DXGISharedHandleManager> manager_;
const gfx::DXGIHandleToken token_;
const base::win::ScopedHandle shared_handle_;
using D3D11TextureStateMap =
base::flat_map<Microsoft::WRL::ComPtr<ID3D11Device>, D3D11TextureState>;
D3D11TextureStateMap d3d11_texture_state_map_ GUARDED_BY(lock_);
using DawnSharedTextureMemoryCache =
base::flat_map<WGPUDevice, wgpu::SharedTextureMemory>;
DawnSharedTextureMemoryCache dawn_shared_texture_memory_cache_
GUARDED_BY(lock_);
const bool has_keyed_mutex_ = false;
bool keyed_mutex_acquired_ GUARDED_BY(lock_) = false;
};
class GPU_GLES2_EXPORT DXGISharedHandleManager
: public base::RefCountedThreadSafe<DXGISharedHandleManager> {
public:
DXGISharedHandleManager();
scoped_refptr<DXGISharedHandleState> GetOrCreateSharedHandleState(
const gfx::DXGIHandleToken& token,
base::win::ScopedHandle shared_handle,
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device);
scoped_refptr<DXGISharedHandleState> CreateAnonymousSharedHandleState(
base::win::ScopedHandle shared_handle,
Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture);
size_t GetSharedHandleMapSizeForTesting() const;
private:
friend class base::RefCountedThreadSafe<DXGISharedHandleManager>;
friend class DXGISharedHandleState;
~DXGISharedHandleManager();
mutable base::Lock lock_;
using SharedHandleMap =
base::flat_map<gfx::DXGIHandleToken, DXGISharedHandleState*>;
SharedHandleMap shared_handle_state_map_ GUARDED_BY(lock_);
};
}
#endif