我的设备是运行 Jelly Bean 4.2 的 Nexus 4。我正在尝试录制屏幕并将其发送出去。互联网上的大多数代码通过读取/dev/graphics/fb0 来达到上限。它在某些设备和旧系统中运行良好。但是当我在我的设备上尝试时,它失败了。它只给我黑屏和原始数据中的所有“0”。我已经运行“adb root”以获得root权限,尝试了“chmod 777 fb0”,“cat fb0 >/sdcard/fb0”。我也尝试过像“mmap”和“memcpy”这样的代码来获取数据。但都失败了。我在互联网上搜索过,似乎没有解决方案。一些线程说内核可能会禁止你读取 fb0。有人对此有想法吗?
最佳答案
随着硬件的进步,您越来越不可能找到其中包含屏幕内容的实际帧缓冲区。
如评论中所述,adb 使用“screencap”命令,该命令通过 Binder 调用联系 surfaceflinger,如果失败则回退到 /dev/graphcs/fb0
。后一种路径现在很少使用。
如果你真的想深入了解它是如何工作的,你需要检查 surfaceflinger 是如何进行合成的,尤其是 hwcomposer HAL。硬件合成器采用多个 gralloc 表面并在扫描输出期间合成它们。它的工作原理因设备而异; hwcomposer 实现通常由图形芯片制造商完成。
应用程序框架使用屏幕截图生成功能为“最近的应用程序”功能生成缩略图,应用与 HWC 相同的合成步骤,但仅使用 GLES。从 Android 4.2 开始,硬件合成器无法合成到缓冲区中。
有时硬件 Composer 会“下注”,例如因为要合成的层数超出了硬件的处理能力。在这种情况下,Surfaceflinger 将恢复为 GLES 合成,某处 将有一个具有完整图像的缓冲区;你是否会通过打开 /dev/graphics/fb0
找到它是另一回事。
一些起点:
- surfaceflinger
- hwcomposer HAL interface
adb shell dumpsys SurfaceFlinger
关于Android读取fb0总是给我黑屏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17304611/