Android 图形系统详解

Posted xyTianZhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 图形系统详解相关的知识,希望对你有一定的参考价值。

概述

一个页面(Activity)显示到屏幕上主要经过一下几个流程:
启动 Activity → 创建 Window → WMS 注册 Window → SurfaceFlinger 创建 Surface → 合成 layer → 显示
主要涉及三个进程:App进程、System_server进程、SurfaceFlinger进程

  1. App 进程:负责发起 Surface 创建的请求。同时触发对控件的测量、布局、绘制以及输入事件的派发处理,主要在 ViewRootImpl中 触发( AMS 作用是统一调度所有 App 的 Activity )
  2. System_server 进程:主要是 WindowManagerService,负责接收 App 请求,同时和 SurfaceFlinger 建立连接,向 SF 发起具体请求创建 Surface,并且创建 Surace 的辅助管理类 SurfaceControl(与 window 一一对应)
  3. SurfaceFlinger:为 App 创建具体的 Surface,在 SurfaceFlinger 对应 Layer,然后负责管理、合成所有图层,最终显示在屏幕上

应用层可通过两种方式将图像绘制到屏幕上:使用 Canvas 或 OpenGL

  • android.graphics.Canvas 是一个 2D 图形 API,从 4.0 开始通过 OpenGLRenderer 的绘制库实现硬件加速,将Canvas 运算转换为 OpenGL 运算,以便它们可以在 GPU 上执行,提升效率
  • OpenGL ES 直接渲染到 Surface ,Android 在 Android.opengl 软件包中提供了 OpenGL ES 接口
    下图是 view 绘制到 display 展示的整体流程,我们主要看左上角虚线框部分,整体分为 App 进程和系统进程两个部分

App 进程

概念解释

  • Activity: 一个 Activity 对应创建一个 Surface,每个 Surface 对应 SurfaceFlinger 中的一个 Layer
  • Window:每个 Activity 包含一个 Window 对象(抽象类,提供绘制窗口的通用API),由 PhoneWindow 实现。是 Activity 和整个 View 系统交互的接口。
  • PhoneWindow: 继承于 Window,是 Window 类的具体实现。该类内部包含了一个 DecorView 对象,该对象是所有应用窗口(Activity 界面)的根 View。把一个 FrameLayout 类,即 DecorView 对象进行一定的包装,将他作为应用窗口的根 View,并提供一组通用的窗口操作接口。
  • DecorView:PhoneWindow setContentView 函数中创建,继承 FrameLayout,是所有应用窗口的根 View。
  • WindowManager :继承 ViewManager ,操作 UI 的接口,具备添加、删除和更新View,具体却委托给了WindowsManagerGlobal来进行实现
  • WindowManagerImpl: 实现了 WindowManager,并持有 WindowManagerGlobal 的对象
  • WindowManagerGlobal:单例模式,每个进程只有一个。持有 ViewRootImpl 的对象
  • ViewRootImpl:所有 View 的根,作为 View 与后台各种服务的桥梁。用户输入系统(接收用户按键,触摸屏输入)、窗口系统(复杂窗口的布局,刷新,动画)、显示合成系统(包括定时器Choreograph, SurfaceFlinger)等
  • Surface:app 层用于绘制的对象

流程分析

源码分析


ActivityThread.java 
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) 
        ......
        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
        ......
        activity.attach(appContext, this, getInstrumentation(), r.token,
                            r.ident, app, r.intent, r.activityInfo, title, r.parent,
                            r.embeddedID, r.lastNonConfigurationInstances, config,
                            r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
                            r.assistToken, r.shareableActivityToken);
        ......
        mInstrumentation.callActivityOnCreate(activity, r.state);
    
    
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
                boolean isForward, String reason) 
        ......
        wm.addView(decor, l);
        ......
    


Activity.java 
    private Window mWindow;
    
    final void attach(......)
        ......
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        ......
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        ......
    
    protected void onCreate(@Nullable Bundle savedInstanceState) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity);
    
    public void setContentView(@LayoutRes int layoutResID) 
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    


Window.java 
    private WindowManager mWindowManager;
    public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
            boolean hardwareAccelerated) 
        ......
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
        ......
    


PhoneWindow.java 
    private DecorView mDecor;
    public void setContentView(View view, ViewGroup.LayoutParams params) 
        ......
        installDecor();
        ......
    
    private void installDecor() 
        ......
        mDecor = generateDecor(-1);
        ......
    
    protected DecorView generateDecor(int featureId) 
        ......
        return new DecorView(context, featureId, this, getAttributes());
    

WindowManagerImpl.java 

    private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
    
    public WindowManagerImpl createLocalWindowManager(Window parentWindow) 
        return new WindowManagerImpl(mContext, parentWindow, mWindowContextToken);
    
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) 
        ......
        mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
                mContext.getUserId());
    

WindowManagerGlobal.java 

    private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
    
    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow, int userId) 
        ......
        ViewRootImpl root = new ViewRootImpl(view.getContext(), display);
        ......
        root = new ViewRootImpl(view.getContext(), display);
        ......
        mRoots.add(root);
        ......
        root.setView(view, wparams, panelParentView, userId);
        ......
    


