#include "gpu/command_buffer/service/dawn_context_provider.h"
#include <memory>
#include <vector>
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/dcheck_is_on.h"
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/task/single_thread_task_runner.h"
#include "base/thread_annotations.h"
#include "base/threading/platform_thread.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/memory_dump_provider.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_arguments.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/crash/core/common/crash_key.h"
#include "gpu/command_buffer/service/dawn_instance.h"
#include "gpu/command_buffer/service/dawn_platform.h"
#include "gpu/command_buffer/service/skia_utils.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/config/gpu_util.h"
#include "third_party/skia/include/gpu/graphite/Context.h"
#include "third_party/skia/include/gpu/graphite/dawn/DawnBackendContext.h"
#include "third_party/skia/include/gpu/graphite/dawn/DawnUtils.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_switches.h"
#if BUILDFLAG(IS_WIN)
#include <d3d11_4.h>
#include "third_party/dawn/include/dawn/native/D3D11Backend.h"
#include "ui/gl/direct_composition_support.h"
#include "ui/gl/gl_angle_util_win.h"
#endif
namespace gpu {
namespace {
BASE_FEATURE(…);
template <uint32_t KeySize>
void SetCrashKeyThreadSafe(crash_reporter::CrashKeyString<KeySize>& crash_key,
std::string_view message) { … }
void SetDawnErrorCrashKey(std::string_view message) { … }
class Platform : public webgpu::DawnPlatform { … };
#if BUILDFLAG(IS_WIN)
bool GetANGLED3D11DeviceLUID(LUID* luid) {
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
gl::QueryD3D11DeviceObjectFromANGLE();
if (!d3d11_device) {
LOG(ERROR) << "Failed to query ID3D11Device from ANGLE.";
return false;
}
Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device;
if (!SUCCEEDED(d3d11_device.As(&dxgi_device))) {
LOG(ERROR) << "Failed to get IDXGIDevice from ANGLE.";
return false;
}
Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter;
if (!SUCCEEDED(dxgi_device->GetAdapter(&dxgi_adapter))) {
LOG(ERROR) << "Failed to get IDXGIAdapter from ANGLE.";
return false;
}
DXGI_ADAPTER_DESC adapter_desc;
if (!SUCCEEDED(dxgi_adapter->GetDesc(&adapter_desc))) {
LOG(ERROR) << "Failed to get DXGI_ADAPTER_DESC from ANGLE.";
return false;
}
*luid = adapter_desc.AdapterLuid;
return true;
}
bool IsD3D11DebugLayerEnabled(
const Microsoft::WRL::ComPtr<ID3D11Device>& d3d11_device) {
Microsoft::WRL::ComPtr<ID3D11Debug> d3d11_debug;
return SUCCEEDED(d3d11_device.As(&d3d11_debug));
}
const char* HRESULTToString(HRESULT result) {
switch (result) {
#define ERROR_CASE …
ERROR_CASE(DXGI_ERROR_DEVICE_HUNG)
ERROR_CASE(DXGI_ERROR_DEVICE_REMOVED)
ERROR_CASE(DXGI_ERROR_DEVICE_RESET)
ERROR_CASE(DXGI_ERROR_DRIVER_INTERNAL_ERROR)
ERROR_CASE(DXGI_ERROR_INVALID_CALL)
ERROR_CASE(S_OK)
#undef ERROR_CASE
default:
return nullptr;
}
}
#endif
}
wgpu::BackendType DawnContextProvider::GetDefaultBackendType() { … }
bool DawnContextProvider::DefaultForceFallbackAdapter() { … }
class DawnSharedContext : public base::RefCountedThreadSafe<DawnSharedContext>,
public base::trace_event::MemoryDumpProvider { … };
DawnSharedContext::~DawnSharedContext() { … }
bool DawnSharedContext::Initialize(
wgpu::BackendType backend_type,
bool force_fallback_adapter,
const GpuPreferences& gpu_preferences,
const GpuDriverBugWorkarounds& gpu_driver_workarounds) { … }
void DawnSharedContext::SetCachingInterface(
std::unique_ptr<webgpu::DawnCachingInterface> caching_interface) { … }
std::optional<error::ContextLostReason> DawnSharedContext::GetResetStatus()
const { … }
void DawnSharedContext::OnError(wgpu::ErrorType error_type,
const char* message) { … }
namespace {
static constexpr char kDawnMemoryDumpPrefix[] = …;
class DawnMemoryDump : public dawn::native::MemoryDump { … };
}
bool DawnSharedContext::OnMemoryDump(
const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) { … }
std::unique_ptr<DawnContextProvider> DawnContextProvider::Create(
const GpuPreferences& gpu_preferences,
const GpuDriverBugWorkarounds& gpu_driver_workarounds) { … }
std::unique_ptr<DawnContextProvider> DawnContextProvider::CreateWithBackend(
wgpu::BackendType backend_type,
bool force_fallback_adapter,
const GpuPreferences& gpu_preferences,
const GpuDriverBugWorkarounds& gpu_driver_workarounds) { … }
std::unique_ptr<DawnContextProvider>
DawnContextProvider::CreateWithSharedDevice(
const DawnContextProvider* existing) { … }
DawnContextProvider::DawnContextProvider(
scoped_refptr<DawnSharedContext> dawn_shared_context)
: … { … }
DawnContextProvider::~DawnContextProvider() = default;
wgpu::Device DawnContextProvider::GetDevice() const { … }
wgpu::BackendType DawnContextProvider::backend_type() const { … }
bool DawnContextProvider::is_vulkan_swiftshader_adapter() const { … }
wgpu::Adapter DawnContextProvider::GetAdapter() const { … }
wgpu::Instance DawnContextProvider::GetInstance() const { … }
bool DawnContextProvider::InitializeGraphiteContext(
const skgpu::graphite::ContextOptions& context_options) { … }
void DawnContextProvider::SetCachingInterface(
std::unique_ptr<webgpu::DawnCachingInterface> caching_interface) { … }
#if BUILDFLAG(IS_WIN)
Microsoft::WRL::ComPtr<ID3D11Device> DawnContextProvider::GetD3D11Device()
const {
return dawn_shared_context_->GetD3D11Device();
}
#endif
bool DawnContextProvider::SupportsFeature(wgpu::FeatureName feature) { … }
std::optional<error::ContextLostReason> DawnContextProvider::GetResetStatus()
const { … }
}