adb screencap 输出与设备上的不同

adb screencap output is different than on the device

我的 OpenGL 应用程序使用 Android NDK 进行混合时出现图形故障。

奇怪的是,当我通过adb screencap命令截图时,问题完全消失,结果看起来还不错。

我的问题是: 有没有办法知道制作屏幕截图的幕后发生了什么?例如,是否有 eglChooseConfig 以整个帧的某些特定值调用?或者可能有一些特定的初始 GL 状态被强制?

一些背景:

我的设备使用的是 Qualcomm Adreno 320。

当我为某些几何体调用 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 时出现故障。

我还发现设置 glColorMask(1, 1, 1, 0) 会导致我的设备出现黑屏(并且只会出现在该设备上),而截屏会导致完整、正确的游戏画面。

该应用程序在其他几个 Android 设备上没有输出故障,并且其他应用程序运行良好,即使是那些广泛使用混合的应用程序。

一般来说,设备没有装满像素的帧缓冲区,您可以在捕获屏幕时从中复制像素。 "screen capture" 函数实际上是 "redraw the screen into a buffer" 函数。如果 "secure" 图层或 DRM 内容在屏幕上,屏幕截图可能会略有不同。

这是一个单一的、完全不透明的表面吗?还是与上面或下面的另一层混合?

造成差异的最常见原因是 Hardware Composer 中的错误,但听起来您看到的是在单个表面上呈现的问题,所以这种可能性较小。如果你有一个 root 设备,你可以使用显示的命令打开和关闭 HWC 组合 here: adb shell service call SurfaceFlinger 1008 i32 1 will disable overlays and force GLES composition. (If none of that made any sense, read through the graphics architecture 文档。)

你能 post 正确和错误图像的图像吗? (一个通过屏幕截图,一个通过使用第二台设备为设备拍照。)

如果使用 adb shell screenrecord 录制屏幕,您会看到类似的问题吗?

我注释掉EGL_ALPHA_SIZE设置后问题就消失了:

const EGLint attribs[] = {
    EGL_BLUE_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_RED_SIZE, 8,
    //EGL_ALPHA_SIZE, 8,
    EGL_NONE
};

看起来 alpha 设置为 8 位,eglChooseConfig 返回了一个有问题的配置对象。

有趣的是,"correct" EGLConfigEGL_ALPHA_SIZE 指定了 0 位,所以起初我认为它根本不起作用。其他设备并不真正关心值,它们在仅提供 RGB 通道深度的情况下表现良好。

我吸取了教训:如果您的设备出现图形故障,请始终检查所有可能的 EGL 配置!

所以我的结论是:是的,可能里面有一个自定义的 EGLConfig 集 adb screencap