深入Android系统(十二)Android图形显示系统-2-SurfaceFlinger与图像输出

  • createEventConnection()方法返回的是一个IDisplayEventConnection对象mEvents

  • 接着通过IDisplayEventConnection对象的stealReceiveChannel()方法

  • 该方法主要是设置mEventTube对象的mReceiveFdmEventTube的类型是BitTube

  • BitTube对象中包含一对FdmReceiveFdmSendFd,初始化时会通过socketpair()创建全双工通信

  • 最后通过Looper类的addFd()方法将mReceiveFd添加到epoll监听列表中,并且传入了MessageQueue::cb_eventReceiver作为事件的回调方法

  • 回调方法如下:

int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
MessageQueue* queue = reinterpret_cast<MessageQueue*>(data);
return queue->eventReceiver(fd, events);
}
int MessageQueue::eventReceiver(int /fd/, int /events/) {
ssize_t n;
DisplayEventReceiver::Event buffer[8];
while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
for (int i = 0; i < n; i++) {
if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
mHandler->dispatchInvalidate();
break;
}
}
}
return 1;
}

  • 方法最后会调用mHandler->dispatchInvalidate();方法,这就会涉及到Handler的处理逻辑

我们看下Handler中的处理逻辑:

void MessageQueue::Handler::handleMessage(const Message& message) {
switch (message.what) {
case INVALIDATE:
android_atomic_and(~eventMaskInvalidate, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
}
}

调用了SurfaceFlingeronMessageReceived()方法,这里才是真正处理消息的地方,后面细讲这个方法哈

我们先看下EventThread

消息和事件分发-EventThread

EventThread的继承关系如下:

class EventThread : public android::EventThread, private VSyncSource::Callback {
}

需要注意的是VSyncSource::Callback类,它提供了一个onVSyncEvent()的回调方法

EventThread的构造方法如下(精简版):

EventThread::EventThread(…){

// 创建线程并开始执行,核心业务通过 threadMain() 方法来完成
mThread = std::thread(&EventThread::threadMain, this);
// 设置一些线程的名称和优先级
pthread_setname_np(mThread.native_handle(), threadName);

// 设置调度策略为 SP_FOREGROUND
set_sched_policy(tid, SP_FOREGROUND);
}

构造方法中启动了一个线程,这个线程的执行逻辑在threadMain()方法中:

void EventThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {
std::unique_lockstd::mutex lock(mMutex);
// mKeepRunning 只会在析构函数中置为 false
while (mKeepRunning) {
DisplayEventReceiver::Event event;
Vector<spEventThread::Connection > signalConnections;
// 通过 waitForEventLocked() 循环等待事件
// 方法中会通过 mCondition 对象的 wait() 方法进行等待
signalConnections = waitForEventLocked(&lock, &event);
const size_t count = signalConnections.size();
for (size_t i = 0; i < count; i++) {
const sp& conn(signalConnections[i]);
// 通过 postEvent() 将事件通知到到 MessageQueue
status_t err = conn->postEvent(event);

}
}
}

threadMain()方法中的重点是:

  • waitForEventLocked()方法会循环等待消息(也就是VSYNC信号),并获取到注册的Connection对象列表
  • 当接收到信号后,通过Connection对象的postEvent()将数据发送到MessageQueue
  • 此时MessageQueue中的Looper会检测到数据输入,然后通知回调MessageQueuecb_eventReceiver()方法

信号分发过程

前面讲过VSYNC信号由HWC产生,为了方便接收,HWComposer提供了一个HW2::ComposerCallback用于监听消息

class ComposerCallback {
public:
virtual void onHotplugReceived(…) = 0;
virtual void onRefreshReceived(…) = 0;
virtual void onVsyncReceived(…) = 0;
virtual ~ComposerCallback() = default;
};

  • 从前面类关系图中可以发现,SurfaceFlinger继承该类,我们重点关注onVsyncReceived()方法

SurfaceFlinger::onVsyncReceived()方法如下:

void SurfaceFlinger::onVsyncReceived(…) {

bool needsHwVsync = false;
{ // Scope for the lock
Mutex::Autolock _l(mHWVsyncLock);
if (type == DisplayDevice::DISPLAY_PRIMARY && mPrimaryHWVsyncEnabled) {
// 通过 addResyncSample 来进一步分发信号
needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
}
}

}

onVsyncReceived()方法调用mPrimaryDispSync对象的addResyncSample()方法来进一步分发VSYNC信号

  • mPrimaryDispSync对象的类型是DispSync,这个类比较简单,核心是它的成员变量mThread,类型是DispSyncThread
DispSync::DispSync(const char* name)
mName(name), mRefreshSkipCount(0), mThread(new DispSyncThread(name)) {}

void DispSync::init(bool hasSyncFramework, int64_t dispSyncPresentTimeOffset) {

mThread->run(“DispSync”, PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);

}

addResyncSample()方法中最重要的

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值