adb screencap 输出与设备上的不同

Posted

技术标签:

【中文标题】adb screencap 输出与设备上的不同【英文标题】:adb screencap output is different than on the device 【发布时间】:2015-07-31 10:38:30 【问题描述】:

我有一个与使用 android NDK 在我的 OpenGL 应用程序中混合相关的图形故障。

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

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

一些背景:

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

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

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

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

【问题讨论】:

【参考方案1】:

一般来说,设备没有一个充满像素的帧缓冲区,您可以在捕获屏幕时复制这些像素。 “屏幕捕获”功能实际上是“将屏幕重绘为缓冲区”功能。如果屏幕上有“安全”层或 DRM 内容,屏幕截图可能会略有不同。

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

产生差异的最常见原因是 Hardware Composer 中的错误,但听起来您在单个表面上渲染时遇到了问题,因此不太可能。如果您有一个根设备,您可以使用here 显示的命令打开和关闭 HWC 组合:adb shell service call SurfaceFlinger 1008 i32 1 将禁用覆盖并强制 GLES 组合。 (如果这些都没有任何意义,请通读graphics architecture 文档。)

您能否发布正确和错误图像的图像? (一种通过屏幕截图,一种通过使用第二台设备拍摄设备的照片。)

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

【讨论】:

非常感谢您的宝贵意见。在开始遵循您提供的提示之前,我解决了这个问题。我将接受我自己的答案,以便每个人都能看到问题的真正原因,但你有我的赞成票。【参考方案2】:

一旦我注释掉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 返回了一个有问题的配置对象。

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

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

所以我的结论是:是的,可能在adb screencap 中设置了自定义 EGLConfig。

【讨论】:

FWIW,Grafika 选择 alpha 大小为 8 (github.com/google/grafika/blob/master/src/com/android/grafika/…),我从未见过任何奇怪的东西。我猜大多数 GLES 应用程序都使用这种配置(32 位 RGBA)。屏幕捕获代码合成了渲染的输出,我不希望用于 blitting 的 EGL 配置具有“修复”渲染的效果。所以这是一个非常有趣的数据点,但我怀疑还有更多。可能值得恢复 alpha 大小并添加 EGL_RENDERABLE_TYPE 以查看这是否也会改变。 对 - 我没有考虑这些其他配置变量。虽然,我已经尝试了 EGL_ALPHA_SIZE 未注释的所有 9 种配置,但它们都产生了不正确的结果。我认为解决这个谜团不值得付出努力,这很可能是这些模型已知的驱动程序错误之一,而这个甚至不支持 glBlendFuncSeparate (!)

以上是关于adb screencap 输出与设备上的不同的主要内容,如果未能解决你的问题,请参考以下文章

使用adb命令对移动设备截图

Android中的adb连接与多个系统

ADB 命令

adb 将远程端口转发到本地机器

adb命令可以给不同手机同时运行重启脚本么

Appium ADB 错误:当设备通过端口 5555 上的 tcpip 连接时,获取设备平台版本时出错