Android 12(S) 图形显示系统 - SurfaceFlinger的启动和消息队列处理机制(四)
1 前言
SurfaceFlinger作为Android图形显示系统处理逻辑的核心单元,我们有必要去了解其是如何启动,初始化及进行消息处理的。这篇文章我们就来简单分析SurfaceFlinger这个Binder系统服务的一些基本处理逻辑。接下来分两部分讲解:
>> SurfaceFlinger启动与初始化
>> SurfaceFlinger消息队列处理机制
Tips:
本篇涉及的代码位置:
/frameworks/native/services/surfaceflinger/
2 SurfaceFlinger的启动与初始化
SurfaceFlinger是一个Binder系统服务,Android设备开机启动时就会带起SurfaceFlinger服务进程并完成一些初始化动作。
从Android S开始,SurfaceFlinger被编译为一个可执行二进制档案:surfaceflinger(放置于设备/system/bin/下)。
可执行档surfaceflinger的makefile
如下这段代码中,可以看到这个可执行档与surfaceflinger.rc这个init rc档相关联,这样开机启动时,init进程就可以解析这个rc档,带起SurfaceFlinger服务进程
cc_binary {
name: "surfaceflinger",
defaults: ["libsurfaceflinger_binary"],
init_rc: ["surfaceflinger.rc"],
srcs: [
":surfaceflinger_binary_sources",
// Note: SurfaceFlingerFactory is not in the filegroup so that it
// can be easily replaced.
"SurfaceFlingerFactory.cpp",
],
shared_libs: [
"libSurfaceFlingerProp",
],
logtags: ["EventLog/EventLogTags.logtags"],
}
再来瞅瞅surfaceflinger.rc这个档案的内容,主要时设置一些SurfaceFlinger服务进程启动属性
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
capabilities SYS_NICE
onrestart restart zygote
task_profiles HighPerformance
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
这里我们就简简单单理解为:设备开机启动时,init进程解析surfaceflinger.rc,然后去执行/system/bin/surfaceflinger,从而启动了SurfaceFlinger服务进程。
如果在设备console下执行ps,你就可以看到这个进程PID了
console:/ $ ps -A | grep surfaceflinger
system 210 1 133412 38160 0 0 S surfaceflinger
可执行档surfaceflinger的main函数入口
在此我们仅摘录主要的代码并注释如下:
* /frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {
...
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
...
// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
...
// 创建SurfaceFlinger对象,由强指针指向。
// SurfaceFlinger继承RefBase类,所以此处一旦new出对象赋给sp指针后,将立刻触发SurfaceFlinger类的onFirstRef方法的调用。
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
...
// SurfaceFlinger类正式初始化
// initialize before clients can connect
flinger->init();
// SurfaceFlinger向ServiceManager注册Binder服务,
// 这样在其他进程中可以通过getService+SERVICE_NAME来获取SurfaceFlinger服务,继而可以和SurfaceFlinger类进行Binder通信。
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
...
// SurfaceFlinger类进入主循环(此处注意SurfaceFlinger类未继承Threads类,不遵循Threads类的接口执行顺序)
// run surface flinger in this thread
flinger->run();
return 0;
}
对于main函数,简简单单把握一下几点就可以了:
- 创建SurfaceFlinger对象,触发执行 SurfaceFlinger::onFirstRef()
- 调用SurfaceFlinger::init()进行初始化
- 注册服务到ServiceManager(名字是"SurfaceFlinger")
- 调用SurfaceFlinger::run()
Tips:
在设备console上执行service list命令就可以看到注册的服务:注册的名称是SurfaceFlinger, 这个服务实现的接口是android.ui.ISurfaceComposer
console:/ $ service list | grep Surface
1 SurfaceFlinger: [android.ui.ISurfaceComposer]
SurfaceFlinger类定义
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback,
private ISchedulerCallback {
创建SurfaceFinger实例对象
调用surfaceflinger::createSurfaceFlinger()来创建SurfaceFlinger实例,并传递一个factory对象作为参数
* /frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp
sp<SurfaceFlinger> createSurfaceFlinger() {
static DefaultFactory factory;
return new SurfaceFlinger(factory);
}
来简单看一下Factory的定义:
* /frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.h
// The interface that SurfaceFlinger uses to create all of the implementations
// of each interface.
class Factory {
public:
virtual std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) = 0;
virtual std::unique_ptr<MessageQueue> createMessageQueue() = 0;
virtual std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration(
Fps currentRefreshRate) = 0;
virtual std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&,
ISchedulerCallback&) = 0;
virtual sp<SurfaceInterceptor> createSurfaceInterceptor() = 0;
virtual sp<StartPropertySetThread> createStartPropertySetThread(
bool timestampPropertyValue) = 0;
virtual sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&) = 0;
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height,
PixelFormat format, uint32_t layerCount,
uint64_t usage, std::string requestorName) = 0;
virtual void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
bool consumerIsSurfaceFlinger) = 0;
virtual sp<IGraphicBufferProducer> createMonitoredProducer(const sp<IGraphicBufferProducer>&,
const sp<SurfaceFlinger>&,
const wp<Layer>&) = 0;
virtual sp<BufferLayerConsumer> createBufferLayerConsumer(const sp<IGraphicBufferConsumer>&,
renderengine::RenderEngine&,
uint32_t tex, Layer*) = 0;
virtual std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
const sp<IGraphicBufferProducer>&) = 0;
virtual std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() = 0;
virtual sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) = 0;
virtual sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) = 0;
virtual sp<EffectLayer> createEffectLayer(const LayerCreationArgs& args) = 0;
virtual sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) = 0;
virtual std::unique_ptr<FrameTracer> createFrameTracer() = 0;
virtual std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline(
std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid) = 0;
protected:
~Factory() = default;
};
Factory中定义了各种create方法,其作用如注释中说明:The interface that SurfaceFlinger uses to create all of the implementations of each interface.
SurfaceFlinger用Factory来创建所有实现了对应接口的对象。SurfaceFlinger中默认使用的是DefaultFactory,其中定义各种createXXX()方法的实现。具体可参见:/frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
SurfaceFlinger构造函数
构造函数的代码就只截取部分贴在这里了,其中主要是读取一些属性值来对一些成员变量进行初始化。其中一些属性值是debug参数。另外就是利用mFactory的createXXX方法去实例化各种对象。
比如 : 创建消息队列 mEventQueue(mFactory.createMessageQueue())
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
: mFactory(factory),
mInterceptor(mFactory.createSurfaceInterceptor()),
mTimeStats(std::make_shared<impl::TimeStats>()),
mFrameTracer(mFactory.createFrameTracer()),
mFrameTimeline(mFactory.createFrameTimeline(mTimeStats, getpid())),
mEventQueue(mFactory.createMessageQueue()),
mCompositionEngine(mFactory.createCompositionEngine()),
mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()),
mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)),
mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)),
mPowerAdvisor(*this) {
ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());
mSetInputWindowsListener = new SetInputWindowsListener([&]() { setInputWindowsFinished(); });
}
SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
ALOGI("SurfaceFlinger is starting");
hasSyncFramework = running_without_sync_framework(true);
dispSyncPresentTimeOffset = present_time_offset_from_vsync_ns(0);
useHwcForRgbToYuv = force_hwc_copy_for_virtual_displays(false);
maxFrameBufferAcquiredBuffers = max_frame_buffer_acquired_buffers(2);
maxGraphicsWidth = std::max(max_graphics_width(0), 0);
maxGraphicsHeight = std::max(max_graphics_height(0), 0);
hasWideColorDisplay = has_wide_color_display(false);
...
}
surfaceflinger 会去读取SurfaceFlingerProperties中的系统属性,具体可以参看源码:/frameworks/native/services/surfaceflinger/sysprop/
Tips:
关于系统属性的知识建议可以参见:
https://source.android.google.cn/devices/architecture/sysprops-apis?hl=zh-cn
https://blog.csdn.net/askfgx2010/article/details/112308665
SurfaceFlinger::onFirstRef
上面创建完SurfaceFlinger对象,立即就会执行到SurfaceFlinger::onFirstRef,这个方法中就做了一件事对消息队列做初始化,如下:
void SurfaceFlinger::onFirstRef() {
mEventQueue->init(this);
}
消息队列运行的详细分析我们下节在讲,这里先不展开。
SurfaceFlinger::init
再回到可执行档surfaceflinger的main函数中,创建完SurfaceFlinger对象后,紧接着调用了SurfaceFlinger::init()方法:
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
Mutex::Autolock _l(mStateLock);
// 对于CompositionEngine 属性进行设置, 创建 RenderEngine 对象
// Get a RenderEngine for the given display / config (can't fail)
// TODO(b/77156734): We need to stop casting and use HAL types when possible.
// Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
renderengine::RenderEngineCreationArgs::Builder()
.setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
.setImageCacheSize(maxFrameBufferAcquiredBuffers)
.setUseColorManagerment(useColorManagement)
.setEnableProtectedContext(enable_protected_contents(false))
.setPrecacheToneMapperShaderOnly(false)
.setSupportsBackgroundBlur(mSupportsBlur)
.setContextPriority(
useContextPriority
? renderengine::RenderEngine::ContextPriority::REALTIME
: renderengine::RenderEngine::ContextPriority::MEDIUM)
.build()));
// Set SF main policy after initializing RenderEngine which has its own policy.
if (!SetTaskProfiles(0, {"SFMainPolicy"})) {
ALOGW("Failed to set main task profile");
}
// 创建HWComposer对象并传入一个name属性,再通过mCompositionEngine->setHwComposer设置对象属性。
mCompositionEngine->setTimeStats(mTimeStats);
mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
mCompositionEngine->getHwComposer().setCallback(this);
ClientCache::getInstance().setRenderEngine(&getRenderEngine());
if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
enableHalVirtualDisplays(true);
}
// processDisplayHotplugEventsLocked(); 处理 任何初始热插拔和显示更改的结果
// 在此方法中主要有调用 initScheduler(displayId);
// Process any initial hotplug and resulting display changes.
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();
LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
const auto displayId = display->getPhysicalId();
LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId),
"Internal display is disconnected.");
// initialize our drawing state
mDrawingState = mCurrentState;
// 初始化Display信息
// set initial conditions (e.g. unblank default device)
initializeDisplays();
mPowerAdvisor.init();
char primeShaderCache[PROPERTY_VALUE_MAX];
property_get("service.sf.prime_shader_cache", primeShaderCache, "1");
if (atoi(primeShaderCache)) {
if (setSchedFifo(false) != NO_ERROR) {
ALOGW("Can't set SCHED_OTHER for primeCache");
}
mRenderEnginePrimeCacheFuture = getRenderEngine().primeCache();
if (setSchedFifo(true) != NO_ERROR) {
ALOGW("Can't set SCHED_OTHER for primeCache");
}
}
getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());
// Inform native graphics APIs whether the present timestamp is supported:
const bool presentFenceReliable =
!getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
// 开启一个设置属性的线程,在这个线程中使用property_set去设置一些属性值
if (mStartPropertySetThread->Start() != NO_ERROR) {
ALOGE("Run StartPropertySetThread failed!");
}
ALOGV("Done initializing");
}
SurfaceFlinger::init方法,完成的工作大概为:
CompositionEngine的配置,创建RenderEngine对象用于Client合成模式(GPU)合成;
初始化HWComposer,注册回调接口mCompositionEngine->getHwComposer().setCallback(this),HAL会回调一些方法;
处理Display显示屏幕的热插拔和更改的事件processDisplayHotplugEventsLocked;
初始化显示设备initializeDisplays;
开启一个设置属性的线程,在这个线程中使用property_set去设置一些属性值mStartPropertySetThread->Start();
SurfaceFlinger::run
可执行档surfaceflinger的main函数中,把SurfaceFinger这个服务注册进ServiceManger中后,后续执行了SurfaceFlinger::run这个方法,代码如下:
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::run() {
while (true) {
mEventQueue->waitMessage();
}
}
这个方法也很简单,一个while(true)的无限死循环,消息队列等待消息的到来。surfaceflinger主线程中等待消息处理。
讲到这里,大概SurfaceFlinger启动的流程就完成了,当然,很多细节我们没有深入去分析。
3 SurfaceFlinger的消息队列处理机制
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h
//成员变量mEventQueue的声明
std::unique_ptr<MessageQueue> mEventQueue;
========
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
// SurfaceFlinger构造函数中创建消息队列
mEventQueue(mFactory.createMessageQueue()),
* /frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
std::unique_ptr<MessageQueue> DefaultFactory::createMessageQueue() {
return std::make_unique<android::impl::MessageQueue>();
}
Tips:
android::impl::MessageQueue的定义
查看代码
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h
namespace impl {
class MessageQueue : public android::MessageQueue {
sp<SurfaceFlinger> mFlinger;
sp<Looper> mLooper;
sp<Handler> mHandler;
...
}
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h
void init(const sp<SurfaceFlinger>& flinger) override;
void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,
std::chrono::nanoseconds workDuration) override;
void setDuration(std::chrono::nanoseconds workDuration) override;
void setInjector(sp<EventThreadConnection>) override;
void waitMessage() override;
void postMessage(sp<MessageHandler>&&) override;
// sends INVALIDATE message at next VSYNC
void invalidate() override;
// sends REFRESH message at next VSYNC
void refresh() override;
MessageQueue::init方法
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
MessageQueue::postMessage方法
void MessageQueue::postMessage(sp<MessageHandler>&& handler) {
mLooper->sendMessage(handler, Message());
}
MessageQueue::waitMessage方法
waitMessage方法中不断去调用mLooper->pollOnce(-1),检查Looper中是否有消息需要处理,如果有,则调用该消息对应的MessageHandler去处理。
void MessageQueue::waitMessage() {
do {
IPCThreadState::self()->flushCommands();
int32_t ret = mLooper->pollOnce(-1);
...
} while (true);
}
Handler的定义
Handler继承自MessageHandler并实现了handleMessage方法,在这个方法中对消息进行处理
Handler中还有一个成员mQueue指向MessageQueue对象引用
class Handler : public MessageHandler {
enum : uint32_t {
eventMaskInvalidate = 0x1,
eventMaskRefresh = 0x2,
eventMaskTransaction = 0x4
};
MessageQueue& mQueue;
std::atomic<uint32_t> mEventMask;
std::atomic<int64_t> mVsyncId;
std::atomic<nsecs_t> mExpectedVSyncTime;
public:
explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {}
void handleMessage(const Message& message) override;
virtual void dispatchRefresh();
virtual void dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp);
virtual bool invalidatePending();
};
前面讲到的都是一些定义啊,方法呀,他们之间的联系,如何运作似乎还是云里雾里,没有讲到。
其实SurfaceFlinger消息队列主要处理2个重要事件:Refresh 和 Invalidate
我们就分析下Refresh的处理流程
某些操作下需要进行refresh动作时,会调用到SurfaceFlinger::signalRefresh()
void SurfaceFlinger::signalRefresh() {
mRefreshPending = true;
mEventQueue->refresh();
}
SurfaceFlinger::signalRefresh()方法中会继续调用mEventQueue->refresh()
void MessageQueue::refresh() {
mHandler->dispatchRefresh();
}
继而调用到mHandler->dispatchRefresh()
void MessageQueue::Handler::dispatchRefresh() {
if ((mEventMask.fetch_or(eventMaskRefresh) & eventMaskRefresh) == 0) {
mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
}
}
Handler::dispatchRefresh()方法中就要准备消息并指定Handler来处理这个消息,然后seedMessage到Looper的消息队列中去,等待后续处理。
对于refresh消息,其what字段为MessageQueue::REFRESH, 处理它就是在MessageQueue::Handler::handleMessage方法中,如下:
void MessageQueue::Handler::handleMessage(const Message& message) {
switch (message.what) {
case INVALIDATE:
mEventMask.fetch_and(~eventMaskInvalidate);
mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime);
break;
case REFRESH:
mEventMask.fetch_and(~eventMaskRefresh);
mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime);
break;
}
}
看到这里是不是稍微清晰一点了,当waitMessage --> Looper::pollOnce 检测到这个refresh消息要处理时,就会回调到MessageQueue::Handler::handleMessage方法,进而执行到SurfaceFlinger::onMessageReceived
void SurfaceFlinger::onMessageReceived(int32_t what, int64_t vsyncId, nsecs_t expectedVSyncTime) {
switch (what) {
case MessageQueue::INVALIDATE: {
onMessageInvalidate(vsyncId, expectedVSyncTime);
break;
}
case MessageQueue::REFRESH: {
onMessageRefresh();
break;
}
}
}
之后就是具体refresh要完成的具体工作了,此处省略一万字....
讲到这里不知您明白了没,没有图形化的注解确实不太系统,不过只要你理解Android Native Looper/Handler/Message机制应该很容易看懂。
简简单单的理解:
- SurfaceFlinger主线程中不断去调用waitMessage --> Looper::pollOnce 检测是否有消息要处理;
- 如果有消息要处理,则Looper就会取出这个消息并回调与之对应的MessageHandler::handleMessage方法,处理消息事件;
- 外部可以通过MessageQueue::postMessage,Looper::sendMessage等方法向消息队列中发送待处理的Message;
实用技巧
武林中有两招绝学,一阳指和狮吼功,我用了整整三十年的时间,将两招绝学并成了一整招。你过来啊!
Android 11之前的一阳指和狮吼功:
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h
// post an asynchronous message to the main thread
status_t postMessageAsync(const sp<MessageBase>& msg, nsecs_t reltime = 0, uint32_t flags = 0);
// post a synchronous message to the main thread
status_t postMessageSync(const sp<MessageBase>& msg, nsecs_t reltime = 0, uint32_t flags = 0);
Android 11之后两招绝学并成了一整招
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h
// Schedule an asynchronous or synchronous task on the main thread.
template <typename F, typename T = std::invoke_result_t<F>>
[[nodiscard]] std::future<T> schedule(F&&);
这些方法的作用就是把指定的任务放到main thread中去执行。
看一下schedule的定义:
template <typename F, typename T>
inline std::future<T> SurfaceFlinger::schedule(F&& f) {
auto [task, future] = makeTask(std::move(f));
mEventQueue->postMessage(std::move(task));
return std::move(future);
}
再看makeTask和Task的定义:
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h
template <typename F>
class Task : public MessageHandler {
template <typename G>
friend auto makeTask(G&&);
explicit Task(F&& f) : mTask(std::move(f)) {}
void handleMessage(const Message&) override { mTask(); }
using T = std::invoke_result_t<F>;
std::packaged_task<T()> mTask;
};
template <typename F>
inline auto makeTask(F&& f) {
sp<Task<F>> task = new Task<F>(std::move(f));
return std::make_pair(task, task->mTask.get_future());
}
MessageQueue::postMessage
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
void MessageQueue::postMessage(sp<MessageHandler>&& handler) {
mLooper->sendMessage(handler, Message());
}
看到这里是不是基本就清楚了,熟悉的字眼:postMessage,MessageHandler,handleMessage本质还是main thread上消息队列处理。
其实换汤不换药,只是利用C++的新特型做了抽象与封装,本质还是向主线程发送一个Message并指定其MessageHandler,主线程收到消息时调用MessageHandler::handleMessage,进而呼叫到我们指定的函数实体代码。
我们已一个例子来说明:
static_cast<void>(schedule([=]() {
ALOGD("我在主线程被打印");
}));
我们传递给schedule的函数实体将在主线程执行。
这在我们修改某些逻辑且要保证主线程执行时可能是个不错的技巧。
4 小结
写到这里 SurfaceFlinger启动与初始化流程和SurfaceFlinger消息队列处理机制就完了,很多内容自己也没有完全吃透,本篇的目的还是着重讲解流程而忽视具体细节,搞懂流程再去按工作需要分析细节,这样感觉会更实用主义。
必读:
Android 12(S) 图形显示系统 - 开篇
最后分享一份好心情
Android 12(S) 图形显示系统 - SurfaceFlinger的启动和消息队列处理机制(四)的更多相关文章
- Android 12(S) 图形显示系统 - createSurface的流程(五)
题外话 刚刚开始着笔写作这篇文章时,正好看电视在采访一位92岁的考古学家,在他的日记中有这样一句话,写在这里与君共勉"不要等待幸运的降临,要去努力的掌握知识".如此朴实的一句话,此 ...
- Android 12(S) 图像显示系统 - SurfaceFlinger之VSync-上篇(十六)
必读: Android 12(S) 图像显示系统 - 开篇 一.前言 为了提高Android系统的UI交互速度和操作的流畅度,在Android 4.1中,引入了Project Butter,即&quo ...
- Android 12(S) 图像显示系统 - SurfaceFlinger GPU合成/CLIENT合成方式 - 随笔1
必读: Android 12(S) 图像显示系统 - 开篇 一.前言 SurfaceFlinger中的图层选择GPU合成(CLIENT合成方式)时,会把待合成的图层Layers通过renderengi ...
- Android 12(S) 图形显示系统 - 应用建立和SurfaceFlinger的沟通桥梁(三)
1 前言 上一篇文章中我们已经创建了一个Native示例应用,从使用者的角度了解了图形显示系统API的基本使用,从这篇文章开始我们将基于这个示例应用深入图形显示系统API的内部实现逻辑,分析运作流程. ...
- Android 12(S) 图形显示系统 - 示例应用(二)
1 前言 为了更深刻的理解Android图形系统抽象的概念和BufferQueue的工作机制,这篇文章我们将从Native Level入手,基于Android图形系统API写作一个简单的图形处理小程序 ...
- Android 12(S) 图形显示系统 - 基本概念(一)
1 前言 Android图形系统是系统框架中一个非常重要的子系统,与其它子系统一样,Android 框架提供了各种用于 2D 和 3D 图形渲染的 API供开发者使用来创建绚丽多彩的应用APP.图形渲 ...
- Android 12(S) 图形显示系统 - BufferQueue/BLASTBufferQueue之初识(六)
题外话 你有没有听见,心里有一声咆哮,那一声咆哮,它好像在说:我就是要从后面追上去! 写文章真的好痛苦,特别是自己对这方面的知识也一知半解就更加痛苦了.这已经是这个系列的第六篇了,很多次都想放弃了,但 ...
- Android 12(S) 图形显示系统 - 初识ANativeWindow/Surface/SurfaceControl(七)
题外话 "行百里者半九十",是说步行一百里路,走过九十里,只能算是走了一半.因为步行越接近目的地,走起来越困难.借指凡事到了接近成功,往往是最吃力.最艰难的时段.劝人做事贵在坚持, ...
- Android 12(S) 图形显示系统 - BufferQueue的工作流程(九)
题外话 Covid-19疫情的强烈反弹,小区里检测出了无症状感染者.小区封闭管理,我也不得不居家办公了.既然这么大把的时间可以光明正大的宅家里,自然要好好利用,八个字 == 努力工作,好好学习 一.前 ...
随机推荐
- layDate设置开始日期选择框和结束日期选择框 之间的相互验证方法
var startDate = laydate.render({ elem: '#_select_start_date', //结束日期框的ID type: 'date', done: functio ...
- Lucene 基础类型
Lucene 索引文件中,用一下基本类型来保存信息:1. Byte:是最基本的类型,长 8 位(bit).2. UInt32:由 4 个 Byte 组成.3. UInt64:由 8 个 Byte 组成 ...
- 【LeetCode】496. Next Greater Element I 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 直接遍历查找 字典保存位置 日期 题目地址:http ...
- 【LeetCode】738. Monotone Increasing Digits 解题报告(Python)
[LeetCode]738. Monotone Increasing Digits 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu ...
- 「算法笔记」快速傅里叶变换(FFT)
一.引入 首先,定义多项式的形式为 \(f(x)=\sum_{i=0}^n a_ix^i\),其中 \(a_i\) 为系数,\(n\) 为次数,这种表示方法称为"系数表示法",一个 ...
- Dimension reduction in principal component analysis for trees
目录 问题 重要的定义 距离 支撑树 交树 序 tree-line path 重要的性质 其它 Alfaro C A, Aydin B, Valencia C E, et al. Dimension ...
- Winform中使用HttpClient与后端api服务进行交互
前端js可以使用ajax.axios发出http请求 在c#中winform.控制台等可以通过WebRequest.WebClient.HttpClient 有关三个类的性能对比大家可以自己搜一下,这 ...
- 编写Java程序,在子类老虎中重写父类动物的吃食方法
返回本章节 返回作业目录 需求说明: 在子类老虎中重写父类动物的吃食方法 实现思路: 在子类老虎中重写父类动物的吃食方法的实现思路如下: 创建各种动物的父类Animal类,在该类中定义eat()方法. ...
- 论文翻译:2020_Attention Wave-U-Net for Acoustic Echo Cancellation
论文地址:http://www.interspeech2020.org/uploadfile/pdf/Thu-1-10-10.pdf Attention Wave-U-Net 的回声消除 摘要 提出了 ...
- 从0开始手把手带你入门Vue3-全网最全(1.1w字)
天命不足畏,祖宗不足法. --王安石 前言 本文并非标题党,而是实实在在的硬核文章,如果有想要学习Vue3的网友,可以大致的浏览一下本文,总体来说本篇博客涵盖了Vue3中绝大部分内容,包含常用的Com ...