mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-04-21 01:33:36 +00:00
Added adaptive virtual display that adjusts to window size
This commit is contained in:
parent
3fcc177da5
commit
52709d60ba
12 changed files with 308 additions and 8 deletions
|
|
@ -25,6 +25,7 @@ public final class ControlMessage {
|
|||
public static final int TYPE_OPEN_HARD_KEYBOARD_SETTINGS = 15;
|
||||
public static final int TYPE_START_APP = 16;
|
||||
public static final int TYPE_RESET_VIDEO = 17;
|
||||
public static final int TYPE_SET_DISPLAY_SIZE = 18;
|
||||
|
||||
public static final long SEQUENCE_INVALID = 0;
|
||||
|
||||
|
|
@ -53,6 +54,9 @@ public final class ControlMessage {
|
|||
private boolean on;
|
||||
private int vendorId;
|
||||
private int productId;
|
||||
private int displayWidth;
|
||||
private int displayHeight;
|
||||
private int displayDpi;
|
||||
|
||||
private ControlMessage() {
|
||||
}
|
||||
|
|
@ -166,6 +170,15 @@ public final class ControlMessage {
|
|||
return msg;
|
||||
}
|
||||
|
||||
public static ControlMessage createSetDisplaySize(int width, int height, int dpi) {
|
||||
ControlMessage msg = new ControlMessage();
|
||||
msg.type = TYPE_SET_DISPLAY_SIZE;
|
||||
msg.displayWidth = width;
|
||||
msg.displayHeight = height;
|
||||
msg.displayDpi = dpi;
|
||||
return msg;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
|
@ -249,4 +262,16 @@ public final class ControlMessage {
|
|||
public int getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public int getDisplayWidth() {
|
||||
return displayWidth;
|
||||
}
|
||||
|
||||
public int getDisplayHeight() {
|
||||
return displayHeight;
|
||||
}
|
||||
|
||||
public int getDisplayDpi() {
|
||||
return displayDpi;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ public class ControlMessageReader {
|
|||
case ControlMessage.TYPE_OPEN_HARD_KEYBOARD_SETTINGS:
|
||||
case ControlMessage.TYPE_RESET_VIDEO:
|
||||
return ControlMessage.createEmpty(type);
|
||||
case ControlMessage.TYPE_SET_DISPLAY_SIZE:
|
||||
return parseSetDisplaySize();
|
||||
case ControlMessage.TYPE_UHID_CREATE:
|
||||
return parseUhidCreate();
|
||||
case ControlMessage.TYPE_UHID_INPUT:
|
||||
|
|
@ -141,6 +143,13 @@ public class ControlMessageReader {
|
|||
return ControlMessage.createSetDisplayPower(on);
|
||||
}
|
||||
|
||||
private ControlMessage parseSetDisplaySize() throws IOException {
|
||||
int width = dis.readUnsignedShort();
|
||||
int height = dis.readUnsignedShort();
|
||||
int dpi = dis.readUnsignedShort();
|
||||
return ControlMessage.createSetDisplaySize(width, height, dpi);
|
||||
}
|
||||
|
||||
private ControlMessage parseUhidCreate() throws IOException {
|
||||
int id = dis.readUnsignedShort();
|
||||
int vendorId = dis.readUnsignedShort();
|
||||
|
|
|
|||
|
|
@ -96,6 +96,9 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
|||
private final MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[PointersState.MAX_POINTERS];
|
||||
|
||||
private boolean keepDisplayPowerOff;
|
||||
private String lastStartedAppPackage;
|
||||
private boolean lastStartedAppForceStop;
|
||||
private boolean pendingRelaunchOnResize;
|
||||
|
||||
// Used for resetting video encoding on RESET_VIDEO message
|
||||
private SurfaceCapture surfaceCapture;
|
||||
|
|
@ -146,6 +149,11 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
|||
displayDataAvailable.notify();
|
||||
}
|
||||
}
|
||||
if (pendingRelaunchOnResize && lastStartedAppPackage != null) {
|
||||
pendingRelaunchOnResize = false;
|
||||
Ln.i("Relaunching app \"" + lastStartedAppPackage + "\" on resized display " + virtualDisplayId + "...");
|
||||
Device.startApp(lastStartedAppPackage, virtualDisplayId, lastStartedAppForceStop);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSurfaceCapture(SurfaceCapture surfaceCapture) {
|
||||
|
|
@ -331,6 +339,9 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
|||
case ControlMessage.TYPE_RESET_VIDEO:
|
||||
resetVideo();
|
||||
break;
|
||||
case ControlMessage.TYPE_SET_DISPLAY_SIZE:
|
||||
setDisplaySize(msg.getDisplayWidth(), msg.getDisplayHeight(), msg.getDisplayDpi());
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
}
|
||||
|
|
@ -691,6 +702,8 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
|||
|
||||
Ln.i("Starting app \"" + app.getName() + "\" [" + app.getPackageName() + "] on display " + startAppDisplayId + "...");
|
||||
Device.startApp(app.getPackageName(), startAppDisplayId, forceStopBeforeStart);
|
||||
lastStartedAppPackage = app.getPackageName();
|
||||
lastStartedAppForceStop = forceStopBeforeStart;
|
||||
}
|
||||
|
||||
private int getStartAppDisplayId() {
|
||||
|
|
@ -754,4 +767,18 @@ public class Controller implements AsyncProcessor, VirtualDisplayListener {
|
|||
surfaceCapture.requestInvalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void setDisplaySize(int width, int height, int dpi) {
|
||||
if (surfaceCapture instanceof com.genymobile.scrcpy.video.NewDisplayCapture) {
|
||||
com.genymobile.scrcpy.video.NewDisplayCapture nd =
|
||||
(com.genymobile.scrcpy.video.NewDisplayCapture) surfaceCapture;
|
||||
Ln.i("Resize virtual display to " + width + "x" + height + "/" + dpi);
|
||||
if (lastStartedAppPackage != null) {
|
||||
pendingRelaunchOnResize = true;
|
||||
}
|
||||
nd.setDisplaySize(width, height, dpi);
|
||||
} else {
|
||||
Ln.w("Display resize ignored: not a virtual display capture");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ public class NewDisplayCapture extends SurfaceCapture {
|
|||
private Size physicalSize; // the physical size of the display (without rotation)
|
||||
|
||||
private int dpi;
|
||||
private Size requestedDisplaySize;
|
||||
private int requestedDpi;
|
||||
private boolean hasRequestedSize;
|
||||
|
||||
public NewDisplayCapture(VirtualDisplayListener vdListener, Options options) {
|
||||
this.vdListener = vdListener;
|
||||
|
|
@ -105,11 +108,20 @@ public class NewDisplayCapture extends SurfaceCapture {
|
|||
public void prepare() {
|
||||
int displayRotation;
|
||||
if (virtualDisplay == null) {
|
||||
if (!newDisplay.hasExplicitSize()) {
|
||||
displaySize = mainDisplaySize;
|
||||
}
|
||||
if (!newDisplay.hasExplicitDpi()) {
|
||||
dpi = scaleDpi(mainDisplaySize, mainDisplayDpi, displaySize);
|
||||
if (hasRequestedSize && requestedDisplaySize != null) {
|
||||
displaySize = requestedDisplaySize;
|
||||
if (requestedDpi != 0) {
|
||||
dpi = requestedDpi;
|
||||
} else {
|
||||
dpi = scaleDpi(mainDisplaySize, mainDisplayDpi, displaySize);
|
||||
}
|
||||
} else {
|
||||
if (!newDisplay.hasExplicitSize()) {
|
||||
displaySize = mainDisplaySize;
|
||||
}
|
||||
if (!newDisplay.hasExplicitDpi()) {
|
||||
dpi = scaleDpi(mainDisplaySize, mainDisplayDpi, displaySize);
|
||||
}
|
||||
}
|
||||
|
||||
videoSize = displaySize;
|
||||
|
|
@ -266,4 +278,33 @@ public class NewDisplayCapture extends SurfaceCapture {
|
|||
public void requestInvalidate() {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public synchronized void setDisplaySize(int width, int height, int dpi) {
|
||||
if (width <= 0 || height <= 0) {
|
||||
return;
|
||||
}
|
||||
requestedDisplaySize = new Size(width, height);
|
||||
requestedDpi = dpi;
|
||||
hasRequestedSize = true;
|
||||
|
||||
if (virtualDisplay != null) {
|
||||
int newDpi = dpi;
|
||||
if (newDpi == 0) {
|
||||
newDpi = scaleDpi(mainDisplaySize, mainDisplayDpi, requestedDisplaySize);
|
||||
}
|
||||
|
||||
try {
|
||||
virtualDisplay.resize(width, height, newDpi);
|
||||
displaySizeMonitor.setSessionDisplaySize(requestedDisplaySize);
|
||||
Ln.i("Virtual display resized in-place to " + width + "x" + height + "/" + newDpi);
|
||||
} catch (Exception e) {
|
||||
Ln.w("Virtual display resize failed, fallback to recreate", e);
|
||||
displaySizeMonitor.stopAndRelease();
|
||||
virtualDisplay.release();
|
||||
virtualDisplay = null;
|
||||
}
|
||||
}
|
||||
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue