微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

深入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;
}

我们看下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()方法中最重要的是执行了dispSyncThread对象的updateModel()方法

void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) {
… // 省略和 VSYNC 信号相关的一些赋值操作
// 重点是此处通过 Conditon.signal() 来唤醒 dispSyncThread 线程
mCond.signal();
}

dispSyncThread线程的执行函数如下:

virtual bool threadLoop() {

while (true) {
Vector callbackInvocations;
nsecs_t targetTime = 0;
{ // Scope for lock

if (Now < targetTime) {
if (targetTime == INT64_MAX) {
err = mCond.wait(mMutex);
} else {
err = mCond.waitRelative(mMutex, targetTime - Now);
}

}
Now = systemTime(SYstem_TIME_MONOTONIC);

// 取得 Callback 列表
callbackInvocations = gatherCallbackInvocationsLocked(Now);
}
// 通过 fireCallbackInvocations() 调用
if (callbackInvocations.size() > 0) {
fireCallbackInvocations(callbackInvocations);
}
}
return false;
}

threadLoop()中大部分是比较和计算时间,决定是否要发送信号

  • 如果没有信号发送,就会在mCond上等待
  • 这也就是updateModel()中需要调用mCondsignal()来唤醒的原因
  • 当确认需要发送信号时,先通过gatherCallbackInvocationsLocked()获取本次VSYNC信号回调通知的监听对象
  • 这些监听对象都是通过addEventListener()方法进行添加

void fireCallbackInvocations(const Vector& callbacks) {
if (kTraceDetailedInfo) ATRACE_CALL();
for (size_t i = 0; i < callbacks.size(); i++) {
callbacks[i].mCallback->ondispSyncEvent(callbacks[i].mEventTime);
}
}

  • 查看CallbackInvocation结构就会发现,回调接口的类型是dispSync::Callback

@H_978_404@那么SurfaceFlinger中哪几个类实现了dispSync::Callback呢?
聪明的我们会发现,SurfaceFlinger中的dispSyncSource继承了这个类,而且重点是下面部分的代码

class dispSyncSource final : public VSyncSource, private dispSync::Callback {
public:

void setVSyncEnabled(bool enable) override {
Mutex::Autolock lock(mVsyncMutex);
if (enable) {
status_t err = mdispSync->addEventListener(mName, mPhaSEOffset, static_castdispSync::Callback*(this));

} else {
status_t err = mdispSync->removeEventListener(static_castdispSync::Callback*(this));

}
mEnabled = enable;
}

private:
virtual void ondispSyncEvent(nsecs_t when) {
VSyncSource::Callback* callback;
… // 省略 VSYNC 信号处理的一些操作
callback = mCallback;
if (callback != nullptr) {
callback->onVSyncEvent(when);
}
}

}

可以发现:

@H_978_404@VSyncSource::Callback对象又是和谁关联呢?
还记得前面的EventThread么!!!EventThread便是继承了VSyncSource::Callback类,我们看下EventThread中关于onVSyncEvent()方法的实现:

void EventThread::onVSyncEvent(nsecs_t timestamp) {
std::lock_guardstd::mutex lock(mMutex);
mVSyncEvent[0].header.type = displayEventReceiver::disPLAY_EVENT_VSYNC;
mVSyncEvent[0].header.id = 0;
mVSyncEvent[0].header.timestamp = timestamp;
mVSyncEvent[0].vsync.count++;
mCondition.notify_all();
}

前面EventThread部分提到过

  • threadMain中的waitForEventLocked()会通过mCondition.wait()等待消息,
  • onVSyncEvent()会通过notify_all()唤醒threadMain处理消息
  • 因此会执行到conn->postEvent(event);方法
  • postEvent()方法会通过BitTube对象将数据发送到MessageQueue
  • 接下来便会触发执行MessageQueuecb_eventReceiver()方法

前面MessageQueue章节提到过,cb_eventReceiver()方法最后会调用的是SurfaceFlingeronMessageReceived()方法,而且消息类型是INVALIDATE

我们看下方法内容

void SurfaceFlinger::onMessageReceived(int32_t what) {
switch (what) {
case Mess


ageQueue::INVALIDATE: {

bool refreshNeeded = handleMessageTransaction();

break;
}
case MessageQueue::REFRESH: {
handleMessageRefresh();
break;
}
}
}

INVALIDATE消息的处理逻辑比较复杂,我们重点关注的是handleMessageTransaction()方法,它会创建displayDevice对象。我们先看下displayDevice对象

显示设备的抽象-displayDevice

displayDevice类是显示设备的抽象,当前Android 9中定义了3种显示设备类型:

这三种显示设备,第一种是基本配置,另外两种需要硬件支持。关于display官网有个极其简单的介绍:传送门

