diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc index 192341a5fad51..f5b4d25d52946 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private.cc @@ -448,7 +448,8 @@ void CollectExtraDevicePerfInfo(const gpu::GPUInfo& gpu_info, if (device.vendor_id == 0xffff /* internal flag for software rendering */ || device.vendor_id == 0x15ad /* VMware */ || device.vendor_id == 0x1414 /* Microsoft software renderer */ || - gpu_info.software_rendering /* SwiftShader */) { + gl::IsSoftwareGLImplementation( + gpu_info.gl_implementation_parts) /* SwiftShader */) { device_perf_info->software_rendering = true; } } diff --git a/content/test/gpu/gpu_tests/gpu_process_integration_test.py b/content/test/gpu/gpu_tests/gpu_process_integration_test.py index d8a3cda267258..cabc13a738392 100644 --- a/content/test/gpu/gpu_tests/gpu_process_integration_test.py +++ b/content/test/gpu/gpu_tests/gpu_process_integration_test.py @@ -497,8 +497,6 @@ def _GpuProcess_swiftshader_for_webgl(self, test_path: str) -> None: self.fail('Target machine must have a GPU') if not gpu.aux_attributes: self.fail('Browser must support GPU aux attributes') - if not gpu.aux_attributes['software_rendering']: - self.fail('Software rendering was disabled') if 'SwiftShader' not in gpu.aux_attributes['gl_renderer']: self.fail('Expected "SwiftShader" in GPU info GL renderer string') if 'Google' not in gpu.aux_attributes['gl_vendor']: diff --git a/gpu/config/gpu_info.cc b/gpu/config/gpu_info.cc index 84f7adabdbe7d..7315dd4a4919d 100644 --- a/gpu/config/gpu_info.cc +++ b/gpu/config/gpu_info.cc @@ -219,7 +219,7 @@ GPUInfo::GPUInfo() : optimus(false), amd_switchable(false), gl_reset_notification_strategy(0), - software_rendering(false), + gl_implementation_parts(gl::kGLImplementationNone), sandboxed(false), in_process_gpu(true), passthrough_cmd_decoder(false), @@ -317,7 +317,7 @@ void GPUInfo::EnumerateFields(Enumerator* enumerator) const { std::string gl_ws_version; std::string gl_ws_extensions; uint32_t gl_reset_notification_strategy; - bool software_rendering; + gl::GLImplementationParts gl_implementation_parts; std::string direct_rendering_version; bool sandboxed; bool in_process_gpu; @@ -390,7 +390,8 @@ void GPUInfo::EnumerateFields(Enumerator* enumerator) const { "glResetNotificationStrategy", static_cast(gl_reset_notification_strategy)); // TODO(kbr): add performance_stats. - enumerator->AddBool("softwareRendering", software_rendering); + enumerator->AddString("glImplementationParts", + gl_implementation_parts.ToString()); enumerator->AddString("directRenderingVersion", direct_rendering_version); enumerator->AddBool("sandboxed", sandboxed); enumerator->AddBool("inProcessGpu", in_process_gpu); diff --git a/gpu/config/gpu_info.h b/gpu/config/gpu_info.h index 151ba49e58024..8b54acc3a88b0 100644 --- a/gpu/config/gpu_info.h +++ b/gpu/config/gpu_info.h @@ -24,6 +24,7 @@ #include "gpu/vulkan/buildflags.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/size.h" +#include "ui/gl/gl_implementation.h" #include "ui/gl/gpu_preference.h" #if BUILDFLAG(IS_WIN) @@ -400,7 +401,7 @@ struct GPU_EXPORT GPUInfo { // reset detection or notification not available. uint32_t gl_reset_notification_strategy; - bool software_rendering; + gl::GLImplementationParts gl_implementation_parts; // Empty means unknown. Defined on X11 as // - "1" means indirect (versions can't be all zero) diff --git a/gpu/ipc/common/gpu_info.mojom b/gpu/ipc/common/gpu_info.mojom index 171ee28c62e61..dd3141c9fdbfb 100644 --- a/gpu/ipc/common/gpu_info.mojom +++ b/gpu/ipc/common/gpu_info.mojom @@ -10,6 +10,7 @@ import "gpu/ipc/common/dx_diag_node.mojom"; import "gpu/ipc/common/luid.mojom"; import "mojo/public/mojom/base/time.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; +import "ui/gl/mojom/gl_implementation.mojom"; import "ui/gl/mojom/gpu_preference.mojom"; [EnableIf=supports_vulkan] @@ -164,7 +165,7 @@ struct GpuInfo { string gl_ws_version; string gl_ws_extensions; uint32 gl_reset_notification_strategy; - bool software_rendering; + gl.mojom.GLImplementationParts gl_implementation_parts; string direct_rendering_version; bool sandboxed; bool in_process_gpu; diff --git a/gpu/ipc/common/gpu_info_mojom_traits.cc b/gpu/ipc/common/gpu_info_mojom_traits.cc index e2fa9128244c4..7fe29e43c16d1 100644 --- a/gpu/ipc/common/gpu_info_mojom_traits.cc +++ b/gpu/ipc/common/gpu_info_mojom_traits.cc @@ -422,7 +422,6 @@ bool StructTraits::Read( out->optimus = data.optimus(); out->amd_switchable = data.amd_switchable(); out->gl_reset_notification_strategy = data.gl_reset_notification_strategy(); - out->software_rendering = data.software_rendering(); out->sandboxed = data.sandboxed(); out->in_process_gpu = data.in_process_gpu(); out->passthrough_cmd_decoder = data.passthrough_cmd_decoder(); @@ -465,6 +464,7 @@ bool StructTraits::Read( data.ReadGlWsVendor(&out->gl_ws_vendor) && data.ReadGlWsVersion(&out->gl_ws_version) && data.ReadGlWsExtensions(&out->gl_ws_extensions) && + data.ReadGlImplementationParts(&out->gl_implementation_parts) && data.ReadDirectRenderingVersion(&out->direct_rendering_version) && #if BUILDFLAG(IS_WIN) data.ReadOverlayInfo(&out->overlay_info) && diff --git a/gpu/ipc/common/gpu_info_mojom_traits.h b/gpu/ipc/common/gpu_info_mojom_traits.h index 7f9615b7b180e..84ae893167a73 100644 --- a/gpu/ipc/common/gpu_info_mojom_traits.h +++ b/gpu/ipc/common/gpu_info_mojom_traits.h @@ -352,8 +352,9 @@ struct GPU_EXPORT StructTraits { return input.gl_reset_notification_strategy; } - static bool software_rendering(const gpu::GPUInfo& input) { - return input.software_rendering; + static const gl::GLImplementationParts gl_implementation_parts( + const gpu::GPUInfo& input) { + return input.gl_implementation_parts; } static const std::string& direct_rendering_version( diff --git a/gpu/ipc/common/mojom_traits_unittest.cc b/gpu/ipc/common/mojom_traits_unittest.cc index d763a1a4ff23b..3a9b90af1110b 100644 --- a/gpu/ipc/common/mojom_traits_unittest.cc +++ b/gpu/ipc/common/mojom_traits_unittest.cc @@ -162,7 +162,8 @@ TEST_F(StructTraitsTest, GpuInfo) { const std::string gl_ws_version = "gl_ws_version"; const std::string gl_ws_extensions = "gl_ws_extensions"; const uint32_t gl_reset_notification_strategy = 0xbeef; - const bool software_rendering = true; + const gl::GLImplementationParts gl_implementation_parts( + gl::ANGLEImplementation::kSwiftShader); const std::string direct_rendering_version = "DRI1"; const bool sandboxed = true; const bool in_process_gpu = true; @@ -201,7 +202,7 @@ TEST_F(StructTraitsTest, GpuInfo) { input.gl_ws_version = gl_ws_version; input.gl_ws_extensions = gl_ws_extensions; input.gl_reset_notification_strategy = gl_reset_notification_strategy; - input.software_rendering = software_rendering; + input.gl_implementation_parts = gl_implementation_parts; input.direct_rendering_version = direct_rendering_version; input.sandboxed = sandboxed; input.in_process_gpu = in_process_gpu; @@ -264,7 +265,7 @@ TEST_F(StructTraitsTest, GpuInfo) { EXPECT_EQ(gl_ws_extensions, output.gl_ws_extensions); EXPECT_EQ(gl_reset_notification_strategy, output.gl_reset_notification_strategy); - EXPECT_EQ(software_rendering, output.software_rendering); + EXPECT_EQ(gl_implementation_parts, output.gl_implementation_parts); EXPECT_EQ(direct_rendering_version, output.direct_rendering_version); EXPECT_EQ(sandboxed, output.sandboxed); EXPECT_EQ(in_process_gpu, output.in_process_gpu); diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc index b80288f6e6148..cf436db509585 100644 --- a/gpu/ipc/service/gpu_init.cc +++ b/gpu/ipc/service/gpu_init.cc @@ -732,9 +732,11 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, } } #endif + gpu_info_.gl_implementation_parts = gl::GetGLImplementationParts(); + bool software_rendering = false; if (gl_use_swiftshader_ || gl::IsSoftwareGLImplementation(gl::GetGLImplementationParts())) { - gpu_info_.software_rendering = true; + software_rendering = true; } else if (gl_disabled) { DCHECK(!recreate_watchdog); watchdog_thread_ = nullptr; @@ -747,7 +749,7 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line, watchdog_init.SetGpuWatchdogPtr(nullptr); watchdog_thread_ = GpuWatchdogThread::Create(gpu_preferences_.watchdog_starts_backgrounded, - gpu_info_.software_rendering, "GpuWatchdog"); + software_rendering, "GpuWatchdog"); watchdog_init.SetGpuWatchdogPtr(watchdog_thread_.get()); } diff --git a/ui/gl/mojom/BUILD.gn b/ui/gl/mojom/BUILD.gn index 3613c635ecac1..1bb2a659de02f 100644 --- a/ui/gl/mojom/BUILD.gn +++ b/ui/gl/mojom/BUILD.gn @@ -4,20 +4,34 @@ import("//mojo/public/tools/bindings/mojom.gni") -mojom("mojom") { +mojom_component("mojom") { + output_prefix = "gl_mojom" + macro_prefix = "GL_MOJOM" + generate_java = true - sources = [ "gpu_preference.mojom" ] + sources = [ + "gl_implementation.mojom", + "gpu_preference.mojom", + ] public_deps = [ "//mojo/public/mojom/base" ] cpp_typemaps = [ { types = [ + { + mojom = "gl.mojom.GLImplementation" + cpp = "::gl::GLImplementation" + }, { mojom = "gl.mojom.GpuPreference" cpp = "::gl::GpuPreference" }, ] - traits_headers = [ "gpu_preference_mojom_traits.h" ] + traits_sources = [ "gl_implementation_mojom_traits.cc" ] + traits_headers = [ + "gl_implementation_mojom_traits.h", + "gpu_preference_mojom_traits.h", + ] traits_public_deps = [ "//ui/gl" ] }, ] diff --git a/ui/gl/mojom/gl_implementation.mojom b/ui/gl/mojom/gl_implementation.mojom new file mode 100644 index 0000000000000..ac8d96ced8b7a --- /dev/null +++ b/ui/gl/mojom/gl_implementation.mojom @@ -0,0 +1,39 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module gl.mojom; + +// Maps to its namesake in ui/gl/gl_implementation.h. +enum GLImplementation { + kGLImplementationNone, + kGLImplementationDesktopGL, + kGLImplementationDesktopGLCoreProfile, + kGLImplementationEGLGLES2, + kGLImplementationMockGL, + kGLImplementationStubGL, + kGLImplementationDisabled, + kGLImplementationEGLANGLE, +}; + +// Maps to its namesake in ui/gl/gl_implementation.h. +enum ANGLEImplementation { + kNone, + kD3D9, + kD3D11, + kOpenGL, + kOpenGLES, + kNull, + kVulkan, + kSwiftShader, + kMetal, + kDefault, +}; + +// Maps to its namesake in ui/gl/gl_implementation.h. +struct GLImplementationParts { + // The GL implementation currently in use. + GLImplementation gl; + // The ANGLE implementation currently in use. + ANGLEImplementation angle; +}; \ No newline at end of file diff --git a/ui/gl/mojom/gl_implementation_mojom_traits.cc b/ui/gl/mojom/gl_implementation_mojom_traits.cc new file mode 100644 index 0000000000000..15d9d7b3597e1 --- /dev/null +++ b/ui/gl/mojom/gl_implementation_mojom_traits.cc @@ -0,0 +1,148 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gl/mojom/gl_implementation_mojom_traits.h" +#include "base/notreached.h" + +namespace mojo { + +// static +gl::mojom::GLImplementation +EnumTraits::ToMojom( + gl::GLImplementation impl) { + switch (impl) { + case gl::kGLImplementationNone: + return gl::mojom::GLImplementation::kGLImplementationNone; + case gl::kGLImplementationDesktopGL: + return gl::mojom::GLImplementation::kGLImplementationDesktopGL; + case gl::kGLImplementationDesktopGLCoreProfile: + return gl::mojom::GLImplementation::kGLImplementationDesktopGLCoreProfile; + case gl::kGLImplementationEGLGLES2: + return gl::mojom::GLImplementation::kGLImplementationEGLGLES2; + case gl::kGLImplementationMockGL: + return gl::mojom::GLImplementation::kGLImplementationMockGL; + case gl::kGLImplementationStubGL: + return gl::mojom::GLImplementation::kGLImplementationStubGL; + case gl::kGLImplementationDisabled: + return gl::mojom::GLImplementation::kGLImplementationDisabled; + case gl::kGLImplementationEGLANGLE: + return gl::mojom::GLImplementation::kGLImplementationEGLANGLE; + } + NOTREACHED(); + return gl::mojom::GLImplementation::kGLImplementationNone; +} + +// static +bool EnumTraits::FromMojom( + gl::mojom::GLImplementation input, + gl::GLImplementation* out) { + switch (input) { + case gl::mojom::GLImplementation::kGLImplementationNone: + *out = gl::kGLImplementationNone; + return true; + case gl::mojom::GLImplementation::kGLImplementationDesktopGL: + *out = gl::kGLImplementationDesktopGL; + return true; + case gl::mojom::GLImplementation::kGLImplementationDesktopGLCoreProfile: + *out = gl::kGLImplementationDesktopGLCoreProfile; + return true; + case gl::mojom::GLImplementation::kGLImplementationEGLGLES2: + *out = gl::kGLImplementationEGLGLES2; + return true; + case gl::mojom::GLImplementation::kGLImplementationMockGL: + *out = gl::kGLImplementationMockGL; + return true; + case gl::mojom::GLImplementation::kGLImplementationStubGL: + *out = gl::kGLImplementationStubGL; + return true; + case gl::mojom::GLImplementation::kGLImplementationDisabled: + *out = gl::kGLImplementationDisabled; + return true; + case gl::mojom::GLImplementation::kGLImplementationEGLANGLE: + *out = gl::kGLImplementationEGLANGLE; + return true; + } + NOTREACHED(); + return false; +} + +// static +gl::mojom::ANGLEImplementation +EnumTraits::ToMojom( + gl::ANGLEImplementation impl) { + switch (impl) { + case gl::ANGLEImplementation::kNone: + return gl::mojom::ANGLEImplementation::kNone; + case gl::ANGLEImplementation::kD3D9: + return gl::mojom::ANGLEImplementation::kD3D9; + case gl::ANGLEImplementation::kD3D11: + return gl::mojom::ANGLEImplementation::kD3D11; + case gl::ANGLEImplementation::kOpenGL: + return gl::mojom::ANGLEImplementation::kOpenGL; + case gl::ANGLEImplementation::kOpenGLES: + return gl::mojom::ANGLEImplementation::kOpenGLES; + case gl::ANGLEImplementation::kNull: + return gl::mojom::ANGLEImplementation::kNull; + case gl::ANGLEImplementation::kVulkan: + return gl::mojom::ANGLEImplementation::kVulkan; + case gl::ANGLEImplementation::kSwiftShader: + return gl::mojom::ANGLEImplementation::kSwiftShader; + case gl::ANGLEImplementation::kMetal: + return gl::mojom::ANGLEImplementation::kMetal; + case gl::ANGLEImplementation::kDefault: + return gl::mojom::ANGLEImplementation::kDefault; + } + NOTREACHED(); + return gl::mojom::ANGLEImplementation::kNone; +} + +// static +bool EnumTraits:: + FromMojom(gl::mojom::ANGLEImplementation input, + gl::ANGLEImplementation* out) { + switch (input) { + case gl::mojom::ANGLEImplementation::kNone: + *out = gl::ANGLEImplementation::kNone; + return true; + case gl::mojom::ANGLEImplementation::kD3D9: + *out = gl::ANGLEImplementation::kD3D9; + return true; + case gl::mojom::ANGLEImplementation::kD3D11: + *out = gl::ANGLEImplementation::kD3D11; + return true; + case gl::mojom::ANGLEImplementation::kOpenGL: + *out = gl::ANGLEImplementation::kOpenGL; + return true; + case gl::mojom::ANGLEImplementation::kOpenGLES: + *out = gl::ANGLEImplementation::kOpenGLES; + return true; + case gl::mojom::ANGLEImplementation::kNull: + *out = gl::ANGLEImplementation::kNull; + return true; + case gl::mojom::ANGLEImplementation::kVulkan: + *out = gl::ANGLEImplementation::kVulkan; + return true; + case gl::mojom::ANGLEImplementation::kSwiftShader: + *out = gl::ANGLEImplementation::kSwiftShader; + return true; + case gl::mojom::ANGLEImplementation::kMetal: + *out = gl::ANGLEImplementation::kMetal; + return true; + case gl::mojom::ANGLEImplementation::kDefault: + *out = gl::ANGLEImplementation::kDefault; + return true; + } + NOTREACHED(); + return false; +} + +// static +bool StructTraits:: + Read(gl::mojom::GLImplementationPartsDataView data, + gl::GLImplementationParts* out) { + return data.ReadGl(&out->gl) && data.ReadAngle(&out->angle); +} + +} // namespace mojo diff --git a/ui/gl/mojom/gl_implementation_mojom_traits.h b/ui/gl/mojom/gl_implementation_mojom_traits.h new file mode 100644 index 0000000000000..d481d4b5fa3e6 --- /dev/null +++ b/ui/gl/mojom/gl_implementation_mojom_traits.h @@ -0,0 +1,48 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GL_MOJOM_GL_IMPLEMENTATION_MOJOM_TRAITS_H_ +#define UI_GL_MOJOM_GL_IMPLEMENTATION_MOJOM_TRAITS_H_ + +#include "base/component_export.h" +#include "ui/gl/gl_implementation.h" +#include "ui/gl/mojom/gl_implementation.mojom.h" + +namespace mojo { + +template <> +struct COMPONENT_EXPORT(GL_MOJOM) + EnumTraits { + static gl::mojom::GLImplementation ToMojom(gl::GLImplementation impl); + static bool FromMojom(gl::mojom::GLImplementation input, + gl::GLImplementation* out); +}; + +template <> +struct COMPONENT_EXPORT(GL_MOJOM) + EnumTraits { + static gl::mojom::ANGLEImplementation ToMojom(gl::ANGLEImplementation impl); + static bool FromMojom(gl::mojom::ANGLEImplementation input, + gl::ANGLEImplementation* out); +}; + +template <> +struct COMPONENT_EXPORT(GL_MOJOM) + StructTraits { + static bool Read(gl::mojom::GLImplementationPartsDataView data, + gl::GLImplementationParts* out); + + static gl::GLImplementation gl(const gl::GLImplementationParts& input) { + return input.gl; + } + + static gl::ANGLEImplementation angle(const gl::GLImplementationParts& input) { + return input.angle; + } +}; + +} // namespace mojo + +#endif // UI_GL_MOJOM_GL_IMPLEMENTATION_MOJOM_TRAITS_H_ diff --git a/ui/gl/mojom/traits_test_service.mojom b/ui/gl/mojom/traits_test_service.mojom index c56c3ee52eb5f..80030552975b5 100644 --- a/ui/gl/mojom/traits_test_service.mojom +++ b/ui/gl/mojom/traits_test_service.mojom @@ -4,11 +4,18 @@ module gl.mojom; +import "ui/gl/mojom/gl_implementation.mojom"; import "ui/gl/mojom/gpu_preference.mojom"; // All functions on this interface echo their arguments to test StructTraits // serialization and deserialization. interface TraitsTestService { + // Serializes and deserializes GpuPreference. [Sync] EchoGpuPreference(GpuPreference g) => (GpuPreference pass); + // Serializes and deserializes GLImplementationParts. + [Sync] + EchoGLImplementationParts( + GLImplementationParts impl) => + (GLImplementationParts pass); };