summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gpu_process_host_ui_shim.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/gpu_process_host_ui_shim.cc')
-rw-r--r--chrome/browser/gpu_process_host_ui_shim.cc172
1 files changed, 156 insertions, 16 deletions
diff --git a/chrome/browser/gpu_process_host_ui_shim.cc b/chrome/browser/gpu_process_host_ui_shim.cc
index c3bcf61..cb49353 100644
--- a/chrome/browser/gpu_process_host_ui_shim.cc
+++ b/chrome/browser/gpu_process_host_ui_shim.cc
@@ -7,14 +7,23 @@
#include "chrome/browser/gpu_process_host_ui_shim.h"
+#include "app/app_switches.h"
+#include "app/gfx/gl/gl_implementation.h"
+#include "base/command_line.h"
#include "base/id_map.h"
+#include "base/metrics/histogram.h"
#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/gpu_data_manager.h"
+#include "chrome/browser/gpu_blacklist.h"
#include "chrome/browser/gpu_process_host.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
+#include "chrome/common/child_process_logging.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/gpu_messages.h"
+#include "chrome/gpu/gpu_info_collector.h"
+#include "grit/browser_resources.h"
+#include "ui/base/resource/resource_bundle.h"
#if defined(OS_LINUX)
// These two #includes need to come after gpu_messages.h.
@@ -53,6 +62,62 @@ class SendOnIOThreadTask : public Task {
} // namespace
+////////////////////////////////////////////////////////////////////////////////
+//
+// Callback0Group
+//
+////////////////////////////////////////////////////////////////////////////////
+
+Callback0Group::Callback0Group() {
+}
+
+Callback0Group::~Callback0Group() {
+}
+
+void Callback0Group::Add(Callback0::Type* callback) {
+ callbacks_.insert(callback);
+}
+
+bool Callback0Group::Remove(Callback0::Type* callback) {
+ std::set<Callback0::Type*>::iterator i = callbacks_.find(callback);
+ if (i != callbacks_.end()) {
+ callbacks_.erase(i);
+ return true;
+ }
+ return false;
+}
+
+void Callback0Group::Run() {
+ std::set<Callback0::Type*>::iterator i = callbacks_.begin();
+ for (; i != callbacks_.end(); ++i) {
+ (*i)->Run();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// GpuProcessHostUIShimManager
+//
+////////////////////////////////////////////////////////////////////////////////
+
+GpuProcessHostUIShimManager::GpuProcessHostUIShimManager() {
+}
+
+GpuProcessHostUIShimManager* GpuProcessHostUIShimManager::GetInstance() {
+ return Singleton<GpuProcessHostUIShimManager>::get();
+}
+
+void GpuProcessHostUIShimManager::SetGpuInfo(const GPUInfo& gpu_info) {
+ gpu_info_ = gpu_info;
+ gpu_info_update_callbacks().Run();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// GpuProcessHostUIShim
+//
+////////////////////////////////////////////////////////////////////////////////
+
class GpuProcessHostUIShim::ViewSurface {
public:
explicit ViewSurface(ViewID view_id);
@@ -102,10 +167,9 @@ RenderWidgetHostView* GpuProcessHostUIShim::ViewSurface::
GpuProcessHostUIShim::GpuProcessHostUIShim()
: host_id_(++g_last_host_id),
- gpu_process_(NULL) {
+ gpu_process_(NULL),
+ gpu_feature_flags_set_(false) {
g_hosts_by_id.AddWithID(this, host_id_);
- gpu_data_manager_ = GpuDataManager::GetInstance();
- DCHECK(gpu_data_manager_);
}
// static
@@ -121,6 +185,10 @@ GpuProcessHostUIShim* GpuProcessHostUIShim::GetForRenderer(int renderer_id) {
}
GpuProcessHostUIShim* ui_shim(new GpuProcessHostUIShim);
+ if (!ui_shim->Init()) {
+ delete ui_shim;
+ return NULL;
+ }
// If Init succeeds, post a task to create the corresponding GpuProcessHost.
// The GpuProcessHost will take ownership of the GpuProcessHostUIShim.
@@ -264,7 +332,7 @@ void GpuProcessHostUIShim::EstablishGpuChannel(
linked_ptr<EstablishChannelCallback> wrapped_callback(callback);
// If GPU features are already blacklisted, no need to establish the channel.
- if (gpu_data_manager_->GetGpuFeatureFlags().flags() != 0) {
+ if (gpu_feature_flags_.flags() != 0) {
EstablishChannelError(
wrapped_callback.release(), IPC::ChannelHandle(), NULL, GPUInfo());
return;
@@ -329,9 +397,8 @@ void GpuProcessHostUIShim::DidDestroyAcceleratedSurface(int renderer_id,
void GpuProcessHostUIShim::CollectGpuInfoAsynchronously(
GPUInfo::Level level) {
DCHECK(CalledOnValidThread());
-
// If GPU is already blacklisted, no more info will be collected.
- if (gpu_data_manager_->GetGpuFeatureFlags().flags() != 0)
+ if (gpu_feature_flags_.flags() != 0)
return;
Send(new GpuMsg_CollectGraphicsInfo(level));
}
@@ -348,7 +415,7 @@ void GpuProcessHostUIShim::SendAboutGpuHang() {
const GPUInfo& GpuProcessHostUIShim::gpu_info() const {
DCHECK(CalledOnValidThread());
- return gpu_data_manager_->gpu_info();
+ return gpu_info_;
}
GpuProcessHostUIShim::~GpuProcessHostUIShim() {
@@ -361,6 +428,10 @@ GpuProcessHostUIShim::~GpuProcessHostUIShim() {
#endif
}
+bool GpuProcessHostUIShim::Init() {
+ return LoadGpuBlacklist();
+}
+
void GpuProcessHostUIShim::AddCustomLogMessage(int level,
const std::string& header,
const std::string& message) {
@@ -405,19 +476,48 @@ bool GpuProcessHostUIShim::OnControlMessageReceived(
void GpuProcessHostUIShim::OnChannelEstablished(
const IPC::ChannelHandle& channel_handle,
const GPUInfo& gpu_info) {
- gpu_data_manager_->UpdateGpuInfo(gpu_info);
-
// The GPU process should have launched at this point and this object should
// have been notified of its process handle.
DCHECK(gpu_process_);
+ uint32 max_entry_id = gpu_blacklist_->max_entry_id();
+ // max_entry_id can be zero if we failed to load the GPU blacklist, don't
+ // bother with histograms then.
+ if (channel_handle.name.size() != 0 && !gpu_feature_flags_set_ &&
+ max_entry_id != 0)
+ {
+ gpu_feature_flags_set_ = true;
+
+ const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
+ if (!browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) &&
+ browser_command_line.GetSwitchValueASCII(
+ switches::kUseGL) != gfx::kGLImplementationOSMesaName) {
+ gpu_feature_flags_ = gpu_blacklist_->DetermineGpuFeatureFlags(
+ GpuBlacklist::kOsAny, NULL, gpu_info);
+
+ if (gpu_feature_flags_.flags() != 0) {
+ std::vector<uint32> flag_entries;
+ gpu_blacklist_->GetGpuFeatureFlagEntries(
+ GpuFeatureFlags::kGpuFeatureAll, flag_entries);
+ DCHECK_GT(flag_entries.size(), 0u);
+ for (size_t i = 0; i < flag_entries.size(); ++i) {
+ UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
+ flag_entries[i], max_entry_id + 1);
+ }
+ } else {
+ // id 0 is never used by any entry, so we use it here to indicate that
+ // gpu is allowed.
+ UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
+ 0, max_entry_id + 1);
+ }
+ }
+ }
linked_ptr<EstablishChannelCallback> callback = channel_requests_.front();
channel_requests_.pop();
// Currently if any of the GPU features are blacklisted, we don't establish a
// GPU channel.
- if (channel_handle.name.size() != 0 &&
- gpu_data_manager_->GetGpuFeatureFlags().flags() != 0) {
+ if (gpu_feature_flags_.flags() != 0) {
Send(new GpuMsg_CloseChannel(channel_handle));
EstablishChannelError(callback.release(),
IPC::ChannelHandle(),
@@ -459,16 +559,43 @@ void GpuProcessHostUIShim::OnDestroyCommandBuffer(
}
void GpuProcessHostUIShim::OnGraphicsInfoCollected(const GPUInfo& gpu_info) {
- gpu_data_manager_->UpdateGpuInfo(gpu_info);
+ gpu_info_ = gpu_info;
+ if (gpu_feature_flags_.flags() != 0)
+ gpu_info_.SetLevel(GPUInfo::kComplete);
+ child_process_logging::SetGpuInfo(gpu_info_);
+
+ GpuProcessHostUIShimManager::GetInstance()->SetGpuInfo(gpu_info);
}
void GpuProcessHostUIShim::OnPreliminaryGraphicsInfoCollected(
const GPUInfo& gpu_info, IPC::Message* reply_msg) {
- gpu_data_manager_->UpdateGpuInfo(gpu_info);
- GpuFeatureFlags flags = gpu_data_manager_->GetGpuFeatureFlags();
+ bool blacklisted = false;
+ const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
+ if (!browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) &&
+ browser_command_line.GetSwitchValueASCII(
+ switches::kUseGL) != gfx::kGLImplementationOSMesaName) {
+ gpu_feature_flags_ = gpu_blacklist_->DetermineGpuFeatureFlags(
+ GpuBlacklist::kOsAny, NULL, gpu_info);
+ if (gpu_feature_flags_.flags() != 0) {
+ blacklisted = true;
+ gpu_feature_flags_set_ = true;
+ gpu_info_ = gpu_info;
+ gpu_info_.SetLevel(GPUInfo::kComplete);
+ child_process_logging::SetGpuInfo(gpu_info_);
+ uint32 max_entry_id = gpu_blacklist_->max_entry_id();
+ std::vector<uint32> flag_entries;
+ gpu_blacklist_->GetGpuFeatureFlagEntries(
+ GpuFeatureFlags::kGpuFeatureAll, flag_entries);
+ DCHECK_GT(flag_entries.size(), 0u);
+ for (size_t i = 0; i < flag_entries.size(); ++i) {
+ UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
+ flag_entries[i], max_entry_id + 1);
+ }
+ }
+ }
GpuHostMsg_PreliminaryGraphicsInfoCollected::WriteReplyParams(
- reply_msg, flags.flags() != 0);
+ reply_msg, blacklisted);
Send(reply_msg);
}
@@ -548,3 +675,16 @@ void GpuProcessHostUIShim::OnScheduleComposite(int renderer_id,
#endif
+bool GpuProcessHostUIShim::LoadGpuBlacklist() {
+ if (gpu_blacklist_.get() != NULL)
+ return true;
+ static const base::StringPiece gpu_blacklist_json(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_GPU_BLACKLIST));
+ gpu_blacklist_.reset(new GpuBlacklist());
+ if (gpu_blacklist_->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true))
+ return true;
+ gpu_blacklist_.reset(NULL);
+ return false;
+}
+