OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 /** | 6 /** |
7 * @fileoverview This view displays information on the current GPU | 7 * @fileoverview This view displays information on the current GPU |
8 * hardware. Its primary usefulness is to allow users to copy-paste | 8 * hardware. Its primary usefulness is to allow users to copy-paste |
9 * their data in an easy to read format for bug reports. | 9 * their data in an easy to read format for bug reports. |
10 */ | 10 */ |
11 cr.define('gpu', function() { | 11 cr.define('gpu', function() { |
12 /** | 12 /** |
13 * Provides information on the GPU process and underlying graphics hardware. | 13 * Provides information on the GPU process and underlying graphics hardware. |
14 * @constructor | 14 * @constructor |
15 * @extends {Tab} | 15 * @extends {Tab} |
16 */ | 16 */ |
17 var InfoView = cr.ui.define(gpu.Tab); | 17 var InfoView = cr.ui.define(gpu.Tab); |
18 | 18 |
19 InfoView.prototype = { | 19 InfoView.prototype = { |
20 __proto__: gpu.Tab.prototype, | 20 __proto__: gpu.Tab.prototype, |
21 | 21 |
22 decorate: function() { | 22 decorate: function() { |
23 gpu.Tab.prototype.decorate.apply(this); | 23 gpu.Tab.prototype.decorate.apply(this); |
24 | 24 |
25 this.beginRequestClientInfo(); | |
26 | |
27 this.logMessages_ = []; | |
28 this.beginRequestLogMessages(); | |
29 | |
30 browserBridge.addEventListener('gpuInfoUpdate', this.refresh.bind(this)); | 25 browserBridge.addEventListener('gpuInfoUpdate', this.refresh.bind(this)); |
| 26 browserBridge.addEventListener('logMessagesChange', |
| 27 this.refresh.bind(this)); |
| 28 browserBridge.addEventListener('clientInfoChange', |
| 29 this.refresh.bind(this)); |
31 this.refresh(); | 30 this.refresh(); |
32 }, | 31 }, |
33 | 32 |
34 /** | 33 /** |
35 * This function begins a request for the ClientInfo. If it comes back | |
36 * as undefined, then we will issue the request again in 250ms. | |
37 */ | |
38 beginRequestClientInfo: function() { | |
39 browserBridge.callAsync('requestClientInfo', undefined, (function(data) { | |
40 this.clientInfo_ = data; | |
41 this.refresh(); | |
42 if (data === undefined) { // try again in 250 ms | |
43 window.setTimeout(this.beginRequestClientInfo.bind(this), 250); | |
44 } | |
45 }).bind(this)); | |
46 }, | |
47 | |
48 /** | |
49 * This function checks for new GPU_LOG messages. | |
50 * If any are found, a refresh is triggered. | |
51 */ | |
52 beginRequestLogMessages: function() { | |
53 browserBridge.callAsync('requestLogMessages', undefined, | |
54 (function(messages) { | |
55 if (messages.length != this.logMessages_.length) { | |
56 this.logMessages_ = messages; | |
57 this.refresh(); | |
58 } | |
59 // check again in 250 ms | |
60 window.setTimeout(this.beginRequestLogMessages.bind(this), 250); | |
61 }).bind(this)); | |
62 }, | |
63 | |
64 /** | |
65 * Updates the view based on its currently known data | 34 * Updates the view based on its currently known data |
66 */ | 35 */ |
67 refresh: function(data) { | 36 refresh: function(data) { |
68 // Client info | 37 // Client info |
69 if (this.clientInfo_) { | 38 if (browserBridge.clientInfo) { |
70 var chromeVersion = this.clientInfo_.version + | 39 var clientInfo = browserBridge.clientInfo; |
71 ' (' + this.clientInfo_.official + | 40 var chromeVersion = clientInfo.version + |
72 ' ' + this.clientInfo_.cl + | 41 ' (' + clientInfo.official + |
73 ') ' + this.clientInfo_.version_mod; | 42 ' ' + clientInfo.cl + |
| 43 ') ' + clientInfo.version_mod; |
74 this.setTable_('client-info', [ | 44 this.setTable_('client-info', [ |
75 { | 45 { |
76 description: 'Data exported', | 46 description: 'Data exported', |
77 value: (new Date()).toLocaleString() | 47 value: (new Date()).toLocaleString() |
78 }, | 48 }, |
79 { | 49 { |
80 description: 'Chrome version', | 50 description: 'Chrome version', |
81 value: chromeVersion | 51 value: chromeVersion |
82 }, | 52 }, |
83 { | 53 { |
84 description: 'Software rendering list version', | 54 description: 'Software rendering list version', |
85 value: this.clientInfo_.blacklist_version | 55 value: clientInfo.blacklist_version |
86 }]); | 56 }]); |
87 } else { | 57 } else { |
88 this.setText_('client-info', '... loading...'); | 58 this.setText_('client-info', '... loading...'); |
89 } | 59 } |
90 | 60 |
| 61 // Feature map |
| 62 var featureNameMap = { |
| 63 'accelerated_2d_canvas': 'Canvas', |
| 64 'accelerated_compositing': '3D CSS', |
| 65 'webgl': 'WebGL', |
| 66 'multisampling': 'WebGL multisampling' |
| 67 }; |
| 68 |
91 // GPU info, basic | 69 // GPU info, basic |
92 var diagnostics = this.querySelector('.diagnostics'); | 70 var diagnostics = this.querySelector('.diagnostics'); |
93 var blacklistedIndicator = this.querySelector('.blacklisted-indicator'); | 71 var featureStatusList = this.querySelector('.feature-status-list'); |
| 72 var problemsDiv = this.querySelector('.problems-div'); |
| 73 var problemsList = this.querySelector('.problems-list'); |
94 var gpuInfo = browserBridge.gpuInfo; | 74 var gpuInfo = browserBridge.gpuInfo; |
| 75 var i; |
95 if (gpuInfo) { | 76 if (gpuInfo) { |
96 if (gpuInfo.blacklistingReasons) { | 77 // Not using jstemplate here for blacklist status because we construct |
97 blacklistedIndicator.hidden = false; | 78 // href from data, which jstemplate can't seem to do. |
98 // Not using jstemplate here because we need to manipulate | 79 if (gpuInfo.featureStatus) { |
99 // href on the fly | 80 // feature status list |
100 var reasonsEl = blacklistedIndicator.querySelector( | 81 featureStatusList.textContent = ''; |
101 '.blacklisted-reasons'); | 82 for (i = 0; i < gpuInfo.featureStatus.featureStatus.length; |
102 reasonsEl.textContent = ''; | 83 i++) { |
103 for (var i = 0; i < gpuInfo.blacklistingReasons.length; i++) { | 84 var feature = gpuInfo.featureStatus.featureStatus[i]; |
104 var reason = gpuInfo.blacklistingReasons[i]; | 85 var featureEl = document.createElement('li'); |
105 | 86 |
106 var reasonEl = document.createElement('li'); | 87 var nameEl = document.createElement('span'); |
| 88 nameEl.textContent = featureNameMap[feature.name] + ': '; |
| 89 featureEl.appendChild(nameEl); |
107 | 90 |
108 // Description of issue | 91 var statusEl = document.createElement('span'); |
109 var desc = document.createElement('a'); | 92 if (feature.status == 'enabled') { |
110 desc.textContent = reason.description; | 93 statusEl.textContent = 'enabled'; |
111 reasonEl.appendChild(desc); | 94 statusEl.className = 'feature-enabled'; |
| 95 } else if (feature.status == 'software') { |
| 96 statusEl.textContent = 'software only'; |
| 97 statusEl.className = 'feature-software'; |
| 98 } else { // disabled |
| 99 statusEl.textContent = 'disabled'; |
| 100 statusEl.className = 'feature-disabled'; |
| 101 } |
| 102 featureEl.appendChild(statusEl); |
112 | 103 |
113 // Spacing ':' element | 104 featureStatusList.appendChild(featureEl); |
114 if (reason.cr_bugs.length + reason.webkit_bugs.length > 0) { | 105 } |
115 var tmp = document.createElement('span'); | 106 |
116 tmp.textContent = ' '; | 107 // problems list |
117 reasonEl.appendChild(tmp); | 108 if (gpuInfo.featureStatus.problems.length) { |
| 109 problemsDiv.hidden = false; |
| 110 problemsList.textContent = ''; |
| 111 for (i = 0; i < gpuInfo.featureStatus.problems.length; i++) { |
| 112 var problem = gpuInfo.featureStatus.problems[i]; |
| 113 var problemEl = this.createProblemEl_(problem); |
| 114 problemsList.appendChild(problemEl); |
118 } | 115 } |
| 116 } else { |
| 117 problemsDiv.hidden = true; |
| 118 } |
119 | 119 |
120 var nreasons = 0; | |
121 var j; | |
122 // cr_bugs | |
123 for (j = 0; j < reason.cr_bugs.length; ++j) { | |
124 if (nreasons > 0) { | |
125 var tmp = document.createElement('span'); | |
126 tmp.textContent = ', '; | |
127 reasonEl.appendChild(tmp); | |
128 } | |
129 | |
130 var link = document.createElement('a'); | |
131 var bugid = parseInt(reason.cr_bugs[j]); | |
132 link.textContent = bugid; | |
133 link.href = 'http://crbug.com/' + bugid; | |
134 reasonEl.appendChild(link); | |
135 nreasons++; | |
136 } | |
137 | |
138 for (j = 0; j < reason.webkit_bugs.length; ++j) { | |
139 if (nreasons > 0) { | |
140 var tmp = document.createElement('span'); | |
141 tmp.textContent = ', '; | |
142 reasonEl.appendChild(tmp); | |
143 } | |
144 | |
145 var link = document.createElement('a'); | |
146 var bugid = parseInt(reason.webkit_bugs[j]); | |
147 link.textContent = bugid; | |
148 | |
149 link.href = 'https://bugs.webkit.org/show_bug.cgi?id=' + bugid; | |
150 reasonEl.appendChild(link); | |
151 nreasons++; | |
152 } | |
153 | |
154 reasonsEl.appendChild(reasonEl); | |
155 } | |
156 } else { | 120 } else { |
157 blacklistedIndicator.hidden = true; | 121 featureStatusList.textContent = ''; |
| 122 problemsList.hidden = true; |
158 } | 123 } |
159 this.setTable_('basic-info', gpuInfo.basic_info); | 124 if (gpuInfo.basic_info) |
| 125 this.setTable_('basic-info', gpuInfo.basic_info); |
| 126 else |
| 127 this.setTable_('basic-info', []); |
160 | 128 |
161 if (gpuInfo.diagnostics) { | 129 if (gpuInfo.diagnostics) { |
162 diagnostics.hidden = false; | 130 diagnostics.hidden = false; |
163 this.setTable_('diagnostics-table', gpuInfo.diagnostics); | 131 this.setTable_('diagnostics-table', gpuInfo.diagnostics); |
164 } else { | 132 } else { |
165 diagnostics.hidden = true; | 133 diagnostics.hidden = true; |
166 } | 134 } |
167 } else { | 135 } else { |
168 blacklistedIndicator.hidden = true; | |
169 this.setText_('basic-info', '... loading ...'); | 136 this.setText_('basic-info', '... loading ...'); |
170 diagnostics.hidden = true; | 137 diagnostics.hidden = true; |
| 138 featureStatusList.textContent = ''; |
| 139 problemsDiv.hidden = true; |
171 } | 140 } |
172 | 141 |
173 // Log messages | 142 // Log messages |
174 if (!browserBridge.debugMode) { | 143 jstProcess(new JsEvalContext({values: browserBridge.logMessages}), |
175 jstProcess(new JsEvalContext({values: this.logMessages_}), | 144 document.getElementById('log-messages')); |
176 document.getElementById('log-messages')); | 145 }, |
| 146 |
| 147 createProblemEl_: function(problem) { |
| 148 var problemEl; |
| 149 problemEl = document.createElement('li'); |
| 150 |
| 151 // Description of issue |
| 152 var desc = document.createElement('a'); |
| 153 desc.textContent = problem.description; |
| 154 problemEl.appendChild(desc); |
| 155 |
| 156 // Spacing ':' element |
| 157 if (problem.crBugs.length + problem.webkitBugs.length > 0) { |
| 158 var tmp = document.createElement('span'); |
| 159 tmp.textContent = ': '; |
| 160 problemEl.appendChild(tmp); |
177 } | 161 } |
| 162 |
| 163 var nbugs = 0; |
| 164 var j; |
| 165 |
| 166 // crBugs |
| 167 for (j = 0; j < problem.crBugs.length; ++j) { |
| 168 if (nbugs > 0) { |
| 169 var tmp = document.createElement('span'); |
| 170 tmp.textContent = ', '; |
| 171 problemEl.appendChild(tmp); |
| 172 } |
| 173 |
| 174 var link = document.createElement('a'); |
| 175 var bugid = parseInt(problem.crBugs[j]); |
| 176 link.textContent = bugid; |
| 177 link.href = 'http://crbug.com/' + bugid; |
| 178 problemEl.appendChild(link); |
| 179 nbugs++; |
| 180 } |
| 181 |
| 182 for (j = 0; j < problem.webkitBugs.length; ++j) { |
| 183 if (nbugs > 0) { |
| 184 var tmp = document.createElement('span'); |
| 185 tmp.textContent = ', '; |
| 186 problemEl.appendChild(tmp); |
| 187 } |
| 188 |
| 189 var link = document.createElement('a'); |
| 190 var bugid = parseInt(problem.webkitBugs[j]); |
| 191 link.textContent = bugid; |
| 192 |
| 193 link.href = 'https://bugs.webkit.org/show_bug.cgi?id=' + bugid; |
| 194 problemEl.appendChild(link); |
| 195 nbugs++; |
| 196 } |
| 197 |
| 198 return problemEl; |
178 }, | 199 }, |
179 | 200 |
180 setText_: function(outputElementId, text) { | 201 setText_: function(outputElementId, text) { |
181 var peg = document.getElementById(outputElementId); | 202 var peg = document.getElementById(outputElementId); |
182 peg.innerText = text; | 203 peg.innerText = text; |
183 }, | 204 }, |
184 | 205 |
185 setTable_: function(outputElementId, inputData) { | 206 setTable_: function(outputElementId, inputData) { |
186 var template = jstGetTemplate('info-view-table-template'); | 207 var template = jstGetTemplate('info-view-table-template'); |
187 jstProcess(new JsEvalContext({value: inputData}), | 208 jstProcess(new JsEvalContext({value: inputData}), |
188 template); | 209 template); |
189 | 210 |
190 var peg = document.getElementById(outputElementId); | 211 var peg = document.getElementById(outputElementId); |
191 if (!peg) | 212 if (!peg) |
192 throw new Error('Node ' + outputElementId + ' not found'); | 213 throw new Error('Node ' + outputElementId + ' not found'); |
193 | 214 |
194 peg.innerHTML = ''; | 215 peg.innerHTML = ''; |
195 peg.appendChild(template); | 216 peg.appendChild(template); |
196 } | 217 } |
197 }; | 218 }; |
198 | 219 |
199 return { | 220 return { |
200 InfoView: InfoView | 221 InfoView: InfoView |
201 }; | 222 }; |
202 }); | 223 }); |
OLD | NEW |