gpu_data_manager_impl_private.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// found in the LICENSE file.
4a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
5a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/browser/gpu/gpu_data_manager_impl_private.h"
6a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
7a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/bind.h"
8a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/bind_helpers.h"
9a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/command_line.h"
10a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/debug/trace_event.h"
11a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/metrics/field_trial.h"
12a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/metrics/histogram.h"
133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/metrics/sparse_histogram.h"
14a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
16a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/sys_info.h"
17a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/version.h"
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "cc/base/switches.h"
19a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/browser/gpu/gpu_process_host.h"
20a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/common/gpu/gpu_messages.h"
21a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
22a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/public/browser/gpu_data_manager_observer.h"
23a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/public/common/content_client.h"
24a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/public/common/content_constants.h"
25a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/public/common/content_switches.h"
26a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "gpu/command_buffer/service/gpu_switches.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_control_list_jsons.h"
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "gpu/config/gpu_driver_bug_workaround_type.h"
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_feature_type.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_info_collector.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/config/gpu_util.h"
32a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ui/base/ui_base_switches.h"
33a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ui/gl/gl_implementation.h"
34a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ui/gl/gl_switches.h"
35a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ui/gl/gpu_switching_manager.h"
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/common/webpreferences.h"
37a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_MACOSX)
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <ApplicationServices/ApplicationServices.h>
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif  // OS_MACOSX
41a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if defined(OS_WIN)
42a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "base/win/windows_version.h"
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif  // OS_WIN
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_ANDROID)
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/gfx/android/device_display_info.h"
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif  // OS_ANDROID
47a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
48a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)namespace content {
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
50a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)namespace {
51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)enum GpuFeatureStatus {
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    kGpuFeatureEnabled = 0,
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    kGpuFeatureBlacklisted = 1,
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    kGpuFeatureDisabled = 2,  // disabled by user but not blacklisted
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    kGpuFeatureNumStatus
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN)
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)enum WinSubVersion {
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  kWinOthers = 0,
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  kWinXP,
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  kWinVista,
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  kWin7,
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  kWin8,
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  kNumWinSubVersions
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int GetGpuBlacklistHistogramValueWin(GpuFeatureStatus status) {
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static WinSubVersion sub_version = kNumWinSubVersions;
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (sub_version == kNumWinSubVersions) {
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    sub_version = kWinOthers;
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string version_str = base::SysInfo::OperatingSystemVersion();
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    size_t pos = version_str.find_first_not_of("0123456789.");
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (pos != std::string::npos)
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      version_str = version_str.substr(0, pos);
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Version os_version(version_str);
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (os_version.IsValid() && os_version.components().size() >= 2) {
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const std::vector<uint16>& version_numbers = os_version.components();
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (version_numbers[0] == 5)
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        sub_version = kWinXP;
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      else if (version_numbers[0] == 6 && version_numbers[1] == 0)
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        sub_version = kWinVista;
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      else if (version_numbers[0] == 6 && version_numbers[1] == 1)
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        sub_version = kWin7;
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      else if (version_numbers[0] == 6 && version_numbers[1] == 2)
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        sub_version = kWin8;
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int entry_index = static_cast<int>(sub_version) * kGpuFeatureNumStatus;
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (status) {
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case kGpuFeatureEnabled:
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case kGpuFeatureBlacklisted:
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      entry_index++;
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case kGpuFeatureDisabled:
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      entry_index += 2;
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return entry_index;
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif  // OS_WIN
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Send UMA histograms about the enabled features and GPU properties.
1073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid UpdateStats(const gpu::GPUInfo& gpu_info,
1083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                 const gpu::GpuBlacklist* blacklist,
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 const std::set<int>& blacklisted_features) {
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  uint32 max_entry_id = blacklist->max_entry_id();
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (max_entry_id == 0) {
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // GPU Blacklist was not loaded.  No need to go further.
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool disabled = false;
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Use entry 0 to capture the total number of times that data
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // was recorded in this histogram in order to have a convenient
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // denominator to compute blacklist percentages for the rest of the
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // entries.
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      0, max_entry_id + 1);
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (blacklisted_features.size() != 0) {
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::vector<uint32> flag_entries;
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    blacklist->GetDecisionEntries(&flag_entries, disabled);
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK_GT(flag_entries.size(), 0u);
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (size_t i = 0; i < flag_entries.size(); ++i) {
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          flag_entries[i], max_entry_id + 1);
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // This counts how many users are affected by a disabled entry - this allows
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // us to understand the impact of an entry before enable it.
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<uint32> flag_disabled_entries;
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  disabled = true;
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  blacklist->GetDecisionEntries(&flag_disabled_entries, disabled);
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < flag_disabled_entries.size(); ++i) {
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerDisabledEntry",
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        flag_disabled_entries[i], max_entry_id + 1);
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const gpu::GpuFeatureType kGpuFeatures[] = {
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING, gpu::GPU_FEATURE_TYPE_WEBGL};
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const std::string kGpuBlacklistFeatureHistogramNames[] = {
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "GPU.BlacklistFeatureTestResults.Accelerated2dCanvas",
1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      "GPU.BlacklistFeatureTestResults.GpuCompositing",
1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      "GPU.BlacklistFeatureTestResults.Webgl", };
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const bool kGpuFeatureUserFlags[] = {
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      command_line.HasSwitch(switches::kDisableAccelerated2dCanvas),
1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      command_line.HasSwitch(switches::kDisableGpu),
1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      command_line.HasSwitch(switches::kDisableExperimentalWebGL), };
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN)
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const std::string kGpuBlacklistFeatureHistogramNamesWin[] = {
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "GPU.BlacklistFeatureTestResultsWindows.Accelerated2dCanvas",
1600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      "GPU.BlacklistFeatureTestResultsWindows.GpuCompositing",
1610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      "GPU.BlacklistFeatureTestResultsWindows.Webgl", };
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const size_t kNumFeatures =
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      sizeof(kGpuFeatures) / sizeof(gpu::GpuFeatureType);
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < kNumFeatures; ++i) {
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // We can't use UMA_HISTOGRAM_ENUMERATION here because the same name is
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // expected if the macro is used within a loop.
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GpuFeatureStatus value = kGpuFeatureEnabled;
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (blacklisted_features.count(kGpuFeatures[i]))
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      value = kGpuFeatureBlacklisted;
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    else if (kGpuFeatureUserFlags[i])
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      value = kGpuFeatureDisabled;
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::HistogramBase* histogram_pointer = base::LinearHistogram::FactoryGet(
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        kGpuBlacklistFeatureHistogramNames[i],
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        1, kGpuFeatureNumStatus, kGpuFeatureNumStatus + 1,
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::HistogramBase::kUmaTargetedHistogramFlag);
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    histogram_pointer->Add(value);
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN)
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    histogram_pointer = base::LinearHistogram::FactoryGet(
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        kGpuBlacklistFeatureHistogramNamesWin[i],
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        1, kNumWinSubVersions * kGpuFeatureNumStatus,
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        kNumWinSubVersions * kGpuFeatureNumStatus + 1,
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::HistogramBase::kUmaTargetedHistogramFlag);
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    histogram_pointer->Add(GetGpuBlacklistHistogramValueWin(value));
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
1873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  UMA_HISTOGRAM_SPARSE_SLOWLY("GPU.GLResetNotificationStrategy",
1893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      gpu_info.gl_reset_notification_strategy);
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
192a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Combine the integers into a string, seperated by ','.
193a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)std::string IntSetToString(const std::set<int>& list) {
194a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string rt;
195a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  for (std::set<int>::const_iterator it = list.begin();
196a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       it != list.end(); ++it) {
197a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (!rt.empty())
198a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      rt += ",";
199a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    rt += base::IntToString(*it);
200a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
201a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return rt;
202a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
203a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
204a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if defined(OS_MACOSX)
205a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void DisplayReconfigCallback(CGDirectDisplayID display,
206a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                             CGDisplayChangeSummaryFlags flags,
207a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                             void* gpu_data_manager) {
208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (flags == kCGDisplayBeginConfigurationFlag)
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return; // This call contains no information about the display change
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GpuDataManagerImpl* manager =
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      reinterpret_cast<GpuDataManagerImpl*>(gpu_data_manager);
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(manager);
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Display change.
2160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool display_changed = false;
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint32_t displayCount;
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CGGetActiveDisplayList(0, NULL, &displayCount);
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (displayCount != manager->GetDisplayCount()) {
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    manager->SetDisplayCount(displayCount);
2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    display_changed = true;
2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Gpu change.
2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool gpu_changed = false;
2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (flags & kCGDisplayAddFlag) {
2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    uint32 vendor_id, device_id;
2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (gpu::CollectGpuID(&vendor_id, &device_id) == gpu::kGpuIDSuccess) {
2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      gpu_changed = manager->UpdateActiveGpu(vendor_id, device_id);
2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
231a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (display_changed || gpu_changed)
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    manager->HandleGpuSwitch();
235a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#endif  // OS_MACOSX
237a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_ANDROID)
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ApplyAndroidWorkarounds(const gpu::GPUInfo& gpu_info,
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                             CommandLine* command_line) {
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string vendor(StringToLowerASCII(gpu_info.gl_vendor));
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string renderer(StringToLowerASCII(gpu_info.gl_renderer));
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool is_img =
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gpu_info.gl_vendor.find("Imagination") != std::string::npos;
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gfx::DeviceDisplayInfo info;
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int default_tile_size = 256;
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(epenner): Now that this is somewhat generic, maybe we can
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // unify this for all platforms (http://crbug.com/159524)
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool real_size_supported = true;
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int display_width = info.GetPhysicalDisplayWidth();
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int display_height = info.GetPhysicalDisplayHeight();
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (display_width == 0 || display_height == 0) {
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    real_size_supported = false;
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    display_width = info.GetDisplayWidth();
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    display_height = info.GetDisplayHeight();
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int portrait_width = std::min(display_width, display_height);
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int landscape_width = std::max(display_width, display_height);
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (real_size_supported) {
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Maximum HD dimensions should be 768x1280
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Maximum FHD dimensions should be 1200x1920
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (portrait_width > 768 || landscape_width > 1280)
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       default_tile_size = 384;
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (portrait_width > 1200 || landscape_width > 1920)
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       default_tile_size = 512;
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Adjust for some resolutions that barely straddle an extra
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // tile when in portrait mode. This helps worst case scroll/raster
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // by not needing a full extra tile for each row.
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (default_tile_size == 256 && portrait_width == 768)
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      default_tile_size += 32;
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (default_tile_size == 384 && portrait_width == 1200)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      default_tile_size += 32;
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // We don't know the exact resolution due to screen controls etc.
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // So this just estimates the values above using tile counts.
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int numTiles = (display_width * display_height) / (256 * 256);
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (numTiles > 16)
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      default_tile_size = 384;
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (numTiles >= 40)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      default_tile_size = 512;
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // IMG: Fast async texture uploads only work with non-power-of-two,
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // but still multiple-of-eight sizes.
29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // http://crbug.com/168099
29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (is_img)
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    default_tile_size -= 8;
29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set the command line if it isn't already set and we changed
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // the default tile size.
29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (default_tile_size != 256 &&
29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      !command_line->HasSwitch(switches::kDefaultTileWidth) &&
29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      !command_line->HasSwitch(switches::kDefaultTileHeight)) {
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::stringstream size;
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    size << default_tile_size;
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    command_line->AppendSwitchASCII(
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        switches::kDefaultTileWidth, size.str());
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    command_line->AppendSwitchASCII(
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        switches::kDefaultTileHeight, size.str());
30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif  // OS_ANDROID
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
310a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Block all domains' use of 3D APIs for this many milliseconds if
311a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// approaching a threshold where system stability might be compromised.
312a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const int64 kBlockAllDomainsMs = 10000;
313a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const int kNumResetsWithinDuration = 1;
314a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
315a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Enums for UMA histograms.
316a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)enum BlockStatusHistogram {
317a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  BLOCK_STATUS_NOT_BLOCKED,
318a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED,
319a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
320a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  BLOCK_STATUS_MAX
321a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)};
322a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
323a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}  // namespace anonymous
324a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
325a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::InitializeForTesting(
326a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const std::string& gpu_blacklist_json,
32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const gpu::GPUInfo& gpu_info) {
328a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // This function is for testing only, so disable histograms.
329a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  update_histograms_ = false;
330a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Prevent all further initialization.
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  finalized_ = true;
3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InitializeImpl(gpu_blacklist_json, std::string(), gpu_info);
335a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
336a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
337a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool GpuDataManagerImplPrivate::IsFeatureBlacklisted(int feature) const {
3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_CHROMEOS)
3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (feature == gpu::GPU_FEATURE_TYPE_PANEL_FITTING &&
3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      CommandLine::ForCurrentProcess()->HasSwitch(
3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          switches::kDisablePanelFitting)) {
3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return true;
3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif  // OS_CHROMEOS
345a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (use_swiftshader_) {
346a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Skia's software rendering is probably more efficient than going through
347a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // software emulation of the GPU, so use that.
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (feature == gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)
349a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return true;
350a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return false;
351a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
352a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
353a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return (blacklisted_features_.count(feature) == 1);
354a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
355a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool GpuDataManagerImplPrivate::IsDriverBugWorkaroundActive(int feature) const {
357424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return (gpu_driver_bugs_.count(feature) == 1);
358424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
359424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
360a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)size_t GpuDataManagerImplPrivate::GetBlacklistedFeatureCount() const {
361a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (use_swiftshader_)
362a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return 1;
363a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return blacklisted_features_.size();
364a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
365a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GpuDataManagerImplPrivate::SetDisplayCount(unsigned int display_count) {
367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  display_count_ = display_count;
368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)unsigned int GpuDataManagerImplPrivate::GetDisplayCount() const {
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return display_count_;
372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfo() const {
375a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return gpu_info_;
376a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
377a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
378a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::GetGpuProcessHandles(
379a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const GpuDataManager::GetGpuProcessHandlesCallback& callback) const {
380a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GpuProcessHost::GetProcessHandles(callback);
381a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
382a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
383a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool GpuDataManagerImplPrivate::GpuAccessAllowed(
384a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    std::string* reason) const {
385a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (use_swiftshader_)
386a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return true;
387a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!gpu_process_accessible_) {
389a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (reason) {
390a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      *reason = "GPU process launch failed.";
391a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
392a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return false;
393a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
394a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
395a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (card_blacklisted_) {
396a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (reason) {
397a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      *reason = "GPU access is disabled ";
398a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      CommandLine* command_line = CommandLine::ForCurrentProcess();
399a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (command_line->HasSwitch(switches::kDisableGpu))
400a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        *reason += "through commandline switch --disable-gpu.";
401a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      else
402a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        *reason += "in chrome://settings.";
403a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
404a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return false;
405a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
406a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
407a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // We only need to block GPU process if more features are disallowed other
408a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // than those in the preliminary gpu feature flags because the latter work
409a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // through renderer commandline switches.
410a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::set<int> features = preliminary_blacklisted_features_;
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gpu::MergeFeatureSets(&features, blacklisted_features_);
412a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (features.size() > preliminary_blacklisted_features_.size()) {
413a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (reason) {
414a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      *reason = "Features are disabled upon full but not preliminary GPU info.";
415a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
416a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return false;
417a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
418a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (blacklisted_features_.size() == gpu::NUMBER_OF_GPU_FEATURE_TYPES) {
420a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // On Linux, we use cached GL strings to make blacklist decsions at browser
421a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // startup time. We need to launch the GPU process to validate these
422a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // strings even if all features are blacklisted. If all GPU features are
423a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // disabled, the GPU process will only initialize GL bindings, create a GL
424a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // context, and collect full GPU info.
425a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if !defined(OS_LINUX)
426a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (reason) {
427a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      *reason = "All GPU features are blacklisted.";
428a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
429a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return false;
430a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#endif
431a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
432a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
433a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return true;
434a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
435a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
436a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::RequestCompleteGpuInfoIfNeeded() {
437a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (complete_gpu_info_already_requested_ || gpu_info_.finalized)
438a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
439a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  complete_gpu_info_already_requested_ = true;
440a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
441a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GpuProcessHost::SendOnIO(
442a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if defined(OS_WIN)
443a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED,
444a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#else
445a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
446a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#endif
447a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      CAUSE_FOR_GPU_LAUNCH_GPUDATAMANAGER_REQUESTCOMPLETEGPUINFOIFNEEDED,
448a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new GpuMsg_CollectGraphicsInfo());
449a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
450a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
451a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool GpuDataManagerImplPrivate::IsCompleteGpuInfoAvailable() const {
452a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return gpu_info_.finalized;
453a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
454a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
455a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::RequestVideoMemoryUsageStatsUpdate() const {
456a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GpuProcessHost::SendOnIO(
457a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
458a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
459a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new GpuMsg_GetVideoMemoryUsageStats());
460a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
461a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
462a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool GpuDataManagerImplPrivate::ShouldUseSwiftShader() const {
463a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return use_swiftshader_;
464a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
465a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
466a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::RegisterSwiftShaderPath(
467a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const base::FilePath& path) {
468a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  swiftshader_path_ = path;
469a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EnableSwiftShaderIfNecessary();
470a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
471a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
472a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::AddObserver(GpuDataManagerObserver* observer) {
473a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GpuDataManagerImpl::UnlockedSession session(owner_);
474a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  observer_list_->AddObserver(observer);
475a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
476a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
477a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::RemoveObserver(
478a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    GpuDataManagerObserver* observer) {
479a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GpuDataManagerImpl::UnlockedSession session(owner_);
480a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  observer_list_->RemoveObserver(observer);
481a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
482a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
483a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::UnblockDomainFrom3DAPIs(const GURL& url) {
484a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // This method must do two things:
485a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  //
486a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  //  1. If the specific domain is blocked, then unblock it.
487a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  //
488a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  //  2. Reset our notion of how many GPU resets have occurred recently.
489a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  //     This is necessary even if the specific domain was blocked.
490a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  //     Otherwise, if we call Are3DAPIsBlocked with the same domain right
491a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  //     after unblocking it, it will probably still be blocked because of
492a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  //     the recent GPU reset caused by that domain.
493a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  //
494a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // These policies could be refined, but at a certain point the behavior
495a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // will become difficult to explain.
496a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string domain = GetDomainFromURL(url);
497a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
498a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  blocked_domains_.erase(domain);
499a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  timestamps_of_gpu_resets_.clear();
500a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
501a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
502a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::DisableGpuWatchdog() {
503a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GpuProcessHost::SendOnIO(
504a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
505a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
506a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new GpuMsg_DisableWatchdog);
507a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
508a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
509a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::SetGLStrings(const std::string& gl_vendor,
510a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                             const std::string& gl_renderer,
511a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                             const std::string& gl_version) {
512a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (gl_vendor.empty() && gl_renderer.empty() && gl_version.empty())
513a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
514a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
515a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // If GPUInfo already got GL strings, do nothing.  This is for the rare
516a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // situation where GPU process collected GL strings before this call.
517a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!gpu_info_.gl_vendor.empty() ||
518a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      !gpu_info_.gl_renderer.empty() ||
519a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      !gpu_info_.gl_version_string.empty())
520a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
521a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
52290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gpu::GPUInfo gpu_info = gpu_info_;
523a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
524a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  gpu_info.gl_vendor = gl_vendor;
525a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  gpu_info.gl_renderer = gl_renderer;
526a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  gpu_info.gl_version_string = gl_version;
527a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
52890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gpu::CollectDriverInfoGL(&gpu_info);
529a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
530a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  UpdateGpuInfo(gpu_info);
531a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  UpdateGpuSwitchingManager(gpu_info);
532a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  UpdatePreliminaryBlacklistedFeatures();
533a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
534a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
535a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::GetGLStrings(std::string* gl_vendor,
536a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                             std::string* gl_renderer,
537a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                             std::string* gl_version) {
538a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(gl_vendor && gl_renderer && gl_version);
539a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
540a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  *gl_vendor = gpu_info_.gl_vendor;
541a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  *gl_renderer = gpu_info_.gl_renderer;
542a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  *gl_version = gpu_info_.gl_version_string;
543a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
544a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
545a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::Initialize() {
546a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TRACE_EVENT0("startup", "GpuDataManagerImpl::Initialize");
5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (finalized_) {
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DVLOG(0) << "GpuDataManagerImpl marked as finalized; skipping Initialize";
5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (command_line->HasSwitch(switches::kSkipGpuDataLoading))
554a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
555a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
55690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  gpu::GPUInfo gpu_info;
5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (command_line->GetSwitchValueASCII(
5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          switches::kUseGL) == gfx::kGLImplementationOSMesaName) {
5594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // If using the OSMesa GL implementation, use fake vendor and device ids to
5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // make sure it never gets blacklisted. This is better than simply
5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // cancelling GPUInfo gathering as it allows us to proceed with loading the
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // blacklist below which may have non-device specific entries we want to
5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // apply anyways (e.g., OS version blacklisting).
5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    gpu_info.gpu.vendor_id = 0xffff;
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    gpu_info.gpu.device_id = 0xffff;
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Also declare the driver_vendor to be osmesa to be able to specify
5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // exceptions based on driver_vendor==osmesa for some blacklist rules.
5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    gpu_info.driver_vendor = gfx::kGLImplementationOSMesaName;
5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
571a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    TRACE_EVENT0("startup",
572a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "GpuDataManagerImpl::Initialize:CollectBasicGraphicsInfo");
57390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gpu::CollectBasicGraphicsInfo(&gpu_info);
574a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
575a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if defined(ARCH_CPU_X86_FAMILY)
576a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!gpu_info.gpu.vendor_id || !gpu_info.gpu.device_id)
577a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    gpu_info.finalized = true;
578a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#endif
579a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
580a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string gpu_blacklist_string;
581a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string gpu_driver_bug_list_string;
5827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!command_line->HasSwitch(switches::kIgnoreGpuBlacklist) &&
5837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      !command_line->HasSwitch(switches::kUseGpuInTests)) {
58490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gpu_blacklist_string = gpu::kSoftwareRenderingListJson;
585a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
586a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) {
58790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gpu_driver_bug_list_string = gpu::kGpuDriverBugListJson;
588a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
589a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  InitializeImpl(gpu_blacklist_string,
590a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                 gpu_driver_bug_list_string,
591a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                 gpu_info);
592a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
593a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
594e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid GpuDataManagerImplPrivate::UpdateGpuInfoHelper() {
595a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GetContentClient()->SetGpuInfo(gpu_info_);
596a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
597a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (gpu_blacklist_) {
598a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    std::set<int> features = gpu_blacklist_->MakeDecision(
59990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        gpu::GpuControlList::kOsAny, std::string(), gpu_info_);
600a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (update_histograms_)
6013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      UpdateStats(gpu_info_, gpu_blacklist_.get(), features);
602a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
603a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    UpdateBlacklistedFeatures(features);
604a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
605e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (gpu_driver_bug_list_) {
606a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    gpu_driver_bugs_ = gpu_driver_bug_list_->MakeDecision(
60790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        gpu::GpuControlList::kOsAny, std::string(), gpu_info_);
60890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
609e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  gpu::GpuDriverBugList::AppendWorkaroundsFromCommandLine(
610e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      &gpu_driver_bugs_, *CommandLine::ForCurrentProcess());
611a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
612a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // We have to update GpuFeatureType before notify all the observers.
613a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  NotifyGpuInfoUpdate();
614a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
615a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
616e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid GpuDataManagerImplPrivate::UpdateGpuInfo(const gpu::GPUInfo& gpu_info) {
617e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // No further update of gpu_info if falling back to SwiftShader.
618e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (use_swiftshader_)
619e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return;
620e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
621e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  gpu::MergeGPUInfo(&gpu_info_, gpu_info);
622e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  complete_gpu_info_already_requested_ =
623e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      complete_gpu_info_already_requested_ || gpu_info_.finalized;
624e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
625e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  UpdateGpuInfoHelper();
626e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
627e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
628a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::UpdateVideoMemoryUsageStats(
629a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const GPUVideoMemoryUsageStats& video_memory_usage_stats) {
630a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GpuDataManagerImpl::UnlockedSession session(owner_);
631a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  observer_list_->Notify(&GpuDataManagerObserver::OnVideoMemoryUsageStatsUpdate,
632a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                         video_memory_usage_stats);
633a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
634a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
635a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::AppendRendererCommandLine(
636a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CommandLine* command_line) const {
637a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(command_line);
638a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
63990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
640a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode))
641a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(ENABLE_WEBRTC)
643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE) &&
644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      !command_line->HasSwitch(switches::kDisableWebRtcHWEncoding))
645a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    command_line->AppendSwitch(switches::kDisableWebRtcHWEncoding);
646a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
648a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(USE_AURA)
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!CanUseGpuBrowserCompositor())
650a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    command_line->AppendSwitch(switches::kDisableGpuCompositing);
651a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
652a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
653a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
654a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::AppendGpuCommandLine(
655a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CommandLine* command_line) const {
656a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(command_line);
657a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
658a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string use_gl =
659a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL);
660a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::FilePath swiftshader_path =
661a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      CommandLine::ForCurrentProcess()->GetSwitchValuePath(
662a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          switches::kSwiftShaderPath);
6637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (gpu_driver_bugs_.find(gpu::DISABLE_D3D11) != gpu_driver_bugs_.end())
6647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    command_line->AppendSwitch(switches::kDisableD3D11);
665a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (use_swiftshader_) {
666a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    command_line->AppendSwitchASCII(switches::kUseGL, "swiftshader");
667a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (swiftshader_path.empty())
668a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      swiftshader_path = swiftshader_path_;
66990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } else if ((IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL) ||
6700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING) ||
67190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              IsFeatureBlacklisted(
67290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS)) &&
6730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch             (use_gl == "any")) {
674a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    command_line->AppendSwitchASCII(
675a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        switches::kUseGL, gfx::kGLImplementationOSMesaName);
676a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  } else if (!use_gl.empty()) {
677a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    command_line->AppendSwitchASCII(switches::kUseGL, use_gl);
678a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus())
680a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "true");
681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  else
682a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    command_line->AppendSwitchASCII(switches::kSupportsDualGpus, "false");
683a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
6847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!swiftshader_path.empty()) {
685a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    command_line->AppendSwitchPath(switches::kSwiftShaderPath,
686a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                   swiftshader_path);
6877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
688a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
689a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!gpu_driver_bugs_.empty()) {
690a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    command_line->AppendSwitchASCII(switches::kGpuDriverBugWorkarounds,
691a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                    IntSetToString(gpu_driver_bugs_));
692a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
693a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
6943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
6953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      !command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
6963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    command_line->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
6973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(ENABLE_WEBRTC)
699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE) &&
700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      !command_line->HasSwitch(switches::kDisableWebRtcHWEncoding)) {
701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    command_line->AppendSwitch(switches::kDisableWebRtcHWEncoding);
702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
7043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
705a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Pass GPU and driver information to GPU process. We try to avoid full GPU
706a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // info collection at GPU process startup, but we need gpu vendor_id,
707a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // device_id, driver_vendor, driver_version for deciding whether we need to
708a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // collect full info (on Linux) and for crash reporting purpose.
709a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  command_line->AppendSwitchASCII(switches::kGpuVendorID,
710a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::StringPrintf("0x%04x", gpu_info_.gpu.vendor_id));
711a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  command_line->AppendSwitchASCII(switches::kGpuDeviceID,
712a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::StringPrintf("0x%04x", gpu_info_.gpu.device_id));
713a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  command_line->AppendSwitchASCII(switches::kGpuDriverVendor,
714a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      gpu_info_.driver_vendor);
715a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  command_line->AppendSwitchASCII(switches::kGpuDriverVersion,
716a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      gpu_info_.driver_version);
717a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
718a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
719a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::AppendPluginCommandLine(
720a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CommandLine* command_line) const {
721a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(command_line);
722a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
723a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if defined(OS_MACOSX)
724a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // TODO(jbauman): Add proper blacklist support for core animation plugins so
725a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // special-casing this video card won't be necessary. See
726a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // http://crbug.com/134015
7270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING)) {
728a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (!command_line->HasSwitch(
729a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)           switches::kDisableCoreAnimationPlugins))
730a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      command_line->AppendSwitch(
731a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          switches::kDisableCoreAnimationPlugins);
732a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
733a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#endif
734a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
735a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
736a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::UpdateRendererWebPrefs(
737a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    WebPreferences* prefs) const {
738a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(prefs);
739a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL)) {
741a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    prefs->experimental_webgl_enabled = false;
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    prefs->pepper_3d_enabled = false;
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
74490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D))
745a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    prefs->flash_3d_enabled = false;
74690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D)) {
747a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    prefs->flash_stage3d_enabled = false;
748a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    prefs->flash_stage3d_baseline_enabled = false;
749a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
75090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE))
751a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    prefs->flash_stage3d_baseline_enabled = false;
75290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS))
753a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    prefs->accelerated_2d_canvas_enabled = false;
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (IsDriverBugWorkaroundActive(gpu::DISABLE_MULTISAMPLING) ||
755424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      (IsDriverBugWorkaroundActive(gpu::DISABLE_MULTIMONITOR_MULTISAMPLING) &&
756424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          display_count_ > 1))
757a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    prefs->gl_multisampling_enabled = false;
758a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  prefs->accelerated_compositing_enabled = true;
7600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  prefs->accelerated_compositing_for_3d_transforms_enabled = true;
7610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  prefs->accelerated_compositing_for_animation_enabled = true;
7620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  prefs->accelerated_compositing_for_plugins_enabled = true;
7630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  prefs->accelerated_compositing_for_video_enabled = true;
764a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
765a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(USE_AURA)
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!CanUseGpuBrowserCompositor()) {
767a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    prefs->accelerated_2d_canvas_enabled = false;
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    prefs->pepper_3d_enabled = false;
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
770a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
771a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
772a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) &&
773a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(
774a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          switches::kDisableAcceleratedVideoDecode)) {
775a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    prefs->pepper_accelerated_video_decode_enabled = true;
776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
777a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
778a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
779a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::DisableHardwareAcceleration() {
780a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  card_blacklisted_ = true;
781a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
78290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (int i = 0; i < gpu::NUMBER_OF_GPU_FEATURE_TYPES; ++i)
783a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    blacklisted_features_.insert(i);
784a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
785a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EnableSwiftShaderIfNecessary();
786a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  NotifyGpuInfoUpdate();
787a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
788a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
789a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)std::string GpuDataManagerImplPrivate::GetBlacklistVersion() const {
790a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (gpu_blacklist_)
791a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return gpu_blacklist_->version();
792a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return "0";
793a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
794a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)std::string GpuDataManagerImplPrivate::GetDriverBugListVersion() const {
796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (gpu_driver_bug_list_)
797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return gpu_driver_bug_list_->version();
798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return "0";
799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
801868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GpuDataManagerImplPrivate::GetBlacklistReasons(
802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::ListValue* reasons) const {
803a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (gpu_blacklist_)
804a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gpu_blacklist_->GetReasons(reasons, "disabledFeatures");
805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (gpu_driver_bug_list_)
806a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gpu_driver_bug_list_->GetReasons(reasons, "workarounds");
807868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
808868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
809868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GpuDataManagerImplPrivate::GetDriverBugWorkarounds(
810868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::ListValue* workarounds) const {
811868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (std::set<int>::const_iterator it = gpu_driver_bugs_.begin();
812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       it != gpu_driver_bugs_.end(); ++it) {
813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    workarounds->AppendString(
814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        gpu::GpuDriverBugWorkaroundTypeToString(
815868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            static_cast<gpu::GpuDriverBugWorkaroundType>(*it)));
816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
817a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
818a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
819a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::AddLogMessage(
820a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    int level, const std::string& header, const std::string& message) {
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  log_messages_.push_back(LogMessage(level, header, message));
822a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
823a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
824a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::ProcessCrashed(
825a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    base::TerminationStatus exit_code) {
826a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
827a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Unretained is ok, because it's posted to UI thread, the thread
828a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // where the singleton GpuDataManagerImpl lives until the end.
829a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    BrowserThread::PostTask(
830a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        BrowserThread::UI,
831a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        FROM_HERE,
832a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        base::Bind(&GpuDataManagerImpl::ProcessCrashed,
833a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   base::Unretained(owner_),
834a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   exit_code));
835a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
836a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
837a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  {
838a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    GpuDataManagerImpl::UnlockedSession session(owner_);
839a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    observer_list_->Notify(
840a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        &GpuDataManagerObserver::OnGpuProcessCrashed, exit_code);
841a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
842a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
843a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
844a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)base::ListValue* GpuDataManagerImplPrivate::GetLogMessages() const {
8455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue* value = new base::ListValue;
8465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t ii = 0; ii < log_messages_.size(); ++ii) {
8475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* dict = new base::DictionaryValue();
8485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetInteger("level", log_messages_[ii].level);
8495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetString("header", log_messages_[ii].header);
8505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dict->SetString("message", log_messages_[ii].message);
8515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    value->Append(dict);
8525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
853a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return value;
854a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
855a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
856a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::HandleGpuSwitch() {
8570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  GpuDataManagerImpl::UnlockedSession session(owner_);
8580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  observer_list_->Notify(&GpuDataManagerObserver::OnGpuSwitching);
8590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
8600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
8610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool GpuDataManagerImplPrivate::UpdateActiveGpu(
8620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    uint32 vendor_id, uint32 device_id) {
8630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (gpu_info_.gpu.vendor_id == vendor_id &&
8640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      gpu_info_.gpu.device_id == device_id) {
8650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // The primary GPU is active.
866e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (gpu_info_.gpu.active)
8670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return false;
8680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gpu_info_.gpu.active = true;
8690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (size_t ii = 0; ii < gpu_info_.secondary_gpus.size(); ++ii)
8700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      gpu_info_.secondary_gpus[ii].active = false;
8710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
8720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // A secondary GPU is active.
873e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    for (size_t ii = 0; ii < gpu_info_.secondary_gpus.size(); ++ii) {
8740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (gpu_info_.secondary_gpus[ii].vendor_id == vendor_id &&
8750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          gpu_info_.secondary_gpus[ii].device_id == device_id) {
8760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        if (gpu_info_.secondary_gpus[ii].active)
8770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          return false;
8780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        gpu_info_.secondary_gpus[ii].active = true;
8790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      } else {
8800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        gpu_info_.secondary_gpus[ii].active = false;
8810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
882e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
8830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gpu_info_.gpu.active = false;
884e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
8850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UpdateGpuInfoHelper();
8860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return true;
887a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
888a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
8897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool GpuDataManagerImplPrivate::CanUseGpuBrowserCompositor() const {
8900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (ShouldUseSwiftShader())
8910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return false;
8920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING))
8930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return false;
8940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return true;
8957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
8967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
897a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIs(
898a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const GURL& url, GpuDataManagerImpl::DomainGuilt guilt) {
899a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now());
900a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
901a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
902a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool GpuDataManagerImplPrivate::Are3DAPIsBlocked(const GURL& url,
903a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                                 int render_process_id,
904a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                                 int render_view_id,
905a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                                 ThreeDAPIType requester) {
906a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  bool blocked = Are3DAPIsBlockedAtTime(url, base::Time::Now()) !=
907a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
908a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (blocked) {
909a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Unretained is ok, because it's posted to UI thread, the thread
910a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // where the singleton GpuDataManagerImpl lives until the end.
911a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    BrowserThread::PostTask(
912a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        BrowserThread::UI, FROM_HERE,
913a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        base::Bind(&GpuDataManagerImpl::Notify3DAPIBlocked,
914a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   base::Unretained(owner_), url, render_process_id,
915a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                   render_view_id, requester));
916a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
917a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
918a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return blocked;
919a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
920a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
921a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::DisableDomainBlockingFor3DAPIsForTesting() {
922a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  domain_blocking_enabled_ = false;
923a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
924a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
925a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// static
926a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)GpuDataManagerImplPrivate* GpuDataManagerImplPrivate::Create(
927a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    GpuDataManagerImpl* owner) {
928a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return new GpuDataManagerImplPrivate(owner);
929a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
930a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
931a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(
932a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    GpuDataManagerImpl* owner)
933a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    : complete_gpu_info_already_requested_(false),
934a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      observer_list_(new GpuDataManagerObserverList),
935a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      use_swiftshader_(false),
936a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      card_blacklisted_(false),
937a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      update_histograms_(true),
938a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      window_count_(0),
939a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      domain_blocking_enabled_(true),
940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      owner_(owner),
941eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      display_count_(0),
942a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      gpu_process_accessible_(true),
9434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      finalized_(false) {
944a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DCHECK(owner_);
945a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
946a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (command_line->HasSwitch(switches::kDisableGpu))
947a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    DisableHardwareAcceleration();
948a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
949a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if defined(OS_MACOSX)
950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CGGetActiveDisplayList (0, NULL, &display_count_);
951a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, owner_);
952a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#endif  // OS_MACOSX
9538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
9548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // For testing only.
9558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (command_line->HasSwitch(switches::kDisableDomainBlockingFor3DAPIs)) {
9568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    domain_blocking_enabled_ = false;
9578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
958a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
959a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
960a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {
961a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#if defined(OS_MACOSX)
962a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, owner_);
963a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#endif
964a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
965a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
966a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::InitializeImpl(
967a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const std::string& gpu_blacklist_json,
968a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const std::string& gpu_driver_bug_list_json,
96990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const gpu::GPUInfo& gpu_info) {
9704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const bool log_gpu_control_list_decisions =
9714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      CommandLine::ForCurrentProcess()->HasSwitch(
9724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          switches::kLogGpuControlListDecisions);
9734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
974a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!gpu_blacklist_json.empty()) {
97590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gpu_blacklist_.reset(gpu::GpuBlacklist::Create());
9764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (log_gpu_control_list_decisions)
9774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      gpu_blacklist_->enable_control_list_logging("gpu_blacklist");
9784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool success = gpu_blacklist_->LoadList(
979a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gpu_blacklist_json, gpu::GpuControlList::kCurrentOsOnly);
9804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DCHECK(success);
981a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
982a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!gpu_driver_bug_list_json.empty()) {
98390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    gpu_driver_bug_list_.reset(gpu::GpuDriverBugList::Create());
9844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (log_gpu_control_list_decisions)
9854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      gpu_driver_bug_list_->enable_control_list_logging("gpu_driver_bug_list");
9864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool success = gpu_driver_bug_list_->LoadList(
987a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gpu_driver_bug_list_json, gpu::GpuControlList::kCurrentOsOnly);
9884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DCHECK(success);
989a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
990a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
991a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  gpu_info_ = gpu_info;
992a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  UpdateGpuInfo(gpu_info);
993a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  UpdateGpuSwitchingManager(gpu_info);
994a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  UpdatePreliminaryBlacklistedFeatures();
99590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
99690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_ANDROID)
9975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ApplyAndroidWorkarounds(gpu_info, CommandLine::ForCurrentProcess());
99890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif  // OS_ANDROID
999a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1000a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1001a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::UpdateBlacklistedFeatures(
1002a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const std::set<int>& features) {
1003a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  blacklisted_features_ = features;
1004a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1005a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Force disable using the GPU for these features, even if they would
1006a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // otherwise be allowed.
10070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (card_blacklisted_) {
10080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    blacklisted_features_.insert(gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING);
100990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    blacklisted_features_.insert(gpu::GPU_FEATURE_TYPE_WEBGL);
1010a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1011a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1012a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EnableSwiftShaderIfNecessary();
1013a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1014a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1015a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::UpdatePreliminaryBlacklistedFeatures() {
1016a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  preliminary_blacklisted_features_ = blacklisted_features_;
1017a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1018a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1019a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::UpdateGpuSwitchingManager(
102090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const gpu::GPUInfo& gpu_info) {
1021a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ui::GpuSwitchingManager::GetInstance()->SetGpuCount(
1022a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      gpu_info.secondary_gpus.size() + 1);
1023a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1024a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (ui::GpuSwitchingManager::GetInstance()->SupportsDualGpus()) {
1025f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (gpu_driver_bugs_.count(gpu::FORCE_DISCRETE_GPU) == 1)
1026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ui::GpuSwitchingManager::GetInstance()->ForceUseOfDiscreteGpu();
1027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    else if (gpu_driver_bugs_.count(gpu::FORCE_INTEGRATED_GPU) == 1)
1028f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ui::GpuSwitchingManager::GetInstance()->ForceUseOfIntegratedGpu();
1029a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1030a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1031a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1032a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::NotifyGpuInfoUpdate() {
1033a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  observer_list_->Notify(&GpuDataManagerObserver::OnGpuInfoUpdate);
1034a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1035a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1036a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::EnableSwiftShaderIfNecessary() {
1037a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!GpuAccessAllowed(NULL) ||
103890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      blacklisted_features_.count(gpu::GPU_FEATURE_TYPE_WEBGL)) {
1039a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (!swiftshader_path_.empty() &&
1040a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        !CommandLine::ForCurrentProcess()->HasSwitch(
1041a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)             switches::kDisableSoftwareRasterizer))
1042a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      use_swiftshader_ = true;
1043a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1044a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1045a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1046a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)std::string GpuDataManagerImplPrivate::GetDomainFromURL(
1047a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const GURL& url) const {
1048a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // For the moment, we just use the host, or its IP address, as the
1049a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // entry in the set, rather than trying to figure out the top-level
1050a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // domain. This does mean that a.foo.com and b.foo.com will be
1051a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // treated independently in the blocking of a given domain, but it
1052a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // would require a third-party library to reliably figure out the
1053a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // top-level domain from a URL.
1054a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!url.has_host()) {
1055a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return std::string();
1056a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1057a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1058a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return url.host();
1059a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1060a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1061a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIsAtTime(
1062a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const GURL& url,
1063a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    GpuDataManagerImpl::DomainGuilt guilt,
1064a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    base::Time at_time) {
1065a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!domain_blocking_enabled_)
1066a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
1067a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1068a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string domain = GetDomainFromURL(url);
1069a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1070a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DomainBlockEntry& entry = blocked_domains_[domain];
1071a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  entry.last_guilt = guilt;
1072a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  timestamps_of_gpu_resets_.push_back(at_time);
1073a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1074a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1075a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)GpuDataManagerImpl::DomainBlockStatus
1076a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(
1077a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const GURL& url, base::Time at_time) const {
1078a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!domain_blocking_enabled_)
1079a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
1080a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1081a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Note: adjusting the policies in this code will almost certainly
1082a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // require adjusting the associated unit tests.
1083a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string domain = GetDomainFromURL(url);
1084a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1085a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  DomainBlockMap::const_iterator iter = blocked_domains_.find(domain);
1086a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (iter != blocked_domains_.end()) {
1087a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Err on the side of caution, and assume that if a particular
1088a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // domain shows up in the block map, it's there for a good
1089a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // reason and don't let its presence there automatically expire.
1090a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1091a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1092a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                              BLOCK_STATUS_SPECIFIC_DOMAIN_BLOCKED,
1093a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                              BLOCK_STATUS_MAX);
1094a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1095a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED;
1096a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1097a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1098a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Look at the timestamps of the recent GPU resets to see if there are
1099a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // enough within the threshold which would cause us to blacklist all
1100a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // domains. This doesn't need to be overly precise -- if time goes
1101a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // backward due to a system clock adjustment, that's fine.
1102a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  //
1103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // TODO(kbr): make this pay attention to the TDR thresholds in the
1104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Windows registry, but make sure it continues to be testable.
1105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  {
1106a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    std::list<base::Time>::iterator iter = timestamps_of_gpu_resets_.begin();
1107a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    int num_resets_within_timeframe = 0;
1108a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    while (iter != timestamps_of_gpu_resets_.end()) {
1109a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::Time time = *iter;
1110a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::TimeDelta delta_t = at_time - time;
1111a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1112a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      // If this entry has "expired", just remove it.
1113a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (delta_t.InMilliseconds() > kBlockAllDomainsMs) {
1114a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        iter = timestamps_of_gpu_resets_.erase(iter);
1115a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        continue;
1116a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      }
1117a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1118a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ++num_resets_within_timeframe;
1119a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ++iter;
1120a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1121a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1122a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (num_resets_within_timeframe >= kNumResetsWithinDuration) {
1123a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1124a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
1125a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                BLOCK_STATUS_MAX);
1126a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1127a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED;
1128a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1129a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1130a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1131a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("GPU.BlockStatusForClient3DAPIs",
1132a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                            BLOCK_STATUS_NOT_BLOCKED,
1133a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                            BLOCK_STATUS_MAX);
1134a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1135a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
1136a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1137a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1138a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)int64 GpuDataManagerImplPrivate::GetBlockAllDomainsDurationInMs() const {
1139a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return kBlockAllDomainsMs;
1140a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1142a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void GpuDataManagerImplPrivate::Notify3DAPIBlocked(const GURL& url,
1143a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                                   int render_process_id,
1144a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                                   int render_view_id,
1145a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                                   ThreeDAPIType requester) {
1146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  GpuDataManagerImpl::UnlockedSession session(owner_);
1147a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  observer_list_->Notify(&GpuDataManagerObserver::DidBlock3DAPIs,
1148a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                         url, render_process_id, render_view_id, requester);
1149a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
1150a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid GpuDataManagerImplPrivate::OnGpuProcessInitFailure() {
1152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gpu_process_accessible_ = false;
1153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gpu_info_.finalized = true;
1154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  complete_gpu_info_already_requested_ = true;
1155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Some observers might be waiting.
1156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  NotifyGpuInfoUpdate();
1157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1159a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}  // namespace content
1160