/chromium/content/browser/gpu/compositor_util.cc
C++ | 414 lines | 346 code | 45 blank | 23 comment | 50 complexity | be759a85ee9f5596de96b395a643a6e1 MD5 | raw file
- // Copyright (c) 2012 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 "content/browser/gpu/compositor_util.h"
- #include "base/command_line.h"
- #include "base/logging.h"
- #include "build/build_config.h"
- #include "cc/base/switches.h"
- #include "content/browser/gpu/gpu_data_manager_impl.h"
- #include "content/public/common/content_switches.h"
- #include "gpu/config/gpu_feature_type.h"
- namespace content {
- namespace {
- struct GpuFeatureInfo {
- std::string name;
- uint32 blocked;
- bool disabled;
- std::string disabled_description;
- bool fallback_to_software;
- };
- #if defined(OS_CHROMEOS)
- const size_t kNumFeatures = 14;
- #else
- const size_t kNumFeatures = 13;
- #endif
- const GpuFeatureInfo GetGpuFeatureInfo(size_t index) {
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
- const GpuFeatureInfo kGpuFeatureInfo[] = {
- {
- "2d_canvas",
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS),
- command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) ||
- !GpuDataManagerImpl::GetInstance()->
- GetGPUInfo().SupportsAccelerated2dCanvas(),
- "Accelerated 2D canvas is unavailable: either disabled at the command"
- " line or not supported by the current system.",
- true
- },
- {
- "compositing",
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING),
- command_line.HasSwitch(switches::kDisableAcceleratedCompositing),
- "Accelerated compositing has been disabled, either via about:flags or"
- " command line. This adversely affects performance of all hardware"
- " accelerated features.",
- true
- },
- {
- "3d_css",
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
- manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS),
- command_line.HasSwitch(switches::kDisableAcceleratedLayers),
- "Accelerated layers have been disabled at the command line.",
- false
- },
- {
- "css_animation",
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
- manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS),
- command_line.HasSwitch(cc::switches::kDisableThreadedAnimation) ||
- command_line.HasSwitch(switches::kDisableAcceleratedCompositing) ||
- command_line.HasSwitch(switches::kDisableAcceleratedLayers),
- "Accelerated CSS animation has been disabled at the command line.",
- true
- },
- {
- "webgl",
- manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL),
- command_line.HasSwitch(switches::kDisableExperimentalWebGL),
- "WebGL has been disabled, either via about:flags or command line.",
- false
- },
- {
- "multisampling",
- manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_MULTISAMPLING),
- command_line.HasSwitch(switches::kDisableGLMultisampling),
- "Multisampling has been disabled, either via about:flags or command"
- " line.",
- false
- },
- {
- "flash_3d",
- manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D),
- command_line.HasSwitch(switches::kDisableFlash3d),
- "Using 3d in flash has been disabled, either via about:flags or"
- " command line.",
- false
- },
- {
- "flash_stage3d",
- manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
- command_line.HasSwitch(switches::kDisableFlashStage3d),
- "Using Stage3d in Flash has been disabled, either via about:flags or"
- " command line.",
- false
- },
- {
- "flash_stage3d_baseline",
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE) ||
- manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
- command_line.HasSwitch(switches::kDisableFlashStage3d),
- "Using Stage3d Baseline profile in Flash has been disabled, either"
- " via about:flags or command line.",
- false
- },
- {
- "texture_sharing",
- manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_TEXTURE_SHARING),
- command_line.HasSwitch(switches::kDisableImageTransportSurface),
- "Sharing textures between processes has been disabled, either via"
- " about:flags or command line.",
- false
- },
- {
- "video_decode",
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE),
- command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode),
- "Accelerated video decode has been disabled, either via about:flags"
- " or command line.",
- true
- },
- #if defined(ENABLE_WEBRTC)
- {
- "video_encode",
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE),
- command_line.HasSwitch(switches::kDisableWebRtcHWEncoding),
- "Accelerated video encode has been disabled, either via about:flags"
- " or command line.",
- true
- },
- #endif
- {
- "video",
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO),
- command_line.HasSwitch(switches::kDisableAcceleratedVideo) ||
- command_line.HasSwitch(switches::kDisableAcceleratedCompositing),
- "Accelerated video presentation has been disabled, either via"
- " about:flags or command line.",
- true
- },
- #if defined(OS_CHROMEOS)
- {
- "panel_fitting",
- manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING),
- command_line.HasSwitch(switches::kDisablePanelFitting),
- "Panel fitting has been disabled, either via about:flags or command"
- " line.",
- false
- },
- #endif
- {
- "force_compositing_mode",
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE) &&
- !IsForceCompositingModeEnabled(),
- !IsForceCompositingModeEnabled() &&
- !manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE),
- "Force compositing mode is off, either disabled at the command"
- " line or not supported by the current system.",
- false
- },
- };
- return kGpuFeatureInfo[index];
- }
- bool CanDoAcceleratedCompositing() {
- const GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
- // Don't use force compositing mode if gpu access has been blocked or
- // accelerated compositing is blacklisted.
- if (!manager->GpuAccessAllowed(NULL) ||
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))
- return false;
- // Check for SwiftShader.
- if (manager->ShouldUseSwiftShader())
- return false;
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kDisableAcceleratedCompositing))
- return false;
- return true;
- }
- bool IsForceCompositingModeBlacklisted() {
- return GpuDataManagerImpl::GetInstance()->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
- }
- } // namespace
- bool IsThreadedCompositingEnabled() {
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- // Command line switches take precedence over blacklist.
- if (command_line.HasSwitch(switches::kDisableForceCompositingMode) ||
- command_line.HasSwitch(switches::kDisableThreadedCompositing)) {
- return false;
- } else if (command_line.HasSwitch(switches::kEnableThreadedCompositing)) {
- return true;
- }
- #if defined(USE_AURA)
- // We always want threaded compositing on Aura.
- return true;
- #endif
- if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
- return false;
- #if defined(OS_MACOSX) || defined(OS_WIN)
- // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
- // Mac OSX 10.8+ since M28. The blacklist check above takes care of returning
- // false before this hits on unsupported Win/Mac versions.
- return true;
- #endif
- return false;
- }
- bool IsForceCompositingModeEnabled() {
- // Force compositing mode is a subset of threaded compositing mode.
- if (IsThreadedCompositingEnabled())
- return true;
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- // Command line switches take precedence over blacklisting.
- if (command_line.HasSwitch(switches::kDisableForceCompositingMode))
- return false;
- else if (command_line.HasSwitch(switches::kForceCompositingMode))
- return true;
- if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
- return false;
- #if defined(OS_MACOSX) || defined(OS_WIN)
- // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
- // Mac OSX 10.8+ since M28. The blacklist check above takes care of returning
- // false before this hits on unsupported Win/Mac versions.
- return true;
- #endif
- return false;
- }
- bool IsDelegatedRendererEnabled() {
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- bool enabled = false;
- #if defined(USE_AURA)
- // Enable on Aura.
- enabled = true;
- #endif
- // Flags override.
- enabled |= command_line.HasSwitch(switches::kEnableDelegatedRenderer);
- enabled &= !command_line.HasSwitch(switches::kDisableDelegatedRenderer);
- // Needs compositing, and thread.
- if (enabled &&
- (!IsForceCompositingModeEnabled() || !IsThreadedCompositingEnabled())) {
- enabled = false;
- LOG(ERROR) << "Disabling delegated-rendering because it needs "
- << "force-compositing-mode and threaded-compositing.";
- }
- return enabled;
- }
- bool IsDeadlineSchedulingEnabled() {
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- // Default to enabled.
- bool enabled = true;
- // Flags override.
- enabled |= command_line.HasSwitch(switches::kEnableDeadlineScheduling);
- enabled &= !command_line.HasSwitch(switches::kDisableDeadlineScheduling);
- return enabled;
- }
- base::Value* GetFeatureStatus() {
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
- std::string gpu_access_blocked_reason;
- bool gpu_access_blocked =
- !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
- base::DictionaryValue* feature_status_dict = new base::DictionaryValue();
- for (size_t i = 0; i < kNumFeatures; ++i) {
- const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i);
- // force_compositing_mode status is part of the compositing status.
- if (gpu_feature_info.name == "force_compositing_mode")
- continue;
- std::string status;
- if (gpu_feature_info.disabled) {
- status = "disabled";
- if (gpu_feature_info.name == "css_animation") {
- status += "_software_animated";
- } else if (gpu_feature_info.name == "raster") {
- if (cc::switches::IsImplSidePaintingEnabled())
- status += "_software_multithreaded";
- else
- status += "_software";
- } else {
- if (gpu_feature_info.fallback_to_software)
- status += "_software";
- else
- status += "_off";
- }
- } else if (manager->ShouldUseSwiftShader()) {
- status = "unavailable_software";
- } else if (gpu_feature_info.blocked ||
- gpu_access_blocked) {
- status = "unavailable";
- if (gpu_feature_info.fallback_to_software)
- status += "_software";
- else
- status += "_off";
- } else {
- status = "enabled";
- if (gpu_feature_info.name == "webgl" &&
- (command_line.HasSwitch(switches::kDisableAcceleratedCompositing) ||
- manager->IsFeatureBlacklisted(
- gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)))
- status += "_readback";
- bool has_thread = IsThreadedCompositingEnabled();
- if (gpu_feature_info.name == "compositing") {
- bool force_compositing = IsForceCompositingModeEnabled();
- if (force_compositing)
- status += "_force";
- if (has_thread)
- status += "_threaded";
- }
- if (gpu_feature_info.name == "css_animation") {
- if (has_thread)
- status = "accelerated_threaded";
- else
- status = "accelerated";
- }
- }
- // TODO(reveman): Remove this when crbug.com/223286 has been fixed.
- if (gpu_feature_info.name == "raster" &&
- cc::switches::IsImplSidePaintingEnabled()) {
- status = "disabled_software_multithreaded";
- }
- feature_status_dict->SetString(
- gpu_feature_info.name.c_str(), status.c_str());
- }
- return feature_status_dict;
- }
- base::Value* GetProblems() {
- GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
- std::string gpu_access_blocked_reason;
- bool gpu_access_blocked =
- !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
- base::ListValue* problem_list = new base::ListValue();
- manager->GetBlacklistReasons(problem_list);
- if (gpu_access_blocked) {
- base::DictionaryValue* problem = new base::DictionaryValue();
- problem->SetString("description",
- "GPU process was unable to boot: " + gpu_access_blocked_reason);
- problem->Set("crBugs", new base::ListValue());
- problem->Set("webkitBugs", new base::ListValue());
- problem_list->Insert(0, problem);
- }
- for (size_t i = 0; i < kNumFeatures; ++i) {
- const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i);
- if (gpu_feature_info.disabled) {
- base::DictionaryValue* problem = new base::DictionaryValue();
- problem->SetString(
- "description", gpu_feature_info.disabled_description);
- problem->Set("crBugs", new base::ListValue());
- problem->Set("webkitBugs", new base::ListValue());
- problem_list->Append(problem);
- }
- }
- return problem_list;
- }
- base::Value* GetDriverBugWorkarounds() {
- base::ListValue* workaround_list = new base::ListValue();
- GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list);
- return workaround_list;
- }
- } // namespace content