SurfaceFlingerdisplayDevice负责与OpenGL ES交互,即使没有任何物理显示设备被检测到,SurfaceFlinger都需要一个displayDevice对象才能正常工作

SurfaceFlinger将需要显示的图层Layer通过displayDevice对象传递到OpenGL ES中进行合成,合成后再通过HWComposer对象传送到FrameBuffer显示

displayDevice对象中的成员变量Vector< sp<Layer> > mVisibleLayeRSSortedByZ;保存了所有需要在本设备中显示Layer对象

displayDevice比较复杂,先简单了解下它的创建流程。前面提到了handleMessageTransaction()方法中会创建displayDevice对象,我们看下具体的创建流程:

void SurfaceFlinger::processdisplayChangesLocked() {

if (!curr.isIdenticalTo(draw)) {

for (size_t i = 0; i < cc; i++) {
if (draw.indexOfKey(curr.keyAt(i)) < 0) {
const displayDeviceState& state(curr[i]);
sp dispSurface;
sp producer;
sp bqProducer;
sp bqConsumer;
// mCreateBufferQueue是一个函数指针,指向的是 BufferQueue::createBufferQueue
// 这就很熟悉了,和我们前面分析 Surface 时创建的 BufferQueue 一样
mCreateBufferQueue(&bqProducer, &bqConsumer, false);
int32_t hwcId = -1;
if (state.isVirtualdisplay()) {
… // 省略虚拟屏幕创建的逻辑
} else {

hwcId = state.type;
// 创建 FramebufferSurface 用于数据传输
dispSurface = new FramebufferSurface(*getBE().mHwc, hwcId, bqConsumer);
producer = bqProducer;
}
const wp& display(curr.keyAt(i));
if (dispSurface != nullptr) {
// 通过 setupNewdisplayDeviceInternal() 创建 displayDevice 对象
// 并添加到 mdisplays 集合中
mdisplays.add(display, setupNewdisplayDeviceInternal(display, hwcId, state, dispSurface, producer));
if (!state.isVirtualdisplay()) {
mEventThread->onHotplugReceived(state.type, true);
}
}
}
}
}
mDrawingState.displays = mCurrentState.displays;
}

  • 上面的代码中通过BufferQueue::createBufferQueue创建了consumerproducer对象(这部分和前面讲的BufferQueue的逻辑是相同的)
  • 并基于创建的consumer对象和一个HWComposer对象创建一个FramebufferSurface对象
  • 最后将上面的对象作为参数通过setupNewdisplayDeviceInternal()方法创建displayDevice对象,并添加mdisplays集合中

sp SurfaceFlinger::setupNewdisplayDeviceInternal(
const wp& display, int hwcId, const displayDeviceState& state,
const sp& dispSurface, const sp& producer) {

// mCreateNativeWindowSurface 也是一个函数指针,执行的是 NativeWindowSurface::create() 方法
// 该方法利用 IGraphicBufferProducer 生成 NativeWindowSurface 和 NativeWindow 对象
// 其实也是 EGL 相关的接口调用
auto nativeWindowSurface = mCreateNativeWindowSurface(producer);
auto nativeWindow = nativeWindowSurface->getNativeWindow();
// 通过渲染引擎创建 OpenGL 渲染的目标 EGLSurface
std::unique_ptrRE::Surface renderSurface = getRenderEngine().createSurface();
renderSurface->setCritical(state.type == displayDevice::disPLAY_PRIMARY);
renderSurface->setAsync(state.type >= displayDevice::disPLAY_VIRTUAL);
// 执行 eglCreateWindowSurface 操作
renderSurface->setNativeWindow(nativeWindow.get());

// 创建 displayDevice 对象
sp hw = new displayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,
dispSurface, std::move(renderSurface), displayWidth, displayHeight,
hasWideColorGamut, hdrCapabilities,
supportedPerFrameMetadata, hwcColorModes, initialPowerMode);

return hw;
}

displayDevice对象创建完成,意味着SurfaceFlinger就可以利用displayDevice对象写入图像数据,并通过

  • EGLSurface–>BufferQueue–>FrameBufferSurface–>HWCComposer–>Gralloc

这样一条路径到达显示设备的FrameBuffer

SurfaceFlingerinit()run()

有了前面的铺垫知识,init()run()就很好理解了

SurfaceFlinger::init

