Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 * @fileoverview | 6 * @fileoverview |
| 7 * Class handling creation and teardown of a remoting client session. | 7 * Class handling creation and teardown of a remoting client session. |
| 8 * | 8 * |
| 9 * The ClientSession class controls lifetime of the client plugin | 9 * The ClientSession class controls lifetime of the client plugin |
| 10 * object and provides the plugin with the functionality it needs to | 10 * object and provides the plugin with the functionality it needs to |
| (...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1248 remoting.ClientSession.prototype.updateDimensions = function() { | 1248 remoting.ClientSession.prototype.updateDimensions = function() { |
| 1249 if (this.plugin_.getDesktopWidth() == 0 || | 1249 if (this.plugin_.getDesktopWidth() == 0 || |
| 1250 this.plugin_.getDesktopHeight() == 0) { | 1250 this.plugin_.getDesktopHeight() == 0) { |
| 1251 return; | 1251 return; |
| 1252 } | 1252 } |
| 1253 | 1253 |
| 1254 var clientArea = this.getClientArea_(); | 1254 var clientArea = this.getClientArea_(); |
| 1255 var desktopWidth = this.plugin_.getDesktopWidth(); | 1255 var desktopWidth = this.plugin_.getDesktopWidth(); |
| 1256 var desktopHeight = this.plugin_.getDesktopHeight(); | 1256 var desktopHeight = this.plugin_.getDesktopHeight(); |
| 1257 | 1257 |
| 1258 // When configured to display a host at its original size, we aim to display | 1258 // We have the following goals in sizing the desktop display at the client: |
| 1259 // it as close to its physical size as possible, without losing data: | 1259 // 1. Avoid losing detail by down-scaling beyond 1:1 host:device pixels. |
| 1260 // - If client and host have matching DPI, render the host pixel-for-pixel. | 1260 // 2. Avoid up-scaling if that will cause the client to need scrollbars. |
| 1261 // - If the host has higher DPI then still render pixel-for-pixel. | 1261 // 3. Avoid introducing blurriness with non-integer up-scaling factors. |
| 1262 // - If the host has lower DPI then let Chrome up-scale it to natural size. | 1262 // 4. Avoid having huge "letterboxes" around the desktop, if it's really |
| 1263 // small. | |
| 1264 // | |
| 1265 // To determine the ideal size we follow a four-stage process: | |
| 1266 // 1. Determine the "natural" size at which to display the desktop. | |
| 1267 // a. Initially assume 1:1 mapping of desktop to client device pixels. | |
| 1268 // b. If host DPI is less than the client's then up-scale accordingly. | |
|
Jamie
2015/01/09 22:23:47
Does this overrule constraint 3, above?
| |
| 1269 // c. If desktopScale is configured for the host then allow that to | |
| 1270 // cancel-out some or all of the up-scaling from (b). | |
|
Jamie
2015/01/09 22:23:47
It's not clear what "some or all" means here. Can
| |
| 1271 // 2. If the natural size of the desktop is smaller than the client device | |
| 1272 // then apply up-scaling by an integer scale factor to avoid excessive | |
| 1273 // letterboxing. | |
|
Jamie
2015/01/09 22:23:47
Does "avoid excessive letterboxing" imply that we'
| |
| 1274 // 3. If shrink-to-fit is configured, and the natural size exceeds the | |
| 1275 // client size then apply down-scaling by an arbitrary scale factor. | |
| 1276 // 4. If the overall scale factor is fractionally over an integer factor | |
| 1277 // then reduce it to that integer factor, to avoid blurring. | |
|
Jamie
2015/01/09 22:23:47
By "fractionally", do mean "only just"? Given that
| |
| 1263 | 1278 |
| 1264 // We specify the plugin dimensions in Density-Independent Pixels, so to | 1279 // All calculations are performed in device pixels. |
| 1265 // render pixel-for-pixel we need to down-scale the host dimensions by the | 1280 var clientWidth = clientArea.width * window.devicePixelRatio; |
| 1266 // devicePixelRatio of the client. To match the host pixel density, we choose | 1281 var clientHeight = clientArea.height * window.devicePixelRatio; |
| 1267 // an initial scale factor based on the client devicePixelRatio and host DPI. | |
| 1268 | 1282 |
| 1269 // Determine the effective device pixel ratio of the host, based on DPI. | 1283 // 1. Determine a "natural" size at which to display the desktop. |
| 1284 var scale = 1.0; | |
| 1285 | |
| 1286 // Determine the effective host device pixel ratio. | |
| 1270 var hostPixelRatioX = Math.ceil(this.plugin_.getDesktopXDpi() / 96); | 1287 var hostPixelRatioX = Math.ceil(this.plugin_.getDesktopXDpi() / 96); |
| 1271 var hostPixelRatioY = Math.ceil(this.plugin_.getDesktopYDpi() / 96); | 1288 var hostPixelRatioY = Math.ceil(this.plugin_.getDesktopYDpi() / 96); |
| 1272 var hostPixelRatio = Math.min(hostPixelRatioX, hostPixelRatioY); | 1289 var hostPixelRatio = Math.min(hostPixelRatioX, hostPixelRatioY); |
| 1273 | 1290 |
| 1274 // Include the desktopScale in the hostPixelRatio before comparing it with | 1291 // Allow up-scaling to account for DPI. |
| 1275 // the client devicePixelRatio to determine the "natural" scale to use. | 1292 scale = Math.max(scale, window.devicePixelRatio / hostPixelRatio); |
| 1276 hostPixelRatio *= this.desktopScale_; | |
| 1277 | 1293 |
| 1278 // Down-scale by the smaller of the client and host ratios. | 1294 // Allow some or all of the up-scaling to be cancelled by the desktopScale. |
| 1279 var scale = 1.0 / Math.min(window.devicePixelRatio, hostPixelRatio); | 1295 if (this.desktopScale_ > 1.0) { |
| 1296 scale = Math.max(1.0, scale / this.desktopScale_); | |
| 1297 } | |
| 1280 | 1298 |
| 1299 // 2. Up-scale to avoid excessive letterboxing, if necessary. | |
| 1300 if (desktopWidth * scale <= clientWidth && | |
| 1301 desktopHeight * scale <= clientHeight) { | |
| 1302 var scaleX = Math.floor(clientWidth / desktopWidth); | |
| 1303 var scaleY = Math.floor(clientHeight / desktopHeight); | |
| 1304 scale = Math.min(scaleX, scaleY); | |
| 1305 } | |
| 1306 | |
| 1307 // 3. Apply shrink-to-fit, if configured. | |
| 1281 if (this.shrinkToFit_) { | 1308 if (this.shrinkToFit_) { |
| 1282 // Reduce the scale, if necessary, to fit the whole desktop in the window. | 1309 var scaleFitWidth = Math.min(scale, 1.0 * clientWidth / desktopWidth); |
| 1283 var scaleFitWidth = Math.min(scale, 1.0 * clientArea.width / desktopWidth); | 1310 var scaleFitHeight = Math.min(scale, 1.0 * clientHeight / desktopHeight); |
| 1284 var scaleFitHeight = | |
| 1285 Math.min(scale, 1.0 * clientArea.height / desktopHeight); | |
| 1286 scale = Math.min(scaleFitHeight, scaleFitWidth); | 1311 scale = Math.min(scaleFitHeight, scaleFitWidth); |
| 1287 | 1312 |
| 1313 // TODO(wez): Fix multi-monitor and wide/tall desktop handling. | |
| 1288 // If we're running full-screen then try to handle common side-by-side | 1314 // If we're running full-screen then try to handle common side-by-side |
| 1289 // multi-monitor combinations more intelligently. | 1315 // multi-monitor combinations more intelligently. |
| 1290 if (remoting.fullscreen.isActive()) { | 1316 if (remoting.fullscreen.isActive()) { |
| 1291 // If the host has two monitors each the same size as the client then | 1317 // If the host has two monitors each the same size as the client then |
| 1292 // scale-to-fit will have the desktop occupy only 50% of the client area, | 1318 // scale-to-fit will have the desktop occupy only 50% of the client area, |
| 1293 // in which case it would be preferable to down-scale less and let the | 1319 // in which case it would be preferable to down-scale less and let the |
| 1294 // user bump-scroll around ("scale-and-pan"). | 1320 // user bump-scroll around ("scale-and-pan"). |
| 1295 // Triggering scale-and-pan if less than 65% of the client area would be | 1321 // Triggering scale-and-pan if less than 65% of the client area would be |
| 1296 // used adds enough fuzz to cope with e.g. 1280x800 client connecting to | 1322 // used adds enough fuzz to cope with e.g. 1280x800 client connecting to |
| 1297 // a (2x1280)x1024 host nicely. | 1323 // a (2x1280)x1024 host nicely. |
| 1298 // Note that we don't need to account for scrollbars while fullscreen. | 1324 // Note that we don't need to account for scrollbars while fullscreen. |
| 1299 if (scale <= scaleFitHeight * 0.65) { | 1325 if (scale <= scaleFitHeight * 0.65) { |
| 1300 scale = scaleFitHeight; | 1326 scale = scaleFitHeight; |
| 1301 } | 1327 } |
| 1302 if (scale <= scaleFitWidth * 0.65) { | 1328 if (scale <= scaleFitWidth * 0.65) { |
| 1303 scale = scaleFitWidth; | 1329 scale = scaleFitWidth; |
| 1304 } | 1330 } |
| 1305 } | 1331 } |
| 1306 } | 1332 } |
| 1307 | 1333 |
| 1334 // 4. Avoid blurring for close-to-integer up-scaling factors. | |
| 1335 if (scale > 1.0) { | |
| 1336 var scaleBlurriness = scale / Math.floor(scale); | |
| 1337 if (scaleBlurriness < 1.1) { | |
| 1338 scale = Math.floor(scale); | |
| 1339 } | |
| 1340 } | |
| 1341 | |
| 1342 // Determine the necessary plugin dimensions in DIPs. | |
| 1343 scale = scale / window.devicePixelRatio; | |
| 1308 var pluginWidth = Math.round(desktopWidth * scale); | 1344 var pluginWidth = Math.round(desktopWidth * scale); |
| 1309 var pluginHeight = Math.round(desktopHeight * scale); | 1345 var pluginHeight = Math.round(desktopHeight * scale); |
| 1310 | 1346 |
| 1311 // Resize the plugin if necessary. | 1347 // Resize the plugin if necessary. |
| 1312 // TODO(wez): Handle high-DPI to high-DPI properly (crbug.com/135089). | 1348 // TODO(wez): Handle high-DPI to high-DPI properly (crbug.com/135089). |
| 1313 this.plugin_.element().style.width = pluginWidth + 'px'; | 1349 this.plugin_.element().style.width = pluginWidth + 'px'; |
| 1314 this.plugin_.element().style.height = pluginHeight + 'px'; | 1350 this.plugin_.element().style.height = pluginHeight + 'px'; |
| 1315 | 1351 |
| 1316 // Position the container. | 1352 // Position the container. |
| 1317 // Note that clientWidth/Height take into account scrollbars. | 1353 // Note that clientWidth/Height take into account scrollbars. |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1726 * @param {Object} message The parsed extension message data. | 1762 * @param {Object} message The parsed extension message data. |
| 1727 * @return {boolean} True if the message was recognized, false otherwise. | 1763 * @return {boolean} True if the message was recognized, false otherwise. |
| 1728 */ | 1764 */ |
| 1729 remoting.ClientSession.prototype.handleExtensionMessage = | 1765 remoting.ClientSession.prototype.handleExtensionMessage = |
| 1730 function(type, message) { | 1766 function(type, message) { |
| 1731 if (this.videoFrameRecorder_) { | 1767 if (this.videoFrameRecorder_) { |
| 1732 return this.videoFrameRecorder_.handleMessage(type, message); | 1768 return this.videoFrameRecorder_.handleMessage(type, message); |
| 1733 } | 1769 } |
| 1734 return false; | 1770 return false; |
| 1735 } | 1771 } |
| OLD | NEW |