summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-27 21:29:42 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-27 21:29:42 +0000
commit59a74142e90e463622aca40f68b210ff360a6bf8 (patch)
treedefb7f383289948bc89decce1b9dd7b7e8eb20b4 /chrome/browser
parent4d5223d547585b7baca9f93b4c5d96cbf91eaf10 (diff)
downloadchromium_src-59a74142e90e463622aca40f68b210ff360a6bf8.zip
chromium_src-59a74142e90e463622aca40f68b210ff360a6bf8.tar.gz
chromium_src-59a74142e90e463622aca40f68b210ff360a6bf8.tar.bz2
Merge 82990 - Move the synchronous GPU messages to the IO thread to avoid deadlock.
I patched in Jonathan's change from http://codereview.chromium.org/6881105/ for the CreateViewCommandBuffer message, and also added the Synchronize and EstablishChannel. The latter required making GpuDataManager callable from the IO thread. I moved the code that loads the blacklist from the prefs and web to Chrome code, since I wanted to do that anyways so that GpuProcessHostUIShim and GpuDataManager can move to content (I'll do that later). Since the messages are filtered on the IO thread, it's now GpuProcessHost that creates GpuProcessHostUIShim. Accordingly, all the code that used to call GpuProcessHostUIShim to send a message now has to call GpuProcessHost, since the logic of when to create a process is there. Also, since there's no IO thread object for the in-process case, I've had to break that in the meantime. Al will take a look at that later. BUG=77536 Review URL: http://codereview.chromium.org/6902021 TBR=jam@chromium.org Review URL: http://codereview.chromium.org/6902087 git-svn-id: svn://svn.chromium.org/chrome/branches/742/src@83219 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/browser_about_handler.cc20
-rw-r--r--chrome/browser/browser_main.cc17
-rw-r--r--chrome/browser/gpu_data_manager.cc190
-rw-r--r--chrome/browser/gpu_data_manager.h24
-rw-r--r--chrome/browser/gpu_process_host_ui_shim.cc363
-rw-r--r--chrome/browser/gpu_process_host_ui_shim.h113
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm55
-rw-r--r--chrome/browser/web_resource/gpu_blacklist_updater.cc76
-rw-r--r--chrome/browser/web_resource/gpu_blacklist_updater.h9
9 files changed, 175 insertions, 692 deletions
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc
index 12f008c..125cb7c 100644
--- a/chrome/browser/browser_about_handler.cc
+++ b/chrome/browser/browser_about_handler.cc
@@ -28,7 +28,6 @@
#include "chrome/browser/about_flags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/defaults.h"
-#include "chrome/browser/gpu_process_host_ui_shim.h"
#include "chrome/browser/memory_details.h"
#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/net/predictor_api.h"
@@ -48,6 +47,7 @@
#include "content/browser/gpu_process_host.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
+#include "content/common/gpu/gpu_messages.h"
#include "googleurl/src/gurl.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
@@ -1334,22 +1334,12 @@ bool WillHandleBrowserAboutURL(GURL* url, Profile* profile) {
// Handle URLs to wreck the gpu process.
if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutGpuCrashURL)) {
- GpuProcessHostUIShim* gpu_ui_shim =
- GpuProcessHostUIShim::GetForRenderer(0,
- content::CAUSE_FOR_GPU_LAUNCH_ABOUT_GPUCRASH);
- if (gpu_ui_shim) {
- gpu_ui_shim->SendAboutGpuCrash();
- return true;
- }
+ GpuProcessHost::SendOnIO(
+ 0, content::CAUSE_FOR_GPU_LAUNCH_ABOUT_GPUCRASH, new GpuMsg_Crash());
}
if (LowerCaseEqualsASCII(url->spec(), chrome::kAboutGpuHangURL)) {
- GpuProcessHostUIShim* gpu_ui_shim =
- GpuProcessHostUIShim::GetForRenderer(0,
- content::CAUSE_FOR_GPU_LAUNCH_ABOUT_GPUHANG);
- if (gpu_ui_shim) {
- gpu_ui_shim->SendAboutGpuHang();
- return true;
- }
+ GpuProcessHost::SendOnIO(
+ 0, content::CAUSE_FOR_GPU_LAUNCH_ABOUT_GPUHANG, new GpuMsg_Hang());
}
// There are a few about: URLs that we hand over to the renderer. If the
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index 1f59543..99543bf 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -43,7 +43,6 @@
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/first_run/first_run_browser_process.h"
#include "chrome/browser/first_run/upgrade_util.h"
-#include "chrome/browser/gpu_data_manager.h"
#include "chrome/browser/jankometer.h"
#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/metrics/metrics_log.h"
@@ -75,6 +74,7 @@
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_init.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager_backend.h"
+#include "chrome/browser/web_resource/gpu_blacklist_updater.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
@@ -113,6 +113,8 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/system_monitor/system_monitor.h"
+#include "ui/gfx/gl/gl_implementation.h"
+#include "ui/gfx/gl/gl_switches.h"
#if defined(USE_LINUX_BREAKPAD)
#include "base/linux_util.h"
@@ -1771,11 +1773,14 @@ int BrowserMain(const MainFunctionParams& parameters) {
// might have shutdown because an update was available.
profile->GetCloudPrintProxyService();
- // Need to initialize GpuDataManager to load the current GPU blacklist,
- // collect preliminary GPU info, run through GPU blacklist, and schedule
- // a GPU blacklist auto update.
- GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance();
- DCHECK(gpu_data_manager);
+ // Schedule a GPU blacklist auto update. This also loads the current one.
+ scoped_refptr<GpuBlacklistUpdater> gpu_blacklist_updater =
+ new GpuBlacklistUpdater();
+ // Don't start auto update in tests.
+ if (parsed_command_line.GetSwitchValueASCII(switches::kUseGL) !=
+ gfx::kGLImplementationOSMesaName) {
+ gpu_blacklist_updater->StartAfterDelay();
+ }
// Start watching all browser threads for responsiveness.
ThreadWatcherList::StartWatchingAll();
diff --git a/chrome/browser/gpu_data_manager.cc b/chrome/browser/gpu_data_manager.cc
index 003eb58..e839072 100644
--- a/chrome/browser/gpu_data_manager.cc
+++ b/chrome/browser/gpu_data_manager.cc
@@ -5,60 +5,30 @@
#include "chrome/browser/gpu_data_manager.h"
#include "base/command_line.h"
-#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/string_number_conversions.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/gpu_process_host_ui_shim.h"
-#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/child_process_logging.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/chrome_version_info.h"
-#include "chrome/common/pref_names.h"
+#include "content/browser/browser_thread.h"
#include "content/browser/gpu_blacklist.h"
+#include "content/browser/gpu_process_host.h"
+#include "content/common/gpu/gpu_messages.h"
#include "content/gpu/gpu_info_collector.h"
-#include "grit/browser_resources.h"
-#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_switches.h"
GpuDataManager::GpuDataManager()
- : complete_gpu_info_already_requested_(false),
- gpu_feature_flags_set_(false),
- gpu_blacklist_cache_(NULL) {
+ : complete_gpu_info_already_requested_(false) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(g_browser_process);
- PrefService* local_state = g_browser_process->local_state();
- // If we bring up chrome normally, prefs should never be NULL; however, we
- // we handle the case where local_state == NULL for certain tests.
- if (local_state) {
- local_state->RegisterDictionaryPref(prefs::kGpuBlacklist);
- gpu_blacklist_cache_ = local_state->GetDictionary(prefs::kGpuBlacklist);
- DCHECK(gpu_blacklist_cache_);
-
- gpu_blacklist_updater_ = new GpuBlacklistUpdater();
- // Don't start auto update in tests.
- const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
- if (browser_command_line.GetSwitchValueASCII(
- switches::kUseGL) != gfx::kGLImplementationOSMesaName)
- gpu_blacklist_updater_->StartAfterDelay();
- }
-
- LoadGpuBlacklist();
- UpdateGpuBlacklist();
GPUInfo gpu_info;
gpu_info_collector::CollectPreliminaryGraphicsInfo(&gpu_info);
UpdateGpuInfo(gpu_info);
- UpdateGpuFeatureFlags();
-
- preliminary_gpu_feature_flags_ = gpu_feature_flags_;
}
GpuDataManager::~GpuDataManager() { }
GpuDataManager* GpuDataManager::GetInstance() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return Singleton<GpuDataManager>::get();
}
@@ -68,26 +38,21 @@ void GpuDataManager::RequestCompleteGpuInfoIfNeeded() {
return;
complete_gpu_info_already_requested_ = true;
- GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::GetForRenderer(0,
- content::
- CAUSE_FOR_GPU_LAUNCH_GPUDATAMANAGER_REQUESTCOMPLETEGPUINFOIFNEEDED);
- if (ui_shim)
- ui_shim->CollectGpuInfoAsynchronously();
+ GpuProcessHost::SendOnIO(
+ 0,
+ content::CAUSE_FOR_GPU_LAUNCH_GPUDATAMANAGER_REQUESTCOMPLETEGPUINFOIFNEEDED,
+ new GpuMsg_CollectGraphicsInfo());
}
void GpuDataManager::UpdateGpuInfo(const GPUInfo& gpu_info) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ base::AutoLock auto_lock(gpu_info_lock_);
if (!gpu_info_.Merge(gpu_info))
return;
child_process_logging::SetGpuInfo(gpu_info_);
- // Clear the flag to triger a re-computation of GpuFeatureFlags using the
- // updated GPU info.
- gpu_feature_flags_set_ = false;
- RunGpuInfoUpdateCallbacks();
}
const GPUInfo& GpuDataManager::gpu_info() const {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ base::AutoLock auto_lock(gpu_info_lock_);
return gpu_info_;
}
@@ -128,22 +93,11 @@ const ListValue& GpuDataManager::log_messages() const {
}
GpuFeatureFlags GpuDataManager::GetGpuFeatureFlags() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- UpdateGpuFeatureFlags();
return gpu_feature_flags_;
}
bool GpuDataManager::GpuAccessAllowed() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- UpdateGpuFeatureFlags();
- // We only need to block GPU process if more features are disallowed other
- // than those in the preliminary gpu feature flags because the latter work
- // through renderer commandline switches.
- // However, if accelerated_compositing is not allowed, then we should always
- // deny gpu access.
- uint32 mask = (~(preliminary_gpu_feature_flags_.flags())) |
- GpuFeatureFlags::kGpuFeatureAcceleratedCompositing;
- return (gpu_feature_flags_.flags() & mask) == 0;
+ return gpu_feature_flags_.flags() == 0;
}
void GpuDataManager::AddGpuInfoUpdateCallback(Callback0::Type* callback) {
@@ -167,7 +121,7 @@ void GpuDataManager::AppendRendererCommandLine(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(command_line);
- uint32 flags = preliminary_gpu_feature_flags_.flags();
+ uint32 flags = gpu_feature_flags_.flags();
if ((flags & GpuFeatureFlags::kGpuFeatureWebgl) &&
!command_line->HasSwitch(switches::kDisableExperimentalWebGL))
command_line->AppendSwitch(switches::kDisableExperimentalWebGL);
@@ -188,6 +142,12 @@ void GpuDataManager::AppendRendererCommandLine(
}
}
+void GpuDataManager::UpdateGpuBlacklist(GpuBlacklist* gpu_blacklist) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ gpu_blacklist_.reset(gpu_blacklist);
+ UpdateGpuFeatureFlags();
+}
+
void GpuDataManager::RunGpuInfoUpdateCallbacks() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
std::set<Callback0::Type*>::iterator i = gpu_info_update_callbacks_.begin();
@@ -196,104 +156,47 @@ void GpuDataManager::RunGpuInfoUpdateCallbacks() {
}
}
-bool GpuDataManager::LoadGpuBlacklist() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (gpu_blacklist_.get() != NULL)
- return true;
- static const base::StringPiece gpu_blacklist_json(
- ResourceBundle::GetSharedInstance().GetRawDataResource(
- IDR_GPU_BLACKLIST));
- chrome::VersionInfo version_info;
- std::string chrome_version_string =
- version_info.is_valid() ? version_info.Version() : "0";
- gpu_blacklist_.reset(new GpuBlacklist(chrome_version_string));
- if (gpu_blacklist_->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) {
- uint16 version_major, version_minor;
- bool succeed = gpu_blacklist_->GetVersion(&version_major,
- &version_minor);
- DCHECK(succeed);
- VLOG(1) << "Using software rendering list version "
- << version_major << "." << version_minor;
- return true;
- }
- gpu_blacklist_.reset(NULL);
- return false;
-}
-
-bool GpuDataManager::UpdateGpuBlacklist() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (gpu_blacklist_cache_ == NULL)
- return false;
- uint16 cached_version_major, cached_version_minor;
- if (!GpuBlacklist::GetVersion(*gpu_blacklist_cache_,
- &cached_version_major,
- &cached_version_minor))
- return false;
- if (gpu_blacklist_.get() != NULL) {
- uint16 current_version_major, current_version_minor;
- if (gpu_blacklist_->GetVersion(&current_version_major,
- &current_version_minor) &&
- (cached_version_major < current_version_major ||
- (cached_version_major == current_version_major &&
- cached_version_minor <= current_version_minor)))
- return false;
- }
- chrome::VersionInfo version_info;
- std::string chrome_version_string =
- version_info.is_valid() ? version_info.Version() : "0";
- GpuBlacklist* updated_list = new GpuBlacklist(chrome_version_string);
- if (!updated_list->LoadGpuBlacklist(*gpu_blacklist_cache_, true)) {
- delete updated_list;
- return false;
- }
- gpu_blacklist_.reset(updated_list);
- VLOG(1) << "Using software rendering list version "
- << cached_version_major << "." << cached_version_minor;
- // Clear the flag to triger a re-computation of GpuFeatureFlags using the
- // updated GPU blacklist.
- gpu_feature_flags_set_ = false;
- return true;
-}
-
void GpuDataManager::UpdateGpuFeatureFlags() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // Need to call this before checking gpu_feature_flags_set_ because it might
- // be reset if a newer version of GPU blacklist is downloaed.
GpuBlacklist* gpu_blacklist = GetGpuBlacklist();
if (gpu_blacklist == NULL)
return;
- if (gpu_feature_flags_set_)
+ // We don't set a lock around modifying gpu_feature_flags_ since it's just an
+ // int.
+ if (!gpu_blacklist) {
+ gpu_feature_flags_.set_flags(0);
return;
+ }
- gpu_feature_flags_set_ = true;
- gpu_feature_flags_.set_flags(0);
-
- if (gpu_blacklist != NULL) {
+ {
+ base::AutoLock auto_lock(gpu_info_lock_);
gpu_feature_flags_ = gpu_blacklist->DetermineGpuFeatureFlags(
GpuBlacklist::kOsAny, NULL, gpu_info_);
- uint32 max_entry_id = gpu_blacklist->max_entry_id();
- if (gpu_feature_flags_.flags() != 0) {
- // If gpu is blacklisted, no further GPUInfo will be collected.
- gpu_info_.finalized = true;
- // Notify clients that GpuInfo state has changed
- RunGpuInfoUpdateCallbacks();
+ // If gpu is blacklisted, no further GPUInfo will be collected.
+ gpu_info_.finalized = true;
+ }
- // TODO(zmo): move histograming to GpuBlacklist::DetermineGpuFeatureFlags.
- 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 {
- UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
- 0, max_entry_id + 1);
- }
+ uint32 max_entry_id = gpu_blacklist->max_entry_id();
+ if (!gpu_feature_flags_.flags()) {
+ UMA_HISTOGRAM_ENUMERATION("GPU.BlacklistTestResultsPerEntry",
+ 0, max_entry_id + 1);
+ return;
+ }
+
+ // Notify clients that GpuInfo state has changed
+ RunGpuInfoUpdateCallbacks();
+
+ // TODO(zmo): move histograming to GpuBlacklist::DetermineGpuFeatureFlags.
+ 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);
}
}
@@ -304,7 +207,6 @@ GpuBlacklist* GpuDataManager::GetGpuBlacklist() {
browser_command_line.GetSwitchValueASCII(
switches::kUseGL) == gfx::kGLImplementationOSMesaName)
return NULL;
- UpdateGpuBlacklist();
// No need to return an empty blacklist.
if (gpu_blacklist_.get() != NULL && gpu_blacklist_->max_entry_id() == 0)
return NULL;
diff --git a/chrome/browser/gpu_data_manager.h b/chrome/browser/gpu_data_manager.h
index 12449fc..723503e 100644
--- a/chrome/browser/gpu_data_manager.h
+++ b/chrome/browser/gpu_data_manager.h
@@ -12,13 +12,12 @@
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
+#include "base/synchronization/lock.h"
#include "base/values.h"
-#include "chrome/browser/web_resource/gpu_blacklist_updater.h"
#include "content/common/gpu/gpu_info.h"
#include "content/common/gpu_feature_flags.h"
class CommandLine;
-class DictionaryValue;
class GpuBlacklist;
class GpuDataManager {
@@ -45,7 +44,7 @@ class GpuDataManager {
const ListValue& log_messages() const;
- // If necessary, compute the flags before returning them.
+ // Can be called on any thread.
GpuFeatureFlags GetGpuFeatureFlags();
// This indicator might change because we could collect more GPU info or
@@ -53,6 +52,7 @@ class GpuDataManager {
// If this returns false, any further GPU access, including launching GPU
// process, establish GPU channel, and GPU info collection, should be
// blocked.
+ // Can be called on any thread.
bool GpuAccessAllowed();
// Add a callback.
@@ -66,19 +66,16 @@ class GpuDataManager {
// in correspondance to preliminary gpu feature flags.
void AppendRendererCommandLine(CommandLine* command_line);
+ // Gives ownership of the latest blacklist. This is always called on the UI
+ // thread.
+ void UpdateGpuBlacklist(GpuBlacklist* gpu_blacklist);
+
private:
friend struct DefaultSingletonTraits<GpuDataManager>;
GpuDataManager();
virtual ~GpuDataManager();
- bool LoadGpuBlacklist();
-
- // Check if a newer version of GPU blacklist has been downloaded from the
- // web (and saved in the local state); if yes, use the newer version instead.
- // Return true if a newer version is installed.
- bool UpdateGpuBlacklist();
-
// Check if we should go ahead and use gpu blacklist.
// If not, return NULL; otherwise, update and return the current list.
GpuBlacklist* GetGpuBlacklist();
@@ -94,17 +91,12 @@ class GpuDataManager {
bool gpu_feature_flags_set_;
GpuFeatureFlags gpu_feature_flags_;
- GpuFeatureFlags preliminary_gpu_feature_flags_;
GPUInfo gpu_info_;
+ mutable base::Lock gpu_info_lock_;
scoped_ptr<GpuBlacklist> gpu_blacklist_;
- scoped_refptr<GpuBlacklistUpdater> gpu_blacklist_updater_;
- // This is the version cached in local state that's automatically updated
- // from the web.
- const DictionaryValue* gpu_blacklist_cache_;
-
// Map of callbacks.
std::set<Callback0::Type*> gpu_info_update_callbacks_;
diff --git a/chrome/browser/gpu_process_host_ui_shim.cc b/chrome/browser/gpu_process_host_ui_shim.cc
index 4d38ad1..9b20c86 100644
--- a/chrome/browser/gpu_process_host_ui_shim.cc
+++ b/chrome/browser/gpu_process_host_ui_shim.cc
@@ -21,7 +21,6 @@
#include "content/common/content_switches.h"
#include "content/common/gpu_messages.h"
#include "gpu/common/gpu_trace_event.h"
-#include "ui/gfx/gl/gl_context.h"
#if defined(OS_LINUX)
// These two #includes need to come after gpu_messages.h.
@@ -38,7 +37,6 @@ namespace {
#undef DestroyAll
#endif
-int g_last_host_id = 0;
IDMap<GpuProcessHostUIShim> g_hosts_by_id;
class SendOnIOThreadTask : public Task {
@@ -112,111 +110,25 @@ void RouteToGpuProcessHostUIShimTask::Run() {
ui_shim->OnMessageReceived(msg_);
}
-#if defined(OS_LINUX)
-// Used to put a lock on surfaces so that the window to which the GPU
-// process is drawing to doesn't disappear while it is drawing when
-// a tab is closed.
-class GpuProcessHostUIShim::SurfaceRef {
- public:
- explicit SurfaceRef(gfx::PluginWindowHandle surface);
- ~SurfaceRef();
- private:
- gfx::PluginWindowHandle surface_;
-};
-
-GpuProcessHostUIShim::SurfaceRef::SurfaceRef(gfx::PluginWindowHandle surface)
- : surface_(surface) {
- GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
- if (!manager->AddRefPermanentXID(surface_)) {
- LOG(ERROR) << "Surface " << surface << " cannot be referenced.";
- }
-}
-
-GpuProcessHostUIShim::SurfaceRef::~SurfaceRef() {
- // TODO(backer): ReleasePermanentXID has to be done on the UI thread.
- // Post task to release once we move this code to the IO thread.
- GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
- manager->ReleasePermanentXID(surface_);
-}
-#endif // defined(OS_LINUX)
-
-GpuProcessHostUIShim::GpuProcessHostUIShim(int host_id,
- content::CauseForGpuLaunch cause_for_gpu_launch)
+GpuProcessHostUIShim::GpuProcessHostUIShim(int host_id)
: host_id_(host_id),
- gpu_process_(base::kNullProcessHandle),
gpu_channel_manager_(NULL),
ui_thread_sender_(NULL) {
g_hosts_by_id.AddWithID(this, host_id_);
- gpu_data_manager_ = GpuDataManager::GetInstance();
- DCHECK(gpu_data_manager_);
-
if (host_id == 0) {
- gpu_process_ = base::GetCurrentProcessHandle();
ui_thread_sender_ = new UIThreadSender;
gpu_channel_manager_ = new GpuChannelManager(
ui_thread_sender_,
NULL,
g_browser_process->io_thread()->message_loop(),
g_browser_process->shutdown_event());
- } else {
- // Post a task to create the corresponding GpuProcessHost.
- // The GpuProcessHostUIShim will be destroyed if either the browser exits,
- // in which case it calls GpuProcessHostUIShim::DestroyAll, or the
- // GpuProcessHost is destroyed, which happens when the corresponding GPU
- // process terminates or fails to launch.
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- NewRunnableFunction(
- &GpuProcessHost::Create,
- host_id,
- GpuDataManager::GetInstance()->GetGpuFeatureFlags(),
- cause_for_gpu_launch));
}
}
// static
-GpuProcessHostUIShim* GpuProcessHostUIShim::GetForRenderer(int renderer_id,
- content::CauseForGpuLaunch cause_for_gpu_launch) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // Don't grant further access to GPU if it is not allowed.
- GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance();
- if (gpu_data_manager != NULL && !gpu_data_manager->GpuAccessAllowed())
- return NULL;
-
- // The current policy is to ignore the renderer ID and use a single GPU
- // process for all renderers. Later this will be extended to allow the
- // use of multiple GPU processes.
- if (!g_hosts_by_id.IsEmpty()) {
- IDMap<GpuProcessHostUIShim>::iterator it(&g_hosts_by_id);
- return it.GetCurrentValue();
- }
-
- if (cause_for_gpu_launch == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH)
- return NULL;
-
- int host_id;
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) ||
- CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) {
- if (!g_browser_process->gpu_thread())
- return NULL;
-
- // Initialize GL on the GPU thread.
- // TODO(apatrick): Handle failure to initialize (asynchronously).
- if (!BrowserThread::PostTask(
- BrowserThread::GPU,
- FROM_HERE,
- NewRunnableFunction(&gfx::GLContext::InitializeOneOff))) {
- return NULL;
- }
-
- host_id = 0;
- } else {
- host_id = ++g_last_host_id;
- }
-
- return new GpuProcessHostUIShim(host_id, cause_for_gpu_launch);
+GpuProcessHostUIShim* GpuProcessHostUIShim::Create(int host_id) {
+ DCHECK(!FromID(host_id));
+ return new GpuProcessHostUIShim(host_id);
}
// static
@@ -235,18 +147,6 @@ void GpuProcessHostUIShim::DestroyAll() {
}
// static
-void GpuProcessHostUIShim::NotifyGpuProcessLaunched(
- int host_id,
- base::ProcessHandle gpu_process) {
- DCHECK(gpu_process);
-
- GpuProcessHostUIShim* ui_shim = FromID(host_id);
- DCHECK(ui_shim);
-
- ui_shim->gpu_process_ = gpu_process;
-}
-
-// static
GpuProcessHostUIShim* GpuProcessHostUIShim::FromID(int host_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return g_hosts_by_id.Lookup(host_id);
@@ -274,86 +174,6 @@ bool GpuProcessHostUIShim::Send(IPC::Message* msg) {
return success;
}
-// Post a Task to execute callbacks on a error conditions in order to
-// clear the call stacks (and aid debugging).
-namespace {
-
-void EstablishChannelCallbackDispatcher(
- GpuProcessHostUIShim::EstablishChannelCallback* callback,
- const IPC::ChannelHandle& channel_handle,
- base::ProcessHandle renderer_process_for_gpu,
- const GPUInfo& gpu_info) {
- scoped_ptr<GpuProcessHostUIShim::EstablishChannelCallback>
- wrapped_callback(callback);
- wrapped_callback->Run(channel_handle, renderer_process_for_gpu, gpu_info);
-}
-
-void EstablishChannelError(
- GpuProcessHostUIShim::EstablishChannelCallback* callback,
- const IPC::ChannelHandle& channel_handle,
- base::ProcessHandle renderer_process_for_gpu,
- const GPUInfo& gpu_info) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableFunction(&EstablishChannelCallbackDispatcher,
- callback,
- channel_handle,
- renderer_process_for_gpu,
- gpu_info));
-}
-
-void SynchronizeCallbackDispatcher(
- GpuProcessHostUIShim::SynchronizeCallback* callback) {
- scoped_ptr<GpuProcessHostUIShim::SynchronizeCallback>
- wrapped_callback(callback);
- wrapped_callback->Run();
-}
-
-void SynchronizeError(
- GpuProcessHostUIShim::SynchronizeCallback* callback) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableFunction(&SynchronizeCallbackDispatcher, callback));
-}
-
-void CreateCommandBufferCallbackDispatcher(
- GpuProcessHostUIShim::CreateCommandBufferCallback* callback,
- int32 route_id) {
- scoped_ptr<GpuProcessHostUIShim::CreateCommandBufferCallback>
- wrapped_callback(callback);
- callback->Run(route_id);
-}
-
-void CreateCommandBufferError(
- GpuProcessHostUIShim::CreateCommandBufferCallback* callback,
- int32 route_id) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableFunction(&CreateCommandBufferCallbackDispatcher,
- callback, route_id));
-}
-
-} // namespace
-
-void GpuProcessHostUIShim::SendOutstandingReplies() {
- // First send empty channel handles for all EstablishChannel requests.
- while (!channel_requests_.empty()) {
- linked_ptr<EstablishChannelCallback> callback = channel_requests_.front();
- channel_requests_.pop();
- EstablishChannelError(callback.release(),
- IPC::ChannelHandle(),
- base::kNullProcessHandle,
- GPUInfo());
- }
-
- // Now unblock all renderers waiting for synchronization replies.
- while (!synchronize_requests_.empty()) {
- linked_ptr<SynchronizeCallback> callback = synchronize_requests_.front();
- synchronize_requests_.pop();
- SynchronizeError(callback.release());
- }
-}
-
bool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
DCHECK(CalledOnValidThread());
@@ -363,78 +183,6 @@ bool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
return OnControlMessageReceived(message);
}
-void GpuProcessHostUIShim::EstablishGpuChannel(
- int renderer_id,
- EstablishChannelCallback *callback) {
- DCHECK(CalledOnValidThread());
- GPU_TRACE_EVENT0("gpu", "GpuProcessHostUIShim::EstablishGpuChannel");
- linked_ptr<EstablishChannelCallback> wrapped_callback(callback);
-
- // If GPU features are already blacklisted, no need to establish the channel.
- if (!gpu_data_manager_->GpuAccessAllowed()) {
- EstablishChannelError(
- wrapped_callback.release(), IPC::ChannelHandle(),
- base::kNullProcessHandle, GPUInfo());
- return;
- }
-
- if (Send(new GpuMsg_EstablishChannel(renderer_id))) {
- channel_requests_.push(wrapped_callback);
- } else {
- EstablishChannelError(
- wrapped_callback.release(), IPC::ChannelHandle(),
- base::kNullProcessHandle, GPUInfo());
- }
-}
-
-void GpuProcessHostUIShim::Synchronize(SynchronizeCallback* callback) {
- DCHECK(CalledOnValidThread());
- linked_ptr<SynchronizeCallback> wrapped_callback(callback);
-
- if (Send(new GpuMsg_Synchronize())) {
- synchronize_requests_.push(wrapped_callback);
- } else {
- SynchronizeError(wrapped_callback.release());
- }
-}
-
-void GpuProcessHostUIShim::CreateViewCommandBuffer(
- gfx::PluginWindowHandle compositing_surface,
- int32 render_view_id,
- int32 renderer_id,
- const GPUCreateCommandBufferConfig& init_params,
- CreateCommandBufferCallback* callback) {
- DCHECK(CalledOnValidThread());
- linked_ptr<CreateCommandBufferCallback> wrapped_callback(callback);
-
-#if defined(OS_LINUX)
- ViewID view_id(renderer_id, render_view_id);
-
- // There should only be one such command buffer (for the compositor). In
- // practice, if the GPU process lost a context, GraphicsContext3D with
- // associated command buffer and view surface will not be gone until new
- // one is in place and all layers are reattached.
- linked_ptr<SurfaceRef> surface_ref;
- SurfaceRefMap::iterator it = surface_refs_.find(view_id);
- if (it != surface_refs_.end())
- surface_ref = (*it).second;
- else
- surface_ref.reset(new SurfaceRef(compositing_surface));
-#endif // defined(OS_LINUX)
-
- if (compositing_surface != gfx::kNullPluginWindow &&
- Send(new GpuMsg_CreateViewCommandBuffer(
- compositing_surface, render_view_id, renderer_id, init_params))) {
- create_command_buffer_requests_.push(wrapped_callback);
-#if defined(OS_LINUX)
- surface_refs_.insert(std::pair<ViewID, linked_ptr<SurfaceRef> >(
- view_id, surface_ref));
-#endif // defined(OS_LINUX)
- } else {
- CreateCommandBufferError(wrapped_callback.release(), MSG_ROUTING_NONE);
- }
-}
-
#if defined(OS_MACOSX)
void GpuProcessHostUIShim::DidDestroyAcceleratedSurface(int renderer_id,
@@ -453,30 +201,10 @@ void GpuProcessHostUIShim::SendToGpuHost(int host_id, IPC::Message* msg) {
#endif
-void GpuProcessHostUIShim::CollectGpuInfoAsynchronously() {
- DCHECK(CalledOnValidThread());
- Send(new GpuMsg_CollectGraphicsInfo());
-}
-
-void GpuProcessHostUIShim::SendAboutGpuCrash() {
- DCHECK(CalledOnValidThread());
- Send(new GpuMsg_Crash());
-}
-
-void GpuProcessHostUIShim::SendAboutGpuHang() {
- DCHECK(CalledOnValidThread());
- Send(new GpuMsg_Hang());
-}
-
GpuProcessHostUIShim::~GpuProcessHostUIShim() {
DCHECK(CalledOnValidThread());
g_hosts_by_id.Remove(host_id_);
-#if defined(OS_WIN)
- if (gpu_process_)
- CloseHandle(gpu_process_);
-#endif
-
// Ensure these are destroyed on the GPU thread.
if (gpu_channel_manager_) {
BrowserThread::DeleteSoon(BrowserThread::GPU,
@@ -492,29 +220,13 @@ GpuProcessHostUIShim::~GpuProcessHostUIShim() {
}
}
-void GpuProcessHostUIShim::AddCustomLogMessage(int level,
- const std::string& header,
- const std::string& message) {
- OnLogMessage(level, header, message);
-}
-
bool GpuProcessHostUIShim::OnControlMessageReceived(
const IPC::Message& message) {
DCHECK(CalledOnValidThread());
IPC_BEGIN_MESSAGE_MAP(GpuProcessHostUIShim, message)
- IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished,
- OnChannelEstablished)
- IPC_MESSAGE_HANDLER(GpuHostMsg_CommandBufferCreated,
- OnCommandBufferCreated)
- IPC_MESSAGE_HANDLER(GpuHostMsg_DestroyCommandBuffer,
- OnDestroyCommandBuffer)
- IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected,
- OnGraphicsInfoCollected)
IPC_MESSAGE_HANDLER(GpuHostMsg_OnLogMessage,
OnLogMessage)
- IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply,
- OnSynchronizeReply)
#if defined(OS_LINUX) && !defined(TOUCH_UI)
IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuHostMsg_ResizeXID, OnResizeXID)
#elif defined(OS_MACOSX)
@@ -531,76 +243,15 @@ bool GpuProcessHostUIShim::OnControlMessageReceived(
return true;
}
-void GpuProcessHostUIShim::OnChannelEstablished(
- const IPC::ChannelHandle& channel_handle) {
- // The GPU process should have launched at this point and this object should
- // have been notified of its process handle.
- DCHECK(gpu_process_);
-
- 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.empty() &&
- !gpu_data_manager_->GpuAccessAllowed()) {
- Send(new GpuMsg_CloseChannel(channel_handle));
- EstablishChannelError(callback.release(),
- IPC::ChannelHandle(),
- base::kNullProcessHandle,
- GPUInfo());
- AddCustomLogMessage(logging::LOG_WARNING, "WARNING",
- "Hardware acceleration is unavailable.");
- return;
- }
-
- callback->Run(channel_handle, gpu_process_, gpu_data_manager_->gpu_info());
-}
-
-void GpuProcessHostUIShim::OnSynchronizeReply() {
- // Guard against race conditions in abrupt GPU process termination.
- if (!synchronize_requests_.empty()) {
- linked_ptr<SynchronizeCallback> callback(synchronize_requests_.front());
- synchronize_requests_.pop();
- callback->Run();
- }
-}
-
-void GpuProcessHostUIShim::OnCommandBufferCreated(const int32 route_id) {
- if (!create_command_buffer_requests_.empty()) {
- linked_ptr<CreateCommandBufferCallback> callback =
- create_command_buffer_requests_.front();
- create_command_buffer_requests_.pop();
- if (route_id == MSG_ROUTING_NONE)
- CreateCommandBufferError(callback.release(), route_id);
- else
- callback->Run(route_id);
- }
-}
-
-void GpuProcessHostUIShim::OnDestroyCommandBuffer(
- gfx::PluginWindowHandle window, int32 renderer_id,
- int32 render_view_id) {
-#if defined(OS_LINUX)
- ViewID view_id(renderer_id, render_view_id);
- SurfaceRefMap::iterator it = surface_refs_.find(view_id);
- if (it != surface_refs_.end())
- surface_refs_.erase(it);
-#endif // defined(OS_LINUX)
-}
-
-void GpuProcessHostUIShim::OnGraphicsInfoCollected(const GPUInfo& gpu_info) {
- gpu_data_manager_->UpdateGpuInfo(gpu_info);
-}
-
-void GpuProcessHostUIShim::OnLogMessage(int level,
+void GpuProcessHostUIShim::OnLogMessage(
+ int level,
const std::string& header,
const std::string& message) {
DictionaryValue* dict = new DictionaryValue();
dict->SetInteger("level", level);
dict->SetString("header", header);
dict->SetString("message", message);
- gpu_data_manager_->AddLogMessage(dict);
+ GpuDataManager::GetInstance()->AddLogMessage(dict);
}
#if defined(OS_LINUX) && !defined(TOUCH_UI)
diff --git a/chrome/browser/gpu_process_host_ui_shim.h b/chrome/browser/gpu_process_host_ui_shim.h
index cd834a5..e611425 100644
--- a/chrome/browser/gpu_process_host_ui_shim.h
+++ b/chrome/browser/gpu_process_host_ui_shim.h
@@ -11,28 +11,22 @@
// portion of this class, the GpuProcessHost, is responsible for
// shuttling messages between the browser and GPU processes.
-#include <map>
#include <queue>
#include "base/callback.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/singleton.h"
-#include "base/process.h"
#include "base/threading/non_thread_safe.h"
#include "content/common/gpu/gpu_channel_manager.h"
#include "content/common/gpu/gpu_info.h"
#include "content/common/gpu_feature_flags.h"
#include "content/common/gpu_process_launch_causes.h"
#include "content/common/message_router.h"
-#include "ui/gfx/native_widget_types.h"
namespace gfx {
class Size;
}
-class GpuDataManager;
struct GPUCreateCommandBufferConfig;
struct GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params;
struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params;
@@ -60,14 +54,9 @@ class GpuProcessHostUIShim
public IPC::Channel::Sender,
public base::NonThreadSafe {
public:
- // Creates a new GpuProcessHostUIShim or gets one for a particular
- // renderer process, resulting in the launching of a GPU process if required.
- // Returns null on failure. It is not safe to store the pointer once control
- // has returned to the message loop as it can be destroyed. Instead store the
- // associated GPU host ID. A renderer ID of zero means the browser process.
- // This could return NULL if GPU access is not allowed (blacklisted).
- static GpuProcessHostUIShim* GetForRenderer(int renderer_id,
- content::CauseForGpuLaunch);
+ // Create a GpuProcessHostUIShim with the given ID. The object can be found
+ // using FromID with the same id.
+ static GpuProcessHostUIShim* Create(int host_id);
// Destroy the GpuProcessHostUIShim with the given host ID. This can only
// be called on the UI thread. Only the GpuProcessHost should destroy the
@@ -77,57 +66,17 @@ class GpuProcessHostUIShim
// Destroy all remaining GpuProcessHostUIShims.
static void DestroyAll();
- // The GPU process is launched asynchronously. If it launches successfully,
- // this function is called on the UI thread with the process handle. On
- // Windows, the UI shim takes ownership of the handle.
- static void NotifyGpuProcessLaunched(int host_id,
- base::ProcessHandle gpu_process);
-
static GpuProcessHostUIShim* FromID(int host_id);
- int host_id() const { return host_id_; }
// IPC::Channel::Sender implementation.
virtual bool Send(IPC::Message* msg);
- // Sends outstanding replies. This is only called
- // in error situations like the GPU process crashing -- but is necessary
- // to prevent the blocked clients from hanging.
- void SendOutstandingReplies();
-
// IPC::Channel::Listener implementation.
// The GpuProcessHost causes this to be called on the UI thread to
// dispatch the incoming messages from the GPU process, which are
// actually received on the IO thread.
virtual bool OnMessageReceived(const IPC::Message& message);
- typedef Callback3<const IPC::ChannelHandle&,
- base::ProcessHandle,
- const GPUInfo&>::Type
- EstablishChannelCallback;
-
- // Tells the GPU process to create a new channel for communication with a
- // renderer. Once the GPU process responds asynchronously with the IPC handle
- // and GPUInfo, we call the callback.
- void EstablishGpuChannel(
- int renderer_id, EstablishChannelCallback* callback);
-
- typedef Callback0::Type SynchronizeCallback;
-
- // Sends a reply message later when the next GpuHostMsg_SynchronizeReply comes
- // in.
- void Synchronize(SynchronizeCallback* callback);
-
- typedef Callback1<int32>::Type CreateCommandBufferCallback;
-
- // Tells the GPU process to create a new command buffer that draws into the
- // window associated with the given renderer.
- void CreateViewCommandBuffer(
- gfx::PluginWindowHandle compositing_surface,
- int32 render_view_id,
- int32 renderer_id,
- const GPUCreateCommandBufferConfig& init_params,
- CreateCommandBufferCallback* callback);
-
#if defined(OS_MACOSX)
// Notify the GPU process that an accelerated surface was destroyed.
void DidDestroyAcceleratedSurface(int renderer_id, int32 render_view_id);
@@ -137,36 +86,15 @@ class GpuProcessHostUIShim
static void SendToGpuHost(int host_id, IPC::Message* msg);
#endif
- // Sends a message to the browser process to collect the information from the
- // graphics card.
- void CollectGpuInfoAsynchronously();
-
- // Tells the GPU process to crash. Useful for testing.
- void SendAboutGpuCrash();
-
- // Tells the GPU process to let its main thread enter an infinite loop.
- // Useful for testing.
- void SendAboutGpuHang();
-
- // Can be called directly from the UI thread to log a message.
- void AddCustomLogMessage(int level, const std::string& header,
- const std::string& message);
-
private:
- explicit GpuProcessHostUIShim(int host_id, content::CauseForGpuLaunch);
+ explicit GpuProcessHostUIShim(int host_id);
virtual ~GpuProcessHostUIShim();
// Message handlers.
bool OnControlMessageReceived(const IPC::Message& message);
- void OnChannelEstablished(const IPC::ChannelHandle& channel_handle);
- void OnCommandBufferCreated(const int32 route_id);
- void OnDestroyCommandBuffer(gfx::PluginWindowHandle window,
- int32 renderer_id, int32 render_view_id);
- void OnGraphicsInfoCollected(const GPUInfo& gpu_info);
void OnLogMessage(int level, const std::string& header,
const std::string& message);
- void OnSynchronizeReply();
#if defined(OS_LINUX)
void OnResizeXID(unsigned long xid, gfx::Size size, IPC::Message* reply_msg);
#elif defined(OS_MACOSX)
@@ -181,39 +109,6 @@ class GpuProcessHostUIShim
// The serial number of the GpuProcessHost / GpuProcessHostUIShim pair.
int host_id_;
- // The handle for the GPU process or null if it is not known to be launched.
- base::ProcessHandle gpu_process_;
-
- // Cached pointer to the singleton for efficiency purpose.
- GpuDataManager* gpu_data_manager_;
-
- // These are the channel requests that we have already sent to
- // the GPU process, but haven't heard back about yet.
- std::queue<linked_ptr<EstablishChannelCallback> > channel_requests_;
-
- // The pending synchronization requests we need to reply to.
- std::queue<linked_ptr<SynchronizeCallback> > synchronize_requests_;
-
- // The pending create command buffer requests we need to reply to.
- std::queue<linked_ptr<CreateCommandBufferCallback> >
- create_command_buffer_requests_;
-
-#if defined(OS_LINUX)
- typedef std::pair<int32 /* renderer_id */,
- int32 /* render_view_id */> ViewID;
-
- // Encapsulates surfaces that we lock when creating view command buffers.
- // We release this lock once the command buffer (or associated GPU process)
- // is destroyed. This prevents the browser from destroying the surface
- // while the GPU process is drawing to it.
-
- // Multimap is used to simulate reference counting, see comment in
- // GpuProcessHostUIShim::CreateViewCommandBuffer.
- class SurfaceRef;
- typedef std::multimap<ViewID, linked_ptr<SurfaceRef> > SurfaceRefMap;
- SurfaceRefMap surface_refs_;
-#endif
-
// In single process and in process GPU mode, this references the
// GpuChannelManager or null otherwise. It must be called and deleted on the
// GPU thread.
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
index 3708e09..d8ef5e5 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1101,14 +1101,12 @@ void RenderWidgetHostViewMac::DeallocFakePluginWindowHandle(
// channel error.
if (render_widget_host_ &&
plugin_container_manager_.IsRootContainer(window)) {
- GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::GetForRenderer(
+ GpuProcessHost::SendOnIO(
render_widget_host_->process()->id(),
- content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH);
- if (ui_shim) {
- ui_shim->DidDestroyAcceleratedSurface(
- render_widget_host_->process()->id(),
- render_widget_host_->routing_id());
- }
+ content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
+ new GpuMsg_DestroyCommandBuffer(
+ render_widget_host_->process()->id(),
+ render_widget_host_->routing_id()));
}
plugin_container_manager_.DestroyFakePluginWindowHandle(window);
@@ -1214,39 +1212,6 @@ void RenderWidgetHostViewMac::HandleDelayedGpuViewHiding() {
}
}
-namespace {
-class BuffersSwappedAcknowledger : public Task {
- public:
- BuffersSwappedAcknowledger(
- int gpu_host_id,
- int renderer_id,
- int32 route_id,
- uint64 swap_buffers_count)
- : gpu_host_id_(gpu_host_id),
- renderer_id_(renderer_id),
- route_id_(route_id),
- swap_buffers_count_(swap_buffers_count) {
- }
-
- void Run() {
- GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
- if (!host)
- return;
-
- host->Send(new GpuMsg_AcceleratedSurfaceBuffersSwappedACK(
- renderer_id_, route_id_, swap_buffers_count_));
- }
-
- private:
- int gpu_host_id_;
- int renderer_id_;
- int32 route_id_;
- uint64 swap_buffers_count_;
-
- DISALLOW_COPY_AND_ASSIGN(BuffersSwappedAcknowledger);
-};
-} // anonymous namespace
-
void RenderWidgetHostViewMac::AcknowledgeSwapBuffers(
int renderer_id,
int32 route_id,
@@ -1279,11 +1244,11 @@ void RenderWidgetHostViewMac::AcknowledgeSwapBuffers(
route_id,
swap_buffers_count)));
} else {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- new BuffersSwappedAcknowledger(
- gpu_host_id, renderer_id, route_id, swap_buffers_count));
+ GpuProcessHost::SendOnIO(
+ gpu_host_id,
+ content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH,
+ new GpuMsg_AcceleratedSurfaceBuffersSwappedACK(
+ renderer_id, route_id, swap_buffers_count));
}
}
diff --git a/chrome/browser/web_resource/gpu_blacklist_updater.cc b/chrome/browser/web_resource/gpu_blacklist_updater.cc
index 3c5897be..800bb38 100644
--- a/chrome/browser/web_resource/gpu_blacklist_updater.cc
+++ b/chrome/browser/web_resource/gpu_blacklist_updater.cc
@@ -4,15 +4,21 @@
#include "chrome/browser/web_resource/gpu_blacklist_updater.h"
+#include "base/logging.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/gpu_data_manager.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
#include "content/browser/browser_thread.h"
+#include "content/browser/gpu_blacklist.h"
#include "content/common/notification_type.h"
+#include "grit/browser_resources.h"
+#include "ui/base/resource/resource_bundle.h"
namespace {
@@ -35,7 +41,18 @@ GpuBlacklistUpdater::GpuBlacklistUpdater()
NotificationType::NOTIFICATION_TYPE_COUNT,
prefs::kGpuBlacklistUpdate,
kStartGpuBlacklistFetchDelay,
- kCacheUpdateDelay) {
+ kCacheUpdateDelay),
+ gpu_blacklist_cache_(NULL) {
+ PrefService* local_state = g_browser_process->local_state();
+ // If we bring up chrome normally, prefs should never be NULL; however, we
+ // we handle the case where local_state == NULL for certain tests.
+ if (local_state) {
+ local_state->RegisterDictionaryPref(prefs::kGpuBlacklist);
+ gpu_blacklist_cache_ = local_state->GetDictionary(prefs::kGpuBlacklist);
+ DCHECK(gpu_blacklist_cache_);
+ }
+
+ LoadGpuBlacklist();
}
GpuBlacklistUpdater::~GpuBlacklistUpdater() { }
@@ -47,5 +64,62 @@ void GpuBlacklistUpdater::Unpack(const DictionaryValue& parsed_json) {
DCHECK(gpu_blacklist_cache);
gpu_blacklist_cache->Clear();
gpu_blacklist_cache->MergeDictionary(&parsed_json);
+
+ LoadGpuBlacklist();
}
+void GpuBlacklistUpdater::LoadGpuBlacklist() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ scoped_ptr<GpuBlacklist> gpu_blacklist;
+ // We first load it from the browser resources, and then check if the cached
+ // version is more up-to-date.
+ static const base::StringPiece gpu_blacklist_json(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_GPU_BLACKLIST));
+ chrome::VersionInfo version_info;
+ std::string chrome_version_string =
+ version_info.is_valid() ? version_info.Version() : "0";
+ gpu_blacklist.reset(new GpuBlacklist(chrome_version_string));
+ if (!gpu_blacklist->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true))
+ return;
+
+ uint16 version_major, version_minor;
+ bool succeed = gpu_blacklist->GetVersion(&version_major, &version_minor);
+ DCHECK(succeed);
+ VLOG(1) << "Using software rendering list version "
+ << version_major << "." << version_minor;
+
+ if (gpu_blacklist_cache_) {
+ uint16 cached_version_major, cached_version_minor;
+ if (GpuBlacklist::GetVersion(*gpu_blacklist_cache_,
+ &cached_version_major,
+ &cached_version_minor)) {
+ if (gpu_blacklist.get() != NULL) {
+ uint16 current_version_major, current_version_minor;
+ if (gpu_blacklist->GetVersion(&current_version_major,
+ &current_version_minor) &&
+ (cached_version_major > current_version_major ||
+ (cached_version_major == current_version_major &&
+ cached_version_minor > current_version_minor))) {
+ chrome::VersionInfo version_info;
+ std::string chrome_version_string =
+ version_info.is_valid() ? version_info.Version() : "0";
+ GpuBlacklist* updated_list = new GpuBlacklist(chrome_version_string);
+ if (updated_list->LoadGpuBlacklist(*gpu_blacklist_cache_, true)) {
+ gpu_blacklist.reset(updated_list);
+ VLOG(1) << "Using software rendering list version "
+ << cached_version_major << "." << cached_version_minor;
+ } else {
+ delete updated_list;
+ }
+ }
+ }
+ }
+ }
+
+ // Need to initialize GpuDataManager to load the current GPU blacklist,
+ // collect preliminary GPU info, and run through GPU blacklist.
+ GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance();
+ gpu_data_manager->UpdateGpuBlacklist(gpu_blacklist.release());
+}
diff --git a/chrome/browser/web_resource/gpu_blacklist_updater.h b/chrome/browser/web_resource/gpu_blacklist_updater.h
index 136fd72..21ccdf9 100644
--- a/chrome/browser/web_resource/gpu_blacklist_updater.h
+++ b/chrome/browser/web_resource/gpu_blacklist_updater.h
@@ -8,6 +8,9 @@
#include "chrome/browser/web_resource/web_resource_service.h"
+class DictionaryValue;
+class GpuBlacklist;
+
class GpuBlacklistUpdater
: public WebResourceService {
public:
@@ -21,6 +24,12 @@ class GpuBlacklistUpdater
virtual void Unpack(const DictionaryValue& parsed_json);
+ void LoadGpuBlacklist();
+
+ // This is the version cached in local state that's automatically updated
+ // from the web.
+ const DictionaryValue* gpu_blacklist_cache_;
+
DISALLOW_COPY_AND_ASSIGN(GpuBlacklistUpdater);
};