void SurfaceFlinger::init() {
// 创建 app 的 dispSyncSource 和 EventThread
mEventThreadSource = std::make_unique(&mPrimarydispSync, SurfaceFlinger::vsyncPhaSEOffsetNs, true, “app”);
mEventThread = std::make_uniqueimpl::EventThread(mEventThreadSource.get(), …, “appEventThread”);
// 创建 sf 的 dispSyncSource 和 EventThread
mSfEventThreadSource = std::make_unique(&mPrimarydispSync, SurfaceFlinger::sfVsyncPhaSEOffsetNs, true, “sf”);
mSFEventThread = std::make_uniqueimpl::EventThread(mSfEventThreadSource.get(), …, “sfEventThread”);
// 将 mSFEventThread 与 MessageQueue 进行关联
mEventQueue->setEventThread(mSFEventThread.get());
// 将 mSFEventThread 和 mEventThread 添加到 VSYNC 信号调制器中
mVsyncModulator.setEventThreads(mSFEventThread.get(), mEventThread.get());
// 创建渲染引擎,主要是选择EGL配置,选择OpenGL版本,创建OpenGL上下文
getBE().mRenderEngine = RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,…);

// 初始化 HWC
getBE().mHwc.reset( new HWComposer(std::make_uniqueHwc2::impl::Composer(getBE().mHwcServiceName)));
// 注册 HWC 的 Callback 监听
// VSYNC 信号便会从这里进行回调通知
getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);

// 创建 VSYNC 事件接收控制对象,enable=true 表示允许 HWC 产生 VSYNC 信号
// sufacefinlger 通过这个对象来控制 HWC 是否产生 VSYNC 信号
mEventControlThread = std::make_uniqueimpl::EventControlThread([this](bool enabled) { setVsyncEnabled(HWC_disPLAY_PRIMARY, enabled); });

// 该方法会通过 MessageQueue 发送一个异步消息
// 消息处理中会完成 primary displayDevice 的创建,并进行 VSYNC 周期的设定
initializedisplays();

// 根据 PresentFenceIsNotReliable 属性创建 StartPropertySetThread对象
if (getHwComposer().hasCapability(HWC2::Capability::PresentFenceIsNotReliable)) {
mStartPropertySetThread = new StartPropertySetThread(false);
} else {
mStartPropertySetThread = new StartPropertySetThread(true);
}
// 执行 StartPropertySetThread,该线程会通过 setProp 触发开机动画,包括设置以下两个Prop
// property_set(“service.bootanim.exit”, “0”); 复位动画退出标记
// property_set(“ctl.start”, “bootanim”); 启动开机动画
if (mStartPropertySetThread->Start() != NO_ERROR) {
ALOGE(“Run StartPropertySetThread Failed!”);
}

ALOGV(“Done initializing”);
}

init()方法初始化了很多重要的对象:

  • 初始化appsf两组dispSyncSourceEventThread对象
  • 这两个分别代表了VSYNC信号的两个消费者:AppSurfaceFlinger
  • sf对应的信号分发逻辑与铺垫知识中的一致,因为是通过mEventQueue->setEventThread()来进行的关联
  • app的信号分发逻辑等下细看
  • 初始化HWComposer,并通过registerCallback()注册HWC2::ComposerCallback监听
  • 初始化EventControlThread对象,SurfaceFlinger用这个对象来控制HWC是否需要产生VSYNC信号
  • 认设置为不需要产生VSYNC信号
  • 初始化StartPropertySetThread线程,该线程会通过setProp的方式触发开机动画

SurfaceFlinger::run

run()方法比较简单:

void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}

方法中执行了一个无限循环来调用waitForEvent(),具体代码如下:

void SurfaceFlinger::waitForEvent() {
mEventQueue->waitMessage();
}

waitForEvent()方法调用MessageQueue对象的waitMessage()方法进入一个无限循环,这个方法MessageQueue部分中已经介绍过就不细讲啦

所以对于SurfaceFlinger进程来说,执行完run()当前线程就会进入一个无限循环,剩下的业务处理都变成了消息驱动来实现

App的绘制通知

SurfaceFlingerinit()方法中初始化了一个appEventThread,在接收到VSYNC信号后,它便会通知App去进行绘制操作,我们看下这个通知流程

再看onResume()

我们已经知道,onResume()方法后才会进行View显示,这部分体现在ActivityThread中的handleResumeActivity()方法中,代码如下:

public void handleResumeActivity(…) {

// Todo Push resumeArgs into the activity for consideration
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r == null) {
// We didn’t actually resume the activity, so skipping any follow-up actions.
return;
}
final Activity a = r.activity;

if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getwindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getwindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;

if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}
}

}

上面performResumeActivity()会回调应用程序的onResume()函数。不过本次我们重点关注的是wm.addView()方法,最后调用到的是WindowManagerGlobal.javaaddView()代码如下:

public void addView(…) {

ViewRootImpl root;
View panelParentView = null;
synchronized (mlock) {

root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
// do this last because it fires off messages to start doing things
try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvaliddisplayException, clean up.
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}

重点是初始化了ViewRootImpl对象,我们看下ViewRootImpl中的setView()方法调用

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;

requestLayout();

}
}
}
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputdispatch) {
scheduleConsumeBatchedinput();
}
notifyRendererOfFramePending();
pokeDrawLockIfNeeded();
}
}

执行到scheduleTraversals()方法就引出来一个最重要的类Choreographer,整个应用布局的渲染依赖这个对象的发动。

scheduleTraversals()方法调用mChoreographer对象的postCallback()方法添加一个回调对象mTraversalRunnable

mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);

mTraversalRunnable回调对象的定义如下:

final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}

doTraversal内部会调用大名鼎鼎的performTraversal()方法,到这里App就可以进行measure/layout/draw三大流程

那么 @H_978_404@mTraversalRunnable对象是在什么时候调用的呢?
我们带着疑问,先看下应用是如何接收VSYNC信号的

Choreographer

App要求渲染动画或者更新画面布局时都会用到Choreographer,接收VSYNC信号也依赖于Choreographer

在上面的scheduleTraversals()方法中执行了Choreographer对象的postCallback()方法

mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);

这个方法的含义就是@H_978_404@应用程序请求VSYNC信号,接收到VSYNC信号后执行mTraversalRunnable回调

那么接下来我们看下Choreographer如何接收vsync信号

displayEventReceiver

应用层可以通过displayEventReceiver类用来接收vsync信号,当接收到vsync信号后,会执行displayEventReceiver对象的onVsync()方法

displayEventReceiver是在AndroidView体系中定义的一个抽象类,对外隐藏的,核心定义如下

public abstract class displayEventReceiver {

// 用来表示 APP 的 VSYNC 信号源
public static final int VSYNC_SOURCE_APP = 0;
public displayEventReceiver(Looper looper) {
this(looper, VSYNC_SOURCE_APP);
}
public displayEventReceiver(Looper looper, int vsyncSource) {

mMessageQueue = looper.getQueue();
mReceiverPtr = nativeInit(new WeakReference(this), mMessageQueue,
vsyncSource);

}
private static native long nativeInit(WeakReference receiver,
MessageQueue messageQueue, int vsyncSource);
private static native void nativedispose(long receiverPtr);
private static native void nativeScheduleVsync(long receiverPtr);

public void onVsync(long timestampNanos, int builtIndisplayId, int frame) {
}

}

需要关注的是

先看下nativeInit()的实现

static jlong nativeInit(jnienv* env, jclass clazz, jobject receiverWeak,
jobject messageQueueObj, jint vsyncSource) {
sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);

sp receiver = new NativedisplayEventReceiver(env,
receiverWeak, messageQueue, vsyncSource);
status_t status = receiver->initialize();

}

nativeInit()方法创建了一个NativedisplayEventReceiver对象,并调用了它的initialize()方法

NativedisplayEventReceiver继承了displayEventdispatcher类,那么我们的重点便是displayEventdispatcher,头文件定义如下:

class displayEventdispatcher : public LooperCallback {
public:
displayEventdispatcher(const sp& looper,
ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp);
status_t initialize();

private:
sp mLooper;
displayEventReceiver mReceiver;

};

核心实现如下:

displayEventdispatcher::displayEventdispatcher(const sp& looper,
ISurfaceComposer::VsyncSource vsyncSource) :
mLooper(looper), mReceiver(vsyncSource), mWaitingForVsync(false) {
ALOGV(“dispatcher %p ~ Initializing display event dispatcher.”, this);
}
status_t displayEventdispatcher::initialize() {
status_t result = mReceiver.initCheck();

int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,
this, NULL);
if (rc < 0) {
return UNKNowN_ERROR;
}
return OK;
}

在铺垫知识部分已经了解到,如果应用要接收VSYNC信号,需要将其添加到对应的EventThread中,SF中一共创建了两个

  • mSFEventThreadSurfaceFlinger专用的
    • SurfaceFlingerinit()中通过mEventQueue->setEventThread()进行关联
    • setEventThread()在铺垫部分也介绍过(铺垫内容-消息和事件分发)
  • mEventThread用来通知App

我们知道mEventQueue->setEventThread()关联VSYNC信号的过程主要分为了两步:

  • 创建连接
    ) {
    ALOGV(“dispatcher %p ~ Initializing display event dispatcher.”, this);
    }
    status_t displayEventdispatcher::initialize() {
    status_t result = mReceiver.initCheck();

    int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,
    this, NULL);
    if (rc < 0) {
    return UNKNowN_ERROR;
    }
    return OK;
    }

在铺垫知识部分已经了解到,如果应用要接收VSYNC信号,需要将其添加到对应的EventThread中,SF中一共创建了两个

  • mSFEventThreadSurfaceFlinger专用的
    • SurfaceFlingerinit()中通过mEventQueue->setEventThread()进行关联
    • setEventThread()在铺垫部分也介绍过(铺垫内容-消息和事件分发)
  • mEventThread用来通知App

我们知道mEventQueue->setEventThread()关联VSYNC信号的过程主要分为了两步:

  • 创建连接

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