blob: e2453b96ee550bf6d7dcc1fd26b2e7a2d75d8ec1 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
[email protected]b7c4f032012-08-07 16:38:562// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]15154932013-08-21 03:27:245#include "content/browser/gpu/compositor_util.h"
[email protected]b7c4f032012-08-07 16:38:566
avib7348942015-12-25 20:57:107#include <stddef.h>
8
Jonathan Backer76dfd502018-05-03 18:34:319#include <algorithm>
10#include <memory>
dcheng98e96a72016-06-11 03:41:4811#include <utility>
12
[email protected]b7c4f032012-08-07 16:38:5613#include "base/command_line.h"
ericrkfc493232016-05-17 22:08:2314#include "base/feature_list.h"
[email protected]eab9db72013-10-30 23:13:1415#include "base/logging.h"
[email protected]8f3f6592014-06-07 00:24:0616#include "base/metrics/field_trial.h"
danakj8a91b032014-08-30 00:04:2217#include "base/strings/string_number_conversions.h"
Kenneth Russellcc1732e02018-07-30 19:42:5618#include "base/strings/string_split.h"
Sebastien Marchand75a7cdf2018-11-13 23:47:0319#include "base/system/sys_info.h"
Austin Sullivanbf2dfe32021-05-07 22:19:5820#include "base/values.h"
[email protected]7aa0d382013-09-06 08:21:1821#include "build/build_config.h"
Zhenyao Mo43539222025-05-07 20:38:0422#include "cc/base/features.h"
[email protected]f454eed2013-10-16 05:48:0223#include "cc/base/switches.h"
Fady Samuel54f7a132018-03-06 17:14:5524#include "components/viz/common/features.h"
Zhenyao Modf928552018-03-30 19:30:0925#include "content/browser/compositor/image_transport_factory.h"
[email protected]f454eed2013-10-16 05:48:0226#include "content/browser/gpu/gpu_data_manager_impl.h"
Ken Russell225fb012018-04-12 18:01:0427#include "content/browser/gpu/gpu_process_host.h"
ericrkfc493232016-05-17 22:08:2328#include "content/public/common/content_features.h"
[email protected]b7c4f032012-08-07 16:38:5629#include "content/public/common/content_switches.h"
Peng Huang9b7d2ee2019-10-02 20:18:2230#include "gpu/command_buffer/service/gpu_switches.h"
Chris Blume29bf5362019-09-06 02:34:4531#include "gpu/config/gpu_blocklist.h"
Zhenyao Mo68ef56d2018-04-21 01:05:1032#include "gpu/config/gpu_driver_bug_list.h"
33#include "gpu/config/gpu_driver_bug_workaround_type.h"
[email protected]d7b5cc72013-05-23 20:05:0034#include "gpu/config/gpu_feature_type.h"
Sunny Sachanandania8bbcf92017-09-20 05:26:0135#include "gpu/config/gpu_finch_features.h"
Zhenyao Mof920e132017-12-19 20:16:5036#include "gpu/config/gpu_switches.h"
Peng Huang9b7d2ee2019-10-02 20:18:2237#include "gpu/vulkan/buildflags.h"
Ted Meyera7b402532020-12-04 10:39:2438#include "media/base/media_switches.h"
Scott Violeta35f9a42018-03-22 22:00:4439#include "media/media_buildflags.h"
Sunny Sachanandanifb74c17f2023-04-10 21:29:1740#include "skia/buildflags.h"
Dave Tapuska9bcf6cc2020-06-25 15:15:0141#include "third_party/blink/public/common/switches.h"
Peng Huang5f3d4352021-11-23 17:51:2942#include "ui/base/ui_base_features.h"
zmo05f50f9b2016-10-29 00:40:2943#include "ui/gl/gl_switches.h"
[email protected]b7c4f032012-08-07 16:38:5644
[email protected]99456fa2012-11-01 18:22:0845namespace content {
[email protected]cb6430932012-10-31 00:53:3646
[email protected]99456fa2012-11-01 18:22:0847namespace {
[email protected]cb6430932012-10-31 00:53:3648
danakj8a91b032014-08-30 00:04:2249const int kMinRasterThreads = 1;
reveman947608502015-06-25 23:10:5650const int kMaxRasterThreads = 4;
[email protected]6fa615b42014-04-28 10:28:2051
senorblancob60ba952015-01-27 19:12:3652const int kMinMSAASampleCount = 0;
53
Zhenyao Mo68ef56d2018-04-21 01:05:1054enum class GpuFeatureInfoType { kCurrent, kForHardwareGpu };
55
kylechar6c29b0c2019-06-07 18:50:4056struct DisableInfo {
57 // The feature being disabled will be listed as a problem with |description|.
58 static DisableInfo Problem(const std::string& description) {
59 return DisableInfo{true, description};
60 }
61
62 // The feature being disabled will not be listed as a problem.
63 static DisableInfo NotProblem() { return DisableInfo{false, ""}; }
64
65 bool is_problem;
66 std::string description;
67};
68
Zhenyao Mof920e132017-12-19 20:16:5069struct GpuFeatureData {
[email protected]f454eed2013-10-16 05:48:0270 std::string name;
Zhenyao Mof920e132017-12-19 20:16:5071 gpu::GpuFeatureStatus status;
kylechare5461b22024-02-27 18:08:4872 DisableInfo disabled_info = DisableInfo::NotProblem();
73 bool fallback_to_software = false;
[email protected]f454eed2013-10-16 05:48:0274};
75
kylecharb920f9a2024-03-04 15:28:4276// Returns enabled/disabled based on a bool for when there is no GpuFeatureType.
77gpu::GpuFeatureStatus GetFakeFeatureStatus(bool enabled) {
78 return enabled ? gpu::kGpuFeatureStatusEnabled
79 : gpu::kGpuFeatureStatusDisabled;
80}
81
kylechar621dd6b2024-03-04 22:08:4982// `force_disabled` should only be true when the feature status from
83// `gpu_feature_info` is missing information. In general this should be avoided
84// and GpuFeatureInfo should be made to be correct.
Zhenyao Mo68ef56d2018-04-21 01:05:1085gpu::GpuFeatureStatus SafeGetFeatureStatus(
86 const gpu::GpuFeatureInfo& gpu_feature_info,
kylecharb920f9a2024-03-04 15:28:4287 gpu::GpuFeatureType feature,
88 bool force_disabled = false) {
89 if (force_disabled) {
90 return gpu::kGpuFeatureStatusDisabled;
91 }
92
Zhenyao Mo68ef56d2018-04-21 01:05:1093 if (!gpu_feature_info.IsInitialized()) {
Ken Russell225fb012018-04-12 18:01:0494 // The GPU process probably crashed during startup, but we can't
95 // assert this as the test bots are slow, and recording the crash
96 // is racy. Be robust and just say that all features are disabled.
97 return gpu::kGpuFeatureStatusDisabled;
98 }
Zhenyao Mo68ef56d2018-04-21 01:05:1099 DCHECK(feature >= 0 && feature < gpu::NUMBER_OF_GPU_FEATURE_TYPES);
100 return gpu_feature_info.status_values[feature];
Ken Russell225fb012018-04-12 18:01:04101}
102
kylechar464200c2024-02-27 17:59:06103std::vector<GpuFeatureData> GetGpuFeatureData(
Zhenyao Mo68ef56d2018-04-21 01:05:10104 const gpu::GpuFeatureInfo& gpu_feature_info,
kylechar464200c2024-02-27 17:59:06105 bool is_gpu_compositing_disabled) {
[email protected]479278702014-08-11 20:32:09106 const base::CommandLine& command_line =
107 *base::CommandLine::ForCurrentProcess();
jbauman63c408492016-07-28 21:21:44108
kylechar464200c2024-02-27 17:59:06109 std::vector<GpuFeatureData> features;
110 features.emplace_back(
111 "2d_canvas",
kylecharb920f9a2024-03-04 15:28:42112 SafeGetFeatureStatus(
113 gpu_feature_info, gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
114 command_line.HasSwitch(switches::kDisableAccelerated2dCanvas)),
kylechar464200c2024-02-27 17:59:06115 DisableInfo::Problem(
116 "Accelerated 2D canvas is unavailable: either disabled "
117 "via blocklist or the command line."),
118 true);
119 features.emplace_back(
kylechar464200c2024-02-27 17:59:06120 "gpu_compositing",
121 // TODO(rivr): Replace with a check to see which backend is used for
122 // compositing; do the same for GPU rasterization if it's enabled. For
123 // now assume that if GL is blocklisted, then Vulkan is also. Check GL to
124 // see if GPU compositing is disabled.
125 SafeGetFeatureStatus(gpu_feature_info,
kylecharb920f9a2024-03-04 15:28:42126 gpu::GPU_FEATURE_TYPE_ACCELERATED_GL,
127 is_gpu_compositing_disabled),
kylechar464200c2024-02-27 17:59:06128 DisableInfo::Problem(
129 "Gpu compositing has been disabled, either via blocklist, "
130 "about:flags "
131 "or the command line. The browser will fall back to software "
132 "compositing and hardware acceleration will be unavailable."),
133 true);
134 features.emplace_back(
135 "webgl",
136 SafeGetFeatureStatus(gpu_feature_info,
kylecharb920f9a2024-03-04 15:28:42137 gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL,
138 command_line.HasSwitch(switches::kDisableWebGL)),
kylechar464200c2024-02-27 17:59:06139 DisableInfo::Problem(
140 "WebGL has been disabled via blocklist or the command line."),
141 false);
142 features.emplace_back(
143 "video_decode",
kylecharb920f9a2024-03-04 15:28:42144 SafeGetFeatureStatus(
145 gpu_feature_info, gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE,
Xiaohan Wang51dde9982022-01-14 18:37:49146#if BUILDFLAG(IS_LINUX)
Robert Mader54822102024-10-02 19:21:17147 !base::FeatureList::IsEnabled(media::kAcceleratedVideoDecodeLinux) ||
Xiaohan Wang51dde9982022-01-14 18:37:49148#endif // BUILDFLAG(IS_LINUX)
kylecharb920f9a2024-03-04 15:28:42149 command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode)),
kylechar464200c2024-02-27 17:59:06150 DisableInfo::Problem(
151 "Accelerated video decode has been disabled, either via blocklist, "
152 "about:flags or the command line."),
153 true);
154 features.emplace_back(
155 "video_encode",
kylecharb920f9a2024-03-04 15:28:42156 SafeGetFeatureStatus(
157 gpu_feature_info, gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE,
Xiaohan Wang51dde9982022-01-14 18:37:49158#if BUILDFLAG(IS_LINUX)
Robert Mader54822102024-10-02 19:21:17159 !base::FeatureList::IsEnabled(media::kAcceleratedVideoEncodeLinux)),
Chunbo Huac6e4a092021-11-17 05:07:43160#else
kylecharb920f9a2024-03-04 15:28:42161 command_line.HasSwitch(switches::kDisableAcceleratedVideoEncode)),
Xiaohan Wang51dde9982022-01-14 18:37:49162#endif // BUILDFLAG(IS_LINUX)
kylechar464200c2024-02-27 17:59:06163 DisableInfo::Problem(
164 "Accelerated video encode has been disabled, either via blocklist, "
165 "about:flags or the command line."),
166 true);
167 features.emplace_back(
168 "rasterization",
kylechar621dd6b2024-03-04 22:08:49169 SafeGetFeatureStatus(gpu_feature_info,
170 gpu::GPU_FEATURE_TYPE_GPU_TILE_RASTERIZATION),
kylechar464200c2024-02-27 17:59:06171 DisableInfo::Problem(
172 "Accelerated rasterization has been disabled, either via blocklist, "
173 "about:flags or the command line."),
174 true);
175 features.emplace_back(
kylechare5461b22024-02-27 18:08:48176 "opengl", SafeGetFeatureStatus(gpu_feature_info,
177 gpu::GPU_FEATURE_TYPE_ACCELERATED_GL));
Peng Huang9b7d2ee2019-10-02 20:18:22178#if BUILDFLAG(ENABLE_VULKAN)
kylechar464200c2024-02-27 17:59:06179 features.emplace_back(
180 "vulkan",
kylechar621dd6b2024-03-04 22:08:49181 SafeGetFeatureStatus(gpu_feature_info, gpu::GPU_FEATURE_TYPE_VULKAN));
Peng Huang9b7d2ee2019-10-02 20:18:22182#endif
kylechar464200c2024-02-27 17:59:06183 features.emplace_back(
kylecharb920f9a2024-03-04 15:28:42184 "multiple_raster_threads",
185 GetFakeFeatureStatus(NumberOfRendererRasterThreads() > 1));
Xiaohan Wang51dde9982022-01-14 18:37:49186#if BUILDFLAG(IS_ANDROID)
Hailey Wang4b2528292025-08-19 18:02:32187 features.emplace_back(
188 "surface_control",
189 SafeGetFeatureStatus(gpu_feature_info,
190 gpu::GPU_FEATURE_TYPE_ANDROID_SURFACE_CONTROL));
Khushalbb1963a2018-10-02 21:02:35191#endif
kylechar464200c2024-02-27 17:59:06192 features.emplace_back(
193 "webgl2",
kylecharb920f9a2024-03-04 15:28:42194 SafeGetFeatureStatus(
195 gpu_feature_info, gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL2,
196 command_line.HasSwitch(switches::kDisableWebGL) ||
197 command_line.HasSwitch(switches::kDisableWebGL2)),
kylechar464200c2024-02-27 17:59:06198 DisableInfo::Problem(
199 "WebGL2 has been disabled via blocklist or the command line."),
200 false);
kylecharb920f9a2024-03-04 15:28:42201 features.emplace_back("raw_draw",
Peter Kasting6e6af3c2024-10-15 00:13:18202 GetFakeFeatureStatus(::features::IsUsingRawDraw()));
Maggie Chen4fa6513a2025-07-09 22:11:19203 features.emplace_back(
204 "direct_rendering_display_compositor",
205 SafeGetFeatureStatus(
206 gpu_feature_info,
207 gpu::GPU_FEATURE_TYPE_DIRECT_RENDERING_DISPLAY_COMPOSITOR));
kylechar464200c2024-02-27 17:59:06208 features.emplace_back(
209 "webgpu",
kylecharb920f9a2024-03-04 15:28:42210 SafeGetFeatureStatus(
211 gpu_feature_info, gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGPU,
212 !command_line.HasSwitch(switches::kEnableUnsafeWebGPU) &&
213 !base::FeatureList::IsEnabled(::features::kWebGPUService)),
kylechar464200c2024-02-27 17:59:06214 DisableInfo::Problem(
215 "WebGPU has been disabled via blocklist or the command line."),
216 false);
217 features.emplace_back(
218 "skia_graphite",
219 SafeGetFeatureStatus(gpu_feature_info,
kylechare5461b22024-02-27 18:08:48220 gpu::GPU_FEATURE_TYPE_SKIA_GRAPHITE));
Pooja Patela00fc492024-03-07 19:24:08221 features.emplace_back(
222 "webnn",
223 SafeGetFeatureStatus(gpu_feature_info, gpu::GPU_FEATURE_TYPE_WEBNN));
Zhenyao Mo43539222025-05-07 20:38:04224 features.emplace_back("trees_in_viz",
225 base::FeatureList::IsEnabled(::features::kTreesInViz)
226 ? gpu::kGpuFeatureStatusEnabled
227 : gpu::kGpuFeatureStatusDisabled);
kylechar464200c2024-02-27 17:59:06228 return features;
[email protected]f454eed2013-10-16 05:48:02229}
230
Austin Sullivanbf2dfe32021-05-07 22:19:58231base::Value GetFeatureStatusImpl(GpuFeatureInfoType type) {
Zhenyao Mo68ef56d2018-04-21 01:05:10232 GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
233 std::string gpu_access_blocked_reason;
Zhenyao Mo811534f32020-12-22 23:17:14234 bool gpu_access_blocked;
235 gpu::GpuFeatureInfo gpu_feature_info;
236 bool is_gpu_compositing_disabled;
237 if (type == GpuFeatureInfoType::kCurrent) {
238 gpu_access_blocked = !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
239 gpu_feature_info = manager->GetGpuFeatureInfo();
240 is_gpu_compositing_disabled = manager->IsGpuCompositingDisabled();
241 } else {
242 gpu_access_blocked =
243 !manager->GpuAccessAllowedForHardwareGpu(&gpu_access_blocked_reason);
244 gpu_feature_info = manager->GetGpuFeatureInfoForHardwareGpu();
245 is_gpu_compositing_disabled =
246 manager->IsGpuCompositingDisabledForHardwareGpu();
247 }
Zhenyao Mo68ef56d2018-04-21 01:05:10248
Matt Menkead6c1a52022-08-12 00:58:25249 base::Value::Dict feature_status_dict;
Zhenyao Mo68ef56d2018-04-21 01:05:10250
kylechar464200c2024-02-27 17:59:06251 for (auto& gpu_feature_data :
252 GetGpuFeatureData(gpu_feature_info, is_gpu_compositing_disabled)) {
Zhenyao Mo68ef56d2018-04-21 01:05:10253 std::string status;
kylechar6c29b0c2019-06-07 18:50:40254 // Features undergoing a finch controlled roll out.
kylechar0b3b0022022-06-07 13:10:26255 if (gpu_feature_data.name == "raw_draw" ||
256 gpu_feature_data.name == "direct_rendering_display_compositor") {
kylecharb920f9a2024-03-04 15:28:42257 status = gpu_feature_data.status == gpu::kGpuFeatureStatusEnabled
258 ? "enabled_on"
259 : "disabled_off_ok";
260 } else if (gpu_access_blocked ||
kylechar0dad9bc72018-08-03 00:35:30261 gpu_feature_data.status == gpu::kGpuFeatureStatusDisabled) {
Zhenyao Mo68ef56d2018-04-21 01:05:10262 status = "disabled";
263 if (gpu_feature_data.fallback_to_software)
264 status += "_software";
265 else
266 status += "_off";
Corentin Wallez5cbffcc2020-07-08 10:23:57267 } else if (gpu_feature_data.status == gpu::kGpuFeatureStatusBlocklisted) {
Zhenyao Mo68ef56d2018-04-21 01:05:10268 status = "unavailable_off";
269 } else if (gpu_feature_data.status == gpu::kGpuFeatureStatusSoftware) {
270 status = "unavailable_software";
271 } else {
272 status = "enabled";
Justin Novosad5a902072021-08-23 15:32:58273 if (gpu_feature_data.name == "canvas_oop_rasterization") {
274 status += "_on";
275 }
Zhenyao Mo68ef56d2018-04-21 01:05:10276 if ((gpu_feature_data.name == "webgl" ||
Yunchao Hee04a479c2022-04-01 18:09:09277 gpu_feature_data.name == "webgl2" ||
278 gpu_feature_data.name == "webgpu") &&
Zhenyao Mo811534f32020-12-22 23:17:14279 is_gpu_compositing_disabled)
Zhenyao Mo68ef56d2018-04-21 01:05:10280 status += "_readback";
281 if (gpu_feature_data.name == "rasterization") {
danakj51faabd2020-03-31 17:25:05282 const base::CommandLine& command_line =
283 *base::CommandLine::ForCurrentProcess();
284 if (command_line.HasSwitch(switches::kEnableGpuRasterization))
Zhenyao Mo68ef56d2018-04-21 01:05:10285 status += "_force";
286 }
287 if (gpu_feature_data.name == "multiple_raster_threads") {
288 const base::CommandLine& command_line =
289 *base::CommandLine::ForCurrentProcess();
Peter Kasting6e6af3c2024-10-15 00:13:18290 if (command_line.HasSwitch(switches::kNumRasterThreads)) {
Zhenyao Mo68ef56d2018-04-21 01:05:10291 status += "_force";
Ken Rockot2ab918c72023-04-13 17:53:17292 }
Zhenyao Mo68ef56d2018-04-21 01:05:10293 status += "_on";
294 }
Sean Gilhuly1e54ddb2019-11-28 18:52:28295 if (gpu_feature_data.name == "opengl" ||
296 gpu_feature_data.name == "metal" ||
Peng Huang9b7d2ee2019-10-02 20:18:22297 gpu_feature_data.name == "vulkan" ||
kylechar67db7ae42024-01-25 20:32:35298 gpu_feature_data.name == "skia_graphite" ||
Pooja Patela00fc492024-03-07 19:24:08299 gpu_feature_data.name == "surface_control" ||
Zhenyao Mo43539222025-05-07 20:38:04300 gpu_feature_data.name == "webnn" ||
301 gpu_feature_data.name == "trees_in_viz") {
Christopher Cameron3a3601892019-05-16 21:43:52302 status += "_on";
kylechar6c29b0c2019-06-07 18:50:40303 }
Zhenyao Mo68ef56d2018-04-21 01:05:10304 }
Matt Menkead6c1a52022-08-12 00:58:25305 feature_status_dict.Set(gpu_feature_data.name, status);
Zhenyao Mo68ef56d2018-04-21 01:05:10306 }
Matt Menkead6c1a52022-08-12 00:58:25307 return base::Value(std::move(feature_status_dict));
Zhenyao Mo68ef56d2018-04-21 01:05:10308}
309
Austin Sullivanbf2dfe32021-05-07 22:19:58310base::Value GetProblemsImpl(GpuFeatureInfoType type) {
Zhenyao Mo68ef56d2018-04-21 01:05:10311 GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
312 std::string gpu_access_blocked_reason;
Zhenyao Mo811534f32020-12-22 23:17:14313 bool gpu_access_blocked;
314 gpu::GpuFeatureInfo gpu_feature_info;
315 bool is_gpu_compositing_disabled;
316 if (type == GpuFeatureInfoType::kCurrent) {
317 gpu_access_blocked = !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
318 gpu_feature_info = manager->GetGpuFeatureInfo();
319 is_gpu_compositing_disabled = manager->IsGpuCompositingDisabled();
320 } else {
321 gpu_access_blocked =
322 !manager->GpuAccessAllowedForHardwareGpu(&gpu_access_blocked_reason);
323 gpu_feature_info = manager->GetGpuFeatureInfoForHardwareGpu();
324 is_gpu_compositing_disabled =
325 manager->IsGpuCompositingDisabledForHardwareGpu();
326 }
Zhenyao Mo68ef56d2018-04-21 01:05:10327
Matt Menkead6c1a52022-08-12 00:58:25328 base::Value::List problem_list;
Corentin Wallez5cbffcc2020-07-08 10:23:57329 if (!gpu_feature_info.applied_gpu_blocklist_entries.empty()) {
330 std::unique_ptr<gpu::GpuBlocklist> blocklist(gpu::GpuBlocklist::Create());
Austin Sullivanbf2dfe32021-05-07 22:19:58331 blocklist->GetReasons(problem_list, "disabledFeatures",
Corentin Wallez5cbffcc2020-07-08 10:23:57332 gpu_feature_info.applied_gpu_blocklist_entries);
Zhenyao Mo68ef56d2018-04-21 01:05:10333 }
334 if (!gpu_feature_info.applied_gpu_driver_bug_list_entries.empty()) {
335 std::unique_ptr<gpu::GpuDriverBugList> bug_list(
336 gpu::GpuDriverBugList::Create());
Austin Sullivanbf2dfe32021-05-07 22:19:58337 bug_list->GetReasons(problem_list, "workarounds",
Zhenyao Mo68ef56d2018-04-21 01:05:10338 gpu_feature_info.applied_gpu_driver_bug_list_entries);
339 }
340
341 if (gpu_access_blocked) {
Matt Menkead6c1a52022-08-12 00:58:25342 base::Value::Dict problem;
343 problem.Set("description",
344 "GPU process was unable to boot: " + gpu_access_blocked_reason);
345 problem.Set("crBugs", base::Value::List());
346 base::Value::List disabled_features;
Austin Sullivanbf2dfe32021-05-07 22:19:58347 disabled_features.Append("all");
Matt Menkead6c1a52022-08-12 00:58:25348 problem.Set("affectedGpuSettings", std::move(disabled_features));
349 problem.Set("tag", "disabledFeatures");
350 problem_list.Insert(problem_list.begin(), base::Value(std::move(problem)));
Zhenyao Mo68ef56d2018-04-21 01:05:10351 }
352
kylechar464200c2024-02-27 17:59:06353 for (auto& gpu_feature_data :
354 GetGpuFeatureData(gpu_feature_info, is_gpu_compositing_disabled)) {
kylecharb920f9a2024-03-04 15:28:42355 if (gpu_feature_data.status != gpu::kGpuFeatureStatusEnabled &&
kylechar6c29b0c2019-06-07 18:50:40356 gpu_feature_data.disabled_info.is_problem) {
Matt Menkead6c1a52022-08-12 00:58:25357 base::Value::Dict problem;
358 problem.Set("description", gpu_feature_data.disabled_info.description);
359 problem.Set("crBugs", base::Value::List());
360 base::Value::List disabled_features;
Austin Sullivanbf2dfe32021-05-07 22:19:58361 disabled_features.Append(gpu_feature_data.name);
Matt Menkead6c1a52022-08-12 00:58:25362 problem.Set("affectedGpuSettings", std::move(disabled_features));
363 problem.Set("tag", "disabledFeatures");
364 problem_list.Insert(problem_list.begin(),
365 base::Value(std::move(problem)));
Zhenyao Mo68ef56d2018-04-21 01:05:10366 }
367 }
Matt Menkead6c1a52022-08-12 00:58:25368 return base::Value(std::move(problem_list));
Zhenyao Mo68ef56d2018-04-21 01:05:10369}
370
371std::vector<std::string> GetDriverBugWorkaroundsImpl(GpuFeatureInfoType type) {
372 GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
373 const gpu::GpuFeatureInfo gpu_feature_info =
374 type == GpuFeatureInfoType::kCurrent
375 ? manager->GetGpuFeatureInfo()
376 : manager->GetGpuFeatureInfoForHardwareGpu();
377
378 std::vector<std::string> workarounds;
379 for (auto workaround : gpu_feature_info.enabled_gpu_driver_bug_workarounds) {
380 workarounds.push_back(gpu::GpuDriverBugWorkaroundTypeToString(
381 static_cast<gpu::GpuDriverBugWorkaroundType>(workaround)));
382 }
Kenneth Russellcc1732e02018-07-30 19:42:56383 // Tell clients about the disabled extensions and disabled WebGL
384 // extensions as well, to avoid confusion. Do this in a way that's
385 // compatible with the current reporting of driver bug workarounds
386 // to DevTools and Telemetry, and from there to the GPU tests.
387 //
388 // This code must be kept in sync with
389 // GpuBenchmarking::GetGpuDriverBugWorkarounds.
390 for (auto ext : base::SplitString(gpu_feature_info.disabled_extensions,
391 " ",
392 base::TRIM_WHITESPACE,
393 base::SPLIT_WANT_NONEMPTY)) {
394 workarounds.push_back("disabled_extension_" + ext);
395 }
396 for (auto ext : base::SplitString(gpu_feature_info.disabled_webgl_extensions,
397 " ",
398 base::TRIM_WHITESPACE,
399 base::SPLIT_WANT_NONEMPTY)) {
400 workarounds.push_back("disabled_webgl_extension_" + ext);
401 }
Zhenyao Mo68ef56d2018-04-21 01:05:10402 return workarounds;
403}
404
[email protected]cb6430932012-10-31 00:53:36405} // namespace
406
danakj8a91b032014-08-30 00:04:22407int NumberOfRendererRasterThreads() {
vmiura6bfd5d892015-06-09 22:47:04408 int num_processors = base::SysInfo::NumberOfProcessors();
409
Xiaohan Wang51dde9982022-01-14 18:37:49410#if BUILDFLAG(IS_ANDROID) || \
411 (BUILDFLAG(IS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY))
reveman1760f2f2016-08-25 23:36:38412 // Android and ChromeOS ARM devices may report 6 to 8 CPUs for big.LITTLE
413 // configurations. Limit the number of raster threads based on maximum of
414 // 4 big cores.
vmiura6bfd5d892015-06-09 22:47:04415 num_processors = std::min(num_processors, 4);
416#endif
417
418 int num_raster_threads = num_processors / 2;
danakj8a91b032014-08-30 00:04:22419
Xiaohan Wang51dde9982022-01-14 18:37:49420#if BUILDFLAG(IS_ANDROID)
reveman0e8fda52015-06-25 21:39:17421 // Limit the number of raster threads to 1 on Android.
422 // TODO(reveman): Remove this when we have a better mechanims to prevent
423 // pre-paint raster work from slowing down non-raster work. crbug.com/504515
424 num_raster_threads = 1;
425#endif
426
revemanfb8bb922015-05-19 17:58:13427 const base::CommandLine& command_line =
428 *base::CommandLine::ForCurrentProcess();
danakj8a91b032014-08-30 00:04:22429
Peter Kasting6e6af3c2024-10-15 00:13:18430 if (command_line.HasSwitch(switches::kNumRasterThreads)) {
Dave Tapuskafcd9bb782022-07-12 18:09:31431 std::string string_value =
Peter Kasting6e6af3c2024-10-15 00:13:18432 command_line.GetSwitchValueASCII(switches::kNumRasterThreads);
revemanfb8bb922015-05-19 17:58:13433 if (!base::StringToInt(string_value, &num_raster_threads)) {
Peter Kasting6e6af3c2024-10-15 00:13:18434 DLOG(WARNING) << "Failed to parse switch " << switches::kNumRasterThreads
435 << ": " << string_value;
revemanfb8bb922015-05-19 17:58:13436 }
437 }
438
Baitinqbc4cea12023-04-22 00:48:39439 return std::clamp(num_raster_threads, kMinRasterThreads, kMaxRasterThreads);
danakj8a91b032014-08-30 00:04:22440}
441
danakj0977ec82015-01-13 01:54:34442bool IsZeroCopyUploadEnabled() {
443 const base::CommandLine& command_line =
444 *base::CommandLine::ForCurrentProcess();
Xiaohan Wang51dde9982022-01-14 18:37:49445#if BUILDFLAG(IS_MAC)
Dave Tapuska9bcf6cc2020-06-25 15:15:01446 return !command_line.HasSwitch(blink::switches::kDisableZeroCopy);
andresantoso67c34a522015-09-23 22:57:15447#else
Dave Tapuska9bcf6cc2020-06-25 15:15:01448 return command_line.HasSwitch(blink::switches::kEnableZeroCopy);
andresantoso67c34a522015-09-23 22:57:15449#endif
danakj0977ec82015-01-13 01:54:34450}
451
ericrk1d17f752015-10-20 03:03:07452bool IsPartialRasterEnabled() {
Peng Huang6cae4102021-09-29 20:46:11453 // Partial raster is not supported with RawDraw.
Peter Kasting6e6af3c2024-10-15 00:13:18454 if (::features::IsUsingRawDraw()) {
Peng Huang6cae4102021-09-29 20:46:11455 return false;
Arthur Sonzognibdeca8e2023-09-11 08:32:12456 }
chrishtra8662c62016-03-30 16:19:24457 const auto& command_line = *base::CommandLine::ForCurrentProcess();
Dave Tapuska9bcf6cc2020-06-25 15:15:01458 return !command_line.HasSwitch(blink::switches::kDisablePartialRaster);
jbroman5f7f71932015-08-18 16:24:46459}
460
ccameronc7fcd132015-11-03 20:14:31461bool IsGpuMemoryBufferCompositorResourcesEnabled() {
Peng Huanga7d30d32021-11-30 19:43:31462 // To use Raw Draw, the Raw Draw shared image backing should be used, so
463 // not use GPU memory buffer shared image backings for compositor resources.
Peter Kasting6e6af3c2024-10-15 00:13:18464 if (::features::IsUsingRawDraw()) {
Peng Huanga7d30d32021-11-30 19:43:31465 return false;
466 }
ccameronc7fcd132015-11-03 20:14:31467 const base::CommandLine& command_line =
468 *base::CommandLine::ForCurrentProcess();
ccamerona956c997f2015-11-10 07:13:28469 if (command_line.HasSwitch(
Dave Tapuska9bcf6cc2020-06-25 15:15:01470 blink::switches::kEnableGpuMemoryBufferCompositorResources)) {
ccamerona956c997f2015-11-10 07:13:28471 return true;
472 }
473 if (command_line.HasSwitch(
474 switches::kDisableGpuMemoryBufferCompositorResources)) {
475 return false;
476 }
477
Maksim Sisova936fcb2023-03-16 20:59:05478#if BUILDFLAG(IS_APPLE)
ccameronc871e302015-11-24 03:42:10479 return true;
Michael Tangbca88672024-07-30 00:24:37480#elif BUILDFLAG(IS_WIN)
481 return features::IsDelegatedCompositingEnabled() &&
Michael Tang54f58c332024-08-06 18:15:07482 features::kDelegatedCompositingModeParam.Get() ==
483 features::DelegatedCompositingMode::kFull;
ccamerona956c997f2015-11-10 07:13:28484#else
485 return false;
486#endif
ccameronc7fcd132015-11-03 20:14:31487}
488
senorblancob60ba952015-01-27 19:12:36489int GpuRasterizationMSAASampleCount() {
490 const base::CommandLine& command_line =
491 *base::CommandLine::ForCurrentProcess();
492
Dave Tapuska9bcf6cc2020-06-25 15:15:01493 if (!command_line.HasSwitch(
494 blink::switches::kGpuRasterizationMSAASampleCount))
Xiaohan Wang51dde9982022-01-14 18:37:49495#if BUILDFLAG(IS_ANDROID)
senorblancofb88a4e2015-05-08 17:28:41496 return 4;
497#else
senorblanco2a5b0e12015-08-14 21:55:37498 // Desktop platforms will compute this automatically based on DPI.
499 return -1;
senorblancofb88a4e2015-05-08 17:28:41500#endif
senorblancob60ba952015-01-27 19:12:36501 std::string string_value = command_line.GetSwitchValueASCII(
Dave Tapuska9bcf6cc2020-06-25 15:15:01502 blink::switches::kGpuRasterizationMSAASampleCount);
senorblancob60ba952015-01-27 19:12:36503 int msaa_sample_count = 0;
504 if (base::StringToInt(string_value, &msaa_sample_count) &&
505 msaa_sample_count >= kMinMSAASampleCount) {
506 return msaa_sample_count;
507 } else {
508 DLOG(WARNING) << "Failed to parse switch "
Dave Tapuska9bcf6cc2020-06-25 15:15:01509 << blink::switches::kGpuRasterizationMSAASampleCount << ": "
senorblancob60ba952015-01-27 19:12:36510 << string_value;
511 return 0;
512 }
513}
514
sunnyps3fe3c982016-05-18 00:22:46515bool IsMainFrameBeforeActivationEnabled() {
516 if (base::SysInfo::NumberOfProcessors() < 4)
517 return false;
518
Sunny Sachanandania8bbcf92017-09-20 05:26:01519 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
Peter Kasting6e6af3c2024-10-15 00:13:18520 switches::kDisableMainFrameBeforeActivation)) {
sunnyps3fe3c982016-05-18 00:22:46521 return false;
Peter Kasting6e6af3c2024-10-15 00:13:18522 }
sunnyps3fe3c982016-05-18 00:22:46523
sunnyps398642c2016-09-03 00:04:09524 return true;
sunnyps3fe3c982016-05-18 00:22:46525}
526
Austin Sullivanbf2dfe32021-05-07 22:19:58527base::Value GetFeatureStatus() {
Zhenyao Mo68ef56d2018-04-21 01:05:10528 return GetFeatureStatusImpl(GpuFeatureInfoType::kCurrent);
[email protected]f454eed2013-10-16 05:48:02529}
530
Austin Sullivanbf2dfe32021-05-07 22:19:58531base::Value GetProblems() {
Zhenyao Mo68ef56d2018-04-21 01:05:10532 return GetProblemsImpl(GpuFeatureInfoType::kCurrent);
[email protected]f454eed2013-10-16 05:48:02533}
534
vkuzkokov7a4981d72014-11-13 10:22:36535std::vector<std::string> GetDriverBugWorkarounds() {
Zhenyao Mo68ef56d2018-04-21 01:05:10536 return GetDriverBugWorkaroundsImpl(GpuFeatureInfoType::kCurrent);
537}
538
Austin Sullivanbf2dfe32021-05-07 22:19:58539base::Value GetFeatureStatusForHardwareGpu() {
Zhenyao Mo68ef56d2018-04-21 01:05:10540 return GetFeatureStatusImpl(GpuFeatureInfoType::kForHardwareGpu);
541}
542
Austin Sullivanbf2dfe32021-05-07 22:19:58543base::Value GetProblemsForHardwareGpu() {
Zhenyao Mo68ef56d2018-04-21 01:05:10544 return GetProblemsImpl(GpuFeatureInfoType::kForHardwareGpu);
545}
546
547std::vector<std::string> GetDriverBugWorkaroundsForHardwareGpu() {
548 return GetDriverBugWorkaroundsImpl(GpuFeatureInfoType::kForHardwareGpu);
[email protected]f454eed2013-10-16 05:48:02549}
550
[email protected]cb6430932012-10-31 00:53:36551} // namespace content