diff options
Diffstat (limited to 'chrome/browser/ui')
-rw-r--r-- | chrome/browser/ui/webui/gpu_internals_ui.cc | 331 | ||||
-rw-r--r-- | chrome/browser/ui/webui/tracing_ui.cc | 49 |
2 files changed, 329 insertions, 51 deletions
diff --git a/chrome/browser/ui/webui/gpu_internals_ui.cc b/chrome/browser/ui/webui/gpu_internals_ui.cc index 219a75b..287a68c 100644 --- a/chrome/browser/ui/webui/gpu_internals_ui.cc +++ b/chrome/browser/ui/webui/gpu_internals_ui.cc @@ -15,8 +15,6 @@ #include "base/sys_info.h" #include "base/values.h" #include "chrome/browser/crash_upload_list.h" -#include "chrome/browser/gpu_blacklist.h" -#include "chrome/browser/gpu_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chrome_url_data_manager.h" #include "chrome/browser/ui/webui/chrome_web_ui_data_source.h" @@ -29,6 +27,9 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_message_handler.h" +#include "content/public/common/compositor_util.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/gpu_info.h" #include "grit/browser_resources.h" #include "grit/generated_resources.h" #include "third_party/angle/src/common/version.h" @@ -41,11 +42,20 @@ using content::BrowserThread; using content::GpuDataManager; +using content::GpuFeatureType; using content::WebContents; using content::WebUIMessageHandler; namespace { +struct GpuFeatureInfo { + std::string name; + uint32 blocked; + bool disabled; + std::string disabled_description; + bool fallback_to_software; +}; + ChromeWebUIDataSource* CreateGpuHTMLSource() { ChromeWebUIDataSource* source = new ChromeWebUIDataSource(chrome::kChromeUIGpuInternalsHost); @@ -56,6 +66,317 @@ ChromeWebUIDataSource* CreateGpuHTMLSource() { return source; } +DictionaryValue* NewDescriptionValuePair(const std::string& desc, + const std::string& value) { + DictionaryValue* dict = new DictionaryValue(); + dict->SetString("description", desc); + dict->SetString("value", value); + return dict; +} + +DictionaryValue* NewDescriptionValuePair(const std::string& desc, + Value* value) { + DictionaryValue* dict = new DictionaryValue(); + dict->SetString("description", desc); + dict->Set("value", value); + return dict; +} + +Value* NewStatusValue(const char* name, const char* status) { + DictionaryValue* value = new DictionaryValue(); + value->SetString("name", name); + value->SetString("status", status); + return value; +} + +// Output DxDiagNode tree as nested array of {description,value} pairs +ListValue* DxDiagNodeToList(const content::DxDiagNode& node) { + ListValue* list = new ListValue(); + for (std::map<std::string, std::string>::const_iterator it = + node.values.begin(); + it != node.values.end(); + ++it) { + list->Append(NewDescriptionValuePair(it->first, it->second)); + } + + for (std::map<std::string, content::DxDiagNode>::const_iterator it = + node.children.begin(); + it != node.children.end(); + ++it) { + ListValue* sublist = DxDiagNodeToList(it->second); + list->Append(NewDescriptionValuePair(it->first, sublist)); + } + return list; +} + +std::string GPUDeviceToString(const content::GPUInfo::GPUDevice& gpu) { + std::string vendor = base::StringPrintf("0x%04x", gpu.vendor_id); + if (!gpu.vendor_string.empty()) + vendor += " [" + gpu.vendor_string + "]"; + std::string device = base::StringPrintf("0x%04x", gpu.device_id); + if (!gpu.device_string.empty()) + device += " [" + gpu.device_string + "]"; + return base::StringPrintf( + "VENDOR = %s, DEVICE= %s", vendor.c_str(), device.c_str()); +} + +DictionaryValue* GpuInfoAsDictionaryValue() { + content::GPUInfo gpu_info = GpuDataManager::GetInstance()->GetGPUInfo(); + ListValue* basic_info = new ListValue(); + basic_info->Append(NewDescriptionValuePair( + "Initialization time", + base::Int64ToString(gpu_info.initialization_time.InMilliseconds()))); + basic_info->Append(NewDescriptionValuePair( + "GPU0", GPUDeviceToString(gpu_info.gpu))); + for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) { + basic_info->Append(NewDescriptionValuePair( + base::StringPrintf("GPU%d", static_cast<int>(i + 1)), + GPUDeviceToString(gpu_info.secondary_gpus[i]))); + } + basic_info->Append(NewDescriptionValuePair( + "Optimus", Value::CreateBooleanValue(gpu_info.optimus))); + basic_info->Append(NewDescriptionValuePair( + "AMD switchable", Value::CreateBooleanValue(gpu_info.amd_switchable))); + basic_info->Append(NewDescriptionValuePair("Driver vendor", + gpu_info.driver_vendor)); + basic_info->Append(NewDescriptionValuePair("Driver version", + gpu_info.driver_version)); + basic_info->Append(NewDescriptionValuePair("Driver date", + gpu_info.driver_date)); + basic_info->Append(NewDescriptionValuePair("Pixel shader version", + gpu_info.pixel_shader_version)); + basic_info->Append(NewDescriptionValuePair("Vertex shader version", + gpu_info.vertex_shader_version)); + basic_info->Append(NewDescriptionValuePair("GL version", + gpu_info.gl_version)); + basic_info->Append(NewDescriptionValuePair("GL_VENDOR", + gpu_info.gl_vendor)); + basic_info->Append(NewDescriptionValuePair("GL_RENDERER", + gpu_info.gl_renderer)); + basic_info->Append(NewDescriptionValuePair("GL_VERSION", + gpu_info.gl_version_string)); + basic_info->Append(NewDescriptionValuePair("GL_EXTENSIONS", + gpu_info.gl_extensions)); + + DictionaryValue* info = new DictionaryValue(); + info->Set("basic_info", basic_info); + +#if defined(OS_WIN) + ListValue* perf_info = new ListValue(); + perf_info->Append(NewDescriptionValuePair( + "Graphics", + base::StringPrintf("%.1f", gpu_info.performance_stats.graphics))); + perf_info->Append(NewDescriptionValuePair( + "Gaming", + base::StringPrintf("%.1f", gpu_info.performance_stats.gaming))); + perf_info->Append(NewDescriptionValuePair( + "Overall", + base::StringPrintf("%.1f", gpu_info.performance_stats.overall))); + info->Set("performance_info", perf_info); + + Value* dx_info; + if (gpu_info.dx_diagnostics.children.size()) + dx_info = DxDiagNodeToList(gpu_info.dx_diagnostics); + else + dx_info = Value::CreateNullValue(); + info->Set("diagnostics", dx_info); +#endif + + return info; +} + +// Determine if accelerated-2d-canvas is supported, which depends on whether +// lose_context could happen and whether skia is the backend. +bool SupportsAccelerated2dCanvas() { + if (GpuDataManager::GetInstance()->GetGPUInfo().can_lose_context) + return false; +#if defined(USE_SKIA) + return true; +#else + return false; +#endif +} + +Value* GetFeatureStatus() { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + bool gpu_access_blocked = !GpuDataManager::GetInstance()->GpuAccessAllowed(); + + uint32 flags = GpuDataManager::GetInstance()->GetBlacklistedFeatures(); + DictionaryValue* status = new DictionaryValue(); + + const GpuFeatureInfo kGpuFeatureInfo[] = { + { + "2d_canvas", + flags & content::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS, + command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) || + !SupportsAccelerated2dCanvas(), + "Accelerated 2D canvas is unavailable: either disabled at the command" + " line or not supported by the current system.", + true + }, + { + "compositing", + flags & content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING, + command_line.HasSwitch(switches::kDisableAcceleratedCompositing), + "Accelerated compositing has been disabled, either via about:flags or" + " command line. This adversely affects performance of all hardware" + " accelerated features.", + true + }, + { + "3d_css", + flags & content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING, + command_line.HasSwitch(switches::kDisableAcceleratedLayers), + "Accelerated layers have been disabled at the command line.", + false + }, + { + "css_animation", + flags & content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING, + command_line.HasSwitch(switches::kDisableThreadedAnimation) || + command_line.HasSwitch(switches::kDisableAcceleratedCompositing), + "Accelerated CSS animation has been disabled at the command line.", + true + }, + { + "webgl", + flags & content::GPU_FEATURE_TYPE_WEBGL, +#if defined(OS_ANDROID) + !command_line.HasSwitch(switches::kEnableExperimentalWebGL), +#else + command_line.HasSwitch(switches::kDisableExperimentalWebGL), +#endif + "WebGL has been disabled, either via about:flags or command line.", + false + }, + { + "multisampling", + flags & content::GPU_FEATURE_TYPE_MULTISAMPLING, + command_line.HasSwitch(switches::kDisableGLMultisampling), + "Multisampling has been disabled, either via about:flags or command" + " line.", + false + }, + { + "flash_3d", + flags & content::GPU_FEATURE_TYPE_FLASH3D, + command_line.HasSwitch(switches::kDisableFlash3d), + "Using 3d in flash has been disabled, either via about:flags or" + " command line.", + false + }, + { + "flash_stage3d", + flags & content::GPU_FEATURE_TYPE_FLASH_STAGE3D, + command_line.HasSwitch(switches::kDisableFlashStage3d), + "Using Stage3d in Flash has been disabled, either via about:flags or" + " command line.", + false + }, + { + "texture_sharing", + flags & content::GPU_FEATURE_TYPE_TEXTURE_SHARING, + command_line.HasSwitch(switches::kDisableImageTransportSurface), + "Sharing textures between processes has been disabled, either via" + " about:flags or command line.", + false + }, + { + "video_decode", + flags & content::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE, + command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode), + "Accelerated video decode has been disabled, either via about:flags" + " or command line.", + true + } + }; + const size_t kNumFeatures = sizeof(kGpuFeatureInfo) / sizeof(GpuFeatureInfo); + + // Build the feature_status field. + { + ListValue* feature_status_list = new ListValue(); + + for (size_t i = 0; i < kNumFeatures; ++i) { + std::string status; + if (kGpuFeatureInfo[i].disabled) { + status = "disabled"; + if (kGpuFeatureInfo[i].name == "css_animation") { + status += "_software_animated"; + } else { + if (kGpuFeatureInfo[i].fallback_to_software) + status += "_software"; + else + status += "_off"; + } + } else if (GpuDataManager::GetInstance()->ShouldUseSoftwareRendering()) { + status = "unavailable_software"; + } else if (kGpuFeatureInfo[i].blocked || + gpu_access_blocked) { + status = "unavailable"; + if (kGpuFeatureInfo[i].fallback_to_software) + status += "_software"; + else + status += "_off"; + } else { + status = "enabled"; + if (kGpuFeatureInfo[i].name == "webgl" && + (command_line.HasSwitch(switches::kDisableAcceleratedCompositing) || + (flags & content::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING))) + status += "_readback"; + bool has_thread = content::IsThreadedCompositingEnabled(); + if (kGpuFeatureInfo[i].name == "compositing") { + bool force_compositing = + content::IsForceCompositingModeEnabled(); + if (force_compositing) + status += "_force"; + if (has_thread) + status += "_threaded"; + } + if (kGpuFeatureInfo[i].name == "css_animation") { + if (has_thread) + status = "accelerated_threaded"; + else + status = "accelerated"; + } + } + feature_status_list->Append( + NewStatusValue(kGpuFeatureInfo[i].name.c_str(), status.c_str())); + } + + status->Set("featureStatus", feature_status_list); + } + + // Build the problems list. + { + ListValue* problem_list = + GpuDataManager::GetInstance()->GetBlacklistReasons(); + + if (gpu_access_blocked) { + DictionaryValue* problem = new DictionaryValue(); + problem->SetString("description", + "GPU process was unable to boot. Access to GPU disallowed."); + problem->Set("crBugs", new ListValue()); + problem->Set("webkitBugs", new ListValue()); + problem_list->Append(problem); + } + + for (size_t i = 0; i < kNumFeatures; ++i) { + if (kGpuFeatureInfo[i].disabled) { + DictionaryValue* problem = new DictionaryValue(); + problem->SetString( + "description", kGpuFeatureInfo[i].disabled_description); + problem->Set("crBugs", new ListValue()); + problem->Set("webkitBugs", new ListValue()); + problem_list->Append(problem); + } + } + + status->Set("problems", problem_list); + } + + return status; +} + // This class receives javascript messages from the renderer. // Note that the WebUI infrastructure runs on the UI thread, therefore all of // this class's methods are expected to run on the UI thread. @@ -240,7 +561,7 @@ Value* GpuMessageHandler::OnRequestClientInfo(const ListValue* list) { dict->SetString("graphics_backend", "Core Graphics"); #endif dict->SetString("blacklist_version", - GpuBlacklist::GetInstance()->GetVersion()); + GpuDataManager::GetInstance()->GetBlacklistVersion()); return dict; } @@ -310,10 +631,10 @@ Value* GpuMessageHandler::OnRequestCrashList(const ListValue*) { void GpuMessageHandler::OnGpuInfoUpdate() { // Get GPU Info. scoped_ptr<base::DictionaryValue> gpu_info_val( - gpu_util::GpuInfoAsDictionaryValue()); + GpuInfoAsDictionaryValue()); // Add in blacklisting features - Value* feature_status = gpu_util::GetFeatureStatus(); + Value* feature_status = GetFeatureStatus(); if (feature_status) gpu_info_val->Set("featureStatus", feature_status); diff --git a/chrome/browser/ui/webui/tracing_ui.cc b/chrome/browser/ui/webui/tracing_ui.cc index 584cd30..9e61fee 100644 --- a/chrome/browser/ui/webui/tracing_ui.cc +++ b/chrome/browser/ui/webui/tracing_ui.cc @@ -15,8 +15,6 @@ #include "base/string_number_conversions.h" #include "base/stringprintf.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/gpu_blacklist.h" -#include "chrome/browser/gpu_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/chrome_select_file_policy.h" #include "chrome/browser/ui/webui/chrome_url_data_manager.h" @@ -70,8 +68,7 @@ class TracingMessageHandler : public WebUIMessageHandler, public ui::SelectFileDialog::Listener, public base::SupportsWeakPtr<TracingMessageHandler>, - public content::TraceSubscriber, - public content::GpuDataManagerObserver { + public content::TraceSubscriber { public: TracingMessageHandler(); virtual ~TracingMessageHandler(); @@ -89,11 +86,6 @@ class TracingMessageHandler const scoped_refptr<base::RefCountedString>& trace_fragment); virtual void OnTraceBufferPercentFullReply(float percent_full); - // GpuDataManagerObserver implementation. - virtual void OnGpuInfoUpdate() OVERRIDE; - virtual void OnVideoMemoryUsageStatsUpdate( - const content::GPUVideoMemoryUsageStats& video_memory) OVERRIDE {} - // Messages. void OnTracingControllerInitialized(const ListValue* list); void OnBeginTracing(const ListValue* list); @@ -123,10 +115,6 @@ class TracingMessageHandler // True while system tracing is active. bool system_trace_in_progress_; - // True if observing the GpuDataManager (re-attaching as observer would - // DCHECK). - bool observing_; - void OnEndSystemTracingAck( const scoped_refptr<base::RefCountedString>& events_str_ptr); @@ -169,13 +157,10 @@ class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> { TracingMessageHandler::TracingMessageHandler() : select_trace_file_dialog_type_(ui::SelectFileDialog::SELECT_NONE), trace_enabled_(false), - system_trace_in_progress_(false), - observing_(false) { + system_trace_in_progress_(false) { } TracingMessageHandler::~TracingMessageHandler() { - GpuDataManager::GetInstance()->RemoveObserver(this); - if (select_trace_file_dialog_) select_trace_file_dialog_->ListenerDestroyed(); @@ -219,19 +204,6 @@ void TracingMessageHandler::OnTracingControllerInitialized( const ListValue* args) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // Watch for changes in GPUInfo - if (!observing_) - GpuDataManager::GetInstance()->AddObserver(this); - observing_ = true; - - // Tell GpuDataManager it should have full GpuInfo. If the - // Gpu process has not run yet, this will trigger its launch. - GpuDataManager::GetInstance()->RequestCompleteGpuInfoIfNeeded(); - - // Run callback immediately in case the info is ready and no update in the - // future. - OnGpuInfoUpdate(); - // Send the client info to the tracingController { scoped_ptr<DictionaryValue> dict(new DictionaryValue()); @@ -256,7 +228,7 @@ void TracingMessageHandler::OnTracingControllerInitialized( } dict->SetString("blacklist_version", - GpuBlacklist::GetInstance()->GetVersion()); + GpuDataManager::GetInstance()->GetBlacklistVersion()); web_ui()->CallJavascriptFunction("tracingController.onClientInfoUpdate", *dict); } @@ -267,21 +239,6 @@ void TracingMessageHandler::OnBeginRequestBufferPercentFull( TraceController::GetInstance()->GetTraceBufferPercentFullAsync(this); } -void TracingMessageHandler::OnGpuInfoUpdate() { - // Get GPU Info. - scoped_ptr<base::DictionaryValue> gpu_info_val( - gpu_util::GpuInfoAsDictionaryValue()); - - // Add in blacklisting features - Value* feature_status = gpu_util::GetFeatureStatus(); - if (feature_status) - gpu_info_val->Set("featureStatus", feature_status); - - // Send GPU Info to javascript. - web_ui()->CallJavascriptFunction("tracingController.onGpuInfoUpdate", - *(gpu_info_val.get())); -} - // A callback used for asynchronously reading a file to a string. Calls the // TaskProxy callback when reading is complete. void ReadTraceFileCallback(TaskProxy* proxy, const FilePath& path) { |