ViewRootImpl.java 

    View mView;//DecorView
    
    public final Surface mSurface = new Surface();
    private final SurfaceControl mSurfaceControl = new SurfaceControl();
    
    // 接收显示系统的时间脉冲(垂直同步信号- VSync 信号)
    // 同 Vsync 机制配合,控制同步处理输入(Input)、动画(Animation)、绘制(Draw)三个UI操作
    final Choreographer mChoreographer;
    
    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
            int userId) 
        ......
        mView = view;
        ......
        mWindowSession.addToDisplayAsUser()
        ......
        requestLayout();
        ......
    
    public void requestLayout() 
        ......
        scheduleTraversals();
        ......
    
    
    final class TraversalRunnable implements Runnable 
        @Override
        public void run() 
            doTraversal();
        
    
    final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
    
    void scheduleTraversals() 
        ......
        mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        ......
    
    void doTraversal() 
        ......
        performTraversals();
        ......
    
    private void performTraversals() 
        ......
        performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
        ......
        performLayout(lp, mWidth, mHeight);
        ......
        performDraw()
        ......
    
    private boolean performDraw() 
        ......
        draw(fullRedrawNeeded, usingAsyncReport && mSyncBuffer);
        ......
    
    private boolean draw(boolean fullRedrawNeeded, boolean forceDraw) 
        ......
        drawSoftware(surface, mAttachInfo, xOffset, yOffset,
                        scalingRequired, dirty, surfaceInsets);
        ......
    
    private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
            boolean scalingRequired, Rect dirty, Rect surfaceInsets) 
        ......
        canvas = mSurface.lockCanvas(dirty);
        ......
        //DecorView
        mView.draw(canvas);
        ......
        surface.unlockCanvasAndPost(canvas);
    

System 进程

概念解释

  • WindowToken:将同一应用组件(Activity、InputMethod、Wallpaper或者Dream)的窗口组织到一起

  • WindowState:表示一个窗口的所有属性,是 WMS 事实上的窗口

  • WindowManagerService:为所有窗口分配 Surface、负责 Surface 的显示顺序(Z序)以及大小尺寸、控制窗口动画,并且还是输入系统的中转站

  • Surface:native 层用于处理窗口的大小位置裁剪等操作

  • SurfaceComposerClient:与 SurfaceFlinger 进行通信,代理对象 mClient,对应 SurfaceFlinger 的 Binder 本地 Client 对象

  • SurfaceControl: app 层 surface 向 native 层提交的 buffer 的控制逻辑

  • BufferQueue:数据的生产者(Surface、BufferQueueProducer)与消费者 (SurfaceFlinger、BufferQueueConsumer)

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

  • SurfaceFlinger:运行在独立进程的 Service, 接收所有 Window 的 Surface 作为输入,根据 Z-Order, 透明度,大小,位置等参数,计算出每个 Surface 在最终合成图像中的位置,然后交由 HWComposer 或 OpenGL 生成最终的显示 Buffer, 然后显示到设备上

对应关系:
Activity -> Window -> DecorView -> ViewRootImpl -> WindowState -> Surface -> Layer 是一一对应的。

流程分析

源码分析

SurfaceFlinger 启动

main_surfaceflinger.cpp 
    int main(int, char**) 
        ......
        sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
        ......
        flinger->init();
        ......
        // publish surface flinger
        sp<IServiceManager> sm(defaultServiceManager());
        sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
        ......
        // run surface flinger in this thread
        flinger->run();
    

SurfaceFlinger.cpp 
    void SurfaceFlinger::onFirstRef() 
        ......
        mEventQueue.init(this);
        ......
    
    void SurfaceFlinger::init()
        ......
        // 初始化OpenGL 图形库相关配置
        mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
        ......
        // 创建显示设备的抽象代表,负责和显示设备打交道
        mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));
        ......
        // app的VSync信号,也就是Systrace中的VSync-app,它最终是发往到choreographer,
        // 主要处理三件事情INPUT、ANIMATION、TRAVERSAL
        // start the EventThread
        sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app");
        mEventThread = new EventThread(vsyncSrc);
        ......
    
    void SurfaceFlinger::run() 
        do 
            //运行线程,等待数据
            waitForEvent();
         while (true);
    
    void SurfaceFlinger::waitForEvent() 
        mEventQueue.waitMessage();
    
    // 发送数据
    status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
        nsecs_t reltime, uint32_t /* flags */) 
        status_t res = mEventQueue.postMessage(msg, reltime);
        if (res == NO_ERROR) 
            msg->wait();
        
        return res;
    

MessageQueue.cpp 
    void MessageQueue::init(const sp<SurfaceFlinger>& flinger) 
        mFlinger = flinger;
        mLooper = new Looper(true);
        mHandler = new Handler(*this);
    
    
    status_t MessageQueue::postMessage(const sp<MessageBase>& messageHandler, nsecs_t relTime) 
        const Message dummyMessage;
        if (relTime > 0) 
            mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
         else 
            mLooper->sendMessage(messageHandler, dummyMessage);
        
        return NO_ERROR;
    

创建 Native 层 Surface 以及 SurfaceFlinger 的 Layer

android_view_Surface.cpp 
    static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz, jlong nativeObject, jlong surfaceControlNativeObj) 
        Surface* self(reinterpret_cast<Surface *>(nativeObject));
        sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
        // If the underlying IGBP's are the same, we don't need to do anything.
        if (self != nullptr &&
                IInterface::asBinder(self->getIGraphicBufferProducer()) ==
                IInterface::asBinder(ctrl->getIGraphicBufferProducer())) 
            return nativeObject;
        
        sp<

以上是关于Android 图形系统详解的主要内容,如果未能解决你的问题,请参考以下文章

Android Drawable - Shape Drawable使用详解(附图)

Android View measure流程详解

Android Relative Layout 安卓相对布局详解

Android RotateAnimation详解

android FrameLayout详解

Android-.9图详解