scrcpy icon indicating copy to clipboard operation
scrcpy copied to clipboard

Android14 mirrordisplay

Open chenxuanyu opened this issue 1 year ago • 7 comments

  • [ ] I have read the FAQ.
  • [ ] I have searched in existing issues.

Environment

  • OS: Android14
  • scrcpy version: [scrcpy-win64-v2.4]
  • installation method: window open
  • device model:
  • Android version: [14]

Describe the bug

When creating a virtual screen in the Android system or using native methods to create a surface, Scrcpy opens with a black screen. I checked the source code of Android 14 and it seems that creating mirrordisplay is required. Scrcpy did not cause a black screen due to this operation. Please help confirm. Thank you

chenxuanyu avatar Apr 16 '24 02:04 chenxuanyu

I'm not sure to understand.

Scrcpy did not cause a black screen due to this operation.

Could you please post some commit/patch to show what you changed?

rom1v avatar Apr 16 '24 08:04 rom1v

in Scrcpy server code, does mirror mian display in android 14,so it show black screen. should use SurfaceComposerClient call mirrorDisplay function. and setLayerStack for the mirror screen

chenxuanyu avatar Apr 16 '24 09:04 chenxuanyu

in Scrcpy server code, does mirror mian display in android 14,so it show black screen.

Scrcpy correctly works on Android 14. It shows a black screen for windows with "secure flag" set (since Android 12, see #2129).

should use SurfaceComposerClient call mirrorDisplay function. and setLayerStack for the mirror screen

Please post a commit/patch to show what you suggest.

rom1v avatar Apr 16 '24 12:04 rom1v

this is my test code: create a surface . run on main display. but not show in scrcpy

sp<SurfaceControl> surfaceControl = client->createSurface(String8("TestSurface"),
                                                              3000, 3000, PIXEL_FORMAT_RGB_565,
                                                              0);
    sp<Surface> surface = surfaceControl->getSurface();
    SurfaceComposerClient::Transaction{}
        .setLayer(surfaceControl, std::numeric_limits<int32_t>::max()).show(surfaceControl).apply();
    SurfaceComposerClient::Transaction t;
    t.setFixedTransformHint(surfaceControl, android::ui::Transform::ROT_0);
    t.setLayerStack(surfaceControl, ui::LayerStack::fromValue(0));
    t.show(surfaceControl);
    t.apply();
    ANativeWindow_Buffer outBuffer;
    surface->lock(&outBuffer, NULL);
    ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
    memset((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);
    surface->unlockAndPost();

chenxuanyu avatar Apr 26 '24 11:04 chenxuanyu

my suggest code is : 1、set scrcpy virtualdisplay layerStack 2、also set the layerStack to mirrordisplay sp<SurfaceComposerClient> client = SurfaceComposerClient::getDefault(); sp<SurfaceControl> surface; surface = client->mirrorDisplay(maindisplayid); SurfaceComposerClient::Transaction t; t.setLayerStack(surface, ui::LayerStack::fromValue(layerStack)); t.apply();

chenxuanyu avatar Apr 26 '24 11:04 chenxuanyu

The screen capture code is here (in java, not in C++): https://github.com/Genymobile/scrcpy/blob/master/server/src/main/java/com/genymobile/scrcpy/ScreenCapture.java

What do you suggest to change here?

rom1v avatar Apr 26 '24 11:04 rom1v

--- a/server/src/main/java/com/genymobile/scrcpy/ScreenCapture.java
+++ b/server/src/main/java/com/genymobile/scrcpy/ScreenCapture.java
@@ -43,11 +43,15 @@ public class ScreenCapture extends SurfaceCapture implements Device.RotationList
virtualDisplay.release();
virtualDisplay = null;
}
     try {
         display = createDisplay();
       setDisplaySurface(display, surface, videoRotation, contentRect, unlockedVideoRect, layerStack);
       Ln.d("cxyDisplay: using SurfaceControl API layerStack:...."+layerStack);
       if(Build.VERSION.SDK_INT >=34){
           setDisplaySurface(display, surface, videoRotation, contentRect, unlockedVideoRect, device.getDisplayLayerStack());
       }else{
           setDisplaySurface(display, surface, videoRotation, contentRect, unlockedVideoRect, layerStack);
       }
       Ln.d("cxyDisplay: using mirror layerStack:"+layerStack+",current displayLayerStack:"+device.getDisplayLayerStack()+",Android:"+Build.VERSION.SDK_INT);
   } catch (Exception surfaceControlException) {
       Rect videoRect = screenInfo.getVideoSize().toRect();
       try {
@@ -106,6 +110,10 @@ public class ScreenCapture extends SurfaceCapture implements Device.RotationList
SurfaceControl.setDisplaySurface(display, surface);
SurfaceControl.setDisplayProjection(display, orientation, deviceRect, displayRect);
SurfaceControl.setDisplayLayerStack(display, layerStack);

       //mirror
       if(Build.VERSION.SDK_INT >=34) {
           SurfaceControl.mirrorMainDisplay(layerStack);
       }
   } finally {
       SurfaceControl.closeTransaction();
   }

mirrorMainDisplay use jni call SurfaceComposerClient set getDisplayLayerStack can get by android api

chenxuanyu avatar Apr 26 '24 11:04 chenxuanyu