Android P图形架构之DisplayManagerService解析

顾名思义,DisplayManagerService是一个用于管理显示的服务。

源码:
\frameworks\base\services\java\com\android\server\SystemServer.java
\frameworks\base\services\core\java\com\android\server\display\DisplayManagerService.java
\frameworks\base\services\core\java\com\android\server\display\DisplayDevice.java
\frameworks\base\services\core\java\com\android\server\display\LogicalDisplay.java

作用:

  • 管理显示器的全局生命周期, 决定如何根据当前连接的物理显示设备配置逻辑显示,在状态更改时向系统和应用程序发送通知等
  • 显示管理服务依赖于DisplayAdapter(LocalDisplayAdapter,OverlayDisplayAdapter,WifiDisplayAdapter)用于发现和配置连接到系统的物理显示设备
  • 设备连接的方式都有单独的DisplayAdapter,一个本地显示器的适配器,用于模拟无头系统(不接显示器)的非功能显示;一个用于开发的模拟overlay显示器;一个用wifi显示器
  • 显示适配器仅与显示管理器服务弱耦合
  • 显示适配器通过显示管理器服务注册的DisplayAdapter.Listener异步地将显示设备状态的变化传送到显示管理器服务

启动过程:
DisplayManagerService是在SystemServer中启动的。
\frameworks\base\services\java\com\android\server\SystemServer.java

private void startBootstrapServices() {
	//...
	
	// Display manager is needed to provide display metrics before package manager
	// starts up.
	traceBeginAndSlog("StartDisplayManager");
	mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
	traceEnd();

	//...
}

代码分析:

LocalDisplayAdapter

DisplayManagerService的onStart()中发送了消息MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS,去执行了registerDefaultDisplayAdapters(),初始化了主屏显示器适配器LocalDisplayAdapter

@Override
public void onStart() {
    // We need to pre-load the persistent data store so it's ready before the default display
    // adapter is up so that we have it's configuration. We could load it lazily, but since
    // we're going to have to read it in eventually we may as well do it here rather than after
    // we've waited for the display to register itself with us.
synchronized(mSyncRoot) {
mPersistentDataStore.loadIfNeeded();
loadStableDisplayValuesLocked();
    }
    mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);

    publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
            true /*allowIsolated*/);
    publishLocalService(DisplayManagerInternal.class, new LocalService());
    publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());
}

//加载LocalDisplayAdapter和getVirtualDisplayAdapter
private void registerDefaultDisplayAdapters() {
    // Register default display adapters.
    synchronized (mSyncRoot) {
        // main display adapter
        registerDisplayAdapterLocked(new LocalDisplayAdapter(
                mSyncRoot, mContext, mHandler, mDisplayAdapterListener));

        // Standalone VR devices rely on a virtual display as their primary display for
        // 2D UI. We register virtual display adapter along side the main display adapter
        // here so that it is ready by the time the system sends the home Intent for
        // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
        // the virtual display inside VR before any VR-specific apps even run.
        mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
                mHandler, mDisplayAdapterListener);
        if (mVirtualDisplayAdapter != null) {
            registerDisplayAdapterLocked(mVirtualDisplayAdapter);
        }
    }
}

registerDisplayAdapterLocked把适配器放入了mDisplayAdapters中,并且执行了LocalDisplayAdapter的registerLocked();

// List of all currently registered display adapters.
private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();

private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
    mDisplayAdapters.add(adapter);
    adapter.registerLocked();
}

LocalDisplayAdapter中则去调用SurfaceFlinger获取物理显示屏的信息,并返回给DisplayManagerService,最终执行了handleDisplayDeviceAddedLocked(),来添加显示器设备。
\frameworks\base\services\core\java\com\android\server\display\LocalDisplayAdapter.java

@Override
public void registerLocked() {
    super.registerLocked();

    mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());

    for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {
        tryConnectDisplayLocked(builtInDisplayId);
    }
}

添加显示器:

// List of all currently connected display devices.
private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();

private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
    DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
    if (mDisplayDevices.contains(device)) {
        Slog.w(TAG, "Attempted to add already added display device: " + info);
        return;
    }

    Slog.i(TAG, "Display device added: " + info);
    
    device.mDebugLastLoggedDeviceInfo = info;

    mDisplayDevices.add(device);
    LogicalDisplay display = addLogicalDisplayLocked(device);
    Runnable work = updateDisplayStateLocked(device);
    if (work != null) {
        work.run();
    }
    scheduleTraversalLocked(false);
}

handleDisplayDeviceAddedLocked()会将显示器设备统一放到mDisplayDevices中,并且执行了addLogicalDisplayLocked(),作用是在一个显示设备中添加逻辑显示,assignDisplayIdLocked()分配一个displayId,并且放入mLogicalDisplays中。

// List of all logical displays indexed by logical display id.
private final SparseArray<LogicalDisplay> mLogicalDisplays = new SparseArray<LogicalDisplay>();

