安卓读fb0老是黑屏
Posted
技术标签:
【中文标题】安卓读fb0老是黑屏【英文标题】:Android read fb0 always give me blackscreen 【发布时间】:2013-06-25 18:14:35 【问题描述】:我的设备是运行 Jelly Bean 4.2 的 Nexus 4。我正在尝试记录屏幕并将其发送出去。互联网上的大多数代码通过读取 /dev/graphics/fb0 来完成上限。它在某些设备和旧系统中运行良好。但是当我在我的设备上尝试它时,它失败了。它只给我黑屏和原始数据中的所有“0”。我已经运行“adb root”来获得 root 权限,尝试了“chmod 777 fb0”、“cat fb0 > /sdcard/fb0”。我也尝试过像“mmap”和“memcpy”这样的代码来获取数据。但都失败了。我在互联网上搜索过,似乎没有解决方案。并且一些线程说内核可能会禁止您读取 fb0。有人对此有想法吗?
【问题讨论】:
对于更现代的 GPU,帧缓冲区可能在大多数情况下都无法被主 CPU 轻松访问(至少不是全部)。很久以前,大多数 ADBD 实现都转向使用外部设备唯一的可执行文件(称为 screencap)来执行捕获帧缓冲区的实际工作。您可以使用它,尝试查找文档/源代码,或尝试对可执行文件进行逆向工程。通常我会在源代码上说“祝你好运”,但对于 Nexus 设备,它可能实际上是可用的(或者他们可能只是提供二进制文件以及其他封闭位) 感谢您的回复。实际上,android 的原始代码包含两个可执行文件名称:screencap 和 screenshot。他们的代码中有两种方式。一种是读取fb0,另一种是调用Android原生库提供的glPixel()。第二个很慢。实际上我已经用第二种方法实现了一个,但是 fps 并不理想。所以我回去尝试以第一种方式来做。我的项目没有限制。我什至可以破解内核来实现它。被这个问题困扰了好几个星期。需要帮助。 您需要的是低级 GPU 编程信息,遗憾的是,制造商通常不会发布这些信息。我不相信他们放弃简单的 fb 阅读是为了困难甚至是为了安全。他们这样做是因为硬件不再容易(或至少可移植地)将整个事物暴露为连续的缓冲区。在此更改之后,我跟踪了另一个实现,即读取与一些低级代码交互的块中的真实帧缓冲区 - 比逐像素方法更有效,但又是特定硬件独有的。 我已尝试更改帧缓冲区和 gralloc 代码中的 fb_post 函数。但还是不行。当一个新的应用程序打开时,我只得到第一帧。是否有任何代码示例或链接详细讨论此问题? 【参考方案1】:随着硬件的进步,您越来越不可能找到包含屏幕内容的实际帧缓冲区。
如 cmets 中所述,adb 使用“screencap”命令,该命令通过 Binder 调用联系 surfaceflinger,如果失败则返回 /dev/graphcs/fb0
。后一种路径现在很少使用了。
如果你真的想深入了解它是如何工作的,你需要研究一下surfaceflinger 是如何进行组合的,尤其是hwcomposer HAL。硬件作曲家采用多个gralloc 表面并在扫描输出期间合成它们。它的工作方式因设备而异; hwcomposer 的实现通常由图形芯片制造商完成。
屏幕截图生成,由应用程序框架用于为“最近的应用程序”功能生成缩略图,应用 HWC 所做的相同合成步骤,但仅适用于 GLES。从 Android 4.2 开始,硬件合成器无法合成到缓冲区中。
有时硬件作曲家“平底船”,例如因为要合成的层数超出了硬件的处理能力。在这种情况下,surfaceflinger 会恢复为 GLES 合成,并且会有一个缓冲区某处包含完整的图像;打开/dev/graphics/fb0
是否能找到它是另一回事。
一些起点:
surfaceflinger hwcomposer HAL interfaceadb shell dumpsys SurfaceFlinger
【讨论】:
以上是关于安卓读fb0老是黑屏的主要内容,如果未能解决你的问题,请参考以下文章