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
返回了一个有问题的配置对象。
有趣的是,“正确的”EGLConfig
为EGL_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 输出与设备上的不同的主要内容,如果未能解决你的问题,请参考以下文章