Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(351)

Side by Side Diff: remoting/webapp/crd/js/client_session.js

Issue 804783002: Improve DPI matching & scaling logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Improve comments Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698