// Adds a new logical display based on the given display device.
// Sends notifications if needed.
private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) {
    DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
    boolean isDefault = (deviceInfo.flags
            & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
    if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
        Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
        isDefault = false;
    }

    if (!isDefault && mSingleDisplayDemoMode) {
        Slog.i(TAG, "Not creating a logical display for a secondary display "
                + " because single display demo mode is enabled: " + deviceInfo);
        return null;
    }

    final int displayId = assignDisplayIdLocked(isDefault);
    final int layerStack = assignLayerStackLocked(displayId);

    LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
    display.updateLocked(mDisplayDevices);
    if (!display.isValidLocked()) {
        // This should never happen currently.
        Slog.w(TAG, "Ignoring display device because the logical display "
                + "created from it was not considered valid: " + deviceInfo);
        return null;
    }

    configureColorModeLocked(display, device);
    if (isDefault) {
        recordStableDisplayStatsIfNeededLocked(display);
        recordTopInsetLocked(display);
    }

    mLogicalDisplays.put(displayId, display);

    // Wake up waitForDefaultDisplay.
    if (isDefault) {
        mSyncRoot.notifyAll();
    }

    sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
    return display;
}

OverlayDisplayAdapter、WifiDisplayAdapter

DisplayManagerService的systemReady()中,发送了MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS,并执行了registerAdditionalDisplayAdapters(),在registerAdditionalDisplayAdapters中完成了OverlayDisplayAdapter和WifiDisplayAdapter的注册。

/**
 * Called when the system is ready to go.
 */
public void systemReady(boolean safeMode, boolean onlyCore) {
    synchronized (mSyncRoot) {
        mSafeMode = safeMode;
        mOnlyCore = onlyCore;
        mSystemReady = true;
        // Just in case the top inset changed before the system was ready. At this point, any
        // relevant configuration should be in place.
        recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY));
    }

    mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
    mHandler.sendEmptyMessage(MSG_REGISTER_BRIGHTNESS_TRACKER);
}

private void registerAdditionalDisplayAdapters() {
    synchronized (mSyncRoot) {
        if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
            registerOverlayDisplayAdapterLocked();
            registerWifiDisplayAdapterLocked();
        }
    }
}

跟LocalDisplayAdapter流程类似:

private void registerOverlayDisplayAdapterLocked() {
    registerDisplayAdapterLocked(new OverlayDisplayAdapter(
            mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
}

private void registerWifiDisplayAdapterLocked() {
    if (mContext.getResources().getBoolean(
            com.android.internal.R.bool.config_enableWifiDisplay)
            || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
        mWifiDisplayAdapter = new WifiDisplayAdapter(
                mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
                mPersistentDataStore);
        registerDisplayAdapterLocked(mWifiDisplayAdapter);
    }
}

VirtualDisplayAdapter

在加载LocalDisplayAdapter的时候就加载了虚拟显示适配器,因为虚拟显示必须依赖于物理屏。
DisplayManagerService的onstart()中执行的,getVirtualDisplayAdapter(),加载虚拟屏。

private void registerDefaultDisplayAdapters() {
    // Register default display adapters.
    synchronized (mSyncRoot) {
        // main display adapter
        registerDisplayAdapterLocked(new LocalDisplayAdapter(
                mSyncRoot, mContext, mHandler, mDisplayAdapterListener));

        // Standalone VR devices rely on a virtual display as their primary display for
        // 2D UI. We register virtual display adapter along side the main display adapter
        // here so that it is ready by the time the system sends the home Intent for
        // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
        // the virtual display inside VR before any VR-specific apps even run.
        mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
                mHandler, mDisplayAdapterListener);
        if (mVirtualDisplayAdapter != null) {
            registerDisplayAdapterLocked(mVirtualDisplayAdapter);
        }
    }
}

@VisibleForTesting
static class Injector {
    VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
            Handler handler, DisplayAdapter.Listener displayAdapterListener) {
        return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
    }

    long getDefaultDisplayDelayTimeout() {
        return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
    }
}
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Android图形显示系统可以分为两个主要部分:图形系统和显示系统。图形系统负责处理图形渲染和图形处理的功能,而显示系统则负责将渲染后的图像显示在屏幕上。 在图形系统中,有几个组件相互协作。首先是SurfaceFlinger,它是一个系统级的服务,负责管理和合成所有应用程序的图形窗口。SurfaceFlinger使用帧缓冲区(Frame Buffer)来保存图像数据,并将多个应用程序的图像合成为最终的显示图像。然后是OpenGL ES(Open Graphics Library for Embedded Systems),它是一种用于渲染2D和3D图形的API。OpenGL ES可以通过硬件加速来提供更快的图形渲染性能。最后是Skia,它是一个跨平台的2D图形库,用于处理矢量图形和文字渲染。 在显示系统中,有几个关键组件。首先是Display Manager,它负责管理和配置所有连接到设备的显示器。然后是HWC(Hardware Composer),它是一个硬件抽象层接口,用于将图像数据从帧缓冲区发送到显示器。HWC可以通过与GPU和显示驱动程序的协作来实现图像的硬件加速合成和显示。最后是Surface Control,它是一个用于创建和管理Surface的系统服务,Surface是应用程序窗口的抽象表示。 这就是Android图形显示系统的基本架构。通过图形系统和显示系统的协作,Android可以提供丰富的图形渲染和显示功能,从而实现各种各样的应用程序界面和图形效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaolin2016

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值