zoukankan      html  css  js  c++  java
  • 安卓高手之路之 GDI图形引擎篇

    安卓高手之路之 GDI图形引擎篇 - 修补C++ - ITeye技术网站

    1.底层C++

      SufaceFlinger类图的静态结构

     2.上层Java的调用流程。

     首先,直接从WindowManagerService入手:

      

    Java代码  收藏代码
    1. public int relayoutWindow(Session session, IWindow client, int seq,  
    2.            WindowManager.LayoutParams attrs, int requestedWidth,  
    3.            int requestedHeight, int viewVisibility, int flags,  
    4.            Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,  
    5.            Configuration outConfig, Surface outSurface)   
     public int relayoutWindow(Session session, IWindow client, int seq,
                WindowManager.LayoutParams attrs, int requestedWidth,
                int requestedHeight, int viewVisibility, int flags,
                Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
                Configuration outConfig, Surface outSurface) 

    这个方法中有一句:

       Surface surface = win.createSurfaceLocked();
    创建Surface,然后继续跟下去,跟到了jni(android_view_Surface.cpp)的如下方法:
    Java代码  收藏代码
    1. static void Surface_init(  
    2.         JNIEnv* env, jobject clazz,  
    3.         jobject session,  
    4.         jint, jstring jname, jint dpy, jint w, jint h, jint format, jint flags)  
    5. {  
    6.     if (session == NULL) {  
    7.         doThrowNPE(env);  
    8.         return;  
    9.     }  
    10.   
    11.     SurfaceComposerClient* client =  
    12.             (SurfaceComposerClient*)env->GetIntField(session, sso.client);  
    13.   
    14.     sp<SurfaceControl> surface;  
    15.     if (jname == NULL) {  
    16.         surface = client->createSurface(dpy, w, h, format, flags);  
    17.     } else {  
    18.         const jchar* str = env->GetStringCritical(jname, 0);  
    19.         const String8 name(str, env->GetStringLength(jname));  
    20.         env->ReleaseStringCritical(jname, str);  
    21.         surface = client->createSurface(name, dpy, w, h, format, flags);  
    22.     }  
    23.   
    24.     if (surface == 0) {  
    25.         jniThrowException(env, OutOfResourcesException, NULL);  
    26.         return;  
    27.     }  
    28.    <span style="background-color: #ffffff; color: #ff0000;"> setSurfaceControl(env, clazz, surface);  
    29. </span>}  
    static void Surface_init(
            JNIEnv* env, jobject clazz,
            jobject session,
            jint, jstring jname, jint dpy, jint w, jint h, jint format, jint flags)
    {
        if (session == NULL) {
            doThrowNPE(env);
            return;
        }
    
        SurfaceComposerClient* client =
                (SurfaceComposerClient*)env->GetIntField(session, sso.client);
    
        sp<SurfaceControl> surface;
        if (jname == NULL) {
            surface = client->createSurface(dpy, w, h, format, flags);
        } else {
            const jchar* str = env->GetStringCritical(jname, 0);
            const String8 name(str, env->GetStringLength(jname));
            env->ReleaseStringCritical(jname, str);
            surface = client->createSurface(name, dpy, w, h, format, flags);
        }
    
        if (surface == 0) {
            jniThrowException(env, OutOfResourcesException, NULL);
            return;
        }
        setSurfaceControl(env, clazz, surface);
    }

     郁闷的是这个session又是如何初始化的,同样在android_view_Surface.cpp中:

    Java代码  收藏代码
    1. static void SurfaceSession_init(JNIEnv* env, jobject clazz)  
    2. {  
    3.     sp<SurfaceComposerClient> client = new SurfaceComposerClient;  
    4.     client->incStrong(clazz);  
    5.     <span style="color: #ff0000;">env->SetIntField(clazz, sso.client, (int)client.get());  
    6. </span>}  
    static void SurfaceSession_init(JNIEnv* env, jobject clazz)
    {
        sp<SurfaceComposerClient> client = new SurfaceComposerClient;
        client->incStrong(clazz);
        env->SetIntField(clazz, sso.client, (int)client.get());
    }
    
    非常好,那么这个client就是和java层SurfaceSession构成了一一对应关系咯?事实的确如此。看java层的
    SurfaceSession的定义,里面仅有的成员变量就是这个client:
    Java代码  收藏代码
    1. public class SurfaceSession {  
    2.     /** Create a new connection with the surface flinger. */  
    3.     public SurfaceSession() {  
    4.         init();  
    5.     }  
    6.   
    7.     /** Forcibly detach native resources associated with this object. 
    8.      *  Unlike destroy(), after this call any surfaces that were created 
    9.      *  from the session will no longer work. The session itself is destroyed. 
    10.      */  
    11.     public native void kill();  
    12.   
    13.     /* no user serviceable parts here ... */  
    14.     @Override  
    15.     protected void finalize() throws Throwable {  
    16.         destroy();  
    17.     }  
    18.       
    19.     private native void init();  
    20.     private native void destroy();  
    21.       
    22.    <span style="color: #ff0000;"private int mClient;  
    23. </span>}  
    public class SurfaceSession {
        /** Create a new connection with the surface flinger. */
        public SurfaceSession() {
            init();
        }
    
        /** Forcibly detach native resources associated with this object.
         *  Unlike destroy(), after this call any surfaces that were created
         *  from the session will no longer work. The session itself is destroyed.
         */
        public native void kill();
    
        /* no user serviceable parts here ... */
        @Override
        protected void finalize() throws Throwable {
            destroy();
        }
    
        private native void init();
        private native void destroy();
    
        private int mClient;
    }

     好了,现在回到java层继续看Surface。现在的概念应该很明确了,从本质上来说,Surface是由SurfaceSession创建的。那么SurfaceSession 又是由谁创建的呢? 既然SurfaceSession 是Session的成员变量,那么就顺藤摸瓜去看:

    Java代码  收藏代码
    1. void windowAddedLocked() {  
    2.       if (mSurfaceSession == null) {  
    3.           if (WindowManagerService.localLOGV) Slog.v(  
    4.               WindowManagerService.TAG, "First window added to " + this + ", creating SurfaceSession");  
    5.         <span style="color: #ff0000;">  mSurfaceSession = new SurfaceSession();  
    6. span>            if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(  
    7.                   WindowManagerService.TAG, "  NEW SURFACE SESSION " + mSurfaceSession);  
    8.           mService.mSessions.add(this);  
    9.       }  
    10.       mNumWindow++;  
    11.   }  
      void windowAddedLocked() {
            if (mSurfaceSession == null) {
                if (WindowManagerService.localLOGV) Slog.v(
                    WindowManagerService.TAG, "First window added to " + this + ", creating SurfaceSession");
                mSurfaceSession = new SurfaceSession();
                if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
                        WindowManagerService.TAG, "  NEW SURFACE SESSION " + mSurfaceSession);
                mService.mSessions.add(this);
            }
            mNumWindow++;
        }

     那么windowAddedLocked又是谁调用的呢?在WIndowState.java中:

      

    Java代码  收藏代码
    1. void attach() {  
    2.        if (WindowManagerService.localLOGV) Slog.v(  
    3.            WindowManagerService.TAG, "Attaching " + this + " token=" + mToken  
    4.            + ", list=" + mToken.windows);  
    5.        mSession.windowAddedLocked();  
    6.    }  
     void attach() {
            if (WindowManagerService.localLOGV) Slog.v(
                WindowManagerService.TAG, "Attaching " + this + " token=" + mToken
                + ", list=" + mToken.windows);
            mSession.windowAddedLocked();
        }

     那么这个attach又是谁调用的呢?WindowManagerService.java的一个方法,如下:

    Java代码  收藏代码
    1. public int addWindow(Session session, IWindow client, int seq,  
    2.            WindowManager.LayoutParams attrs, int viewVisibility,  
    3.            Rect outContentInsets, InputChannel outInputChannel)  
     public int addWindow(Session session, IWindow client, int seq,
                WindowManager.LayoutParams attrs, int viewVisibility,
                Rect outContentInsets, InputChannel outInputChannel)

     由于这个方法比较长,就不贴了,只看其中最关键的地方,其中有这么一句话:

      win.attach();
    经过这么一分析,清楚了,SurfaceSession是WindowManagerService在addWindow的时候创建的。而
    Surface是在WIndowManagerService进行relayoutWindow时创建的。
  • 相关阅读:
    tr的最后一个td
    Jquery的parent方法,这里只讲parent方法
    js判断字符串包含字符串的方法 | 标签包含文本
    js中substring和substr的用法
    一个由印度人编写的VC串口类
    VS2010编译Qt5.4.0静态库
    QT5.4关联VS2010,配置VAssistX关联Qt类
    iOS 关于tableView中有多个textField,输入框被遮住的解决方法
    iOS 之URL schemes
    iOS 之改变状态栏颜色
  • 原文地址:https://www.cnblogs.com/seven1979/p/4369597.html
Copyright © 2011-2022 走看看