android GUI 记录(1)

/ android / 没有评论 / 810浏览

用到的代码文件

frameworks/native/services/surfaceflinger/SurfaceFlinger.h
frameworks/native/services/surfaceflinger/DisplayDevice.h
frameworks/native/services/surfaceflinger/Layer.h
frameworks/native/include/ui/Region.h
frameworks/base/core/java/android/view/Surface.java
frameworks/base/core/java/android/view/Window.java
frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java

相关概念

下面的代码是以android N(api 24)为基础来进行流程分析。

android.view.Window.java 这个Window是一个抽象类。
PhoneWindow.java 继承自android.viw.Window类。
在Activity中有一个mWindow对象:mWindow = new PhoneWindow(this, window)。
Surface.java 处理一个开始被屏幕合成器管理的未加工的buffer,可以理解为Android系统中的一个基本显示单元。只要使用Android任意一种API绘图,绘制的结果都将反映在Surface上。

在WindowManagerService里,Window指的是WindowState对象,即一个特定的显示区域。
下文中的Window均指的是WindowManagerService里的WindowState对象。

在Android中,Window与Surface一一对应。

Window的内容是变化的,Surface需要有空间来记录每个时刻Window的内容。在Android的SurfaceFlinger实现里,通常一个Surface有两块 Buffer, 一块用于绘画,一块用于显示,两个Buffer按照固定的频率进行交换,从而实现Window的动态刷新。现在已经是 三重缓冲区(>=Android 4.1)。

Layer是SurfaceFlinger 进行合成的基本操作单元。Layer在应用请求创建Surface的时候在SurfaceFlinger内部创建,因此一个Surface对应一个 Layer。

void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
        bool useIdentityTransform) const
{
    ATRACE_CALL();

    if (CC_UNLIKELY(mActiveBuffer == 0)) {
        // the texture has not been created yet, this Layer has
        // in fact never been drawn into. This happens frequently with
        // SurfaceView because the WindowManager can't know when the client
        // has drawn the first time.

        // If there is nothing under us, we paint the screen in black, otherwise
        // we just skip this update.

        // figure out if there is something below us
        Region under;
        const SurfaceFlinger::LayerVector& drawingLayers(
                mFlinger->mDrawingState.layersSortedByZ);
        const size_t count = drawingLayers.size();
        for (size_t i=0 ; i<count ; ++i) {
            const sp<Layer>& layer(drawingLayers[i]);
            if (layer.get() == static_cast<Layer const*>(this))
                break;
            under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
        }
        // if not everything below us is covered, we plug the holes!
        Region holes(clip.subtract(under));
        if (!holes.isEmpty()) {
            clearWithOpenGL(hw, holes, 0, 0, 0, 1);
        }
        return;
    }
    ......
}

当多个Layer进行合成的时候,并不是整个Layer的空间都会被完全显示,根据这个Layer最终的显示效果,一个Layer可以被划分成很多的Region, Android SurfaceFlinger 定义了以下一些Region类型:

 TransparantRegion: 完全透明的区域,在它之下的区域将被显示出来。
 OpaqueRegion: 完全不透明的区域,是否显示取决于它上面是否有遮挡或是否透明。
 VisibleRegion: 可见区域,包括完全不透明无遮挡区域或半透明区域。 visibleRegion = Region - above OpaqueRegion.
 CoveredRegion: 被遮挡区域,在它之上,有不透明或半透明区域。
 DirtyRegion: 可见部分改变区域,包括新的被遮挡区域,和新的露出区域。

Android 系统支持多种显示设备。Android用DisplayDevice类来表示这样的设备。

Layer的输出与DisplayDevice存在对应关系。只有当Layer中的layerStack数值与Display 对象的mLayerStack一样,才会将某个Layer输出到某个DisplayDevice。

SurfaceFlinger的工作内容,就是定期检查所有Layer的参数更新(layerStack等),计算新的DirtyRegion, 然后将结果推送给底层显示驱动进行显示。

SurfaceFlinger 是一个独立的Service,服务运行在System进程中,用来统一管理系统的帧缓冲区设备。它接收所有Window的Surface作为输入。根据Z-Order, 透明度,大小,位置等参数计算出每个Surface在最终合成图像中的位置,然后交由HWComposer或OpenGL生成最终的显示Buffer, 然后显示到指定设备上。

android N