参考:
Vsync虚拟化
Android SurfaceFlinger SW Vsync模型
Android SurfaceFlinger服务的消息队列创建过程分析
Android6.0 显示系统(六) 图像的输出过程
Android图形显示系统(一)
要理解SurfaceFlinger的工作机制,必须要理解SF所有线程的工作内容。从SF的启动流程入手分析整个SF的工作机制~ PS. 这篇笔记写的时间较早,基于Andorid 8.0(O). 不过大致流程没有变化,凑合看。
Android7.0以后的版本对init.rc脚本进行了重构,将各种服务进行归类拆分,而其中的SurfaceFlinger服务作为独立进程由surfaceflinger.rc脚本启动。
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
onrestart restart zygote
writepid /dev/stune/foreground/tasks
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
这里的 /system/bin/surfaceflinger 可以从Android.mk文件中看到具体启动的代码:
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_INIT_RC := surfaceflinger.rc
ifeq ($(TARGET_USES_HWC2),true)
LOCAL_CFLAGS += -DUSE_HWC2
endif
LOCAL_SRC_FILES := \
main_surfaceflinger.cpp
......
LOCAL_MODULE := surfaceflinger
重点来了:main_surfaceflinger.cpp
int main(int, char**) {
// 从8.0开始,Android提供了hidl机制,将原先直接由
// JNI->Native->HAL的接口调用形式,统一规范成hidl service/client
// 交互形式。该方式从一方面规范和统一了Android Framework和HAL
// 的调用机制,这个是Android O的Treble计划核心,mark一下,有空研究
startHidlServices();
// 忽略SIGPIPE信息,IPC机制中如果客户端关闭了,可能会产生SIGPIPE信号
// 该信号是进程终止信号,SF进程不应该响应这个信号
signal(SIGPIPE, SIG_IGN);
// 设置进程最大线程数为4(主线程不计入),线程过多会影响性能
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// 开启线程池
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// 1.3 实例化SurfaceFlinger,注意这里的flinger是一个强引用指针
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
// 设置SF进程的优先级为高优先级(PRIORITY_URGENT_DISPLAY = -8)
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
// 设置为前台调度策略
set_sched_policy(0, SP_FOREGROUND);
// 将SF的大多数线程优先级设为SP_SYSTEM
if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);
// 1.4 初始化SurfaceFlinger
flinger->init();
// 将SF服务添加至ServiceManager中
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// 添加GpuService至ServiceManager
sp<GpuService> gpuservice = new GpuService();
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO");
}
// 1.5 SF运行在当前线程中
flinger->run();
return 0;
}
先看一下SurfaceFlinger的定义:
class SurfaceFlinger : public BnSurfaceComposer,
private IBinder::DeathRecipient,
private HWComposer::EventHandler{
......
}
可以看到SF是继承了BnSurfaceComposer、DeathRecipient和 HWComposer::EventHandler的。
BnSurfaceComposer继承了BnInterface,提供onTranscat(SF实现)接口供客户端调用
DeathRecipient是Android的Binder机制提供的死亡监听
HWComposer::EventHandler,这个用来处理来自硬件或软件产生的Vsync信号,包括其他各种消息
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(),
mTransactionFlags(0),
mTransactionPending(false),
mAnimTransactionPending(false),
mLayersRemoved(false),
mLayersAdded(false),
mRepaintEverything(0),
mHwc(nullptr), // mHwc = nullptr
mRealHwc(nullptr), // mRealHwc = nullptr
mVrHwc(nullptr),
mRenderEngine(nullptr),
mBootTime(systemTime()),
mBuiltinDisplays(),
mVisibleRegionsDirty(false),
mGeometryInvalid(false),
mAnimCompositionPending(false),
mDebugRegion(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugDisableTransformHint(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
mForceFullDamage(false),
mInterceptor(this),
mPrimaryDispSync("PrimaryDispSync"),
mPrimaryHWVsyncEnabled(false), //mPrimaryHWVsyncEnabled = false
mHWVsyncAvailable(false),
mHasColorMatrix(false),
mHasPoweredOff(false),
mFrameBuckets(),
mTotalTime(0),
mLastSwapTime(0),
mNumLayers(0),
mVrFlingerRequestsDisplay(false)
{
ALOGI("SurfaceFlinger is starting");
vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);
sfVsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs>(1000000);
hasSyncFramework = getBool< ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::hasSyncFramework>(true);
useContextPriority = getBool< ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::useContextPriority>(false);
dispSyncPresentTimeOffset = getInt64< ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0);
useHwcForRgbToYuv = getBool< ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::useHwcForRGBtoYUV>(false);
maxVirtualDisplaySize = getUInt64(0);
// VrFlinger仅支持DayDream设备
useVrFlinger = getBool< ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::useVrFlinger>(false);
maxFrameBufferAcquiredBuffers = getInt64< ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2);
hasWideColorDisplay =
getBool(false);
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
mGpuToCpuSupported = !atoi(value);
property_get("debug.sf.showupdates", value, "0");
mDebugRegion = atoi(value);
property_get("debug.sf.ddms", value, "0");
mDebugDDMS = atoi(value);
if (mDebugDDMS) {
if (!startDdmConnection()) {
// start failed, and DDMS debugging not enabled
mDebugDDMS = 0;
}
}
ALOGI_IF(mDebugRegion, "showupdates enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
property_get("debug.sf.disable_backpressure", value, "0");
mPropagateBackpressure = !atoi(value);
ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");
property_get("debug.sf.enable_hwc_vds", value, "0");
mUseHwcVirtualDisplays = atoi(value);
ALOGI_IF(!mUseHwcVirtualDisplays, "Enabling HWC virtual displays");
property_get("ro.sf.disable_triple_buffer", value, "1");
mLayerTripleBufferingDisabled = atoi(value);
ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
}
实例化过程中中会启动DDMS调试工具,这里重点注意:mHwc,mRealHwc均为nullptr;且mPrimaryHWVsyncEnabled=false。
智能指针第一被引用时会调用该方法。
void SurfaceFlinger::onFirstRef()
{ // 1.3.2 初始化Looper和Handler
mEventQueue.init(this);
}
先看下mEventQueue究竟是什么:
class SurfaceFlinger : public BnSurfaceComposer,
private IBinder::DeathRecipient,
private HWComposer::EventHandler{
......
private:
// 线程安全
mutable MessageQueue mEventQueue;
}
MessageQueue的定义:
class MessageQueue {
class Handler : public MessageHandler {
enum {
eventMaskInvalidate = 0x1, // Invalidate消息
eventMaskRefresh = 0x2, // Refresh消息
eventMaskTransaction = 0x4 // Transaction消息
};
MessageQueue& mQueue;
int32_t mEventMask;
public:
explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { }
virtual void handleMessage(const Message& message);
void dispatchRefresh();
void dispatchInvalidate();
};
friend class Handler;
sp mFlinger;
sp mLooper;
sp mEventThread;
sp mEvents;
gui::BitTube mEventTube; // BitTube对象,用于Socket监听VSYNC信号
sp mHandler;
static int cb_eventReceiver(int fd, int events, void* data);
int eventReceiver(int fd, int events);
public:
enum {
INVALIDATE = 0,
REFRESH = 1,
};
MessageQueue();
~MessageQueue();
void init(const sp& flinger);
void setEventThread(const sp& events);
void waitMessage();
status_t postMessage(const sp& message, nsecs_t reltime=0);
// 下一次接收到 VSYNC 时发送INVALIDATE 消息
void invalidate();
// 下一次接收到 VSYNC 时发送 REFRESH 消息
void refresh();
};
这里的MessageQueue是native层实现的,位于:frameworks/native/services/surfaceflinger/MessageQueue.cpp
void MessageQueue::init(const sp& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true); //绑定到SF主线程
mHandler = new Handler(*this);
}
这个方法比较长,主要做了如下工作:
为OpenGL渲染准备环境;
启动App EventThread和SF EventThread;
初始化HWComposer;
启动EventControlThread;
初始化图层状态,显示状态,最后启动开机动画线程!
重点关注2,3,4步骤。
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
ALOGI("Phase offest NS: %" PRId64 "", vsyncPhaseOffsetNs);
{ // Autolock scope
Mutex::Autolock _l(mStateLock);
// 初始化EGL作为默认显示,为OpenGL渲染准备环境
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
// 1.4.1 启动App EventThread,该线程用于接收vsync信号并且上报给App进程,App开始画图
sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc, *this, false);
// 启动SF EventThread,该线程用于SurfaceFlinger接收vsync信号用于渲染
sp sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
// 1.4.1.3 创建BitTube并监听其文件描述符
mEventQueue.setEventThread(mSFEventThread);
// 设置App EventThread和SF EventThread线程的调度策略为SCHED_FIFO(实时调度策略,先到先服务)
// 这样可以优化阻塞,更流畅
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
}
if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO for EventThread");
}
// 创建渲染引擎,主要是选择EGL配置,选择OpenGL版本,创建OpenGL上下文
// 后续有时间跟进瞅一下
mRenderEngine = RenderEngine::create(mEGLDisplay,
HAL_PIXEL_FORMAT_RGBA_8888);
}
// 暂时不支持vr flinger
LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
"Starting with vr flinger active is not currently supported.");
// 1.4.2 初始化Hwc,这里的参数控制vr Composer
mRealHwc = new HWComposer(false);
mHwc = mRealHwc;
// 1.4.2.1 由SF主线程处理event
mHwc->setEventHandler(static_cast(this));
Mutex::Autolock _l(mStateLock);
// 通知本地图形API是否支持当前时间戳
if (getHwComposer().hasCapability(
HWC2::Capability::PresentFenceIsNotReliable)) {
property_set(kTimestampProperty, "0");
} else {
property_set(kTimestampProperty, "1");
}
if (useVrFlinger) { // 不考虑Vr Flinger
auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
mVrFlingerRequestsDisplay = requestDisplay;
signalTransaction();
};
mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),
vrFlingerRequestDisplayCallback);
if (!mVrFlinger) {
ALOGE("Failed to start vrflinger");
}
}
// 获取EGL上下文
mEGLContext = mRenderEngine->getEGLContext();
LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
// 设置当前GL上下文以便创建图层时创建纹理
getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);
// 1.4.3 启动EventControlThread,VSync信号闸刀控制线程
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
// 1.4.4 初始化绘图状态
// mDrawingState : 上一次绘图图层状态
// mCurrentState : 当前图层状态
mDrawingState = mCurrentState;
// 初始化显示状态
initializeDisplays();
// 内存缓存增强
mRenderEngine->primeCache();
// 启动开机动画线程!
mStartBootAnimThread = new StartBootAnimThread();
if (mStartBootAnimThread->Start() != NO_ERROR) {
ALOGE("Run StartBootAnimThread failed!");
}
ALOGV("Done initializing");
}
App EventThread和SF EventThread的区别除了名称,只在于相移phase offset。
名称|作用|相移
—|---|—
app|用于接收vsync信号并且上报给App进程,App开始画图|VSYNC_EVENT_PHASE_OFFSET_NS
sf|用于SurfaceFlinger接收vsync信号用于渲染|SF_VSYNC_EVENT_PHASE_OFFSET_NS
这两个值都可配,这两个一般用来调节performance. 具体可在 BoardConfig.mk里配置。
这里要解释下相移的作用。Android 4.1(Jelly Bean)引入了Vsync(Vertical Syncronization)用于渲染同步,使得App UI和SurfaceFlinger可以按硬件产生的VSync节奏来进行工作。
但新的问题产生了,App UI和SurfaceFlinger的工作都是流水线模型,对应一帧内容,AppUI先绘制完毕后由SurfaceFlinger合成渲染放入FrameBuffer,最终显示到屏幕上。这样从AppUI接收到Vsync信号到最终显示过去了2个Vsync周期(2 * 16.6ms),严重影响体验。针对这个问题Android4.4引入了虚拟Vsync,也就是将硬件产生的Vsync信号同步到本地Vsync模型后一分为二,引出两个Vsync线程,如下图:
为了好理解,做个假设:产生Vsync信号,先通知AppUI绘制,一段时间后通知SurfaceFlinger合成。如果AppUI绘制速度够快,SurfaceFlinger就可以不用等待而直接渲染合成图像了。
理解这个,app和sf EventThread我们就看其中一个的初始化即可。
先瞅瞅DispSyncSource,该类继承了VSyncSource,实现了其虚函数,主要功能恰如其名:设置相移、Vsync开关和提供接收Vsync事件的回调。
// 定义在SurfaceFlinger.cpp中
class DispSyncSource : public VSyncSource, private DispSync::Callback {
public:
DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
const char* name) :
mName(name),
mValue(0),
mTraceVsync(traceVsync),
mVsyncOnLabel(String8::format("VsyncOn-%s", name)),
mVsyncEventLabel(String8::format("VSYNC-%s", name)),
mDispSync(dispSync),
mCallbackMutex(),
mCallback(),
mVsyncMutex(),
mPhaseOffset(phaseOffset),
mEnabled(false) {} // 默认mEnable为false
......
};
// 定义在EventThread.h文件中
class VSyncSource : public virtual RefBase {
public:
class Callback: public virtual RefBase {
public:
virtual ~Callback() {}
virtual void onVSyncEvent(nsecs_t when) = 0;
};
virtual ~VSyncSource() {}
virtual void setVSyncEnabled(bool enable) = 0;
virtual void setCallback(const sp& callback) = 0;
virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
};
照惯例,初始化之前看看EventThread的定义:
class EventThread : public Thread, private VSyncSource::Callback {
class Connection : public BnDisplayEventConnection {
public:
explicit Connection(const sp& eventThread);
status_t postEvent(const DisplayEventReceiver::Event& event);
// count >= 1 : 连续vsync事件,count为vsync频次
// count == 0 : 一次vsync事件
// count ==-1 : one-shot event that fired this round / disabled
int32_t count;
private:
virtual ~Connection();
virtual void onFirstRef();
status_t stealReceiveChannel(gui::BitTube* outChannel) override; // 设置BitTube通道
status_t setVsyncRate(uint32_t count) override; // 设置Vsync频率
void requestNextVsync() override; // 异步请求Vsync
sp const mEventThread;
gui::BitTube mChannel; // 用于Vsync信号传输的BitTube
};
public:
EventThread(const sp& src, SurfaceFlinger& flinger, bool interceptVSyncs);
sp createEventConnection() const;
status_t registerDisplayEventConnection(const sp& connection);
void setVsyncRate(uint32_t count, const sp& connection);
void requestNextVsync(const sp& connection);
// called before the screen is turned off from main thread
void onScreenReleased();
// called after the screen is turned on from main thread
void onScreenAcquired();
// called when receiving a hotplug event
void onHotplugReceived(int type, bool connected);
Vector< sp > waitForEvent(
DisplayEventReceiver::Event* event);
void dump(String8& result) const;
void sendVsyncHintOff();
void setPhaseOffset(nsecs_t phaseOffset);
private:
virtual bool threadLoop();
virtual void onFirstRef();
virtual void onVSyncEvent(nsecs_t timestamp);
void removeDisplayEventConnection(const wp& connection);
void enableVSyncLocked();
void disableVSyncLocked();
void sendVsyncHintOnLocked();
// constants
sp mVSyncSource;
PowerHAL mPowerHAL;
SurfaceFlinger& mFlinger;
mutable Mutex mLock;
mutable Condition mCondition;
// protected by mLock
SortedVector< wp > mDisplayEventConnections;
Vector< DisplayEventReceiver::Event > mPendingEvents;
DisplayEventReceiver::Event mVSyncEvent[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES];
bool mUseSoftwareVSync;
bool mVsyncEnabled;
// for debugging
bool mDebugVsyncEnabled;
bool mVsyncHintSent;
const bool mInterceptVSyncs;
timer_t mTimerId;
};
不难发现,EventThread除了继承Thread,同时还是VSyncSource的内部类Callback的子类。并且还有一个继承了BnDisplayEventConnection的内部类Connection。
这个Connection的作用是作为服务端分发Vsync信号给app或者sf进程,后面详细介绍。
// 初始化
EventThread::EventThread(const sp& src, SurfaceFlinger& flinger, bool interceptVSyncs)
: mVSyncSource(src), // Vsync事件源:1、app;2、sf
mFlinger(flinger),
mUseSoftwareVSync(false),
mVsyncEnabled(false),
mDebugVsyncEnabled(false),
mVsyncHintSent(false),
mInterceptVSyncs(interceptVSyncs) {
// DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES默认为2,也就是默认最多支持双屏显示
// 初始化 mVSyncEvent
for (int32_t i=0 ; i
void MessageQueue::setEventThread(const sp& eventThread)
{
mEventThread = eventThread;
// 创建BitTube连接
mEvents = eventThread->createEventConnection();
// 获取BitTube文件描述符
mEvents->stealReceiveChannel(&mEventTube);
// SF主线程监听该文件描述符,重点注意这里传入
// 的回调函数:cb_eventReceiver,后续会遇到的
mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT,
MessageQueue::cb_eventReceiver, this);
}
上面的初始化过程很完美,但总感觉少了什么。EventThread线程是什么时候run的呢?仔细看SurfaceFlinger.h中关于EventThread的定义。
// SurfaceFlinger.h:两个强引用类型
sp mEventThread;
sp mSFEventThread;
所以看EventThread:onFirstRef
void EventThread::onFirstRef() {
// 这里运行该线程,设置调度策略
run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
}
bool EventThread::threadLoop() {
DisplayEventReceiver::Event event;
Vector< sp > signalConnections;
// 2.1 等待Vsync事件,其实也将本线程注册进监听了DispSync
signalConnections = waitForEvent(&event);
// 分发事件给监听者
const size_t count = signalConnections.size();
for (size_t i=0 ; i& conn(signalConnections[i]);
// 上报该事件
status_t err = conn->postEvent(event);
if (err == -EAGAIN || err == -EWOULDBLOCK) {
// 目标不接收事件,可能队列已满,现在直接丢弃
ALOGW("EventThread: dropping event (%08x) for connection %p",
event.header.type, conn.get());
} else if (err < 0) {
// 处理pipe错误
removeDisplayEventConnection(signalConnections[i]);
}
}
return true;
}
#### 1.4.1.5 EventThread.Connection:postEvent() ```c++ status_t EventThread::Connection::postEvent( const DisplayEventReceiver::Event& event) {
// 通过BitTube发送Vsync事件。这里Send的事件,会被SurfaceFlinger主线程
// 响应,也就是MessageQueue.hanlder,1.4.1.3:MessageQueue:setEventThread(sf)
ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
### 1.4.2 初始化HWComposer
回到1.4 SurfaceFlinger.init()方法,初始化的HWComposer是负责接收并转发来自硬件的VSync信号。
```c++
HWComposer::HWComposer(bool useVrComposer)
: mHwcDevice(),
mDisplayData(2),
mFreeDisplaySlots(),
mHwcDisplaySlots(),
mCBContext(),
mEventHandler(nullptr),
mVSyncCounts(),
mRemainingHwcVirtualDisplays(0)
{ // HWC_NUM_PHYSICAL_DISPLAY_TYPES = 2
for (size_t i=0 ; i
设置HWC的EventHandler,这里传入的handler就是继承了EventHandler的SurfaceFlinger本身。
void HWComposer::setEventHandler(EventHandler* handler)
{
if (handler == nullptr) {
ALOGE("setEventHandler: Rejected attempt to clear handler");
return;
}
bool wasNull = (mEventHandler == nullptr);
mEventHandler = handler;
// 第一次设置EventHandler时进入
if (wasNull) {
// 注册热插拔回调
auto hotplugHook = std::bind(&HWComposer::hotplug, this,
std::placeholders::_1, std::placeholders::_2);
mHwcDevice->registerHotplugCallback(hotplugHook);
// 注册刷新回调
auto invalidateHook = std::bind(&HWComposer::invalidate, this,
std::placeholders::_1);
mHwcDevice->registerRefreshCallback(invalidateHook);
// 1.4.2.2 注册Vsync回调,注意这里传入的参数 &HWComposer::vsync
auto vsyncHook = std::bind(&HWComposer::vsync, this,
std::placeholders::_1, std::placeholders::_2);
mHwcDevice->registerVsyncCallback(vsyncHook);
}
}
这里为display注册监听了vsync,这里稍稍注意下传入的参数类型:
VsyncCallback : typedef std::function
这是个函数指针,c++11引入的标准,暂时只要明确这是一个回调。
void Device::registerVsyncCallback(VsyncCallback vsync)
{
mVsync = vsync;
for (auto& pending : mPendingVsyncs) {
auto& display = pending.first;
auto timestamp = pending.second;
mVsync(std::move(display), timestamp); // 传入display
}
}
这里已经准备好接收Vsync信号了,但接下来我们继续分析SurfaceFlinger的启动。
Andorid5.0以后,专门启用一个线程控制Vsync信号,这个线程就是EventControlThread,先看下定义:
class EventControlThread: public Thread {
public:
explicit EventControlThread(const sp& flinger);
virtual ~EventControlThread() {}
void setVsyncEnabled(bool enabled);
virtual bool threadLoop();
private:
sp mFlinger;
bool mVsyncEnabled;
Mutex mMutex;
Condition mCond;
};
定义很简单,继承了Thread类,持有一个SurfaceFlinger的强引用。
EventControlThread::EventControlThread(const sp& flinger):
mFlinger(flinger),
mVsyncEnabled(false) { // 默认禁止Vsync信号,当然了,原因SF现在还没准备好嘛
}
android native中的Thread.run就是不断运行threadLoop()。
这里通过Condition来控制SurfaceFlinger是否接收Vsync信号。
bool EventControlThread::threadLoop() {
Mutex::Autolock lock(mMutex); //持锁
bool vsyncEnabled = mVsyncEnabled;
#ifdef USE_HWC2
mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, mVsyncEnabled);
#else
mFlinger->eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC,
mVsyncEnabled);
#endif
while (true) {
// mCond阻塞,通过信号量控制
status_t err = mCond.wait(mMutex);
if (err != NO_ERROR) {
ALOGE("error waiting for new events: %s (%d)",
strerror(-err), err);
return false;
}
// 解除阻塞后,如果开关状态发生变化,调用mFlinger->eventControl
// 之后保存当前开关状态
if (vsyncEnabled != mVsyncEnabled) {
#ifdef USE_HWC2
mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, mVsyncEnabled);
#else
mFlinger->eventControl(HWC_DISPLAY_PRIMARY,
SurfaceFlinger::EVENT_VSYNC, mVsyncEnabled);
#endif
vsyncEnabled = mVsyncEnabled;
}
}
return false;
}
看完这个函数自然有两个疑问,谁控制mCond?SF->eventControl的作用?先不着急,回到SurfaceFlinger.init()继续分析SF的启动流程。
需要看这个State的定义–在SurfaceFlinger.h文件中;State是个私有内部类,主要功能是按照Z轴顺序储存了一组layer。
private:
class State {
public:
explicit State(LayerVector::StateSet set) : stateSet(set) {}
State& operator=(const State& other) {
// We explicitly don't copy stateSet so that, e.g., mDrawingState
// always uses the Drawing StateSet.
layersSortedByZ = other.layersSortedByZ;
displays = other.displays;
return *this;
}
const LayerVector::StateSet stateSet = LayerVector::StateSet::Invalid;
LayerVector layersSortedByZ;
DefaultKeyedVector< wp, DisplayDeviceState> displays;
void traverseInZOrder(const LayerVector::Visitor& visitor) const;
void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const;
};
// 必须被mStateLock锁保护
State mCurrentState{LayerVector::StateSet::Current};
// 只能被SF主线程访问,不需要同步
State mDrawingState{LayerVector::StateSet::Drawing};
在初始化所有资源和状态后,SF开始处理。
void SurfaceFlinger::run() {
do {
// 死循环一直执行。
waitForEvent();
} while (true);
}
void SurfaceFlinger::waitForEvent() {
// 1.5.1 上面分析得知,mEventQueue是MessageQueue类型
mEventQueue.waitMessage();
}
void MessageQueue::waitMessage() {
do {
IPCThreadState::self()->flushCommands();
// 1.5.2 重点在这里,Looper接收消息给主线程的handler处理
//([1.3.2]MessageQueue.init & [1.4.1.3]MessageQueue:setEventThread)。
int32_t ret = mLooper->pollOnce(-1);
switch (ret) {
case Looper::POLL_WAKE:
case Looper::POLL_CALLBACK:
continue;
case Looper::POLL_ERROR:
ALOGE("Looper::POLL_ERROR");
continue;
case Looper::POLL_TIMEOUT:
// timeout (should not happen)
continue;
default:
// should not happen
ALOGE("Looper::pollOnce() returned unknown status %d", ret);
continue;
}
} while (true); // 双重死循环??
}
从1.4.1.3MessageQueue:setEventThread 可知对应Fd有事件,会调用这个回调函数。
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
MessageQueue* queue = reinterpret_cast(data);
//1.5.3
return queue->eventReceiver(fd, events);
}
int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
ssize_t n;
DisplayEventReceiver::Event buffer[8];
// 从BitTube读取事件
while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
for (int i=0 ; idispatchInvalidate();
break;
}
}
}
return 1;
}
void MessageQueue::Handler::dispatchInvalidate() {
// 给mEventMask标上eventMaskInvalidate标识,表明SurfaceFlinger正在处理Invalidate事件
// 这也说明了如果SF正在处理消息时,会忽略重复的消息
if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
// 通过Looper发送INVALIDATE消息
mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
}
}
这里就有个问题,为什么通过BitTube读取的事件不直接处理,反而要多此一举重新进入消息队列处理呢?:
void MessageQueue::Handler::handleMessage(const Message& message) {
switch (message.what) {
case INVALIDATE:
// 移除标识,表明可以接收处理下一次事件
android_atomic_and(~eventMaskInvalidate, &mEventMask);
// 1.5.6 转交给SF处理咯
mQueue.mFlinger->onMessageReceived(message.what);
break;
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
}
}
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
// 这个frameMissed 暂时还没看出是什么意思,涉及到Fence机制
// 先从字面意思理解,这里判断是否跳过该帧
bool frameMissed = !mHadClientComposition &&
mPreviousPresentFence != Fence::NO_FENCE &&
(mPreviousPresentFence->getSignalTime() ==
Fence::SIGNAL_TIME_PENDING);
ATRACE_INT("FrameMissed", static_cast(frameMissed));
if (mPropagateBackpressure && frameMissed) {
ALOGD("Backpressure trigger, skipping transaction & refresh!");
// 1.5.6.1 请求Vsync信号
// Backpressure被触发,frameMissed = true,跳过此次的Transaction和refresh
signalLayerUpdate();
break;
}
// 目前忽略VrFlinger
updateVrFlinger();
// 1.5.7 处理Transaction消息,每个layer处理(doTransaction)
bool refreshNeeded = handleMessageTransaction();
// 1.5.8 处理Invalidate消息,重绘
refreshNeeded |= handleMessageInvalidate();
refreshNeeded |= mRepaintEverything;
if (refreshNeeded) {
// 1.5.9 如果事务修改了窗口状态,锁定了新的缓冲区,
// 或者HWC请求完全重新绘制,则发出刷新信号
signalRefresh();
}
break;
}
case MessageQueue::REFRESH: {
// 1.5.9.1 刷新
handleMessageRefresh();
break;
}
}
}
这个方法最终是通过SurfaceFlinger请求Vsync信号,为什么绕个圈子请求?注意 mCondition.broadcast
void SurfaceFlinger::signalLayerUpdate() {
// 通过MessageQueue使EventThread请求下一次Vsync信号
mEventQueue.invalidate();
}
// MessageQueue.cpp
void MessageQueue::invalidate() {
// 1.5.6.2 这里的 mEvents 是EventThread.Connection
mEvents->requestNextVsync();
}
#### 1.5.6.2 EventThread::Connection::requestNextVsync() ```c++ void EventThread::Connection::requestNextVsync() {
mEventThread->requestNextVsync(this);
}
void EventThread::requestNextVsync(
const sp& connection) {
Mutex::Autolock _l(mLock);
// SF向硬件请求Vsync,两次请求间隔必须大于500ns,否则忽略
mFlinger.resyncWithRateLimit();
if (connection->count < 0) {
connection->count = 0;
// 通知有Vsync信号来了,1.4.1.4:EventThread:threadLoop()中
// waitForEvent 终于等到事件了。
mCondition.broadcast();
}
}
### 1.5.7 SurfaceFlinger:handleMessageTransaction()
```c++
void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
{
ATRACE_CALL();
// 拷贝mDrawingState副本,避免死锁
State drawingState(mDrawingState);
Mutex::Autolock _l(mStateLock);
const nsecs_t now = systemTime();
mDebugInTransaction = now;
// 标记Transaction
transactionFlags = getTransactionFlags(eTransactionMask);
// 这部分代码过长,稍后分析。主要功能是调用每个 Layer
// 的 doTransaction,处理系统在两次刷新期间的各种变化
handleTransactionLocked(transactionFlags);
mLastTransactionTime = systemTime() - now;
mDebugInTransaction = 0;
invalidateHwcGeometry();
}
bool SurfaceFlinger::handleMessageInvalidate() {
ATRACE_CALL();
// 重绘,更新每个layer状态,后续分析
return handlePageFlip();
}
这里的流程是通过MessageQueue将Refresh消息添加至消息队列后,回到SurfaceFlinger处理。
MessageQueue.handler收到REFRESH消息,转交给SurfaceFlinger:onMessageReceived处理。
void SurfaceFlinger::signalRefresh() {
mEventQueue.refresh();
}
// MessageQueue.cpp
void MessageQueue::refresh() {
mHandler->dispatchRefresh();
}
void MessageQueue::Handler::dispatchRefresh() {
if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
}
}
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);
// 1.5.6 回到SF处理该消息
mQueue.mFlinger->onMessageReceived(message.what);
break;
}
}
处理刷新,SF的消息处理流程复杂。这刷新操作后续分析。
void SurfaceFlinger::handleMessageRefresh() {
ATRACE_CALL();
nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
preComposition(refreshStartTime);
rebuildLayerStacks();
setUpHWComposer();
doDebugFlashRegions();
doComposition();
postComposition(refreshStartTime);
mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
mHadClientComposition = false;
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
const sp& displayDevice = mDisplays[displayId];
mHadClientComposition = mHadClientComposition ||
mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
}
mLayersWithQueuedFrames.clear();
}
好了,SF启动流程分析完了。
SF启动完成了,万事俱备就等着硬件设备的Vsync信号了~等一下,Vsync信号是怎么传递给SF的呢?
1.4.1.4 EventThread.run()中等待Vsync信号,我们从这里开始分析,在分析之前先看一下DisplayEventReceiver这个类。
这个类其实就是传输VSync信号,也包括Hotplug事件。先看定义:
class DisplayEventReceiver {
public:
enum {
DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'), // vsyn
DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'), // plug
};
struct Event {
struct Header {
uint32_t type; // 事件类型:1、vsyn;2、plug
uint32_t id; // 0:vsyn plug:plug
nsecs_t timestamp __attribute__((aligned(8))); // 时间戳
};
struct VSync {
uint32_t count;
};
struct Hotplug {
bool connected;
};
Header header;
union {
VSync vsync;
Hotplug hotplug;
};
};
public:
// DisplayEventReceiver创建并注册了SF的一个事件连接,默认禁止VSync
// 通过调用setVSyncRate、requestNextVsync开始接受。其他事件则即刻分发
DisplayEventReceiver(
ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp);
~DisplayEventReceiver();
status_t initCheck() const;
// 获取用于接收事件的文件描述符,该描述符由本类持有,不得关闭
int getFd() const;
// 从队列中读取事件并返回事件个数如果返回NOT_ENOUGH_DATA
// 表示这个对象永远无效,不能继续调用本方法
ssize_t getEvents(Event* events, size_t count);
static ssize_t getEvents(gui::BitTube* dataChannel, Event* events, size_t count);
// 向队列中写入事件并返回写入的数量
static ssize_t sendEvents(gui::BitTube* dataChannel, Event const* events, size_t count);
// 设置VSync分发频率,每次VSync事件返回1,其他事件返回2,没有事件返回0。
status_t setVsyncRate(uint32_t count);
// 请求下一次Vsync
status_t requestNextVsync();
private:
sp mEventConnection;
std::unique_ptr mDataChannel;
};
Vector< sp > EventThread::waitForEvent(
DisplayEventReceiver::Event* event)
{
Mutex::Autolock _l(mLock);
Vector< sp > signalConnections;
do {
bool eventPending = false;
bool waitForVSync = false;
size_t vsyncCount = 0;
nsecs_t timestamp = 0;
// 从mVSyncEvent数组中读取timestamp
// 其实只有mVSyncEvent[0]中存入了Vsync事件信息
for (int32_t i=0 ; i connection(mDisplayEventConnections[i].promote());
if (connection != NULL) {
bool added = false;
if (connection->count >= 0) {
// we need vsync events because at least
// one connection is waiting for it
waitForVSync = true;
if (timestamp) {
// we consume the event only if it's time
// (ie: we received a vsync event)
if (connection->count == 0) {
// fired this time around
connection->count = -1;
signalConnections.add(connection);
added = true;
} else if (connection->count == 1 ||
(vsyncCount % connection->count) == 0) {
// continuous event, and time to report it
signalConnections.add(connection);
added = true;
}
}
}
if (eventPending && !timestamp && !added) {
// we don't have a vsync event to process
// (timestamp==0), but we have some pending
// messages.
signalConnections.add(connection);
}
} else {
// we couldn't promote this reference, the connection has
// died, so clean-up!
mDisplayEventConnections.removeAt(i);
--i; --count;
}
}
// Here we figure out if we need to enable or disable vsyncs
if (timestamp && !waitForVSync) {
// we received a VSYNC but we have no clients
// don't report it, and disable VSYNC events
disableVSyncLocked();
} else if (!timestamp && waitForVSync) {
// we have at least one client, so we want vsync enabled
// (TODO: this function is called right after we finish
// notifying clients of a vsync, so this call will be made
// at the vsync rate, e.g. 60fps. If we can accurately
// track the current state we could avoid making this call
// so often.)
enableVSyncLocked();
}
// note: !timestamp implies signalConnections.isEmpty(), because we
// don't populate signalConnections if there's no vsync pending
if (!timestamp && !eventPending) {
// wait for something to happen
if (waitForVSync) {
// This is where we spend most of our time, waiting
// for vsync events and new client registrations.
//
// If the screen is off, we can't use h/w vsync, so we
// use a 16ms timeout instead. It doesn't need to be
// precise, we just need to keep feeding our clients.
//
// We don't want to stall if there's a driver bug, so we
// use a (long) timeout when waiting for h/w vsync, and
// generate fake events when necessary.
bool softwareSync = mUseSoftwareVSync;
nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);
if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {
if (!softwareSync) {
ALOGW("Timed out waiting for hw vsync; faking it");
}
// FIXME: how do we decide which display id the fake
// vsync came from ?
mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;
mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
mVSyncEvent[0].vsync.count++;
}
} else {
// Nobody is interested in vsync, so we just want to sleep.
// h/w vsync should be disabled, so this will wait until we
// get a new connection, or an existing connection becomes
// interested in receiving vsync again.
mCondition.wait(mLock);
}
}
} while (signalConnections.isEmpty());
// here we're guaranteed to have a timestamp and some connections to signal
// (The connections might have dropped out of mDisplayEventConnections
// while we were asleep, but we'll still have strong references to them.)
return signalConnections;
}
这里是初动力,来自硬件的vsync信号:
void HWComposer::vsync(const std::shared_ptr& display,
int64_t timestamp) {
auto displayType = HWC2::DisplayType::Invalid;
auto error = display->getType(&displayType);
if (error != HWC2::Error::None) {
ALOGE("vsync: Failed to determine type of display %" PRIu64,
display->getId());
return;
}
if (displayType == HWC2::DisplayType::Virtual) {
ALOGE("Virtual display %" PRIu64 " passed to vsync callback",
display->getId());
return;
}
if (mHwcDisplaySlots.count(display->getId()) == 0) {
ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",
display->getId());
return;
}
int32_t disp = mHwcDisplaySlots[display->getId()];
{
Mutex::Autolock _l(mLock);
// There have been reports of HWCs that signal several vsync events
// with the same timestamp when turning the display off and on. This
// is a bug in the HWC implementation, but filter the extra events
// out here so they don't cause havoc downstream.
if (timestamp == mLastHwVSync[disp]) {
ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
timestamp);
return;
}
mLastHwVSync[disp] = timestamp;
}
char tag[16];
snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
// 收到Vsync,发送给mEventHandler,也就是SurfaceFlinger
mEventHandler->onVSyncReceived(this, disp, timestamp);
}
Vsync信号不仅仅只有来自HWC的硬件Vsync,也有使用软件模拟的Vsync,甚至大多数情况下app收到的vsync信号都是来自软件模拟的。更多请关注DispSync探秘。