diff options
author | ccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-18 03:11:41 +0000 |
---|---|---|
committer | ccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-18 03:11:41 +0000 |
commit | fb246af3f30a1775ffbcf4bdcf6bb347cd5382d1 (patch) | |
tree | 96b7c08eece7a503bffeff78a5a05e84fa8e82da | |
parent | 29ba4e8e183d317620e75fc54f46c96e3ce7c061 (diff) | |
download | chromium_src-fb246af3f30a1775ffbcf4bdcf6bb347cd5382d1.zip chromium_src-fb246af3f30a1775ffbcf4bdcf6bb347cd5382d1.tar.gz chromium_src-fb246af3f30a1775ffbcf4bdcf6bb347cd5382d1.tar.bz2 |
Add GPU memory tab to the task manager.
Each renderer process will have all of the resources that the GPU process has allocated on its behalf (including WebGL resources, compositor resources, and the backbuffer) included in its printed total.
The GPU process will have the all resources currently allocated by the GPU process in its column. This will be approximately the sum of all other rows. The row for the GPU process is printed in ()s to draw attention to the fact that its size includes duplicates from other processes' sizes.
I happy this UI scheme (having played with a few), but I'd wider feedback.
Note that we do not account for swapchains or for backbuffers allocated by the browser process, so those allocations are not counted in the total.
BUG=140157
Review URL: https://chromiumcodereview.appspot.com/10854076
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152233 0039d316-1c4b-4281-b951-d872f2087c98
33 files changed, 445 insertions, 16 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index facfede..f756418 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -4140,6 +4140,9 @@ Public Exponent (<ph name="PUBLIC_EXPONENT_NUM_BITS">$3<ex>24</ex></ph> bits): <message name="IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN" desc="Task manager WebCore CSS cache size column."> CSS cache </message> + <message name="IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN" desc="The text of the video memory usage column"> + GPU Memory + </message> <message name="IDS_TASK_MANAGER_FPS_COLUMN" desc="The text of the FPS column"> FPS </message> @@ -4202,6 +4205,9 @@ Public Exponent (<ph name="PUBLIC_EXPONENT_NUM_BITS">$3<ex>24</ex></ph> bits): <message name="IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN" desc="Task manager WebCore CSS cache size column."> CSS Cache </message> + <message name="IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN" desc="The text of the video memory usage column"> + GPU Memory + </message> <message name="IDS_TASK_MANAGER_FPS_COLUMN" desc="The text of the FPS column"> FPS </message> diff --git a/chrome/browser/component_updater/swiftshader_component_installer.cc b/chrome/browser/component_updater/swiftshader_component_installer.cc index f24828f..da38e19 100644 --- a/chrome/browser/component_updater/swiftshader_component_installer.cc +++ b/chrome/browser/component_updater/swiftshader_component_installer.cc @@ -165,6 +165,9 @@ class UpdateChecker : public content::GpuDataManagerObserver { explicit UpdateChecker(ComponentUpdateService* cus); virtual void OnGpuInfoUpdate() OVERRIDE; + virtual void OnVideoMemoryUsageStatsUpdate( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) + OVERRIDE {} private: ComponentUpdateService* cus_; diff --git a/chrome/browser/gpu_blacklist.h b/chrome/browser/gpu_blacklist.h index a1eb385..c4c72c7 100644 --- a/chrome/browser/gpu_blacklist.h +++ b/chrome/browser/gpu_blacklist.h @@ -385,6 +385,8 @@ class GpuBlacklist : public content::GpuDataManagerObserver { // GpuDataManager::Observer implementation. virtual void OnGpuInfoUpdate() OVERRIDE; + virtual void OnVideoMemoryUsageStatsUpdate( + const content::GPUVideoMemoryUsageStats& video_memory) OVERRIDE {} // Returns the number of entries. This is only for tests. size_t num_entries() const; diff --git a/chrome/browser/gpu_feature_checker.h b/chrome/browser/gpu_feature_checker.h index dd54f32c..8e1d0ac 100644 --- a/chrome/browser/gpu_feature_checker.h +++ b/chrome/browser/gpu_feature_checker.h @@ -29,6 +29,9 @@ class GPUFeatureChecker : public base::RefCountedThreadSafe<GPUFeatureChecker>, // content::GpuDataManagerObserver virtual void OnGpuInfoUpdate() OVERRIDE; + virtual void OnVideoMemoryUsageStatsUpdate( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) + OVERRIDE {} private: friend class base::RefCountedThreadSafe<GPUFeatureChecker>; diff --git a/chrome/browser/resources/task_manager/defines.js b/chrome/browser/resources/task_manager/defines.js index e66791e..51141fb 100644 --- a/chrome/browser/resources/task_manager/defines.js +++ b/chrome/browser/resources/task_manager/defines.js @@ -30,6 +30,7 @@ var DEFAULT_COLUMNS = [ ['webCoreScriptsCacheSize', 'webcoreScriptsCacheColumn', 120, false], ['webCoreCSSCacheSize', 'webcoreCSSCacheColumn', 120, false], ['fps', 'fpsColumn', 50, true], + ['videoMemory', 'videoMemoryColumn', 80, false], ['sqliteMemoryUsed', 'sqliteMemoryUsedColumn', 80, false], ['goatsTeleported', 'goatsTeleportedColumn', 80, false], ['v8MemoryAllocatedSize', 'javascriptMemoryAllocatedColumn', 120, false], diff --git a/chrome/browser/resources/task_manager/main.js b/chrome/browser/resources/task_manager/main.js index 3c0ae98..436089d 100644 --- a/chrome/browser/resources/task_manager/main.js +++ b/chrome/browser/resources/task_manager/main.js @@ -115,8 +115,8 @@ TaskManager.prototype = { var COLUMNS_SORTED_BY_VALUE = [ 'cpuUsage', 'physicalMemory', 'sharedMemory', 'privateMemory', 'networkUsage', 'webCoreImageCacheSize', 'webCoreScriptsCacheSize', - 'webCoreCSSCacheSize', 'fps', 'sqliteMemoryUsed', 'goatsTeleported', - 'v8MemoryAllocatedSize']; + 'webCoreCSSCacheSize', 'fps', 'videoMemory', 'sqliteMemoryUsed', + 'goatsTeleported', 'v8MemoryAllocatedSize']; for (var i = 0; i < DEFAULT_COLUMNS.length; i++) { var columnId = DEFAULT_COLUMNS[i][0]; diff --git a/chrome/browser/task_manager/task_manager.cc b/chrome/browser/task_manager/task_manager.cc index f089752..241e8ca 100644 --- a/chrome/browser/task_manager/task_manager.cc +++ b/chrome/browser/task_manager/task_manager.cc @@ -31,6 +31,8 @@ #include "chrome/common/view_type.h" #include "content/public/browser/browser_child_process_host.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/gpu_data_manager.h" +#include "content/public/browser/gpu_data_manager_observer.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/resource_request_info.h" #include "content/public/browser/web_contents.h" @@ -83,7 +85,8 @@ string16 FormatStatsSize(const WebKit::WebCache::ResourceTypeStat& stat) { //////////////////////////////////////////////////////////////////////////////// TaskManagerModel::TaskManagerModel(TaskManager* task_manager) - : update_requests_(0), + : pending_video_memory_usage_stats_update_(false), + update_requests_(0), listen_requests_(0), update_state_(IDLE), goat_salt_(base::RandUint64()), @@ -255,6 +258,25 @@ string16 TaskManagerModel::GetResourceWebCoreCSSCacheSize( return FormatStatsSize(stats.cssStyleSheets); } +string16 TaskManagerModel::GetResourceVideoMemory(int index) const { + CHECK_LT(index, ResourceCount()); + + bool result; + size_t video_memory; + bool has_duplicates; + result = GetVideoMemory(index, &video_memory, &has_duplicates); + + if (!result || !video_memory) { + return ASCIIToUTF16("N/A"); + } else if (has_duplicates) { + return ASCIIToUTF16("(") + + GetMemCellText(video_memory) + + ASCIIToUTF16(")"); + } else { + return GetMemCellText(video_memory); + } +} + string16 TaskManagerModel::GetResourceFPS( int index) const { CHECK_LT(index, ResourceCount()); @@ -448,6 +470,13 @@ int TaskManagerModel::CompareValues(int row1, int row2, int col_id) const { } else if (col_id == IDS_TASK_MANAGER_FPS_COLUMN) { return ValueCompare<float>(resources_[row1]->GetFPS(), resources_[row2]->GetFPS()); + } else if (col_id == IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN) { + size_t value1; + size_t value2; + bool has_duplicates; + if (!GetVideoMemory(row1, &value1, &has_duplicates)) value1 = 0; + if (!GetVideoMemory(row2, &value2, &has_duplicates)) value2 = 0; + return ValueCompare<size_t>(value1, value2); } else if (col_id == IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN) { return ValueCompare<int>(GetGoatsTeleported(row1), GetGoatsTeleported(row2)); @@ -567,6 +596,22 @@ bool TaskManagerModel::GetWebCoreCacheStats( return true; } +bool TaskManagerModel::GetVideoMemory( + int index, size_t* video_memory, bool* has_duplicates) const { + TaskManager::Resource* resource = resources_[index]; + base::ProcessId pid = base::GetProcId(resource->GetProcess()); + content::GPUVideoMemoryUsageStats::ProcessMap::const_iterator i = + video_memory_usage_stats_.process_map.find(pid); + if (i == video_memory_usage_stats_.process_map.end()) { + *video_memory = 0; + *has_duplicates = false; + return false; + } + *video_memory = (*i).second.video_memory; + *has_duplicates = (*i).second.has_duplicates; + return true; +} + bool TaskManagerModel::GetFPS(int index, float* result) const { *result = 0; if (!resources_[index]->ReportsFPS()) @@ -885,6 +930,13 @@ void TaskManagerModel::NotifyFPS(base::ProcessId renderer_id, } } +void TaskManagerModel::NotifyVideoMemoryUsageStats( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) { + DCHECK(pending_video_memory_usage_stats_update_); + video_memory_usage_stats_ = video_memory_usage_stats; + pending_video_memory_usage_stats_update_ = false; +} + void TaskManagerModel::NotifyV8HeapStats(base::ProcessId renderer_id, size_t v8_memory_allocated, size_t v8_memory_used) { @@ -896,6 +948,50 @@ void TaskManagerModel::NotifyV8HeapStats(base::ProcessId renderer_id, } } +class TaskManagerModelGpuDataManagerObserver + : public content::GpuDataManagerObserver { + public: + + TaskManagerModelGpuDataManagerObserver() { + content::GpuDataManager::GetInstance()->AddObserver(this); + } + + virtual ~TaskManagerModelGpuDataManagerObserver() { + content::GpuDataManager::GetInstance()->RemoveObserver(this); + } + + static void NotifyVideoMemoryUsageStats( + content::GPUVideoMemoryUsageStats video_memory_usage_stats) { + TaskManager::GetInstance()->model()->NotifyVideoMemoryUsageStats( + video_memory_usage_stats); + } + + virtual void OnGpuInfoUpdate() OVERRIDE {} + + virtual void OnVideoMemoryUsageStatsUpdate( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) + OVERRIDE { + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { + NotifyVideoMemoryUsageStats(video_memory_usage_stats); + } else { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, base::Bind( + &TaskManagerModelGpuDataManagerObserver:: + NotifyVideoMemoryUsageStats, + video_memory_usage_stats)); + } + delete this; + } +}; + +void TaskManagerModel::RefreshVideoMemoryUsageStats() +{ + if (pending_video_memory_usage_stats_update_) return; + pending_video_memory_usage_stats_update_ = true; + new TaskManagerModelGpuDataManagerObserver; + content::GpuDataManager::GetInstance()->RequestVideoMemoryUsageStatsUpdate(); +} + void TaskManagerModel::Refresh() { DCHECK_NE(IDLE, update_state_); @@ -928,6 +1024,9 @@ void TaskManagerModel::Refresh() { // Clear the memory values so they can be querried lazily. memory_usage_map_.clear(); + // Send a request to refresh GPU memory consumption values + RefreshVideoMemoryUsageStats(); + // Compute the new network usage values. displayed_network_usage_map_.clear(); base::TimeDelta update_time = diff --git a/chrome/browser/task_manager/task_manager.h b/chrome/browser/task_manager/task_manager.h index 640d7a6..fc47ddc 100644 --- a/chrome/browser/task_manager/task_manager.h +++ b/chrome/browser/task_manager/task_manager.h @@ -18,6 +18,7 @@ #include "base/string16.h" #include "base/timer.h" #include "chrome/browser/renderer_host/web_cache_manager.h" +#include "content/public/common/gpu_memory_stats.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h" class TaskManagerModel; @@ -312,6 +313,7 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> { string16 GetResourceWebCoreImageCacheSize(int index) const; string16 GetResourceWebCoreScriptsCacheSize(int index) const; string16 GetResourceWebCoreCSSCacheSize(int index) const; + string16 GetResourceVideoMemory(int index) const; string16 GetResourceFPS(int index) const; string16 GetResourceSqliteMemoryUsed(int index) const; string16 GetResourceGoatsTeleported(int index) const; @@ -336,6 +338,11 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> { bool GetWebCoreCacheStats(int index, WebKit::WebCache::ResourceTypeStats* result) const; + // Gets the GPU memory allocated of the given page. + bool GetVideoMemory(int index, + size_t* video_memory, + bool* has_duplicates) const; + // Gets the fps of the given page. Return false if the resource for the given // row isn't a renderer. bool GetFPS(int index, float* result) const; @@ -437,6 +444,9 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> { int routing_id, float fps); + void NotifyVideoMemoryUsageStats( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats); + void NotifyV8HeapStats(base::ProcessId renderer_id, size_t v8_memory_allocated, size_t v8_memory_used); @@ -492,6 +502,8 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> { // Updates the values for all rows. void Refresh(); + void RefreshVideoMemoryUsageStats(); + void AddItem(TaskManager::Resource* resource, bool notify_table); void RemoveItem(TaskManager::Resource* resource); @@ -556,6 +568,10 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> { // A map that contains the CPU usage (in %) for a process since last refresh. CPUUsageMap cpu_usage_map_; + // A map that contains the video memory usage for a process + content::GPUVideoMemoryUsageStats video_memory_usage_stats_; + bool pending_video_memory_usage_stats_update_; + // A map that contains the private/shared memory usage of the process. We // cache this because the same APIs are called on linux and windows, and // because the linux call takes >10ms to complete. This cache is cleared on diff --git a/chrome/browser/ui/cocoa/task_manager_mac.mm b/chrome/browser/ui/cocoa/task_manager_mac.mm index 3f622c1..dcc571d 100644 --- a/chrome/browser/ui/cocoa/task_manager_mac.mm +++ b/chrome/browser/ui/cocoa/task_manager_mac.mm @@ -54,6 +54,8 @@ const struct ColumnWidth { arraysize("2000.0K (2000.0 live)") * kCharWidth, -1 }, { IDS_TASK_MANAGER_FPS_COLUMN, arraysize("100") * kCharWidth, -1 }, + { IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN, + arraysize("2000.0K") * kCharWidth, -1 }, { IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN, arraysize("800 kB") * kCharWidth, -1 }, { IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN, @@ -305,6 +307,7 @@ class SortHelper { visible:NO]; [self addColumnWithId:IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN visible:NO]; [self addColumnWithId:IDS_TASK_MANAGER_FPS_COLUMN visible:YES]; + [self addColumnWithId:IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN visible:NO]; [self addColumnWithId:IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN visible:NO]; [self addColumnWithId:IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN visible:NO]; @@ -488,6 +491,9 @@ class SortHelper { case IDS_TASK_MANAGER_FPS_COLUMN: return base::SysUTF16ToNSString(model_->GetResourceFPS(row)); + case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN: + return base::SysUTF16ToNSString(model_->GetResourceVideoMemory(row)); + case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN: if (!model_->IsResourceFirstInGroup(row)) return @""; diff --git a/chrome/browser/ui/gtk/task_manager_gtk.cc b/chrome/browser/ui/gtk/task_manager_gtk.cc index 7a93341..792308d 100644 --- a/chrome/browser/ui/gtk/task_manager_gtk.cc +++ b/chrome/browser/ui/gtk/task_manager_gtk.cc @@ -67,6 +67,7 @@ enum TaskManagerColumn { kTaskManagerWebCoreImageCache, kTaskManagerWebCoreScriptsCache, kTaskManagerWebCoreCssCache, + kTaskManagerVideoMemory, kTaskManagerFPS, kTaskManagerSqliteMemoryUsed, kTaskManagerGoatsTeleported, @@ -104,6 +105,8 @@ TaskManagerColumn TaskManagerResourceIDToColumnID(int id) { return kTaskManagerWebCoreScriptsCache; case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN: return kTaskManagerWebCoreCssCache; + case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN: + return kTaskManagerVideoMemory; case IDS_TASK_MANAGER_FPS_COLUMN: return kTaskManagerFPS; case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN: @@ -140,6 +143,8 @@ int TaskManagerColumnIDToResourceID(int id) { return IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN; case kTaskManagerWebCoreCssCache: return IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN; + case kTaskManagerVideoMemory: + return IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN; case kTaskManagerFPS: return IDS_TASK_MANAGER_FPS_COLUMN; case kTaskManagerSqliteMemoryUsed: @@ -579,7 +584,7 @@ void TaskManagerGtk::CreateTaskManagerTreeview() { process_list_ = gtk_list_store_new(kTaskManagerColumnCount, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_COLOR); // Support sorting on all columns. @@ -619,6 +624,9 @@ void TaskManagerGtk::CreateTaskManagerTreeview() { kTaskManagerWebCoreCssCache, CompareWebCoreCssCache, this, NULL); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(process_list_sort_), + kTaskManagerVideoMemory, + CompareVideoMemory, this, NULL); + gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(process_list_sort_), kTaskManagerFPS, CompareFPS, this, NULL); gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(process_list_sort_), @@ -643,6 +651,7 @@ void TaskManagerGtk::CreateTaskManagerTreeview() { TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN); TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN); + TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN); TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_FPS_COLUMN); TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN); TreeViewInsertColumn(treeview_, IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN); @@ -655,6 +664,7 @@ void TaskManagerGtk::CreateTaskManagerTreeview() { TreeViewColumnSetVisible(treeview_, kTaskManagerWebCoreImageCache, false); TreeViewColumnSetVisible(treeview_, kTaskManagerWebCoreScriptsCache, false); TreeViewColumnSetVisible(treeview_, kTaskManagerWebCoreCssCache, false); + TreeViewColumnSetVisible(treeview_, kTaskManagerVideoMemory, false); TreeViewColumnSetVisible(treeview_, kTaskManagerSqliteMemoryUsed, false); TreeViewColumnSetVisible(treeview_, kTaskManagerGoatsTeleported, false); @@ -716,6 +726,9 @@ std::string TaskManagerGtk::GetModelText(int row, int col_id) { case IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN: return UTF16ToUTF8(model_->GetResourceWebCoreCSSCacheSize(row)); + case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN: + return UTF16ToUTF8(model_->GetResourceVideoMemory(row)); + case IDS_TASK_MANAGER_FPS_COLUMN: return UTF16ToUTF8(model_->GetResourceFPS(row)); @@ -778,6 +791,9 @@ void TaskManagerGtk::SetRowDataFromModel(int row, GtkTreeIter* iter) { wk_css_cache = GetModelText(row, IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN); } + std::string video_memory; + if (TreeViewColumnIsVisible(treeview_, kTaskManagerVideoMemory)) + video_memory = GetModelText(row, IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN); std::string fps; if (TreeViewColumnIsVisible(treeview_, kTaskManagerFPS)) fps = GetModelText(row, IDS_TASK_MANAGER_FPS_COLUMN); @@ -805,6 +821,7 @@ void TaskManagerGtk::SetRowDataFromModel(int row, GtkTreeIter* iter) { kTaskManagerWebCoreImageCache, wk_img_cache.c_str(), kTaskManagerWebCoreScriptsCache, wk_scripts_cache.c_str(), kTaskManagerWebCoreCssCache, wk_css_cache.c_str(), + kTaskManagerVideoMemory, video_memory.c_str(), kTaskManagerFPS, fps.c_str(), kTaskManagerSqliteMemoryUsed, sqlite_memory.c_str(), kTaskManagerGoatsTeleported, goats.c_str(), diff --git a/chrome/browser/ui/gtk/task_manager_gtk.h b/chrome/browser/ui/gtk/task_manager_gtk.h index 677bc93..7df063d 100644 --- a/chrome/browser/ui/gtk/task_manager_gtk.h +++ b/chrome/browser/ui/gtk/task_manager_gtk.h @@ -185,6 +185,13 @@ class TaskManagerGtk : public TaskManagerModelObserver { CompareImpl(model, a, b, IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN); } + // Video memory sorting callback. + static gint CompareVideoMemory(GtkTreeModel* model, GtkTreeIter* a, + GtkTreeIter* b, gpointer task_manager) { + return reinterpret_cast<TaskManagerGtk*>(task_manager)-> + CompareImpl(model, a, b, IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN); + } + // FPS sorting callback. static gint CompareFPS(GtkTreeModel* model, GtkTreeIter* a, GtkTreeIter* b, gpointer task_manager) { diff --git a/chrome/browser/ui/views/task_manager_view.cc b/chrome/browser/ui/views/task_manager_view.cc index 164fa85..00a50d2 100644 --- a/chrome/browser/ui/views/task_manager_view.cc +++ b/chrome/browser/ui/views/task_manager_view.cc @@ -151,6 +151,9 @@ string16 TaskManagerTableModel::GetText(int row, int col_id) { case IDS_TASK_MANAGER_FPS_COLUMN: return model_->GetResourceFPS(row); + case IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN: + return model_->GetResourceVideoMemory(row); + case IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN: if (!model_->IsResourceFirstInGroup(row)) return string16(); @@ -426,6 +429,8 @@ void TaskManagerView::Init() { columns_.back().sortable = true; columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_FPS_COLUMN, ui::TableColumn::RIGHT, -1, 0)); + columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN, + ui::TableColumn::RIGHT, -1, 0)); columns_.back().sortable = true; columns_.push_back(ui::TableColumn(IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN, ui::TableColumn::RIGHT, -1, 0)); @@ -449,6 +454,8 @@ void TaskManagerView::Init() { false); tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN, false); + tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN, + false); tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN, false); tab_table_->SetColumnVisibility( diff --git a/chrome/browser/ui/webui/flash_ui.cc b/chrome/browser/ui/webui/flash_ui.cc index 6045026..21f5d62 100644 --- a/chrome/browser/ui/webui/flash_ui.cc +++ b/chrome/browser/ui/webui/flash_ui.cc @@ -91,6 +91,9 @@ class FlashDOMHandler : public WebUIMessageHandler, // GpuDataManager::Observer implementation. virtual void OnGpuInfoUpdate() OVERRIDE; + virtual void OnVideoMemoryUsageStatsUpdate( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) + OVERRIDE {} // Callback for the "requestFlashInfo" message. void HandleRequestFlashInfo(const ListValue* args); diff --git a/chrome/browser/ui/webui/gpu_internals_ui.cc b/chrome/browser/ui/webui/gpu_internals_ui.cc index c55d267..9340e2e 100644 --- a/chrome/browser/ui/webui/gpu_internals_ui.cc +++ b/chrome/browser/ui/webui/gpu_internals_ui.cc @@ -68,6 +68,9 @@ class GpuMessageHandler // GpuDataManagerObserver implementation. virtual void OnGpuInfoUpdate() OVERRIDE; + virtual void OnVideoMemoryUsageStatsUpdate( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) + OVERRIDE {} // CrashUploadList::Delegate implemenation. virtual void OnCrashListAvailable() OVERRIDE; diff --git a/chrome/browser/ui/webui/task_manager/task_manager_handler.cc b/chrome/browser/ui/webui/task_manager/task_manager_handler.cc index 35e0ce5..08ea4bb 100644 --- a/chrome/browser/ui/webui/task_manager/task_manager_handler.cc +++ b/chrome/browser/ui/webui/task_manager/task_manager_handler.cc @@ -104,6 +104,18 @@ Value* CreateColumnValue(const TaskManagerModel* tm, tm->GetFPS(i, &fps); return Value::CreateDoubleValue(fps); } + if (column_name == "videoMemory") + return Value::CreateStringValue(tm->GetResourceVideoMemory(i)); + if (column_name == "videoMemoryValue") { + size_t video_memory; + bool has_duplicates; + double value; + if (tm->GetVideoMemory(i, &video_memory, &has_duplicates)) + value = static_cast<double>(video_memory); + else + value = 0; + return Value::CreateDoubleValue(value); + } if (column_name == "sqliteMemoryUsed") return Value::CreateStringValue(tm->GetResourceSqliteMemoryUsed(i)); if (column_name == "sqliteMemoryUsedValue") { @@ -170,6 +182,7 @@ const ColumnType kColumnsList[] = { {"profileName", false, true}, {"networkUsage", true, true}, {"fps", true, true}, + {"videoMemory", true, false}, {"goatsTeleported", true, true}, {"canInspect", false, true}, {"canActivate", false, true} diff --git a/chrome/browser/ui/webui/task_manager/task_manager_ui.cc b/chrome/browser/ui/webui/task_manager/task_manager_ui.cc index a696f98..69f5734 100644 --- a/chrome/browser/ui/webui/task_manager/task_manager_ui.cc +++ b/chrome/browser/ui/webui/task_manager/task_manager_ui.cc @@ -55,6 +55,8 @@ ChromeWebUIDataSource* CreateTaskManagerUIHTMLSource() { IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN); source->AddLocalizedString("webcoreCSSCacheColumn", IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN); + source->AddLocalizedString("videoMemoryColumn", + IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN); source->AddLocalizedString("fpsColumn", IDS_TASK_MANAGER_FPS_COLUMN); source->AddLocalizedString("sqliteMemoryUsedColumn", IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN); diff --git a/chrome/browser/ui/webui/tracing_ui.cc b/chrome/browser/ui/webui/tracing_ui.cc index 3808fb2..72effee 100644 --- a/chrome/browser/ui/webui/tracing_ui.cc +++ b/chrome/browser/ui/webui/tracing_ui.cc @@ -90,6 +90,8 @@ class TracingMessageHandler // GpuDataManagerObserver implementation. virtual void OnGpuInfoUpdate() OVERRIDE; + virtual void OnVideoMemoryUsageStatsUpdate( + const content::GPUVideoMemoryUsageStats& video_memory) OVERRIDE {} // Messages. void OnTracingControllerInitialized(const ListValue* list); diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc index 8c05064..d45b4d8 100644 --- a/content/browser/gpu/gpu_data_manager_impl.cc +++ b/content/browser/gpu/gpu_data_manager_impl.cc @@ -118,6 +118,13 @@ content::GPUInfo GpuDataManagerImpl::GetGPUInfo() const { return gpu_info_; } +void GpuDataManagerImpl::RequestVideoMemoryUsageStatsUpdate() { + GpuProcessHost::SendOnIO( + GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, + content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, + new GpuMsg_GetVideoMemoryUsageStats()); +} + void GpuDataManagerImpl::AddLogMessage(Value* msg) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); log_messages_.Append(msg); @@ -298,6 +305,12 @@ void GpuDataManagerImpl::NotifyGpuInfoUpdate() { observer_list_->Notify(&GpuDataManagerObserver::OnGpuInfoUpdate); } +void GpuDataManagerImpl::UpdateVideoMemoryUsageStats( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) { + observer_list_->Notify(&GpuDataManagerObserver::OnVideoMemoryUsageStatsUpdate, + video_memory_usage_stats); +} + void GpuDataManagerImpl::UpdateGpuFeatureType( GpuFeatureType embedder_feature_type) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h index 7104ed0..4c3c238 100644 --- a/content/browser/gpu/gpu_data_manager_impl.h +++ b/content/browser/gpu/gpu_data_manager_impl.h @@ -17,6 +17,7 @@ #include "base/values.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/common/gpu_info.h" +#include "content/public/common/gpu_memory_stats.h" class CommandLine; @@ -33,6 +34,7 @@ class CONTENT_EXPORT GpuDataManagerImpl virtual bool GpuAccessAllowed() OVERRIDE; virtual void RequestCompleteGpuInfoIfNeeded() OVERRIDE; virtual bool IsCompleteGPUInfoAvailable() const OVERRIDE; + virtual void RequestVideoMemoryUsageStatsUpdate() OVERRIDE; virtual bool ShouldUseSoftwareRendering() OVERRIDE; virtual void RegisterSwiftShaderPath(const FilePath& path) OVERRIDE; virtual const base::ListValue& GetLogMessages() const OVERRIDE; @@ -43,6 +45,9 @@ class CONTENT_EXPORT GpuDataManagerImpl // Only update if the current GPUInfo is not finalized. void UpdateGpuInfo(const content::GPUInfo& gpu_info); + void UpdateVideoMemoryUsageStats( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats); + void AddLogMessage(Value* msg); // Insert disable-feature switches corresponding to preliminary gpu feature diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc index beee4f3..323aa0c 100644 --- a/content/browser/gpu/gpu_process_host_ui_shim.cc +++ b/content/browser/gpu/gpu_process_host_ui_shim.cc @@ -207,7 +207,8 @@ bool GpuProcessHostUIShim::OnControlMessageReceived( OnAcceleratedSurfaceNew) IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceRelease, OnAcceleratedSurfaceRelease) - + IPC_MESSAGE_HANDLER(GpuHostMsg_VideoMemoryUsageStats, + OnVideoMemoryUsageStatsReceived); #if defined(TOOLKIT_GTK) || defined(OS_WIN) IPC_MESSAGE_HANDLER(GpuHostMsg_ResizeView, OnResizeView) #endif @@ -367,3 +368,10 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceRelease( return; view->AcceleratedSurfaceRelease(params.identifier); } + +void GpuProcessHostUIShim::OnVideoMemoryUsageStatsReceived( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats) { + GpuDataManagerImpl::GetInstance()->UpdateVideoMemoryUsageStats( + video_memory_usage_stats); +} + diff --git a/content/browser/gpu/gpu_process_host_ui_shim.h b/content/browser/gpu/gpu_process_host_ui_shim.h index 5f3f4c8..f313863 100644 --- a/content/browser/gpu/gpu_process_host_ui_shim.h +++ b/content/browser/gpu/gpu_process_host_ui_shim.h @@ -20,6 +20,7 @@ #include "content/common/content_export.h" #include "content/common/message_router.h" #include "content/public/common/gpu_info.h" +#include "content/public/common/gpu_memory_stats.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" @@ -100,6 +101,8 @@ class GpuProcessHostUIShim const GpuHostMsg_AcceleratedSurfaceNew_Params& params); void OnAcceleratedSurfaceRelease( const GpuHostMsg_AcceleratedSurfaceRelease_Params& params); + void OnVideoMemoryUsageStatsReceived( + const content::GPUVideoMemoryUsageStats& video_memory_usage_stats); // The serial number of the GpuProcessHost / GpuProcessHostUIShim pair. int host_id_; diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index 15302bf..4b0e8d0 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -15,6 +15,7 @@ #include "content/common/gpu/gpu_channel_manager.h" #include "content/common/gpu/gpu_command_buffer_stub.h" #include "content/common/gpu/gpu_memory_manager.h" +#include "content/common/gpu/gpu_memory_tracking.h" #include "content/common/gpu/gpu_messages.h" #include "content/common/gpu/gpu_watchdog.h" #include "content/common/gpu/image_transport_surface.h" @@ -38,15 +39,22 @@ namespace { // ContextGroup's memory type managers and the GpuMemoryManager class. class GpuCommandBufferMemoryTracker : public gpu::gles2::MemoryTracker { public: - GpuCommandBufferMemoryTracker(GpuMemoryManager* gpu_memory_manager) - : gpu_memory_manager_(gpu_memory_manager) {} + GpuCommandBufferMemoryTracker(GpuChannel* channel) { + gpu_memory_manager_tracking_group_ = new GpuMemoryTrackingGroup( + channel->renderer_pid(), + channel->gpu_channel_manager()->gpu_memory_manager()); + } + void TrackMemoryAllocatedChange(size_t old_size, size_t new_size) { - gpu_memory_manager_->TrackMemoryAllocatedChange(old_size, new_size); + gpu_memory_manager_tracking_group_->TrackMemoryAllocatedChange( + old_size, new_size); } private: - ~GpuCommandBufferMemoryTracker() {} - GpuMemoryManager* gpu_memory_manager_; + ~GpuCommandBufferMemoryTracker() { + delete gpu_memory_manager_tracking_group_; + } + GpuMemoryTrackingGroup* gpu_memory_manager_tracking_group_; DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferMemoryTracker); }; @@ -122,10 +130,9 @@ GpuCommandBufferStub::GpuCommandBufferStub( context_group_ = share_group->context_group_; } else { context_group_ = new gpu::gles2::ContextGroup( - mailbox_manager, - new GpuCommandBufferMemoryTracker( - channel->gpu_channel_manager()->gpu_memory_manager()), - true); + mailbox_manager, + new GpuCommandBufferMemoryTracker(channel), + true); } if (surface_id != 0) surface_state_.reset(new GpuCommandBufferStubBase::SurfaceState( diff --git a/content/common/gpu/gpu_memory_manager.cc b/content/common/gpu/gpu_memory_manager.cc index a52443d..66f16c0 100644 --- a/content/common/gpu/gpu_memory_manager.cc +++ b/content/common/gpu/gpu_memory_manager.cc @@ -12,9 +12,11 @@ #include "base/command_line.h" #include "base/debug/trace_event.h" #include "base/message_loop.h" +#include "base/process_util.h" #include "base/string_number_conversions.h" #include "content/common/gpu/gpu_command_buffer_stub.h" #include "content/common/gpu/gpu_memory_allocation.h" +#include "content/common/gpu/gpu_memory_tracking.h" #include "gpu/command_buffer/service/gpu_switches.h" namespace { @@ -92,6 +94,7 @@ GpuMemoryManager::GpuMemoryManager(GpuMemoryManagerClient* client, } GpuMemoryManager::~GpuMemoryManager() { + DCHECK(tracking_groups_.empty()); } bool GpuMemoryManager::StubWithSurfaceComparator::operator()( @@ -129,8 +132,7 @@ void GpuMemoryManager::ScheduleManage(bool immediate) { } void GpuMemoryManager::TrackMemoryAllocatedChange(size_t old_size, - size_t new_size) -{ + size_t new_size) { if (new_size < old_size) { size_t delta = old_size - new_size; DCHECK(bytes_allocated_current_ >= delta); @@ -150,6 +152,34 @@ void GpuMemoryManager::TrackMemoryAllocatedChange(size_t old_size, } } +void GpuMemoryManager::AddTrackingGroup( + GpuMemoryTrackingGroup* tracking_group) { + tracking_groups_.insert(tracking_group); +} + +void GpuMemoryManager::RemoveTrackingGroup( + GpuMemoryTrackingGroup* tracking_group) { + tracking_groups_.erase(tracking_group); +} + +void GpuMemoryManager::GetVideoMemoryUsageStats( + content::GPUVideoMemoryUsageStats& video_memory_usage_stats) const { + // For each context group, assign its memory usage to its PID + video_memory_usage_stats.process_map.clear(); + for (std::set<GpuMemoryTrackingGroup*>::const_iterator i = + tracking_groups_.begin(); i != tracking_groups_.end(); ++i) { + const GpuMemoryTrackingGroup* tracking_group = (*i); + video_memory_usage_stats.process_map[ + tracking_group->GetPid()].video_memory += tracking_group->GetSize(); + } + + // Assign the total across all processes in the GPU process + video_memory_usage_stats.process_map[ + base::GetCurrentProcId()].video_memory = bytes_allocated_current_; + video_memory_usage_stats.process_map[ + base::GetCurrentProcId()].has_duplicates = true; +} + // The current Manage algorithm simply classifies contexts (stubs) into // "foreground", "background", or "hibernated" categories. // For each of these three categories, there are predefined memory allocation diff --git a/content/common/gpu/gpu_memory_manager.h b/content/common/gpu/gpu_memory_manager.h index 85c0e01..015f0b0 100644 --- a/content/common/gpu/gpu_memory_manager.h +++ b/content/common/gpu/gpu_memory_manager.h @@ -7,6 +7,7 @@ #if defined(ENABLE_GPU) +#include <set> #include <vector> #include "base/basictypes.h" @@ -15,9 +16,11 @@ #include "base/memory/weak_ptr.h" #include "content/common/content_export.h" #include "content/common/gpu/gpu_memory_allocation.h" +#include "content/public/common/gpu_memory_stats.h" #include "ui/gfx/size.h" class GpuCommandBufferStubBase; +class GpuMemoryTrackingGroup; #if defined(COMPILER_GCC) namespace BASE_HASH_NAMESPACE { @@ -63,6 +66,14 @@ class CONTENT_EXPORT GpuMemoryManager : // queued delayed manage. void ScheduleManage(bool immediate); + // Retrieve GPU Resource consumption statistics for the task manager + void GetVideoMemoryUsageStats( + content::GPUVideoMemoryUsageStats& video_memory_usage_stats) const; + + // Add and remove structures to track context groups' memory consumption + void AddTrackingGroup(GpuMemoryTrackingGroup* tracking_group); + void RemoveTrackingGroup(GpuMemoryTrackingGroup* tracking_group); + // Returns StubMemoryStat's for each GpuCommandBufferStubBase, which were // assigned during the most recent call to Manage(). // Useful for tracking the memory-allocation-related presumed state of the @@ -81,6 +92,9 @@ class CONTENT_EXPORT GpuMemoryManager : void Manage(); + // The context groups' tracking structures + std::set<GpuMemoryTrackingGroup*> tracking_groups_; + size_t CalculateBonusMemoryAllocationBasedOnSize(gfx::Size size) const; size_t GetAvailableGpuMemory() const { diff --git a/content/common/gpu/gpu_memory_tracking.h b/content/common/gpu/gpu_memory_tracking.h new file mode 100644 index 0000000..c20ad85 --- /dev/null +++ b/content/common/gpu/gpu_memory_tracking.h @@ -0,0 +1,53 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_COMMON_GPU_GPU_MEMORY_TRACKING_H_ +#define CONTENT_COMMON_GPU_GPU_MEMORY_TRACKING_H_ + +#if defined(ENABLE_GPU) + +#include "base/basictypes.h" +#include "content/common/gpu/gpu_memory_manager.h" + +// All decoders in a context group point to a single GpuMemoryTrackingGroup, +// which tracks GPU resource consumption for the entire context group. +class GpuMemoryTrackingGroup { + public: + GpuMemoryTrackingGroup(base::ProcessId pid, GpuMemoryManager* memory_manager) + : pid_(pid), + size_(0), + memory_manager_(memory_manager) { + memory_manager_->AddTrackingGroup(this); + } + ~GpuMemoryTrackingGroup() { + memory_manager_->RemoveTrackingGroup(this); + } + void TrackMemoryAllocatedChange(size_t old_size, size_t new_size) { + if (old_size < new_size) { + size_t delta = new_size - old_size; + size_ += delta; + } + if (new_size < old_size) { + size_t delta = old_size - new_size; + DCHECK(size_ >= delta); + size_ -= delta; + } + memory_manager_->TrackMemoryAllocatedChange(old_size, new_size); + } + base::ProcessId GetPid() const { + return pid_; + } + size_t GetSize() const { + return size_; + } + + private: + base::ProcessId pid_; + size_t size_; + GpuMemoryManager* memory_manager_; +}; + +#endif + +#endif // CONTENT_COMMON_GPU_GPU_MEMORY_TRACKING_H_ diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index 2415fa8..3e96bb7 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -14,6 +14,7 @@ #include "content/common/gpu/gpu_process_launch_causes.h" #include "content/public/common/common_param_traits.h" #include "content/public/common/gpu_info.h" +#include "content/public/common/gpu_memory_stats.h" #include "gpu/command_buffer/common/command_buffer.h" #include "gpu/command_buffer/common/constants.h" #include "gpu/ipc/gpu_command_buffer_traits.h" @@ -162,6 +163,15 @@ IPC_STRUCT_TRAITS_BEGIN(content::GPUInfo) #endif IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(content::GPUVideoMemoryUsageStats::ProcessStats) + IPC_STRUCT_TRAITS_MEMBER(video_memory) + IPC_STRUCT_TRAITS_MEMBER(has_duplicates) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(content::GPUVideoMemoryUsageStats) + IPC_STRUCT_TRAITS_MEMBER(process_map) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(GpuMemoryAllocationForRenderer) IPC_STRUCT_TRAITS_MEMBER(gpu_resource_size_in_bytes) IPC_STRUCT_TRAITS_MEMBER(suggest_have_backbuffer) @@ -221,6 +231,9 @@ IPC_MESSAGE_CONTROL4(GpuMsg_CreateViewCommandBuffer, // information. IPC_MESSAGE_CONTROL0(GpuMsg_CollectGraphicsInfo) +// Tells the GPU process to report video_memory information for the task manager +IPC_MESSAGE_CONTROL0(GpuMsg_GetVideoMemoryUsageStats) + // Tells the GPU process that the browser process has finished resizing the // view. IPC_MESSAGE_ROUTED0(AcceleratedSurfaceMsg_ResizeViewACK) @@ -282,6 +295,10 @@ IPC_MESSAGE_CONTROL1(GpuHostMsg_DestroyCommandBuffer, IPC_MESSAGE_CONTROL1(GpuHostMsg_GraphicsInfoCollected, content::GPUInfo /* GPU logging stats */) +// Response from GPU to a GpuMsg_GetVideoMemory. +IPC_MESSAGE_CONTROL1(GpuHostMsg_VideoMemoryUsageStats, + content::GPUVideoMemoryUsageStats /* GPU memory stats */) + // Message from GPU to add a GPU log message to the about:gpu page. IPC_MESSAGE_CONTROL3(GpuHostMsg_OnLogMessage, int /*severity*/, diff --git a/content/content_common.gypi b/content/content_common.gypi index 755ea29..54974ae 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -57,6 +57,8 @@ 'public/common/gpu_feature_type.h', 'public/common/gpu_info.cc', 'public/common/gpu_info.h', + 'public/common/gpu_memory_stats.cc', + 'public/common/gpu_memory_stats.h', 'public/common/gpu_performance_stats.h', 'public/common/injection_test_mac.h', 'public/common/injection_test_win.h', @@ -213,6 +215,7 @@ 'common/gpu/gpu_memory_allocation.h', 'common/gpu/gpu_memory_manager.cc', 'common/gpu/gpu_memory_manager.h', + 'common/gpu/gpu_memory_tracking.h', 'common/gpu/gpu_messages.h', 'common/gpu/gpu_process_launch_causes.h', 'common/gpu/gpu_surface_lookup.h', diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc index 338c8f9..bb2a6d7a 100644 --- a/content/gpu/gpu_child_thread.cc +++ b/content/gpu/gpu_child_thread.cc @@ -99,6 +99,8 @@ bool GpuChildThread::OnControlMessageReceived(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP_EX(GpuChildThread, msg, msg_is_ok) IPC_MESSAGE_HANDLER(GpuMsg_Initialize, OnInitialize) IPC_MESSAGE_HANDLER(GpuMsg_CollectGraphicsInfo, OnCollectGraphicsInfo) + IPC_MESSAGE_HANDLER(GpuMsg_GetVideoMemoryUsageStats, + OnGetVideoMemoryUsageStats) IPC_MESSAGE_HANDLER(GpuMsg_Clean, OnClean) IPC_MESSAGE_HANDLER(GpuMsg_Crash, OnCrash) IPC_MESSAGE_HANDLER(GpuMsg_Hang, OnHang) @@ -221,6 +223,14 @@ void GpuChildThread::OnCollectGraphicsInfo() { Send(new GpuHostMsg_GraphicsInfoCollected(gpu_info_)); } +void GpuChildThread::OnGetVideoMemoryUsageStats() { + content::GPUVideoMemoryUsageStats video_memory_usage_stats; + if (gpu_channel_manager_.get()) + gpu_channel_manager_->gpu_memory_manager()->GetVideoMemoryUsageStats( + video_memory_usage_stats); + Send(new GpuHostMsg_VideoMemoryUsageStats(video_memory_usage_stats)); +} + void GpuChildThread::OnClean() { VLOG(1) << "GPU: Removing all contexts"; if (gpu_channel_manager_.get()) diff --git a/content/gpu/gpu_child_thread.h b/content/gpu/gpu_child_thread.h index d0993e4..3590cf3 100644 --- a/content/gpu/gpu_child_thread.h +++ b/content/gpu/gpu_child_thread.h @@ -52,6 +52,7 @@ class GpuChildThread : public ChildThread { // Message handlers. void OnInitialize(); void OnCollectGraphicsInfo(); + void OnGetVideoMemoryUsageStats(); void OnClean(); void OnCrash(); void OnHang(); diff --git a/content/public/browser/gpu_data_manager.h b/content/public/browser/gpu_data_manager.h index 68b5173..9149ead 100644 --- a/content/public/browser/gpu_data_manager.h +++ b/content/public/browser/gpu_data_manager.h @@ -47,6 +47,10 @@ class GpuDataManager { virtual bool IsCompleteGPUInfoAvailable() const = 0; + // Requests that the GPU process report its current video memory usage stats, + // which can be retrieved via the GPU data manager's on-update function. + virtual void RequestVideoMemoryUsageStatsUpdate() = 0; + // Returns true if the software rendering should currently be used. virtual bool ShouldUseSoftwareRendering() = 0; diff --git a/content/public/browser/gpu_data_manager_observer.h b/content/public/browser/gpu_data_manager_observer.h index 67d8d4a..c5b1b3d 100644 --- a/content/public/browser/gpu_data_manager_observer.h +++ b/content/public/browser/gpu_data_manager_observer.h @@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_BROWSER_GPU_DATA_MANAGER_OBSERVER_H_ #include "content/common/content_export.h" +#include "content/public/common/gpu_memory_stats.h" namespace content { @@ -16,6 +17,10 @@ class GpuDataManagerObserver { // Called for any observers whenever there is a GPU info update. virtual void OnGpuInfoUpdate() = 0; + // Called for any observers whenever there is a GPU video memory update. + virtual void OnVideoMemoryUsageStatsUpdate( + const GPUVideoMemoryUsageStats& video_memory_usage_stats) = 0; + protected: virtual ~GpuDataManagerObserver() {} }; diff --git a/content/public/common/gpu_memory_stats.cc b/content/public/common/gpu_memory_stats.cc new file mode 100644 index 0000000..b593ab4 --- /dev/null +++ b/content/public/common/gpu_memory_stats.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/public/common/gpu_memory_stats.h" + +namespace content { + +GPUVideoMemoryUsageStats::GPUVideoMemoryUsageStats() { +} + +GPUVideoMemoryUsageStats::~GPUVideoMemoryUsageStats() { +} + +GPUVideoMemoryUsageStats::ProcessStats::ProcessStats() + : video_memory(0), + has_duplicates(false) { +} + +GPUVideoMemoryUsageStats::ProcessStats::~ProcessStats() { +} + +} // namespace content diff --git a/content/public/common/gpu_memory_stats.h b/content/public/common/gpu_memory_stats.h new file mode 100644 index 0000000..5ae6e97 --- /dev/null +++ b/content/public/common/gpu_memory_stats.h @@ -0,0 +1,43 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_COMMON_GPU_MEMORY_STATS_H_ +#define CONTENT_PUBLIC_COMMON_GPU_MEMORY_STATS_H_ + +// Provides access to the GPU information for the system +// on which chrome is currently running. + +#include <map> + +#include "base/basictypes.h" +#include "base/process.h" +#include "content/common/content_export.h" + +namespace content { + +struct CONTENT_EXPORT GPUVideoMemoryUsageStats { + GPUVideoMemoryUsageStats(); + ~GPUVideoMemoryUsageStats(); + + struct CONTENT_EXPORT ProcessStats { + ProcessStats(); + ~ProcessStats(); + + // The bytes of GPU resources accessible by this process + size_t video_memory; + + // Set to true if this process' GPU resource count is inflated because + // it is counting other processes' resources (e.g, the GPU process has + // duplicate set to true because it is the aggregate of all processes) + bool has_duplicates; + }; + typedef std::map<base::ProcessId, ProcessStats> ProcessMap; + + // A map of processes to their GPU resource consumption + ProcessMap process_map; +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_COMMON_GPU_MEMORY_STATS_H_ |