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 "base/metrics/field_trial.h"
     10 #include "build/build_config.h"
     11 #include "cc/base/switches.h"
     12 #include "content/browser/gpu/gpu_data_manager_impl.h"
     13 #include "content/public/common/content_switches.h"
     14 #include "gpu/config/gpu_feature_type.h"
     15 
     16 namespace content {
     17 
     18 namespace {
     19 
     20 static bool IsGpuRasterizationBlacklisted() {
     21   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
     22   bool field_trial_enabled =
     23       (base::FieldTrialList::FindFullName(
     24            "GpuRasterizationExpandedDeviceWhitelist") == "Enabled");
     25 
     26   if (field_trial_enabled) {
     27     return manager->IsFeatureBlacklisted(
     28                gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION) &&
     29            manager->IsFeatureBlacklisted(
     30                gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION_FIELD_TRIAL);
     31   }
     32 
     33   return manager->IsFeatureBlacklisted(
     34         gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION);
     35 }
     36 
     37 const char* kGpuCompositingFeatureName = "gpu_compositing";
     38 const char* kWebGLFeatureName = "webgl";
     39 const char* kRasterizationFeatureName = "rasterization";
     40 const char* kThreadedRasterizationFeatureName = "threaded_rasterization";
     41 
     42 struct GpuFeatureInfo {
     43   std::string name;
     44   bool blocked;
     45   bool disabled;
     46   std::string disabled_description;
     47   bool fallback_to_software;
     48 };
     49 
     50 const GpuFeatureInfo GetGpuFeatureInfo(size_t index, bool* eof) {
     51   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
     52   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
     53 
     54   const GpuFeatureInfo kGpuFeatureInfo[] = {
     55       {
     56           "2d_canvas",
     57           manager->IsFeatureBlacklisted(
     58               gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS),
     59           command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) ||
     60           !GpuDataManagerImpl::GetInstance()->
     61               GetGPUInfo().SupportsAccelerated2dCanvas(),
     62           "Accelerated 2D canvas is unavailable: either disabled at the command"
     63           " line or not supported by the current system.",
     64           true
     65       },
     66       {
     67           kGpuCompositingFeatureName,
     68           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING),
     69           false,
     70           "Gpu compositing has been disabled, either via about:flags or"
     71           " command line. The browser will fall back to software compositing"
     72           " and hardware acceleration will be unavailable.",
     73           true
     74       },
     75       {
     76           kWebGLFeatureName,
     77           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL),
     78           command_line.HasSwitch(switches::kDisableExperimentalWebGL),
     79           "WebGL has been disabled, either via about:flags or command line.",
     80           false
     81       },
     82       {
     83           "flash_3d",
     84           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D),
     85           command_line.HasSwitch(switches::kDisableFlash3d),
     86           "Using 3d in flash has been disabled, either via about:flags or"
     87           " command line.",
     88           true
     89       },
     90       {
     91           "flash_stage3d",
     92           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
     93           command_line.HasSwitch(switches::kDisableFlashStage3d),
     94           "Using Stage3d in Flash has been disabled, either via about:flags or"
     95           " command line.",
     96           true
     97       },
     98       {
     99           "flash_stage3d_baseline",
    100           manager->IsFeatureBlacklisted(
    101               gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE) ||
    102           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
    103           command_line.HasSwitch(switches::kDisableFlashStage3d),
    104           "Using Stage3d Baseline profile in Flash has been disabled, either"
    105           " via about:flags or command line.",
    106           true
    107       },
    108       {
    109           "video_decode",
    110           manager->IsFeatureBlacklisted(
    111               gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE),
    112           command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode),
    113           "Accelerated video decode has been disabled, either via about:flags"
    114           " or command line.",
    115           true
    116       },
    117 #if defined(ENABLE_WEBRTC)
    118       {
    119           "video_encode",
    120           manager->IsFeatureBlacklisted(
    121               gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE),
    122           command_line.HasSwitch(switches::kDisableWebRtcHWEncoding),
    123           "Accelerated video encode has been disabled, either via about:flags"
    124           " or command line.",
    125           true
    126       },
    127 #endif
    128 #if defined(OS_CHROMEOS)
    129       {
    130           "panel_fitting",
    131           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING),
    132           command_line.HasSwitch(switches::kDisablePanelFitting),
    133           "Panel fitting has been disabled, either via about:flags or command"
    134           " line.",
    135           false
    136       },
    137 #endif
    138       {
    139           kRasterizationFeatureName,
    140           IsGpuRasterizationBlacklisted() &&
    141           !IsGpuRasterizationEnabled() && !IsForceGpuRasterizationEnabled(),
    142           !IsGpuRasterizationEnabled() && !IsForceGpuRasterizationEnabled() &&
    143           !IsGpuRasterizationBlacklisted(),
    144           "Accelerated rasterization has been disabled, either via about:flags"
    145           " or command line.",
    146           true
    147       },
    148       {
    149           kThreadedRasterizationFeatureName,
    150           false,
    151           !IsImplSidePaintingEnabled(),
    152           "Threaded rasterization has not been enabled or"
    153           " is not supported by the current system.",
    154           false
    155       }
    156 
    157   };
    158   DCHECK(index < arraysize(kGpuFeatureInfo));
    159   *eof = (index == arraysize(kGpuFeatureInfo) - 1);
    160   return kGpuFeatureInfo[index];
    161 }
    162 
    163 }  // namespace
    164 
    165 bool IsPinchVirtualViewportEnabled() {
    166   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    167 
    168   // Command line switches take precedence over platform default.
    169   if (command_line.HasSwitch(cc::switches::kDisablePinchVirtualViewport))
    170     return false;
    171   if (command_line.HasSwitch(cc::switches::kEnablePinchVirtualViewport))
    172     return true;
    173 
    174 #if defined(OS_CHROMEOS)
    175   return true;
    176 #else
    177   return false;
    178 #endif
    179 }
    180 
    181 bool IsThreadedCompositingEnabled() {
    182   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    183 
    184   // Command line switches take precedence over blacklist.
    185   if (command_line.HasSwitch(switches::kDisableThreadedCompositing))
    186     return false;
    187   if (command_line.HasSwitch(switches::kEnableThreadedCompositing))
    188     return true;
    189 
    190 #if defined(USE_AURA) || defined(OS_MACOSX)
    191   // We always want threaded compositing on Aura and Mac (the fallback is a
    192   // threaded software compositor).
    193   return true;
    194 #else
    195   return false;
    196 #endif
    197 }
    198 
    199 bool IsDelegatedRendererEnabled() {
    200   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    201   bool enabled = false;
    202 
    203 #if defined(USE_AURA)
    204   // Enable on Aura.
    205   enabled = true;
    206 #endif
    207 
    208   // Flags override.
    209   enabled |= command_line.HasSwitch(switches::kEnableDelegatedRenderer);
    210   enabled &= !command_line.HasSwitch(switches::kDisableDelegatedRenderer);
    211 
    212   // Needs compositing, and thread.
    213   if (enabled && !IsThreadedCompositingEnabled()) {
    214     enabled = false;
    215     LOG(ERROR) << "Disabling delegated-rendering because it needs "
    216                << "force-compositing-mode and threaded-compositing.";
    217   }
    218 
    219   return enabled;
    220 }
    221 
    222 bool IsImplSidePaintingEnabled() {
    223   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    224 
    225   if (command_line.HasSwitch(switches::kDisableImplSidePainting))
    226     return false;
    227   else if (command_line.HasSwitch(switches::kEnableImplSidePainting))
    228     return true;
    229   else if (command_line.HasSwitch(
    230       switches::kEnableBleedingEdgeRenderingFastPaths))
    231     return true;
    232 
    233 #if defined(OS_MACOSX) || defined(OS_WIN)
    234   return false;
    235 #else
    236   return IsThreadedCompositingEnabled();
    237 #endif
    238 }
    239 
    240 bool IsGpuRasterizationEnabled() {
    241   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    242 
    243   if (!IsImplSidePaintingEnabled())
    244     return false;
    245 
    246   if (command_line.HasSwitch(switches::kDisableGpuRasterization))
    247     return false;
    248   else if (command_line.HasSwitch(switches::kEnableGpuRasterization))
    249     return true;
    250 
    251   if (IsGpuRasterizationBlacklisted()) {
    252     return false;
    253   }
    254 
    255   return true;
    256 }
    257 
    258 bool IsForceGpuRasterizationEnabled() {
    259   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    260 
    261   if (!IsImplSidePaintingEnabled())
    262     return false;
    263 
    264   return command_line.HasSwitch(switches::kForceGpuRasterization);
    265 }
    266 
    267 base::Value* GetFeatureStatus() {
    268   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
    269   std::string gpu_access_blocked_reason;
    270   bool gpu_access_blocked =
    271       !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
    272 
    273   base::DictionaryValue* feature_status_dict = new base::DictionaryValue();
    274 
    275   bool eof = false;
    276   for (size_t i = 0; !eof; ++i) {
    277     const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i, &eof);
    278     std::string status;
    279     if (gpu_feature_info.disabled) {
    280       status = "disabled";
    281       if (gpu_feature_info.fallback_to_software)
    282         status += "_software";
    283       else
    284         status += "_off";
    285       if (gpu_feature_info.name == kThreadedRasterizationFeatureName)
    286         status += "_ok";
    287     } else if (gpu_feature_info.blocked ||
    288                gpu_access_blocked) {
    289       status = "unavailable";
    290       if (gpu_feature_info.fallback_to_software) {
    291         status += "_software";
    292       } else
    293         status += "_off";
    294     } else {
    295       status = "enabled";
    296       if (gpu_feature_info.name == kWebGLFeatureName &&
    297           manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING))
    298         status += "_readback";
    299       if (gpu_feature_info.name == kRasterizationFeatureName) {
    300         if (IsForceGpuRasterizationEnabled())
    301           status += "_force";
    302       }
    303       if (gpu_feature_info.name == kThreadedRasterizationFeatureName)
    304         status += "_on";
    305     }
    306     if (gpu_feature_info.name == kGpuCompositingFeatureName) {
    307       if (IsThreadedCompositingEnabled())
    308         status += "_threaded";
    309     }
    310     if (gpu_feature_info.name == kWebGLFeatureName &&
    311         (gpu_feature_info.blocked || gpu_access_blocked) &&
    312         manager->ShouldUseSwiftShader()) {
    313       status = "unavailable_software";
    314     }
    315 
    316     feature_status_dict->SetString(
    317         gpu_feature_info.name.c_str(), status.c_str());
    318   }
    319   return feature_status_dict;
    320 }
    321 
    322 base::Value* GetProblems() {
    323   GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
    324   std::string gpu_access_blocked_reason;
    325   bool gpu_access_blocked =
    326       !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
    327 
    328   base::ListValue* problem_list = new base::ListValue();
    329   manager->GetBlacklistReasons(problem_list);
    330 
    331   if (gpu_access_blocked) {
    332     base::DictionaryValue* problem = new base::DictionaryValue();
    333     problem->SetString("description",
    334         "GPU process was unable to boot: " + gpu_access_blocked_reason);
    335     problem->Set("crBugs", new base::ListValue());
    336     problem->Set("webkitBugs", new base::ListValue());
    337     base::ListValue* disabled_features = new base::ListValue();
    338     disabled_features->AppendString("all");
    339     problem->Set("affectedGpuSettings", disabled_features);
    340     problem->SetString("tag", "disabledFeatures");
    341     problem_list->Insert(0, problem);
    342   }
    343 
    344   bool eof = false;
    345   for (size_t i = 0; !eof; ++i) {
    346     const GpuFeatureInfo gpu_feature_info = GetGpuFeatureInfo(i, &eof);
    347     if (gpu_feature_info.disabled) {
    348       base::DictionaryValue* problem = new base::DictionaryValue();
    349       problem->SetString(
    350           "description", gpu_feature_info.disabled_description);
    351       problem->Set("crBugs", new base::ListValue());
    352       problem->Set("webkitBugs", new base::ListValue());
    353       base::ListValue* disabled_features = new base::ListValue();
    354       disabled_features->AppendString(gpu_feature_info.name);
    355       problem->Set("affectedGpuSettings", disabled_features);
    356       problem->SetString("tag", "disabledFeatures");
    357       problem_list->Append(problem);
    358     }
    359   }
    360   return problem_list;
    361 }
    362 
    363 base::Value* GetDriverBugWorkarounds() {
    364   base::ListValue* workaround_list = new base::ListValue();
    365   GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list);
    366   return workaround_list;
    367 }
    368 
    369 }  // namespace content
    370