原文参考链接:原文链接:https://blog.csdn.net/qq_34211365/article/details/105206088
一、View向SurfaceFlinger注册 Vysnc信号
1. Choreographer注册DisplayEventReceiver
private Choreographer(Looper looper, int vsyncSource) {
//UI线程的looper
mLooper = looper;
mHandler = new FrameHandler(looper);
//USE_VSYNC为true,使用VSYNC
//注册DisplayEventReceiver 入口
mDisplayEventReceiver = USE_VSYNC
? new FrameDisplayEventReceiver(looper, vsyncSource)
: null;
mLastFrameTimeNanos = Long.MIN_VALUE;
//Android默认60FPS,mFrameIntervalNanos为16.6
mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());
mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
for (int i = 0; i <= CALLBACK_LAST; i++) {
mCallbackQueues[i] = new CallbackQueue();
}
// b/68769804: For low FPS experiments.
setFPSDivisor(SystemProperties.getInt(ThreadedRenderer.DEBUG_FPS_DIVISOR, 1));
}
//父类DisplayEventReceiver
public DisplayEventReceiver(Looper looper, int vsyncSource) {
if (looper == null) {
throw new IllegalArgumentException("looper must not be null");
}
mMessageQueue = looper.getQueue();
//JNI
mReceiverPtr = nativeInit(new WeakReference(this), mMessageQueue,
vsyncSource);
mCloseGuard.open("dispose");
}
FrameDisplayEventReceiver 继承 DisplayEventReceiver ,在初始化的时候构造方法中显式调用了父类DisplayEventReceiver 的构造方法。
VSYNC有两种:APP和SurfaceFlinger。
NativeDisplayEventReceiver构造方法中调用了父类DisplayEventDispatcher的构造方法,并且将java层传递下来的VSYNC_SOURCE_APP强转为了ISurfaceComposer::VsyncSource传递给了DisplayEventDispatcher,VsyncSource是枚举类型,VSYNC_SOURCE_APP 为0。
2.进入JNI nativeInit 主要有两步
//nativeInit 步骤1
sp receiver = new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource);
//nativeInit 步骤2
status_t status = receiver->initialize();
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
jobject messageQueueObj, jint vsyncSource) {
//根据java层messageQueue的到native层messageQueue
sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
//2.1 步骤1 nativeInit->step 1
sp receiver = new NativeDisplayEventReceiver(env,
receiverWeak, messageQueue, vsyncSource);
//2.2 步骤2 nativeInit->step 2
status_t status = receiver->initialize();
if (status) {
String8 message;
message.appendFormat("Failed to initialize display event receiver. status=%d", status);
jniThrowRuntimeException(env, message.string());
return 0;
}
receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object
return reinterpret_cast(receiver.get());
}
//nativeInit->step 1:创建 NativeDisplayEventReceiver
NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env,
jobject receiverWeak, const sp& messageQueue, jint vsyncSource) :
DisplayEventDispatcher(messageQueue->getLooper(),
static_cast<:vsyncsource>(vsyncSource)),</:vsyncsource>
mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
mMessageQueue(messageQueue) {
ALOGV("receiver %p ~ Initializing display event receiver.", this);
}
//nativeInit->step 1:DisplayEventDispatcher构造方法中将vsyncSource赋值给了mReceiver
DisplayEventDispatcher::DisplayEventDispatcher(const sp& looper,
ISurfaceComposer::VsyncSource vsyncSource) :
mLooper(looper), mReceiver(vsyncSource), mWaitingForVsync(false) {
ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
}
//nativeInit->step 1:调用DisplayEventReceiver的构造函数进行初始化
DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource) {
//步骤1 通过binder获取SurfaceFlinger服务
//获取的是SurfaceFlinger的Bp端BpSurfaceComposer,
//SurfaceFlinger的是它的Bn端BnSurfaceComposer的子类
sp sf(ComposerService::getComposerService());
if (sf != nullptr) {
//步骤2 调用SurfaceFlinger创建 BitTube 用于监听VSYNC
mEventConnection = sf->createDisplayEventConnection(vsyncSource);
if (mEventConnection != nullptr) {
//步骤3 返回创建BitTube
mDataChannel = std::make_unique<:bittube>();</:bittube>
//步骤4 在surfaceFlinger进程中创建的mReceiveFd传递到app进程中去
mEventConnection->stealReceiveChannel(mDataChannel.get());
}
}
}
//nativeInit->step 1:Binder实现跨进程调用
//SurfaceFlinger返回的也是EventThreadConnection的Bp端BpDisplayEventConnection,EventThreadConnection继承自BnDisplayEventConnection
//mEventConnection = sf->createDisplayEventConnection(vsyncSource);
//调用到 SurfaceFlinger::createDisplayEventConnection
virtual sp createDisplayEventConnection(VsyncSource vsyncSource)
{
.....
err = remote()->transact(
BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,
data, &reply);
......
lt = interface_cast(reply.readStrongBinder());
return result;
}
//nativeInit->step 1:SurfaceFlinger::createDisplayEventConnection
sp SurfaceFlinger::createDisplayEventConnection(
ISurfaceComposer::VsyncSource vsyncSource) {
auto resyncCallback = mScheduler->makeResyncCallback([this] {
Mutex::Autolock lock(mStateLock);
return getVsyncPeriod();
});
const auto& handle =
vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle : mAppConnectionHandle;
//Scheduler::createDisplayEventConnection
return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback));
}
//createConnection函数根据connectionName创建EventThread,
//根据EventThread创建EventThreadConnection,然后创建ConnectionHandle,
//根据ConnectionHandle,EventThreadConnection,
//EventThread最终创建Connection,并以id为key,Connection为value加入到mConnections的map中,
//最终返回”app“的ConnectionHandle
//nativeInit->step 1:mScheduler 在 SurfaceFlinger::init() 中创建
void SurfaceFlinger::init() {
......
mScheduler =
getFactory().createScheduler([this](bool enabled) { setPrimaryVsyncEnabled(enabled); },
mRefreshRateConfigs);
auto resyncCallback =
mScheduler->makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));
mAppConnectionHandle =
mScheduler->createConnection("app", mPhaseOffsets->getCurrentAppOffset(),
resyncCallback,
impl::EventThread::InterceptVSyncsCallback());
......
}
//Scheduler::createConnection
//一次是创建"app"的Connection,一次是创建"sf"的Connection
//两套连接的用connectionName以及id进行标识,(id为0,connectionName等于”app“的)与(id为1,connectionName等于”sf“的)
//createConnection函数根据connectionName创建EventThread,
//根据EventThread创建EventThreadConnection,
//然后创建ConnectionHandle,根据ConnectionHandle,EventThreadConnection,
//EventThread最终创建Connection,并以id为key,
//Connection为value加入到mConnections的map中,
//最终返回”app“的ConnectionHandle
//原文链接:https://blog.csdn.net/qq_34211365/article/details/105123790
sp<:connectionhandle> Scheduler::createConnection(</:connectionhandle>
const char* connectionName, int64_t phaseOffsetNs, ResyncCallback resyncCallback,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
//id从0累加
const int64_t id = sNextId++;
ALOGV("Creating a connection handle with ID: %" PRId64 "n", id);
//创建对应connectionName名字的EventThread
std::unique_ptr eventThread =
makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs,
std::move(interceptCallback));
//创建EventThreadConnection
auto eventThreadConnection =
createConnectionInternal(eventThread.get(), std::move(resyncCallback));
//创建ConnectionHandle,与id对应
mConnections.emplace(id,
std::make_unique(new ConnectionHandle(id),
eventThreadConnection,
std::move(eventThread)));
//返回”app“的ConnectionHandle
return mConnections[id]->handle;
}
//nativeInit->step 1:Scheduler::createDisplayEventConnection
sp Scheduler::createDisplayEventConnection(
const sp<:connectionhandle>& handle, ResyncCallback resyncCallback) {</:connectionhandle>
RETURN_VALUE_IF_INVALID(nullptr);
//handle->id用于标识这套连接是app还是surfaceFlinger
return createConnectionInternal(mConnections[handle->id]->thread.get(),
std::move(resyncCallback));
}
sp Scheduler::createDisplayEventConnection(
const sp<:connectionhandle>& handle, ResyncCallback resyncCallback) {</:connectionhandle>
RETURN_VALUE_IF_INVALID(nullptr);
return createConnectionInternal(mConnections[handle->id]->thread.get(),
std::move(resyncCallback));
}
sp Scheduler::createConnectionInternal(EventThread* eventThread,
ResyncCallback&& resyncCallback) {
return eventThread->createEventConnection(std::move(resyncCallback));
}
sp EventThread::createEventConnection(ResyncCallback resyncCallback) const {
return new EventThreadConnection(const_cast(this), std::move(resyncCallback));
}
EventThreadConnection::EventThreadConnection(EventThread* eventThread,
ResyncCallback resyncCallback)
: resyncCallback(std::move(resyncCallback)),
mEventThread(eventThread),
mChannel(gui::BitTube::DefaultSize)
//构造函数中最重要的就是创建了mChannel,
//mChannel是gui::BitTube类型接着看gui::BitTube的构造函数
{
}
DisplayEventReceiver 步骤4 BitTube的构造函数
BitTube::BitTube(size_t bufsize) {
init(bufsize, bufsize);
}
//mReceiveFd.reset(sockets[0]),mSendFd.reset(sockets[1]);建立Fd与socket的关联,
//一对sockets一个用来接受消息,一个用来发送消息,
//Vsync到来的时候通过mSendFd写入消息,然后app监听mReceiveFd接受消息,就完成了app对Vsync的接收
//原文链接:https://blog.csdn.net/qq_34211365/article/details/105123790
void BitTube::init(size_t rcvbuf, size_t sndbuf) {
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
size_t size = DEFAULT_SOCKET_BUFFER_SIZE;
setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
// since we don't use the "return channel", we keep it small...
setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
fcntl(sockets[0], F_SETFL, O_NONBLOCK);
fcntl(sockets[1], F_SETFL, O_NONBLOCK);
mReceiveFd.reset(sockets[0]);
mSendFd.reset(sockets[1]);
} else {
mReceiveFd.reset();
ALOGE("BitTube: pipe creation failed (%s)", strerror(errno));
}
}
DisplayEventReceiver 步骤5 传递mReceiveFd到app进程
class BpDisplayEventConnection : public SafeBpInterface<IDisplayEventConnection> {
public:
......
status_t stealReceiveChannel(gui::BitTube* outChannel) override {
return callRemote<decltype(
&IDisplayEventConnection::stealReceiveChannel)>(Tag::STEAL_RECEIVE_CHANNEL,
outChannel);
}
}
status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
outChannel->setReceiveFd(mChannel.moveReceiveFd());
return NO_ERROR;
}
base::unique_fd BitTube::moveReceiveFd() {
return std::move(mReceiveFd);
}
void BitTube::setReceiveFd(base::unique_fd&& receiveFd) {
mReceiveFd = std::move(receiveFd);
}
DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource) {
//步骤1
sp sf(ComposerService::getComposerService());
if (sf != nullptr) {
//步骤2
mEventConnection = sf->createDisplayEventConnection(vsyncSource);
if (mEventConnection != nullptr) {
//步骤3
mDataChannel = std::make_unique<:bittube>();</:bittube>
//步骤4
mEventConnection->stealReceiveChannel(mDataChannel.get());
}
}
}
2.2 步骤1
DisplayEventDispatcher::initialize 方法,调用Looper的addFd将我们前面得到的mReceiveFd添加到Handler进行监听。
status_t DisplayEventDispatcher::initialize() {
//检查mReceiver是否异常
status_t result = mReceiver.initCheck();
...
//调用Looper的addFd将我们前面得到的mReceiveFd添加到Handler进行监听
int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT,
this, NULL);
if (rc < 0) {
return UNKNOWN_ERROR;
}
return OK;
}
二、View向SurfaceFlinger申请下一次Vsync信号
如调用invalidate()方法主动请求重绘,ViewRoot接收到刷新请求,通过scheduleTraversals()调度traversal,就会调用到 nativeScheduleVsync 用于应用层向native层注册监听下一次Vsync信号,在UI需要刷新时调用。
也就是调用到:mReceiver.requestNextVsync。
//android_view_DisplayEventReceiver.cpp
static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
sp receiver =
reinterpret_cast(receiverPtr);
status_t status = receiver->scheduleVsync();
if (status) {
String8 message;
message.appendFormat("Failed to schedule next vertical sync pulse. status=%d", status);
jniThrowRuntimeException(env, message.string());
}
}
//NativeDisplayEventReceiver继承DisplayEventReceiver,scheduleVsync这个函数是在父类实现的
status_t DisplayEventDispatcher::scheduleVsync() {
if (!mWaitingForVsync) {
ALOGV("dispatcher %p ~ Scheduling vsync.", this);
// Drain all pending events.
nsecs_t vsyncTimestamp;
PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
//步骤1
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "",
this, ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));
}
//步骤2
status_t status = mReceiver.requestNextVsync();
if (status) {
ALOGW("Failed to request next vsync, status=%d", status);
return status;
}
mWaitingForVsync = true;
}
return OK;
}
步骤1. processPendingEvents获取最新到来的Vsync
//通过mReceiver.getEvents获取事件,
//mReceiver类型为DisplayEventReceiver,然后处理事件
然后根据不同类型的事件,调用不同的处理方式,事件有三种,定义在
DisplayEventReceiver.h中
//DisplayEventReceiver.h
enum {
DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'),
DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'),
DISPLAY_EVENT_CONFIG_CHANGED = fourcc('c', 'o', 'n', 'f'),
};
bool DisplayEventDispatcher::processPendingEvents(
nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId, uint32_t* outCount) {
bool gotVsync = false;
DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
ssize_t n;
//mReceiver.getEvents
while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
ALOGV("dispatcher %p ~ Read %d events.", this, int(n));
for (ssize_t i = 0; i < n; i++) {
const DisplayEventReceiver::Event& ev = buf[i];
switch (ev.header.type) {
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
// Later vsync events will just overwrite the info from earlier
// ones. That's fine, we only care about the most recent.
gotVsync = true;
*outTimestamp = ev.header.timestamp;
*outDisplayId = ev.header.displayId;
*outCount = ev.vsync.count;
break;
case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
......
break;
case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED:
.....
break;
default:
break;
}
}
}
...
return gotVsync;
}
1.1 mReceiver.getEvents
//mDataChannel是在nativeInit过程中创建的,
//这个过程创建了一套”app“的连接用来接收Vsync信号,而gui::BitTube则作为这套连接的数据收发的管理类
ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
size_t count) {
return DisplayEventReceiver::getEvents(mDataChannel.get(), events, count);
}
ssize_t DisplayEventReceiver::getEvents(gui::BitTube* dataChannel,
Event* events, size_t count)
{
return gui::BitTube::recvObjects(dataChannel, events, count);
}
1.2 gui::BitTube::recvObjects
//BitTube.h
template <typename T>
static ssize_t recvObjects(BitTube* tube, T* events, size_t count) {
return recvObjects(tube, events, count, sizeof(T));
}
ssize_t BitTube::recvObjects(BitTube* tube, void* events, size_t count, size_t objSize) {
char* vaddr = reinterpret_cast<char*>(events);
ssize_t size = tube->read(vaddr, count * objSize);
.....
return size < 0 ? size : size / static_cast<ssize_t>(objSize);
}
ssize_t BitTube::read(void* vaddr, size_t size) {
ssize_t err, len;
do {
len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT);
err = len < 0 ? errno : 0;
} while (err == EINTR);
if (err == EAGAIN || err == EWOULDBLOCK) {
return 0;
}
return err == 0 ? len : -err;
}
步骤2. requestNextVsync()函数
//mEventConnection是在nativeInit过程中创建的,类型为BpDisplayEventConnection,
//这里最终通过Binder调到surfaceFlinger进程中BnDisplayEventConnection的实现类EventThreadConnection中,
status_t DisplayEventReceiver::requestNextVsync() {
if (mEventConnection != nullptr) {
//调到surfaceFlinger进程中BnDisplayEventConnection的实现类EventThreadConnection中,
mEventConnection->requestNextVsync();
return NO_ERROR;
}
return NO_INIT;
}
//EventThread.cpp
void EventThreadConnection::requestNextVsync() {
ATRACE_NAME("requestNextVsync");
mEventThread->requestNextVsync(this);
}
void EventThread::requestNextVsync(const sp& connection) {
if (connection->resyncCallback) {
connection->resyncCallback();
}
std::lock_guard<std::mutex> lock(mMutex);
if (connection->vsyncRequest == VSyncRequest::None) {
connection->vsyncRequest = VSyncRequest::Single;
//条件变量使用notify_all会唤醒所有调用了wait的线程,
//wait在哪里调用的呢?是在EventThread创建的时候,
//它的构造函数中创建了一个线程,这个线程一启动就调用了threadMain函数,
//threadMain中通过条件变量调用wait使线程陷入等待
mCondition.notify_all();
}
}
2.1 EventThread 构造函数
EventThread::EventThread(VSyncSource* src, std::unique_ptr uniqueSrc,
InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
: mVSyncSource(src),
mVSyncSourceUnique(std::move(uniqueSrc)),
mInterceptVSyncsCallback(std::move(interceptVSyncsCallback)),
mThreadName(threadName) {
...
mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS {
std::unique_lock<std::mutex> lock(mMutex);
//threadMain函数
threadMain(lock);
});
...
}
2.2 threadMain调用dispatchEvent分发事件
void EventThread::threadMain(std::unique_lock<:mutex>& lock) {</:mutex>
DisplayEventConsumers consumers;
while (mState != State::Quit) {
...
if (!mPendingEvents.empty()) {
event = mPendingEvents.front();
....
if (!consumers.empty()) {
//调用dispatchEvent分发事件
dispatchEvent(*event, consumers);
consumers.clear();
}
...
// Wait for event or client registration/request.
if (mState == State::Idle) {
//如果mState为Idle,就让此线程陷入等待,唤醒条件就是调用notify函数
mCondition.wait(lock);
} else {
...
}
}
}
2.3 dispatchEvent分发VSync的流程
dispatchEvent分发VSync的流程其实也很简单,最终就是调用gui::BitTube::sendObjects函数,通过socket 通知View 进行刷新。通过scheduleTraversals()调度traversal,performTraversals()调用performMeasure()、performLayout()、performDraw()进行刷新。
mSendFd和mReceiveFd对应一对可连接的socket,sendObjects内部write函数,write函数就是向mSendFd中写数据。当mSendFd写入数据之后,对应的mReceiveFd就能收到,并且会调用DisplayEventDispatcher::
handleEvent回调函数。
//sendObjects和recvObjects对应的,sendObjects函数再调用内部write函数,write函数就是向mSendFd中写数据,
//mSendFd和mReceiveFd对应一对可连接的socket
//调用gui::BitTube::sendObjects函数
ssize_t BitTube::sendObjects(BitTube* tube, void const* events, size_t count, size_t objSize) {
const char* vaddr = reinterpret_cast<const char*>(events);
ssize_t size = tube->write(vaddr, count * objSize);
......
return size < 0 ? size : size / static_cast<ssize_t>(objSize);
}
ssize_t BitTube::write(void const* vaddr, size_t size) {
ssize_t err, len;
do {
len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
// cannot return less than size, since we're using SOCK_SEQPACKET
err = len < 0 ? errno : 0;
} while (err == EINTR);
return err == 0 ? len : -err;
}
//nativeInit过程中mReceiveFd会被添加到handler的epoll中进行监听
//当mSendFd写入数据之后,对应的mReceiveFd就能收到,
//并且会调用handleEvent回调函数,这个回调是在添加mReceiveFd时一并注册的
int DisplayEventDispatcher::handleEvent(int, int events, void*) {
...
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%"
ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%d",
this, ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount);
mWaitingForVsync = false;
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
}
return 1; // keep the callback
}
2.4 NativeDisplayEventReceiver::dispatchVsync
dispatchVsync的实现在DisplayEventDispatcher子类NativeDisplayEventReceiver 中,通过JAVA反射将Vsync信号相关信息发送到应用层。分发的实质就是通过gui::BitTube::sendObjects向mSendFd写入数据,监听的mReceiveFd就能收到数据并调用回调函数handleEvent,将Vsync信息分发到了应用层,开始处理View的绘制工作。
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
uint32_t count) {
......
//通过 反射 DisplayEventReceiver的dispatchVsync方法就将Vsync信号相关信息发送到了应用层
env->CallVoidMethod(receiverObj.get(),
gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, displayId, count);
......
}
2.5 dispatchVsync 应用层:
//frameworks/base/core/java/android/view/DisplayEventReceiver.java
// Called from native code.
@SuppressWarnings("unused")
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame,
VsyncEventData vsyncEventData
//开始处理View的绘制工作,也即是调用 scheduleTraversals()调度traversal
onVsync(timestampNanos, physicalDisplayId, frame, vsyncEventData);
}
// Called from native code.
@SuppressWarnings("unused")
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private void dispatchHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
onHotplug(timestampNanos, physicalDisplayId, connected);
}
// Called from native code.
@SuppressWarnings("unused")
private void dispatchModeChanged(long timestampNanos, long physicalDisplayId, int modeId) {
onModeChanged(timestampNanos, physicalDisplayId, modeId);
}
// Called from native code.
@SuppressWarnings("unused")
private void dispatchFrameRateOverrides(long timestampNanos, long physicalDisplayId,
FrameRateOverride[] overrides) {
onFrameRateOverridesChanged(timestampNanos, physicalDisplayId, overrides);
}
自此完成了VIEW 注册与接受 SurfaceFlinger VSYNC 信号完成。
觉得写的不错就点个赞吧!关注我下文更精彩!
原文参考链接:原文链接:https://blog.csdn.net/qq_34211365/article/details/105206088
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/21406,转载请注明出处。
评论0