Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / browser / gpu / gpu_internals_ui.cc
blobedf020eaaf5db9e8be659d36f9d77d90101c16c0
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/gpu/gpu_internals_ui.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/command_line.h"
12 #include "base/i18n/time_formatting.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/sys_info.h"
16 #include "base/values.h"
17 #include "cc/base/switches.h"
18 #include "content/browser/gpu/gpu_data_manager_impl.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/compositor_util.h"
21 #include "content/public/browser/gpu_data_manager_observer.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_ui.h"
24 #include "content/public/browser/web_ui_data_source.h"
25 #include "content/public/browser/web_ui_message_handler.h"
26 #include "content/public/common/content_client.h"
27 #include "content/public/common/content_switches.h"
28 #include "content/public/common/url_constants.h"
29 #include "gpu/config/gpu_feature_type.h"
30 #include "gpu/config/gpu_info.h"
31 #include "grit/content_resources.h"
34 #if defined(ANGLE_DX11)
35 #include "third_party/angle_dx11/src/common/version.h"
36 #else
37 #include "third_party/angle/src/common/version.h"
38 #endif
40 namespace content {
41 namespace {
43 struct GpuFeatureInfo {
44 std::string name;
45 uint32 blocked;
46 bool disabled;
47 std::string disabled_description;
48 bool fallback_to_software;
51 WebUIDataSource* CreateGpuHTMLSource() {
52 WebUIDataSource* source = WebUIDataSource::Create(kChromeUIGpuHost);
54 source->SetJsonPath("strings.js");
55 source->AddResourcePath("gpu_internals.js", IDR_GPU_INTERNALS_JS);
56 source->SetDefaultResource(IDR_GPU_INTERNALS_HTML);
57 return source;
60 base::DictionaryValue* NewDescriptionValuePair(const std::string& desc,
61 const std::string& value) {
62 base::DictionaryValue* dict = new base::DictionaryValue();
63 dict->SetString("description", desc);
64 dict->SetString("value", value);
65 return dict;
68 base::DictionaryValue* NewDescriptionValuePair(const std::string& desc,
69 base::Value* value) {
70 base::DictionaryValue* dict = new base::DictionaryValue();
71 dict->SetString("description", desc);
72 dict->Set("value", value);
73 return dict;
76 base::Value* NewStatusValue(const char* name, const char* status) {
77 base::DictionaryValue* value = new base::DictionaryValue();
78 value->SetString("name", name);
79 value->SetString("status", status);
80 return value;
83 #if defined(OS_WIN)
84 // Output DxDiagNode tree as nested array of {description,value} pairs
85 base::ListValue* DxDiagNodeToList(const gpu::DxDiagNode& node) {
86 base::ListValue* list = new base::ListValue();
87 for (std::map<std::string, std::string>::const_iterator it =
88 node.values.begin();
89 it != node.values.end();
90 ++it) {
91 list->Append(NewDescriptionValuePair(it->first, it->second));
94 for (std::map<std::string, gpu::DxDiagNode>::const_iterator it =
95 node.children.begin();
96 it != node.children.end();
97 ++it) {
98 base::ListValue* sublist = DxDiagNodeToList(it->second);
99 list->Append(NewDescriptionValuePair(it->first, sublist));
101 return list;
103 #endif
105 std::string GPUDeviceToString(const gpu::GPUInfo::GPUDevice& gpu) {
106 std::string vendor = base::StringPrintf("0x%04x", gpu.vendor_id);
107 if (!gpu.vendor_string.empty())
108 vendor += " [" + gpu.vendor_string + "]";
109 std::string device = base::StringPrintf("0x%04x", gpu.device_id);
110 if (!gpu.device_string.empty())
111 device += " [" + gpu.device_string + "]";
112 return base::StringPrintf(
113 "VENDOR = %s, DEVICE= %s", vendor.c_str(), device.c_str());
116 base::DictionaryValue* GpuInfoAsDictionaryValue() {
117 gpu::GPUInfo gpu_info = GpuDataManagerImpl::GetInstance()->GetGPUInfo();
118 base::ListValue* basic_info = new base::ListValue();
119 basic_info->Append(NewDescriptionValuePair(
120 "Initialization time",
121 base::Int64ToString(gpu_info.initialization_time.InMilliseconds())));
122 basic_info->Append(NewDescriptionValuePair(
123 "Sandboxed", new base::FundamentalValue(gpu_info.sandboxed)));
124 basic_info->Append(NewDescriptionValuePair(
125 "GPU0", GPUDeviceToString(gpu_info.gpu)));
126 for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) {
127 basic_info->Append(NewDescriptionValuePair(
128 base::StringPrintf("GPU%d", static_cast<int>(i + 1)),
129 GPUDeviceToString(gpu_info.secondary_gpus[i])));
131 basic_info->Append(NewDescriptionValuePair(
132 "Optimus", new base::FundamentalValue(gpu_info.optimus)));
133 basic_info->Append(NewDescriptionValuePair(
134 "AMD switchable", new base::FundamentalValue(gpu_info.amd_switchable)));
135 if (gpu_info.lenovo_dcute) {
136 basic_info->Append(NewDescriptionValuePair(
137 "Lenovo dCute", new base::FundamentalValue(true)));
139 if (gpu_info.display_link_version.IsValid()) {
140 basic_info->Append(NewDescriptionValuePair(
141 "DisplayLink Version", gpu_info.display_link_version.GetString()));
143 basic_info->Append(NewDescriptionValuePair("Driver vendor",
144 gpu_info.driver_vendor));
145 basic_info->Append(NewDescriptionValuePair("Driver version",
146 gpu_info.driver_version));
147 basic_info->Append(NewDescriptionValuePair("Driver date",
148 gpu_info.driver_date));
149 basic_info->Append(NewDescriptionValuePair("Pixel shader version",
150 gpu_info.pixel_shader_version));
151 basic_info->Append(NewDescriptionValuePair("Vertex shader version",
152 gpu_info.vertex_shader_version));
153 basic_info->Append(NewDescriptionValuePair("Machine model",
154 gpu_info.machine_model));
155 basic_info->Append(NewDescriptionValuePair("GL version",
156 gpu_info.gl_version));
157 basic_info->Append(NewDescriptionValuePair("GL_VENDOR",
158 gpu_info.gl_vendor));
159 basic_info->Append(NewDescriptionValuePair("GL_RENDERER",
160 gpu_info.gl_renderer));
161 basic_info->Append(NewDescriptionValuePair("GL_VERSION",
162 gpu_info.gl_version_string));
163 basic_info->Append(NewDescriptionValuePair("GL_EXTENSIONS",
164 gpu_info.gl_extensions));
165 basic_info->Append(NewDescriptionValuePair("Window system binding vendor",
166 gpu_info.gl_ws_vendor));
167 basic_info->Append(NewDescriptionValuePair("Window system binding version",
168 gpu_info.gl_ws_version));
169 basic_info->Append(NewDescriptionValuePair("Window system binding extensions",
170 gpu_info.gl_ws_extensions));
172 base::DictionaryValue* info = new base::DictionaryValue();
173 info->Set("basic_info", basic_info);
175 #if defined(OS_WIN)
176 base::ListValue* perf_info = new base::ListValue();
177 perf_info->Append(NewDescriptionValuePair(
178 "Graphics",
179 base::StringPrintf("%.1f", gpu_info.performance_stats.graphics)));
180 perf_info->Append(NewDescriptionValuePair(
181 "Gaming",
182 base::StringPrintf("%.1f", gpu_info.performance_stats.gaming)));
183 perf_info->Append(NewDescriptionValuePair(
184 "Overall",
185 base::StringPrintf("%.1f", gpu_info.performance_stats.overall)));
186 info->Set("performance_info", perf_info);
188 base::Value* dx_info = gpu_info.dx_diagnostics.children.size() ?
189 DxDiagNodeToList(gpu_info.dx_diagnostics) :
190 base::Value::CreateNullValue();
191 info->Set("diagnostics", dx_info);
192 #endif
194 return info;
197 // Determine if accelerated-2d-canvas is supported, which depends on whether
198 // lose_context could happen.
199 bool SupportsAccelerated2dCanvas() {
200 if (GpuDataManagerImpl::GetInstance()->GetGPUInfo().can_lose_context)
201 return false;
202 return true;
205 base::Value* GetFeatureStatus() {
206 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
207 GpuDataManagerImpl* manager = GpuDataManagerImpl::GetInstance();
208 std::string gpu_access_blocked_reason;
209 bool gpu_access_blocked =
210 !manager->GpuAccessAllowed(&gpu_access_blocked_reason);
212 base::DictionaryValue* status = new base::DictionaryValue();
214 const GpuFeatureInfo kGpuFeatureInfo[] = {
216 "2d_canvas",
217 manager->IsFeatureBlacklisted(
218 gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS),
219 command_line.HasSwitch(switches::kDisableAccelerated2dCanvas) ||
220 !SupportsAccelerated2dCanvas(),
221 "Accelerated 2D canvas is unavailable: either disabled at the command"
222 " line or not supported by the current system.",
223 true
226 "compositing",
227 manager->IsFeatureBlacklisted(
228 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING),
229 command_line.HasSwitch(switches::kDisableAcceleratedCompositing),
230 "Accelerated compositing has been disabled, either via about:flags or"
231 " command line. This adversely affects performance of all hardware"
232 " accelerated features.",
233 true
236 "3d_css",
237 manager->IsFeatureBlacklisted(
238 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
239 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS),
240 command_line.HasSwitch(switches::kDisableAcceleratedLayers),
241 "Accelerated layers have been disabled at the command line.",
242 false
245 "css_animation",
246 manager->IsFeatureBlacklisted(
247 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING) ||
248 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_3D_CSS),
249 command_line.HasSwitch(cc::switches::kDisableThreadedAnimation) ||
250 command_line.HasSwitch(switches::kDisableAcceleratedCompositing) ||
251 command_line.HasSwitch(switches::kDisableAcceleratedLayers),
252 "Accelerated CSS animation has been disabled at the command line.",
253 true
256 "webgl",
257 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_WEBGL),
258 #if defined(OS_ANDROID)
259 !command_line.HasSwitch(switches::kEnableExperimentalWebGL),
260 #else
261 command_line.HasSwitch(switches::kDisableExperimentalWebGL),
262 #endif
263 "WebGL has been disabled, either via about:flags or command line.",
264 false
267 "multisampling",
268 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_MULTISAMPLING),
269 command_line.HasSwitch(switches::kDisableGLMultisampling),
270 "Multisampling has been disabled, either via about:flags or command"
271 " line.",
272 false
275 "flash_3d",
276 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH3D),
277 command_line.HasSwitch(switches::kDisableFlash3d),
278 "Using 3d in flash has been disabled, either via about:flags or"
279 " command line.",
280 false
283 "flash_stage3d",
284 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
285 command_line.HasSwitch(switches::kDisableFlashStage3d),
286 "Using Stage3d in Flash has been disabled, either via about:flags or"
287 " command line.",
288 false
291 "flash_stage3d_baseline",
292 manager->IsFeatureBlacklisted(
293 gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D_BASELINE) ||
294 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_FLASH_STAGE3D),
295 command_line.HasSwitch(switches::kDisableFlashStage3d),
296 "Using Stage3d Baseline profile in Flash has been disabled, either"
297 " via about:flags or command line.",
298 false
301 "texture_sharing",
302 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_TEXTURE_SHARING),
303 command_line.HasSwitch(switches::kDisableImageTransportSurface),
304 "Sharing textures between processes has been disabled, either via"
305 " about:flags or command line.",
306 false
309 "video_decode",
310 manager->IsFeatureBlacklisted(
311 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE),
312 command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode),
313 "Accelerated video decode has been disabled, either via about:flags"
314 " or command line.",
315 true
318 "video",
319 manager->IsFeatureBlacklisted(
320 gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO),
321 command_line.HasSwitch(switches::kDisableAcceleratedVideo) ||
322 command_line.HasSwitch(switches::kDisableAcceleratedCompositing),
323 "Accelerated video presentation has been disabled, either via"
324 " about:flags or command line.",
325 true
327 #if defined(OS_CHROMEOS)
329 "panel_fitting",
330 manager->IsFeatureBlacklisted(gpu::GPU_FEATURE_TYPE_PANEL_FITTING),
331 command_line.HasSwitch(switches::kDisablePanelFitting),
332 "Panel fitting has been disabled, either via about:flags or command"
333 " line.",
334 false
336 #endif
338 "force_compositing_mode",
339 manager->IsFeatureBlacklisted(
340 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE) &&
341 !IsForceCompositingModeEnabled(),
342 !IsForceCompositingModeEnabled() &&
343 !manager->IsFeatureBlacklisted(
344 gpu::GPU_FEATURE_TYPE_FORCE_COMPOSITING_MODE),
345 "Force compositing mode is off, either disabled at the command"
346 " line or not supported by the current system.",
347 false
350 const size_t kNumFeatures = sizeof(kGpuFeatureInfo) / sizeof(GpuFeatureInfo);
352 // Build the feature_status field.
354 base::ListValue* feature_status_list = new base::ListValue();
356 for (size_t i = 0; i < kNumFeatures; ++i) {
357 // force_compositing_mode status is part of the compositing status.
358 if (kGpuFeatureInfo[i].name == "force_compositing_mode")
359 continue;
361 std::string status;
362 if (kGpuFeatureInfo[i].disabled) {
363 status = "disabled";
364 if (kGpuFeatureInfo[i].name == "css_animation") {
365 status += "_software_animated";
366 } else if (kGpuFeatureInfo[i].name == "raster") {
367 if (cc::switches::IsImplSidePaintingEnabled())
368 status += "_software_multithreaded";
369 else
370 status += "_software";
371 } else {
372 if (kGpuFeatureInfo[i].fallback_to_software)
373 status += "_software";
374 else
375 status += "_off";
377 } else if (GpuDataManagerImpl::GetInstance()->ShouldUseSwiftShader()) {
378 status = "unavailable_software";
379 } else if (kGpuFeatureInfo[i].blocked ||
380 gpu_access_blocked) {
381 status = "unavailable";
382 if (kGpuFeatureInfo[i].fallback_to_software)
383 status += "_software";
384 else
385 status += "_off";
386 } else {
387 status = "enabled";
388 if (kGpuFeatureInfo[i].name == "webgl" &&
389 (command_line.HasSwitch(switches::kDisableAcceleratedCompositing) ||
390 manager->IsFeatureBlacklisted(
391 gpu::GPU_FEATURE_TYPE_ACCELERATED_COMPOSITING)))
392 status += "_readback";
393 bool has_thread = IsThreadedCompositingEnabled();
394 if (kGpuFeatureInfo[i].name == "compositing") {
395 bool force_compositing = IsForceCompositingModeEnabled();
396 if (force_compositing)
397 status += "_force";
398 if (has_thread)
399 status += "_threaded";
401 if (kGpuFeatureInfo[i].name == "css_animation") {
402 if (has_thread)
403 status = "accelerated_threaded";
404 else
405 status = "accelerated";
408 // TODO(reveman): Remove this when crbug.com/223286 has been fixed.
409 if (kGpuFeatureInfo[i].name == "raster" &&
410 cc::switches::IsImplSidePaintingEnabled()) {
411 status = "disabled_software_multithreaded";
413 feature_status_list->Append(
414 NewStatusValue(kGpuFeatureInfo[i].name.c_str(), status.c_str()));
416 gpu::GpuSwitchingOption gpu_switching_option =
417 GpuDataManagerImpl::GetInstance()->GetGpuSwitchingOption();
418 if (gpu_switching_option != gpu::GPU_SWITCHING_OPTION_UNKNOWN) {
419 std::string gpu_switching;
420 switch (gpu_switching_option) {
421 case gpu::GPU_SWITCHING_OPTION_AUTOMATIC:
422 gpu_switching = "gpu_switching_automatic";
423 break;
424 case gpu::GPU_SWITCHING_OPTION_FORCE_DISCRETE:
425 gpu_switching = "gpu_switching_force_discrete";
426 break;
427 case gpu::GPU_SWITCHING_OPTION_FORCE_INTEGRATED:
428 gpu_switching = "gpu_switching_force_integrated";
429 break;
430 default:
431 break;
433 feature_status_list->Append(
434 NewStatusValue("gpu_switching", gpu_switching.c_str()));
436 status->Set("featureStatus", feature_status_list);
439 // Build the problems list.
441 base::ListValue* problem_list = new base::ListValue();
442 GpuDataManagerImpl::GetInstance()->GetBlacklistReasons(problem_list);
444 if (gpu_access_blocked) {
445 base::DictionaryValue* problem = new base::DictionaryValue();
446 problem->SetString("description",
447 "GPU process was unable to boot: " + gpu_access_blocked_reason);
448 problem->Set("crBugs", new base::ListValue());
449 problem->Set("webkitBugs", new base::ListValue());
450 problem_list->Insert(0, problem);
453 for (size_t i = 0; i < kNumFeatures; ++i) {
454 if (kGpuFeatureInfo[i].disabled) {
455 base::DictionaryValue* problem = new base::DictionaryValue();
456 problem->SetString(
457 "description", kGpuFeatureInfo[i].disabled_description);
458 problem->Set("crBugs", new base::ListValue());
459 problem->Set("webkitBugs", new base::ListValue());
460 problem_list->Append(problem);
464 status->Set("problems", problem_list);
467 // Build driver bug workaround list.
469 base::ListValue* workaround_list = new base::ListValue();
470 GpuDataManagerImpl::GetInstance()->GetDriverBugWorkarounds(workaround_list);
471 status->Set("workarounds", workaround_list);
474 return status;
477 // This class receives javascript messages from the renderer.
478 // Note that the WebUI infrastructure runs on the UI thread, therefore all of
479 // this class's methods are expected to run on the UI thread.
480 class GpuMessageHandler
481 : public WebUIMessageHandler,
482 public base::SupportsWeakPtr<GpuMessageHandler>,
483 public GpuDataManagerObserver {
484 public:
485 GpuMessageHandler();
486 virtual ~GpuMessageHandler();
488 // WebUIMessageHandler implementation.
489 virtual void RegisterMessages() OVERRIDE;
491 // GpuDataManagerObserver implementation.
492 virtual void OnGpuInfoUpdate() OVERRIDE;
493 virtual void OnGpuSwitching() OVERRIDE;
495 // Messages
496 void OnBrowserBridgeInitialized(const base::ListValue* list);
497 void OnCallAsync(const base::ListValue* list);
499 // Submessages dispatched from OnCallAsync
500 base::Value* OnRequestClientInfo(const base::ListValue* list);
501 base::Value* OnRequestLogMessages(const base::ListValue* list);
503 private:
504 // True if observing the GpuDataManager (re-attaching as observer would
505 // DCHECK).
506 bool observing_;
508 DISALLOW_COPY_AND_ASSIGN(GpuMessageHandler);
511 ////////////////////////////////////////////////////////////////////////////////
513 // GpuMessageHandler
515 ////////////////////////////////////////////////////////////////////////////////
517 GpuMessageHandler::GpuMessageHandler()
518 : observing_(false) {
521 GpuMessageHandler::~GpuMessageHandler() {
522 GpuDataManagerImpl::GetInstance()->RemoveObserver(this);
525 /* BrowserBridge.callAsync prepends a requestID to these messages. */
526 void GpuMessageHandler::RegisterMessages() {
527 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
529 web_ui()->RegisterMessageCallback("browserBridgeInitialized",
530 base::Bind(&GpuMessageHandler::OnBrowserBridgeInitialized,
531 base::Unretained(this)));
532 web_ui()->RegisterMessageCallback("callAsync",
533 base::Bind(&GpuMessageHandler::OnCallAsync,
534 base::Unretained(this)));
537 void GpuMessageHandler::OnCallAsync(const base::ListValue* args) {
538 DCHECK_GE(args->GetSize(), static_cast<size_t>(2));
539 // unpack args into requestId, submessage and submessageArgs
540 bool ok;
541 const base::Value* requestId;
542 ok = args->Get(0, &requestId);
543 DCHECK(ok);
545 std::string submessage;
546 ok = args->GetString(1, &submessage);
547 DCHECK(ok);
549 base::ListValue* submessageArgs = new base::ListValue();
550 for (size_t i = 2; i < args->GetSize(); ++i) {
551 const base::Value* arg;
552 ok = args->Get(i, &arg);
553 DCHECK(ok);
555 base::Value* argCopy = arg->DeepCopy();
556 submessageArgs->Append(argCopy);
559 // call the submessage handler
560 base::Value* ret = NULL;
561 if (submessage == "requestClientInfo") {
562 ret = OnRequestClientInfo(submessageArgs);
563 } else if (submessage == "requestLogMessages") {
564 ret = OnRequestLogMessages(submessageArgs);
565 } else { // unrecognized submessage
566 NOTREACHED();
567 delete submessageArgs;
568 return;
570 delete submessageArgs;
572 // call BrowserBridge.onCallAsyncReply with result
573 if (ret) {
574 web_ui()->CallJavascriptFunction("browserBridge.onCallAsyncReply",
575 *requestId,
576 *ret);
577 delete ret;
578 } else {
579 web_ui()->CallJavascriptFunction("browserBridge.onCallAsyncReply",
580 *requestId);
584 void GpuMessageHandler::OnBrowserBridgeInitialized(
585 const base::ListValue* args) {
586 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
588 // Watch for changes in GPUInfo
589 if (!observing_)
590 GpuDataManagerImpl::GetInstance()->AddObserver(this);
591 observing_ = true;
593 // Tell GpuDataManager it should have full GpuInfo. If the
594 // Gpu process has not run yet, this will trigger its launch.
595 GpuDataManagerImpl::GetInstance()->RequestCompleteGpuInfoIfNeeded();
597 // Run callback immediately in case the info is ready and no update in the
598 // future.
599 OnGpuInfoUpdate();
602 base::Value* GpuMessageHandler::OnRequestClientInfo(
603 const base::ListValue* list) {
604 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
606 base::DictionaryValue* dict = new base::DictionaryValue();
608 dict->SetString("version", GetContentClient()->GetProduct());
609 dict->SetString("command_line",
610 CommandLine::ForCurrentProcess()->GetCommandLineString());
611 dict->SetString("operating_system",
612 base::SysInfo::OperatingSystemName() + " " +
613 base::SysInfo::OperatingSystemVersion());
614 dict->SetString("angle_revision", base::UintToString(BUILD_REVISION));
615 dict->SetString("graphics_backend", "Skia");
616 dict->SetString("blacklist_version",
617 GpuDataManagerImpl::GetInstance()->GetBlacklistVersion());
618 dict->SetString("driver_bug_list_version",
619 GpuDataManagerImpl::GetInstance()->GetDriverBugListVersion());
621 return dict;
624 base::Value* GpuMessageHandler::OnRequestLogMessages(const base::ListValue*) {
625 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
627 return GpuDataManagerImpl::GetInstance()->GetLogMessages();
630 void GpuMessageHandler::OnGpuInfoUpdate() {
631 // Get GPU Info.
632 scoped_ptr<base::DictionaryValue> gpu_info_val(GpuInfoAsDictionaryValue());
634 // Add in blacklisting features
635 base::Value* feature_status = GetFeatureStatus();
636 if (feature_status)
637 gpu_info_val->Set("featureStatus", feature_status);
639 // Send GPU Info to javascript.
640 web_ui()->CallJavascriptFunction("browserBridge.onGpuInfoUpdate",
641 *(gpu_info_val.get()));
644 void GpuMessageHandler::OnGpuSwitching() {
645 GpuDataManagerImpl::GetInstance()->RequestCompleteGpuInfoIfNeeded();
648 } // namespace
651 ////////////////////////////////////////////////////////////////////////////////
653 // GpuInternalsUI
655 ////////////////////////////////////////////////////////////////////////////////
657 GpuInternalsUI::GpuInternalsUI(WebUI* web_ui)
658 : WebUIController(web_ui) {
659 web_ui->AddMessageHandler(new GpuMessageHandler());
661 // Set up the chrome://gpu/ source.
662 BrowserContext* browser_context =
663 web_ui->GetWebContents()->GetBrowserContext();
664 WebUIDataSource::Add(browser_context, CreateGpuHTMLSource());
667 } // namespace content