SurfaceFlinger::init()
我们开始init的第三阶段的学习。
1. //frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
2. void SurfaceFlinger::onComposerHalHotplug(hal::HWDisplayId hwcDisplayId,
3. hal::Connection connection) {
4. //省略
5. if (std::this_thread::get_id() == mMainThreadId) {
6. // Process all pending hot plug events immediately if we are on the main thread.
7. processDisplayHotplugEventsLocked();
8. }
9. //省略
10. }
11.
12. void SurfaceFlinger::init() {
13. //省略
14. // Process any initial hotplug and resulting display changes.
15. processDisplayHotplugEventsLocked();
16. //省略
17. }
主要就是讲processDisplayHotplugEventsLocked()函数,第一次被执行其实还是在onComposerHalHotplug里面。对于我们只有一个屏且没有热插拔另一个屏的情况下,init()里的processDisplayHotplugEventsLocked()就是空运行了一下,没有做任何事情。
就这一个函数,里面的内容也忒多了,看着头疼,但还是得硬着头皮看:
1. //frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
2. void SurfaceFlinger::processDisplayHotplugEventsLocked() {
3. for (const auto& event : mPendingHotplugEvents) {
4. std::optional<DisplayIdentificationInfo> info =
5. getHwComposer().onHotplug(event.hwcDisplayId, event.connection);
6.
7. if (!info) {
8. continue;
9. }
10.
11. const auto displayId = info->id;
12. const auto it = mPhysicalDisplayTokens.find(displayId);
13.
14. if (event.connection == hal::Connection::CONNECTED) {
15. DisplayModes supportedModes;
16. DisplayModePtr activeMode;
17. loadDisplayModes(displayId, supportedModes, activeMode);
18.
19. if (it == mPhysicalDisplayTokens.end()) {
20. ALOGV("Creating display %s", to_string(displayId).c_str());
21.
22. DisplayDeviceState state;
23. state.physical = {.id = displayId,
24. .type = getHwComposer().getDisplayConnectionType(displayId),
25. .hwcDisplayId = event.hwcDisplayId,
26. .deviceProductInfo = std::move(info->deviceProductInfo),
27. .supportedModes = std::move(supportedModes),
28. .activeMode = activeMode};
29. state.isSecure = true; // All physical displays are currently considered secure.
30. state.displayName = std::move(info->name);
31.
32. sp<IBinder> token = new BBinder();
33. mCurrentState.displays.add(token, state);
34. mPhysicalDisplayTokens.emplace(displayId, std::move(token));
35.
36. if (event.hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
37. initScheduler(state);
38. }
39.
40. mInterceptor->saveDisplayCreation(state);
41. } else {
42. ALOGV("Recreating display %s", to_string(displayId).c_str());
43.
44. const auto token = it->second;
45. auto& state = mCurrentState.displays.editValueFor(token);
46. state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId
47. state.physical->supportedModes = std::move(supportedModes);
48. state.physical->activeMode = activeMode;
49. if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) {
50. state.physical->deviceProductInfo = std::move(info->deviceProductInfo);
51. }
52. }
53. } else {
54. ALOGV("Removing display %s", to_string(displayId).c_str());
55.
56. const ssize_t index = mCurrentState.displays.indexOfKey(it->second);
57. if (index >= 0) {
58. const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
59. mInterceptor->saveDisplayDeletion(state.sequenceId);
60. mCurrentState.displays.removeItemsAt(index);
61. }
62. mPhysicalDisplayTokens.erase(it);
63. }
64.
65. processDisplayChangesLocked();
66. }
67.
68. mPendingHotplugEvents.clear();
69. }
初一看,有点熟悉感,这里要被轮询的mPendingHotplugEvents不就是上一节中结尾所讲到的注册hotplug消息回调上来的那个消息么!我们单屏的情况只轮询一次了。
对于init阶段来说,我们把这个函数不会被执行的地方全部省略掉再来看一下:
1. //frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
2. void SurfaceFlinger::processDisplayHotplugEventsLocked() {
3. for (const auto& event : mPendingHotplugEvents) {
4. std::optional<DisplayIdentificationInfo> info =
5. getHwComposer().onHotplug(event.hwcDisplayId, event.connection);
6. //省略
7. const auto displayId = info->id;
8. const auto it = mPhysicalDisplayTokens.find(displayId);
9.
10. if (event.connection == hal::Connection::CONNECTED) {
11. DisplayModes supportedModes;
12. DisplayModePtr activeMode;
13. loadDisplayModes(displayId, supportedModes, activeMode);
14.
15. if (it == mPhysicalDisplayTokens.end()) {
16. ALOGV("Creating display %s", to_string(displayId).c_str());
17.
18. DisplayDeviceState state;
19. state.physical = {.id = displayId,
20. .type = getHwComposer().getDisplayConnectionType(displayId),
21. .hwcDisplayId = event.hwcDisplayId,
22. .deviceProductInfo = std::move(info->deviceProductInfo),
23. .supportedModes = std::move(supportedModes),
24. .activeMode = activeMode};
25. state.isSecure = true; // All physical displays are currently considered secure.
26. state.displayName = std::move(info->name);
27.
28. sp<IBinder> token = new BBinder();
29. mCurrentState.displays.add(token, state);
30. mPhysicalDisplayTokens.emplace(displayId, std::move(token));
31.
32. if (event.hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
33. initScheduler(state);
34. }
35. //省略
36. }
37. }
38. //省略
39.
40. processDisplayChangesLocked();
41. }
42.
43. mPendingHotplugEvents.clear();
44. }
现在看上去稍微顺眼了那么一点。先看看onHotplug()干了什么:
onHotplug()
1. //frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
2. std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hal::HWDisplayId hwcDisplayId,
3. hal::Connection connection) {
4. switch (connection) {
5. case hal::Connection::CONNECTED:
6. return onHotplugConnect(hwcDisplayId);
7. case hal::Connection::DISCONNECTED:
8. return onHotplugDisconnect(hwcDisplayId);
9. case hal::Connection::INVALID:
10. return {};
11. }
12. }
13.
14. std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(
15. hal::HWDisplayId hwcDisplayId) {
16. std::optional<DisplayIdentificationInfo> info;
17. if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
18. //省略
19. } else {
20. uint8_t port;
21. DisplayIdentificationData data;
22. const bool hasDisplayIdentificationData =
23. getDisplayIdentificationData(hwcDisplayId, &port, &data);
24. if (mPhysicalDisplayIdMap.empty()) {
25. mHasMultiDisplaySupport = hasDisplayIdentificationData;
26. ALOGI("Switching to %s multi-display mode",
27. mHasMultiDisplaySupport ? "generalized" : "legacy");
28. }
29.
30. if (shouldIgnoreHotplugConnect(hwcDisplayId, hasDisplayIdentificationData)) {
31. return {};
32. }
33.
34. info = [this, hwcDisplayId, &port, &data, hasDisplayIdentificationData] {
35. const bool isPrimary = !mInternalHwcDisplayId;
36. if (mHasMultiDisplaySupport) {
37. if (const auto info = parseDisplayIdentificationData(port, data)) {
38. return *info;
39. }
40. ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
41. } else {
42. ALOGW_IF(hasDisplayIdentificationData,
43. "Ignoring identification data for display %" PRIu64, hwcDisplayId);
44. port = isPrimary ? LEGACY_DISPLAY_TYPE_PRIMARY : LEGACY_DISPLAY_TYPE_EXTERNAL;
45. }
46.
47. return DisplayIdentificationInfo{.id = PhysicalDisplayId::fromPort(port),
48. .name = isPrimary ? "Internal display"
49. : "External display",
50. .deviceProductInfo = std::nullopt};
51. }();
52.
53. if (!isConnected(info->id)) {
54. allocatePhysicalDisplay(hwcDisplayId, info->id);
55. }
56. return info;
57. }
onHotplug()接收的两个参数在第二阶段的时候已经确定过了,hwcDisplayId=0/ connection= CONNECTED,所以继续看onHotplugConnect()。
toPhysicalDisplayId()转换函数第一次返回空值,因此走else分支。
getDisplayIdentificationData()属于composer 2.3版本的接口,我们未实现,所以hasDisplayIdentificationData的值为false了。mPhysicalDisplayIdMap初始为空,因此mHasMultiDisplaySupport的值也为false。
shouldIgnoreHotplugConnect()直接返回false。
重点来了,这里需要为主屏(primary display)构造一个DisplayIdentificationInfo类型的实例。这个实例的成员:以value值0构造一个PhysicalDisplayId赋值给成员id,以"Internal display"赋值给成员name,成员deviceProductInfo暂时为空。
最后,为主屏创建一个Display并保存到mDisplayData中且设置为connected状态。若有其他屏则同理。
总结一下,onHotplug()的作用就是为所有的物理屏幕创建对应的Display实例。
loadDisplayModes()
mPhysicalDisplayTokens中此时还没有任何内容,往下看loadDisplayModes()函数功能:
1. //frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
2. void SurfaceFlinger::loadDisplayModes(PhysicalDisplayId displayId, DisplayModes& outModes,
3. DisplayModePtr& outActiveMode) const {
4. std::vector<HWComposer::HWCDisplayMode> hwcModes;
5. std::optional<hal::HWDisplayId> activeModeHwcId;
6. bool activeModeIsSupported;
7. int attempt = 0;
8. constexpr int kMaxAttempts = 3;
9. do {
10. hwcModes = getHwComposer().getModes(displayId);
11. activeModeHwcId = getHwComposer().getActiveMode(displayId);
12. LOG_ALWAYS_FATAL_IF(!activeModeHwcId, "HWC returned no active mode");
13.
14. activeModeIsSupported =
15. std::any_of(hwcModes.begin(), hwcModes.end(),
16. [activeModeHwcId](const HWComposer::HWCDisplayMode& mode) {
17. return mode.hwcId == *activeModeHwcId;
18. });
19. } while (!activeModeIsSupported && ++attempt < kMaxAttempts);
20.
21. //初始化阶段没有任何Display Mode添加过,所以oldModes为空。
22. DisplayModes oldModes;
23. //省略
24.
25. DisplayModes newModes;
26. int32_t nextModeId = largestUsedModeId + 1;//=0
27. for (const auto& hwcMode : hwcModes) {
28. newModes.push_back(DisplayMode::Builder(hwcMode.hwcId)
29. .setId(DisplayModeId{nextModeId++})
30. .setWidth(hwcMode.width)
31. .setHeight(hwcMode.height)
32. .setVsyncPeriod(hwcMode.vsyncPeriod)
33. .setDpiX(hwcMode.dpiX)
34. .setDpiY(hwcMode.dpiY)
35. .setGroup(hwcMode.configGroup)
36. .build());
37. }
38.
39. const bool modesAreSame =
40. std::equal(newModes.begin(), newModes.end(), oldModes.begin(), oldModes.end(),
41. [](DisplayModePtr left, DisplayModePtr right) {
42. return left->equalsExceptDisplayModeId(right);
43. });
44. //modesAreSame == false
45. if (modesAreSame) {
46. // The supported modes have not changed, keep the old IDs.
47. outModes = oldModes;
48. } else {
49. outModes = newModes;
50. }
51.
52. outActiveMode = *std::find_if(outModes.begin(), outModes.end(),
53. [activeModeHwcId](const DisplayModePtr& mode) {
54. return mode->getHwcId() == *activeModeHwcId;
55. });
56. }
do while循环体中通过getHwComposer().getModes()来获取底层支持的所有Display Mode,再通过getHwComposer().getActiveMode()来获取底层当前在用的Display Mode。
for循环体则只是做个简单的格式转换。
关于std::any_of/std::equal/std::find_if这三个内容将在附录中介绍。
总结一下,loadDisplayModes()的作用就是获取底层支持的所有Display Mode以及当前正在使用的Display Mode。
mPhysicalDisplayTokens
创建一个DisplayDeviceState对象,并将前面获取到的id、mode、name等信息存入其中。再创建一个binder对象,将它和DisplayDeviceState对象以键值对的形式存入mCurrentState中。同时,将它和PhysicalDisplayId成对也存入mPhysicalDisplayTokens中。
initScheduler()和processDisplayChangesLocked()这两个功能内容比较多,考虑了一下还是放在后面的章节讲解。
init()第三阶段走到这一步,我们来看看surfaceflinger又创建了哪些内容: