Home | History | Annotate | Download | only in gpu
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/gpu/compositor_util.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/logging.h"
      9 #include "build/build_config.h"
     10 #include "cc/base/switches.h"
     11 #include "content/browser/gpu/gpu_data_manager_impl.h"
     12 #include "content/public/common/content_switches.h"
     13 #include "gpu/config/gpu_feature_type.h"
     14 
     15 namespace content {
     16 
     17 namespace {
     18 
     19 struct GpuFeatureInfo {
     20   std::string name;
     21   uint32 blocked;
     22   bool disabled;
     23   std::string disabled_description;
     24   bool fallback_to_software;
     25 };
     26 
     27 #if defined(OS_CHROMEOS)
     28 const size_t kNumFeatures = 14;
     29 #else
     30 const size_t kNumFeatures = 13;
     31 #endif
     32 const GpuFeatureInfo GetGpuFeatureInfo(size_t index) {
     33   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
     34   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
     35 
     36   const GpuFeatureInfo kGpuFeatureInfo[] = {
     37       {
     38           "2d_canvas",
     39           manager->IsFeatureBlacklisted(
     40               gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS),
     41           command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) ||
     42           !GpuDataManagerImpl::GetInstance()->
     43               GetGPUInfo().SupportsAccelerated2dCanvas(),
     44           "Accelerated 2D canvas is unavailable: either disabled at the command"
     45           " line or not supported by the current system.",
     46           true
     47       },
     48       {
     49           "compositing",
     50           manager->IsFeatureBlacklisted(
     51               gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING),
     52           command_line.HasSwitch(switches::kDisableAcceleratedCompositing),
     53           "Accelerated compositing has been disabled, either via about:flags or"
     54           " command line. This adversely affects performance of all hardware"
     55           " accelerated features.",
     56           true
     57       },
     58       {
     59           "3d_css",
     60           manager->IsFeatureBlacklisted(
     61               gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
     62           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS),
     63           command_line.HasSwitch(switches::kDisableAcceleratedLayers),
     64           "Accelerated layers have been disabled at the command line.",
     65           false
     66       },
     67       {
     68           "css_animation",
     69           manager->IsFeatureBlacklisted(
     70               gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
     71           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS),
     72           command_line.HasSwitch(cc::switches::kDisableThreadedAnimation) ||
     73           command_line.HasSwitch(switches::kDisableAcceleratedCompositing) ||
     74           command_line.HasSwitch(switches::kDisableAcceleratedLayers),
     75           "Accelerated CSS animation has been disabled at the command line.",
     76           true
     77       },
     78       {
     79           "webgl",
     80           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL),
     81           command_line.HasSwitch(switches::kDisableExperimentalWebGL),
     82           "WebGL has been disabled, either via about:flags or command line.",
     83           false
     84       },
     85       {
     86           "multisampling",
     87           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_MULTISAMPLING),
     88           command_line.HasSwitch(switches::kDisableGLMultisampling),
     89           "Multisampling has been disabled, either via about:flags or command"
     90           " line.",
     91           false
     92       },
     93       {
     94           "flash_3d",
     95           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D),
     96           command_line.HasSwitch(switches::kDisableFlash3d),
     97           "Using 3d in flash has been disabled, either via about:flags or"
     98           " command line.",
     99           false
    100       },
    101       {
    102           "flash_stage3d",
    103           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
    104           command_line.HasSwitch(switches::kDisableFlashStage3d),
    105           "Using Stage3d in Flash has been disabled, either via about:flags or"
    106           " command line.",
    107           false
    108       },
    109       {
    110           "flash_stage3d_baseline",
    111           manager->IsFeatureBlacklisted(
    112               gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE) ||
    113           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
    114           command_line.HasSwitch(switches::kDisableFlashStage3d),
    115           "Using Stage3d Baseline profile in Flash has been disabled, either"
    116           " via about:flags or command line.",
    117           false
    118       },
    119       {
    120           "texture_sharing",
    121           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_TEXTURE_SHARING),
    122           command_line.HasSwitch(switches::kDisableImageTransportSurface),
    123           "Sharing textures between processes has been disabled, either via"
    124           " about:flags or command line.",
    125           false
    126       },
    127       {
    128           "video_decode",
    129           manager->IsFeatureBlacklisted(
    130               gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE),
    131           command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode),
    132           "Accelerated video decode has been disabled, either via about:flags"
    133           " or command line.",
    134           true
    135       },
    136 #if defined(ENABLE_WEBRTC)
    137       {
    138           "video_encode",
    139           manager->IsFeatureBlacklisted(
    140               gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE),
    141           command_line.HasSwitch(switches::kDisableWebRtcHWEncoding),
    142           "Accelerated video encode has been disabled, either via about:flags"
    143           " or command line.",
    144           true
    145       },
    146 #endif
    147       {
    148           "video",
    149           manager->IsFeatureBlacklisted(
    150               gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO),
    151           command_line.HasSwitch(switches::kDisableAcceleratedVideo) ||
    152           command_line.HasSwitch(switches::kDisableAcceleratedCompositing),
    153           "Accelerated video presentation has been disabled, either via"
    154           " about:flags or command line.",
    155           true
    156       },
    157 #if defined(OS_CHROMEOS)
    158       {
    159           "panel_fitting",
    160           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING),
    161           command_line.HasSwitch(switches::kDisablePanelFitting),
    162           "Panel fitting has been disabled, either via about:flags or command"
    163           " line.",
    164           false
    165       },
    166 #endif
    167       {
    168           "force_compositing_mode",
    169           manager->IsFeatureBlacklisted(
    170               gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE) &&
    171           !IsForceCompositingModeEnabled(),
    172           !IsForceCompositingModeEnabled() &&
    173           !manager->IsFeatureBlacklisted(
    174               gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE),
    175           "Force compositing mode is off, either disabled at the command"
    176           " line or not supported by the current system.",
    177           false
    178       },
    179   };
    180   return kGpuFeatureInfo[index];
    181 }
    182 
    183 bool CanDoAcceleratedCompositing() {
    184   const GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
    185 
    186   // Don't use force compositing mode if gpu access has been blocked or
    187   // accelerated compositing is blacklisted.
    188   if (!manager->GpuAccessAllowed(NULL) ||
    189       manager->IsFeatureBlacklisted(
    190           gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))
    191     return false;
    192 
    193   // Check for SwiftShader.
    194   if (manager->ShouldUseSwiftShader())
    195     return false;
    196 
    197   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    198   if (command_line.HasSwitch(switches::kDisableAcceleratedCompositing))
    199     return false;
    200 
    201   return true;
    202 }
    203 
    204 bool IsForceCompositingModeBlacklisted() {
    205   return GpuDataManagerImpl::GetInstance()->IsFeatureBlacklisted(
    206       gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE);
    207 }
    208 
    209 }  // namespace
    210 
    211 bool IsThreadedCompositingEnabled() {
    212   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    213 
    214   // Command line switches take precedence over blacklist.
    215   if (command_line.HasSwitch(switches::kDisableForceCompositingMode) ||
    216       command_line.HasSwitch(switches::kDisableThreadedCompositing)) {
    217     return false;
    218   } else if (command_line.HasSwitch(switches::kEnableThreadedCompositing)) {
    219     return true;
    220   }
    221 
    222 #if defined(USE_AURA)
    223   // We always want threaded compositing on Aura.
    224   return true;
    225 #endif
    226 
    227   if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
    228     return false;
    229 
    230 #if defined(OS_MACOSX) || defined(OS_WIN)
    231   // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
    232   // Mac OSX 10.8+ since M28. The blacklist check above takes care of returning
    233   // false before this hits on unsupported Win/Mac versions.
    234   return true;
    235 #endif
    236 
    237   return false;
    238 }
    239 
    240 bool IsForceCompositingModeEnabled() {
    241   // Force compositing mode is a subset of threaded compositing mode.
    242   if (IsThreadedCompositingEnabled())
    243     return true;
    244 
    245   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    246 
    247   // Command line switches take precedence over blacklisting.
    248   if (command_line.HasSwitch(switches::kDisableForceCompositingMode))
    249     return false;
    250   else if (command_line.HasSwitch(switches::kForceCompositingMode))
    251     return true;
    252 
    253   if (!CanDoAcceleratedCompositing() || IsForceCompositingModeBlacklisted())
    254     return false;
    255 
    256 #if defined(OS_MACOSX) || defined(OS_WIN)
    257   // Windows Vista+ has been shipping with TCM enabled at 100% since M24 and
    258   // Mac OSX 10.8+ since M28. The blacklist check above takes care of returning
    259   // false before this hits on unsupported Win/Mac versions.
    260   return true;
    261 #endif
    262 
    263   return false;
    264 }
    265 
    266 bool IsDelegatedRendererEnabled() {
    267   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    268   bool enabled = false;
    269 
    270 #if defined(USE_AURA)
    271   // Enable on Aura.
    272   enabled = true;
    273 #endif
    274 
    275   // Flags override.
    276   enabled |= command_line.HasSwitch(switches::kEnableDelegatedRenderer);
    277   enabled &= !command_line.HasSwitch(switches::kDisableDelegatedRenderer);
    278 
    279   // Needs compositing, and thread.
    280   if (enabled &&
    281       (!IsForceCompositingModeEnabled() || !IsThreadedCompositingEnabled())) {
    282     enabled = false;
    283     LOG(ERROR) << "Disabling delegated-rendering because it needs "
    284                << "force-compositing-mode and threaded-compositing.";
    285   }
    286 
    287   return enabled;
    288 }
    289 
    290 bool IsDeadlineSchedulingEnabled() {
    291   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    292 
    293   // Default to enabled.
    294   bool enabled = true;
    295 
    296   // Flags override.
    297   enabled |= command_line.HasSwitch(switches::kEnableDeadlineScheduling);
    298   enabled &= !command_line.HasSwitch(switches::kDisableDeadlineScheduling);
    299 
    300   return enabled;
    301 }
    302 
    303 base::Value* GetFeatureStatus() {
    304   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    305   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
    306   std::string gpu_access_blocked_reason;
    307   bool gpu_access_blocked =
    308       !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
    309 
    310   base::DictionaryValue* feature_status_dict = new base::DictionaryValue();
    311 
    312   for (size_t i = 0; i < kNumFeatures; ++i) {
    313     const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i);
    314     // force_compositing_mode status is part of the compositing status.
    315     if (gpu_feature_info.name == "force_compositing_mode")
    316       continue;
    317 
    318     std::string status;
    319     if (gpu_feature_info.disabled) {
    320       status = "disabled";
    321       if (gpu_feature_info.name == "css_animation") {
    322         status += "_software_animated";
    323       } else if (gpu_feature_info.name == "raster") {
    324         if (cc::switches::IsImplSidePaintingEnabled())
    325           status += "_software_multithreaded";
    326         else
    327           status += "_software";
    328       } else {
    329         if (gpu_feature_info.fallback_to_software)
    330           status += "_software";
    331         else
    332           status += "_off";
    333       }
    334     } else if (manager->ShouldUseSwiftShader()) {
    335       status = "unavailable_software";
    336     } else if (gpu_feature_info.blocked ||
    337                gpu_access_blocked) {
    338       status = "unavailable";
    339       if (gpu_feature_info.fallback_to_software)
    340         status += "_software";
    341       else
    342         status += "_off";
    343     } else {
    344       status = "enabled";
    345       if (gpu_feature_info.name == "webgl" &&
    346           (command_line.HasSwitch(switches::kDisableAcceleratedCompositing) ||
    347            manager->IsFeatureBlacklisted(
    348                gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)))
    349         status += "_readback";
    350       bool has_thread = IsThreadedCompositingEnabled();
    351       if (gpu_feature_info.name == "compositing") {
    352         bool force_compositing = IsForceCompositingModeEnabled();
    353         if (force_compositing)
    354           status += "_force";
    355         if (has_thread)
    356           status += "_threaded";
    357       }
    358       if (gpu_feature_info.name == "css_animation") {
    359         if (has_thread)
    360           status = "accelerated_threaded";
    361         else
    362           status = "accelerated";
    363       }
    364     }
    365     // TODO(reveman): Remove this when crbug.com/223286 has been fixed.
    366     if (gpu_feature_info.name == "raster" &&
    367         cc::switches::IsImplSidePaintingEnabled()) {
    368       status = "disabled_software_multithreaded";
    369     }
    370     feature_status_dict->SetString(
    371         gpu_feature_info.name.c_str(), status.c_str());
    372   }
    373   return feature_status_dict;
    374 }
    375 
    376 base::Value* GetProblems() {
    377   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
    378   std::string gpu_access_blocked_reason;
    379   bool gpu_access_blocked =
    380       !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
    381 
    382   base::ListValue* problem_list = new base::ListValue();
    383   manager->GetBlacklistReasons(problem_list);
    384 
    385   if (gpu_access_blocked) {
    386     base::DictionaryValue* problem = new base::DictionaryValue();
    387     problem->SetString("description",
    388         "GPU process was unable to boot: " + gpu_access_blocked_reason);
    389     problem->Set("crBugs", new base::ListValue());
    390     problem->Set("webkitBugs", new base::ListValue());
    391     problem_list->Insert(0, problem);
    392   }
    393 
    394   for (size_t i = 0; i < kNumFeatures; ++i) {
    395     const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i);
    396     if (gpu_feature_info.disabled) {
    397       base::DictionaryValue* problem = new base::DictionaryValue();
    398       problem->SetString(
    399           "description", gpu_feature_info.disabled_description);
    400       problem->Set("crBugs", new base::ListValue());
    401       problem->Set("webkitBugs", new base::ListValue());
    402       problem_list->Append(problem);
    403     }
    404   }
    405   return problem_list;
    406 }
    407 
    408 base::Value* GetDriverBugWorkarounds() {
    409   base::ListValue* workaround_list = new base::ListValue();
    410   GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list);
    411   return workaround_list;
    412 }
    413 
    414 }  // namespace content
    415