系列文章请扫关注公众号!
前面文章聊得都是理论知识,对于程序猿来讲很无聊。不是有句话”Talk is cheap, show me the code ” 嘛,所以从最简单的显示demo开始实践吧。
- Android系统编译
Android的系统编译一般按照步骤
$source build/envsetup.sh
$lunch qssi-userdebug
$mmm 或 mm 或make编译
编译出的bin或so在 out/target/product/qssi/下
例如frameworks/native/libs/gui/tests/编译
$mmm frameworks/native/libs/gui/tests/ -j16
生成的测试bin在out/target/product/qssi/data/nativetest64/下。
2、效果显示视频:
cc
3、Code重点类说明:
ComposerServiceAIDL::getComposerService();
libgui库中的功能函数,是一个Singleton单例,通过它获取surfacefligner服务
const String16 name("SurfaceFlinger");
mComposerService = waitForService<ISurfaceComposer>(name);
也可以通过它调用captureDisplay()实现屏幕截取。
SurfaceComposerClient()
是创建和管理 Surface 的一个关键类,可以与 SurfaceFlinger 通信。进而通过getInternalDisplayToken()接口获取屏幕Token信息。
进而通过getActiveDisplayMode()获取对应display的宽高等信息。
使用获取到的宽高,通过createSurface()创建Surface。
BLASTBufferQueue()
创建一个缓冲区队列,并使用上面创建的Surface作为初始化参数,实现了Surface和BBQ的绑定。
IGraphicBufferProducer
是生产者-消费者模型中的生产者接口。这个类提供了一组方法,用于请求新的缓冲区、提交缓冲区、取消缓冲区等操作。
典型使用场景是应用程序的绘制线程通过 IGraphicBufferProducer 将绘制的内容提交给 SurfaceFlinger,SurfaceFlinger 然后将这些内容合成并显示到屏幕上。
IGraphicBufferProducer 的方法
requestBuffer(int slot, sp<GraphicBuffer>* buf):
请求一个图形缓冲区。slot 是缓冲区的插槽编号,buf 是返回的缓冲区对象。
dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t width, uint32_t height, PixelFormat format, uint32_t usage):
从缓冲区队列中取出一个空闲的缓冲区,以便生产者进行写操作。返回缓冲区的插槽编号和同步围栏。
queueBuffer(int slot, const QueueBufferInput& input, QueueBufferOutput* output):
将填充好的缓冲区提交给消费者。slot 是缓冲区的插槽编号,input 包含缓冲区的信息,output 包含提交后的返回信息。
cancelBuffer(int slot, const sp<Fence>& fence):
取消对一个缓冲区的请求。slot 是缓冲区的插槽编号,fence 是同步围栏。
connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp, QueueBufferOutput* output):
连接生产者到缓冲区队列。listener 是生产者的监听器,api 是使用的 API 类型,producerControlledByApp 指示生产者是否由应用控制,output 包含连接后的返回信息。
disconnect(int api):
断开生产者与缓冲区队列的连接。api 是使用的 API 类型。
Capture Display
屏幕抓取有两个类需要关注
DisplayCaptureArgs:这是传入参数,包含displayToken,width、height等信息。
ScreenCaptureResults:是传出参数,主要用来存放buffer数据。
通过sf = ComposerServiceAIDL::getComposerService();得到composer服务,再调用其接口sf->captureDisplay(captureArgs, captureListener);获取Buffer数据。
遍历每个像素值,比较是否和之前绘制上去的颜色值一致。
代码下载:见公众号地址: