From 4b1d402d8e3e4d26bc400b425ffa4d39b1a0fb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norbert=20Musia=C5=82?= <54953461+normusF7@users.noreply.github.com> Date: Fri, 6 Jun 2025 01:31:14 +0200 Subject: [PATCH 1/2] screen: crop without opengl on simple case --- .../scrcpy/video/ScreenCapture.java | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java b/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java index 5f4e1803f9..3100e504b6 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java @@ -45,6 +45,8 @@ public class ScreenCapture extends SurfaceCapture { private AffineMatrix transform; private OpenGLRunner glRunner; + private boolean useGl; + private Rect layerStackRect; public ScreenCapture(VirtualDisplayListener vdListener, Options options) { this.vdListener = vdListener; @@ -85,19 +87,40 @@ public void prepare() throws ConfigurationException { captureOrientation = Orientation.fromRotation(displayInfo.getRotation()); } + layerStackRect = null; + + boolean simpleCrop = crop != null + && angle == 0f + && captureOrientationLock == Orientation.Lock.Unlocked + && captureOrientation == Orientation.Orient0; + VideoFilter filter = new VideoFilter(displaySize); if (crop != null) { boolean transposed = (displayInfo.getRotation() % 2) != 0; filter.addCrop(crop, transposed); + if (simpleCrop) { + if (transposed) { + layerStackRect = new Rect(crop.top, crop.left, crop.bottom, crop.right); + } else { + layerStackRect = new Rect(crop); + } + } } - boolean locked = captureOrientationLock != Orientation.Lock.Unlocked; - filter.addOrientation(displayInfo.getRotation(), locked, captureOrientation); - filter.addAngle(angle); + if (simpleCrop) { + useGl = false; + transform = filter.getInverseTransform(); + videoSize = filter.getOutputSize().limit(maxSize).round8(); + } else { + useGl = true; + boolean locked = captureOrientationLock != Orientation.Lock.Unlocked; + filter.addOrientation(displayInfo.getRotation(), locked, captureOrientation); + filter.addAngle(angle); - transform = filter.getInverseTransform(); - videoSize = filter.getOutputSize().limit(maxSize).round8(); + transform = filter.getInverseTransform(); + videoSize = filter.getOutputSize().limit(maxSize).round8(); + } } @Override @@ -112,7 +135,7 @@ public void start(Surface surface) throws IOException { } Size inputSize; - if (transform != null) { + if (useGl) { // If there is a filter, it must receive the full display content inputSize = displayInfo.getSize(); assert glRunner == null; @@ -134,7 +157,8 @@ public void start(Surface surface) throws IOException { Size deviceSize = displayInfo.getSize(); int layerStack = displayInfo.getLayerStack(); - setDisplaySurface(display, surface, deviceSize.toRect(), inputSize.toRect(), layerStack); + Rect deviceRect = layerStackRect != null ? layerStackRect : deviceSize.toRect(); + setDisplaySurface(display, surface, deviceRect, inputSize.toRect(), layerStack); Ln.d("Display: using SurfaceControl API"); } catch (Exception surfaceControlException) { Ln.e("Could not create display using DisplayManager", displayManagerException); From 10e1442e3ae8ecdd8fbb2bf9c2df374908c181d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norbert=20Musia=C5=82?= <54953461+normusF7@users.noreply.github.com> Date: Fri, 6 Jun 2025 09:12:35 +0200 Subject: [PATCH 2/2] Fix crop to use SurfaceControl --- .../scrcpy/video/ScreenCapture.java | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java b/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java index 3100e504b6..be1375f592 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java @@ -147,11 +147,28 @@ public void start(Surface surface) throws IOException { inputSize = videoSize; } - try { - virtualDisplay = ServiceManager.getDisplayManager() - .createVirtualDisplay("scrcpy", inputSize.getWidth(), inputSize.getHeight(), displayId, surface); - Ln.d("Display: using DisplayManager API"); - } catch (Exception displayManagerException) { + boolean wantSurfaceControl = layerStackRect != null; + if (!wantSurfaceControl) { + try { + virtualDisplay = ServiceManager.getDisplayManager() + .createVirtualDisplay("scrcpy", inputSize.getWidth(), inputSize.getHeight(), displayId, surface); + Ln.d("Display: using DisplayManager API"); + } catch (Exception displayManagerException) { + try { + display = createDisplay(); + + Size deviceSize = displayInfo.getSize(); + int layerStack = displayInfo.getLayerStack(); + Rect deviceRect = layerStackRect != null ? layerStackRect : deviceSize.toRect(); + setDisplaySurface(display, surface, deviceRect, inputSize.toRect(), layerStack); + Ln.d("Display: using SurfaceControl API"); + } catch (Exception surfaceControlException) { + Ln.e("Could not create display using DisplayManager", displayManagerException); + Ln.e("Could not create display using SurfaceControl", surfaceControlException); + throw new AssertionError("Could not create display"); + } + } + } else { try { display = createDisplay(); @@ -161,9 +178,15 @@ public void start(Surface surface) throws IOException { setDisplaySurface(display, surface, deviceRect, inputSize.toRect(), layerStack); Ln.d("Display: using SurfaceControl API"); } catch (Exception surfaceControlException) { - Ln.e("Could not create display using DisplayManager", displayManagerException); Ln.e("Could not create display using SurfaceControl", surfaceControlException); - throw new AssertionError("Could not create display"); + try { + virtualDisplay = ServiceManager.getDisplayManager() + .createVirtualDisplay("scrcpy", inputSize.getWidth(), inputSize.getHeight(), displayId, surface); + Ln.d("Display: fallback to DisplayManager API"); + } catch (Exception displayManagerException) { + Ln.e("Could not create display using DisplayManager", displayManagerException); + throw new AssertionError("Could not create display"); + } } }