diff options
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_ |