Layer visibleRegion的計算過程

Layer::State介紹

這裏寫圖片描述

[Layer.cpp]

//Layer::State
    struct State {
        Geometry active;
        Geometry requested;
        uint32_t z;
        uint32_t layerStack;
        uint8_t alpha;
        uint8_t flags;
        uint8_t reserved[2];
        int32_t sequence; // changes when visible regions can change
        Transform transform; //表示Layer的旋轉,平移,縮放
        // the transparentRegion hint is a bit special, it's latched only
        // when we receive a buffer -- this is because it's "content"
        // dependent.
        Region activeTransparentRegion;//當前顯示的transparentRegion,也就是dumpsf的transparentRegion
        Region requestedTransparentRegion;
    };

[Layer.cpp]

    struct Geometry {
        uint32_t w; //size的寬高
        uint32_t h;
        Rect crop; //crop
        inline bool operator ==(const Geometry& rhs) const {
            return (w == rhs.w && h == rhs.h && crop == rhs.crop);
        }
        inline bool operator !=(const Geometry& rhs) const {
            return !operator ==(rhs);
        }
    };

Layer::State設置流程

這裏寫圖片描述

java層的就不看了,直接看Native層的例子 resize

http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/tests/resize/resize.cpp#60

60    SurfaceComposerClient::openGlobalTransaction();
61    surfaceControl->setSize(320, 240);
62    SurfaceComposerClient::closeGlobalTransaction();

http://androidxref.com/6.0.1_r10/xref/frameworks/native/libs/gui/SurfaceControl.cpp#110

107status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
108    status_t err = validate();
109    if (err < 0) return err;
110    return mClient->setSize(mHandle, w, h);//這個mClinet就是SurfaceCompserClient強引用對象
111}

http://androidxref.com/6.0.1_r10/xref/frameworks/native/libs/gui/SurfaceComposerClient.cpp#570

569status_t SurfaceComposerClient::setSize(const sp<IBinder>& id, uint32_t w, uint32_t h) {
570    return getComposer().setSize(this, id, w, h);//Composer是個單例
571}

http://androidxref.com/6.0.1_r10/xref/frameworks/native/libs/gui/SurfaceComposerClient.cpp#282

279status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
280        const sp<IBinder>& id, uint32_t w, uint32_t h) {
281    Mutex::Autolock _l(mLock);
282    layer_state_t* s = getLayerStateLocked(client, id);
283    if (!s)
284        return BAD_INDEX;
       //每層Layer的屬性暫存到Layer_state_t Struct
285    s->what |= layer_state_t::eSizeChanged;
286    s->w = w;
287    s->h = h;
288
289    // Resizing a surface makes the transaction synchronous.
290    mForceSynchronous = true;
291
292    return NO_ERROR;
293}

http://androidxref.com/6.0.1_r10/xref/frameworks/native/libs/gui/SurfaceComposerClient.cpp#getLayerStateLocked

////每層Layer的屬性暫存到SurfaceomposerClient對象Client,一起包裝爲ComposerState
250layer_state_t* Composer::getLayerStateLocked(
251        const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) {
252
253    ComposerState s;
254    s.client = client->mClient;
255    s.state.surface = id;
256
257    ssize_t index = mComposerStates.indexOf(s);
258    if (index < 0) {
259        // we don't have it, add an initialized layer_state to our list
260        index = mComposerStates.add(s);
261    }
262
263    ComposerState* const out = mComposerStates.editArray();
264    return &(out[index].state);
265}

closeTransaction這邊流程就不具體看了,直接看函數 SurfaceFlinger::setTransactionState

http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

2093void SurfaceFlinger::setTransactionState(
2094        const Vector<ComposerState>& state,
2095        const Vector<DisplayState>& displays,
2096        uint32_t flags)
2097{
2098    ATRACE_CALL();
2099    Mutex::Autolock _l(mStateLock);
2100    uint32_t transactionFlags = 0;
        ...
2124    count = state.size();
2125    for (size_t i=0 ; i<count ; i++) { //遍歷每層Layer
2126        const ComposerState& s(state[i]);
        ...
2134        if (s.client != NULL) {
2135            sp<IBinder> binder = IInterface::asBinder(s.client);
2136            if (binder != NULL) {
2137                String16 desc(binder->getInterfaceDescriptor());
2138                if (desc == ISurfaceComposerClient::descriptor) {
2139                    sp<Client> client( static_cast<Client *>(s.client.get()) );
                        //設置Layer屬性,返回flags(表示Layer屬性是否有變化)
2140                    transactionFlags |= setClientStateLocked(client, s.state);
2141                }
2142            }
2143        }
2144    }
2145
2146    if (transactionFlags) {
2147        // this triggers the transaction
2148        setTransactionFlags(transactionFlags);
2149        ...
2168    }
2169}
2221uint32_t SurfaceFlinger::setClientStateLocked(
2222        const sp<Client>& client,
2223        const layer_state_t& s)
2224{
2225    uint32_t flags = 0;
2226    sp<Layer> layer(client->getLayerUser(s.surface));
2227    if (layer != 0) {
        ...
2244        if (what & layer_state_t::eSizeChanged) {
2245            if (layer->setSize(s.w, s.h)) {
2246                flags |= eTraversalNeeded; //設置eTraversalNeeded flags
2247            }
2248        }
        ...
2281    return flags;
2282}

[frameworks/native/services/surfaceflinger/Layer.cpp]

1137bool Layer::setSize(uint32_t w, uint32_t h) {
1138    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
1139        return false;
        // size,crop傳給mCurrentState.requested
1140    mCurrentState.requested.w = w;
1141    mCurrentState.requested.h = h;
1142    setTransactionFlags(eTransactionNeeded);
1143    return true;
1144}
2085uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
2086    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
2087    if ((old & flags)==0) { // wake the server up, Layer屬性發生變化
2088        signalTransaction();
2089    }
2090    return old;
2091}
760void SurfaceFlinger::signalTransaction() {
761    mEventQueue.invalidate();
762}

Vsync信號到來時

Layer 屬性發生變化做的操作

SurfaceFlinger::handleTransactionLocked
->Layer::doTransaction()

  1. 根據Layer的size是否變化,改變buffer大小
  2. mCurrentSate.active=mCurrentSate.requested(一般情況下都會賦值,除非flags設置了eDontUpdateGeometryState),
  3. 修改flags(使之重新計算visibelRegion的值)

–>Layer::commitTransaction() : 賦值 mDrawingState = mCurrentState;

uint32_t Layer::doTransaction(uint32_t flags) {
    ATRACE_CALL();

    const Layer::State& s(getDrawingState());
    const Layer::State& c(getCurrentState());

    const bool sizeChanged = (c.requested.w != s.requested.w) ||
                             (c.requested.h != s.requested.h);

    if (sizeChanged) {//根據Layer的size是否變化,改變buffer大小
        // the size changed, we need to ask our client to request a new buffer
        ALOGE("...");

        // record the new size, form this point on, when the client request
        // a buffer, it'll get the new size.
        mSurfaceFlingerConsumer->setDefaultBufferSize(
                c.requested.w, c.requested.h);
    }

    if (!isFixedSize()) {

        const bool resizePending = (c.requested.w != c.active.w) ||
                                   (c.requested.h != c.active.h);

        if (resizePending && mSidebandStream == NULL) {
            // don't let Layer::doTransaction update the drawing state
            // if we have a pending resize, unless we are in fixed-size mode.
            // the drawing state will be updated only once we receive a buffer
            // with the correct size.
            //
            // in particular, we want to make sure the clip (which is part
            // of the geometry state) is latched together with the size but is
            // latched immediately when no resizing is involved.
            //
            // If a sideband stream is attached, however, we want to skip this
            // optimization so that transactions aren't missed when a buffer
            // never arrives

            flags |= eDontUpdateGeometryState; //設置了這個flag就不會用requested的值
        }
    }

    // always set active to requested, unless we're asked not to
    // this is used by Layer, which special cases resizes.
    if (flags & eDontUpdateGeometryState)  {
    } else {
        Layer::State& editCurrentState(getCurrentState());
        editCurrentState.active = c.requested; //mCurrentSate.active=mCurrentSate.requested
    }

    if (s.active != c.active) {
        // invalidate and recompute the visible regions if needed
        flags |= Layer::eVisibleRegion; //修改flags(使之重新計算visibelRegion的值)
    }

    if (c.sequence != s.sequence) {
        // invalidate and recompute the visible regions if needed
        flags |= eVisibleRegion;
        this->contentDirty = true;

        // we may use linear filtering, if the matrix scales us
        const uint8_t type = c.transform.getType();
        mNeedsFiltering = (!c.transform.preserveRects() ||
                (type >= Transform::SCALE));
    }

    // Commit the transaction
    commitTransaction();
    return flags;
}
void Layer::commitTransaction() {
    mDrawingState = mCurrentState;
}

重點介紹一下 transform的值
1.先介紹一下Transform類
[frameworks/native/services/surfaceflinger/Transform.h]

這裏寫圖片描述

成員變量:
Mmatrix: mat33類型,就是一個3X3矩陣
mType: uint32_t類型,最低位爲1表示需要translate(還有其他位表示ROT_90…)

成員函數:
transform(): 執行變換的函數

1.1 Transform.mat33的賦值

這裏寫圖片描述

右邊的矩陣是mat33,每個變量的分別表示:
scaleX: x軸的縮放因子
skewX: x軸的斜交因子(錯切因子)
translateX: x軸的平移向量
scaleY: y軸的縮放因子
skewY: y軸的斜交因子
translateX: y軸的平移向量
最後一排: 3D效果,透視變換

Transform.mat33 的值由position和 matrix組成,由setMatirx和setPosition賦值

bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
    mCurrentState.sequence++;
    mCurrentState.transform.set(
            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
    setTransactionFlags(eTransactionNeeded);
    return true;
}
bool Layer::setPosition(float x, float y) {
    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
        return false;
    mCurrentState.sequence++;
    mCurrentState.transform.set(x, y);
    setTransactionFlags(eTransactionNeeded);
    return true;
}

1.2 Transfrom.transform() 函數

這裏寫圖片描述

203Rect Transform::transform(const Rect& bounds) const
204{
205    Rect r;
206    vec2 lt( bounds.left,  bounds.top    );//四個頂點的座標
          ...
211    lt = transform(lt);//每個頂點根據mat33的值重新計算(平移,縮放)
          ...
216    r.left   = floorf(min(lt[0], rt[0], lb[0], rb[0]) + 0.5f);//left的值是最小的x值
          ...
221    return r;
222}
//根據mat33重新計算頂點座標
176vec2 Transform::transform(const vec2& v) const {
177    vec2 r;
178    const mat33& M(mMatrix);
179    r[0] = M[0][0]*v[0] + M[1][0]*v[1] + M[2][0];//x=scaleX*x+skewY*y+translateX
180    r[1] = M[0][1]*v[0] + M[1][1]*v[1] + M[2][1];//y=scaleY*Y+skewX*x+translateY
181    return r;
182}

SurfaceFlinger層對visibelRegion的計算過程

Layer的visibleRegion值和 position, transform.mMatrix, size, transparentRegion 有關。
Layer的position, transform.mMatrix, size,都是由SurfaceControl.java設置的。

SurfaceFlinger::handleMessageRefresh()
->SurfaceFlinger::rebuildLayerStacks()
–>SurfaceFlinger::computeVisibleRegions
—> Layer::setVisibleRegion

void SurfaceFlinger::computeVisibleRegions(size_t dpy,
        const LayerVector& currentLayers, uint32_t layerStack,
        Region& outDirtyRegion, Region& outOpaqueRegion)
{
    ...
    while (i--) {
        const sp<Layer>& layer = currentLayers[i];

        // start with the whole surface at its current location
        const Layer::State& s(layer->getDrawingState());   //得到mDrawingState
        ...
        // handle hidden surfaces by setting the visible region to empty
        if (CC_LIKELY(layer->isVisible())) {
            Rect bounds(s.transform.transform(layer->computeBounds()));      //計算visibleRegion
            visibleRegion.set(bounds);
            ...
            }

        // Store the visible region in screen space
        layer->setVisibleRegion(visibleRegion);     //設置到visibleRegion
    }
    ...
}
  1. layer->computeBounds()
Rect Layer::computeBounds() const {
    const Layer::State& s(getDrawingState());
    return computeBounds(s.activeTransparentRegion);
}

Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
    const Layer::State& s(getDrawingState());
    //這個w,h值是size值,由setSize()賦值
    Rect win(s.active.w, s.active.h);
    if (!s.active.crop.isEmpty()) {
        //和crop值相交,setCrop()
        win.intersect(s.active.crop, &win);
    }
    // subtract the transparent region and snap to the bounds
    //去掉TransparentRegion透明區域的值
    return reduce(win, activeTransparentRegion);
}
  1. s.transform.transform()
    根據mDrawingState.transform 進行 transfrom操作

Framewrok層


Android窗口管理系統類圖(部分)

這裏寫圖片描述

幾個概念
Window和Surface一一對應 (SurfaceView是個window)
(Window指的是WMS管理的WindowState們)
Surface和Layer一一對應

WindowState介紹
顧名思義表示window的狀態,主要指寬高,位置,動畫等信息

TODO 圖 mContentFramee mVisibelFrame

WindowManager.LayoutParams
java.lang.Object
↳ android.view.ViewGroup.LayoutParams
↳ android.view.WindowManager.LayoutParams
http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html
LayoutParams are used by views to tell their parents how they want to be laid out. See ViewGroup Layout Attributes for a list of all child view attributes that this class supports.
The base LayoutParams class just describes how big the view wants to be for both width and height. For each dimension, it can specify one of:
FILL_PARENT (renamed MATCH_PARENT in API Level 8 and higher), which means that the view wants to be as big as its parent (minus padding)
WRAP_CONTENT, which means that the view wants to be just big enough to enclose its content (plus padding)
an exact number
There are subclasses of LayoutParams for different subclasses of ViewGroup. For example, AbsoluteLayout has its own subclass of LayoutParams which adds an X and Y value.
以上是谷歌的解釋
WindowManager.LayoutParams 是 WindowManager 接口的嵌套類;它繼承於 ViewGroup.LayoutParams; 設置Windows 的Layout屬性

WindowManager.LayoutParams

1368         * Positive insets between the drawing surface and window content.
1372        public final Rect surfaceInsets = new Rect();

APP可以調用setLayouParams 進行設置

這裏寫圖片描述
紫色的是主要進行計算的地方

ViewRootImpl那邊就不看了,直接從SystemServer這邊開始

http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java#3087

3087    public int relayoutWindow(Session session, IWindow client, int seq,
3088            WindowManager.LayoutParams attrs, int requestedWidth,
3089            int requestedHeight, int viewVisibility, int flags,
3090            Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
3091            Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Configuration outConfig,
3092            Surface outSurface) {
            ...
3104        synchronized(mWindowMap) {
3105            WindowState win = windowForClientLocked(session, client, false);
                ...
3164            final boolean scaledWindow =
3165                ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
3166
3167            if (scaledWindow) {
3168                // requested{Width|Height} Surface's physical size
3169                // attrs.{width|height} Size on screen
                    //需要縮放時,真正的顯示在屏幕的size是attrs.{width|height}會在後面解釋
3170                win.mHScale = (attrs.width  != requestedWidth)  ?
3171                        (attrs.width  / (float)requestedWidth) : 1.0f;
3172                win.mVScale = (attrs.height != requestedHeight) ?
3173                        (attrs.height / (float)requestedHeight) : 1.0f;
3174            } else {
3175                win.mHScale = win.mVScale = 1;
3176            }
                ...
3201            if (viewVisibility == View.VISIBLE &&
3202                    (win.mAppToken == null || !win.mAppToken.clientHidden)) {
                    ...
3245                try {
3246                    if (!win.mHasSurface) {
3247                        surfaceChanged = true;
3248                    }
3249                    SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
3250                    if (surfaceControl != null) {
3251                        outSurface.copyFrom(surfaceControl);
3254                    } 
                    ...
3259                }
                  ...
3289            } else {
                  ...
3335            }
                //計算WindowState的其他變量,下面這些傳出去的變量都在這裏計算
3368            performLayoutAndPlaceSurfacesLocked();
                ...
3377            outFrame.set(win.mCompatFrame);
3378            outOverscanInsets.set(win.mOverscanInsets);
3379            outContentInsets.set(win.mContentInsets);
3380            outVisibleInsets.set(win.mVisibleInsets);
3381            outStableInsets.set(win.mStableInsets);
3382            outOutsets.set(win.mOutsets);
                ...
3401        }
            ...
3409        return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
3410                | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
3411                | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0);
3412    }

performLayoutAndPlaceSurfacesLocked:
主要功能:刷新系統的UI,順便計算一下window大小。

Activity窗口在其屬性發生了變化,例如,可見性、大小發生了變化,又或者它新增、刪除了子視圖,都需要重新計算大小,而這些變化都是要求WindowManagerService服務重新刷新系統的UI的。事實上,刷新系統的UI是WindowManagerService服務的主要任務,在新增和刪除了窗口、窗口動畫顯示過程、窗口切換過程中,WindowManagerService服務都需要不斷地刷新系統的UI。

WindowManagerService類的成員函數performLayoutAndPlaceSurfacesLocked主要是通過調用另外一個成員函數performLayoutAndPlaceSurfacesLockedInner來刷新系統的UI的,而在刷新的過程中,就會對系統中的各個窗口的大小進行計算。

8926    private final void performLayoutAndPlaceSurfacesLocked() {
8927        int loopCount = 6;
8928        do {
8929            mTraversalScheduled = false;
8930            performLayoutAndPlaceSurfacesLockedLoop();
8931            mH.removeMessages(H.DO_TRAVERSAL);
8932            loopCount--;
8933        } while (mTraversalScheduled && loopCount > 0);
8934        mInnerFields.mWallpaperActionPending = false;
8935    }
        //標誌是否在刷新UI,防止performLayoutAndPlaceSurfacesLockedInner被多次調用
8937    private boolean mInLayout = false;
8938    private final void performLayoutAndPlaceSurfacesLockedLoop() {
8939        if (mInLayout) {
8940            if (DEBUG) {
8941                throw new RuntimeException("Recursive call!");
8942            }
8943            Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
8944                    + Debug.getCallers(3));
8945            return;
8946        }

8961        mInLayout = true;
8962
8963        boolean recoveringMemory = false;
8964        if (!mForceRemoves.isEmpty()) {//Memory不足時,把可強制移除的windows移除以便回收內存
8965            recoveringMemory = true;
8966            // Wait a little bit for things to settle down, and off we go.
8967            while (!mForceRemoves.isEmpty()) {
8968                WindowState ws = mForceRemoves.remove(0);
8969                Slog.i(TAG, "Force removing: " + ws);
8970                removeWindowInnerLocked(ws);
8971            }
8972            Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
8973            Object tmp = new Object();
8974            synchronized (tmp) {
8975                try {
8976                    tmp.wait(250);
8977                } catch (InterruptedException e) {
8978                }
8979            }
8980        }
8981
8982        try {
                //調用performLayoutAndPlaceSurfacesLockedInner
8983            performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
8984
8985            mInLayout = false;
8986
8987            if (needsLayout()) {
8988                if (++mLayoutRepeatCount < 6) {
8989                    requestTraversalLocked();
8990                } else {
8991                    Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
8992                    mLayoutRepeatCount = 0;
8993                }
8994            } else {
8995                mLayoutRepeatCount = 0;
8996            }
8997
8998            if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
8999                mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
9000                mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE);
9001            }
9002        } catch (RuntimeException e) {
9003            mInLayout = false;
9004            Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
9005        }
9006
9007        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
9008    }

performLayoutAndPlaceSurfacesLockedInner

是WindowManagerService的核心函數。(所以它非常……長,大概600行,不僅僅是計算windows大小,實際上是完成了一次UI的刷新)

主要步驟:
1. 調用performLayoutLockedInner 計算各個windows大小。
2. 執行windows Animation。
3. step1,2 是打包成一個Transaction的,通過closeTransaction函數
去設置Layer的屬性。

 經過step1,2,3的操作之後,一次系統UI的刷新過程就完成了
  1. 銷燬系統中的不會再顯示的windows的drawing surface;
    移除已經完成Exiting的window token;
    移除已經退出了的Activity 的AppWindowToken.
9875    private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
            ...
9923        SurfaceControl.openTransaction();
            ...
9941            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
                ...
9944                WindowList windows = displayContent.getWindowList();
                    ...
9958                int repeats = 0;
9959                do {
9960                    repeats++;
                        ...
9991                    // FIRST LOOP: Perform a layout, if needed.
9992                    if (repeats < 4) {
9993                        performLayoutLockedInner(displayContent, repeats == 1,
9994                                false /*updateInputWindows*/); //計算各個windows的大小
9995                    } else {
9996                        Slog.w(TAG, "Layout repeat skipped after too many iterations");
9997                    }

9999                    // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
10000                    // it is animating.
                         . . .

10015                } while (displayContent.pendingLayoutChanges != 0);
                     ...
10024                final int N = windows.size();
10025                for (i=N-1; i>=0; i--) {
10026                    WindowState w = windows.get(i);
                     ...
10086                    // Moved from updateWindowsAndWallpaperLocked().
10087                    if (w.mHasSurface) {
                         ...
10119                        winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
10120                    }

10199        } finally {
10200            SurfaceControl.closeTransaction();
             }

10287        // Destroy the surface of any windows that are no longer visible.
             ...
10306        // Time to remove any exiting tokens?
             ...
10321        // Time to remove any exiting applications?
             ...
10355        // Finally update all input windows now that the window changes have stabilized.
             ...
10440        scheduleAnimationLocked(); //通知WindowAnimator執行動畫

performLayoutLockedInner的執行過程,主要是分三個階段:

    1. 準備階段:調用PhoneWindowManager類的成員函數beginLayoutLw來設置屏幕的大小。屏幕的大小可以通過調用WindowManagerService類的成員變量mDisplay所描述的一個Display對象的成員函數getWidth和getHeight來獲得。

    2. 計算階段:調用PhoneWindowManager類的成員函數layoutWindowLw來計算各個窗口的大小、內容區域邊襯大小以及可見區域邊襯大小。

    3. 結束階段:調用PhoneWindowManager類的成員函數finishLayoutLw來執行一些清理工作。
9048    private final void performLayoutLockedInner(final DisplayContent displayContent,
9049                                    boolean initial, boolean updateInputWindows) {

9054        WindowList windows = displayContent.getWindowList();

9074        mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);

9090        // First perform layout of any root windows (not attached
9091        // to another window).
9092        int topAttached = -1;
9093        for (i = N-1; i >= 0; i--) {
9094            final WindowState win = windows.get(i);
9096            // Don't do layout of a window if it is not visible, or
9097            // soon won't be visible, to avoid wasting time and funky
9098            // changes while a window is animating away.
9099            final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
9100                    || win.isGoneForLayoutLw();

9122            // If this view is GONE, then skip it -- keep the current
9123            // frame, and let the caller know so they can ignore it
9124            // if they want.  (We do the normal layout for INVISIBLE
9125            // windows, since that means "perform layout as normal,
9126            // just don't display").
9127            if (!gone || !win.mHaveFrame || win.mLayoutNeeded
9128                    || ((win.isConfigChanged() || win.setInsetsChanged()) &&
9129                            ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
9130                            (win.mHasSurface && win.mAppToken != null &&
9131                            win.mAppToken.layoutConfigChanges)))) {
9132                if (!win.mLayoutAttached) { //通過mLayoutAttached這個flag判斷是否是父window

9145                    mPolicy.layoutWindowLw(win, null);//計算父window,真正計算工作在這個函數執行
                    }
                 }
            }

9159        // Now perform layout of attached windows, which usually
9160        // depend on the position of the window they are attached to.
9161        // XXX does not deal with windows that are attached to windows
9162        // that are themselves attached.
9163        for (i = topAttached; i >= 0; i--) {
9164            final WindowState win = windows.get(i);

9171                // If this view is GONE, then skip it -- keep the current
9172                // frame, and let the caller know so they can ignore it
9173                // if they want.  (We do the normal layout for INVISIBLE
9174                // windows, since that means "perform layout as normal,
9175                // just don't display").
9176                if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
9177                    continue;
9178                }
9179                if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
9180                        || !win.mHaveFrame || win.mLayoutNeeded) {

9187                    mPolicy.layoutWindowLw(win, win.mAttachedWindow);//計算子窗口,會把父窗口的WindowState也傳進去
            ...
9208        mPolicy.finishLayoutLw(); //這個函數直接return,啥都沒做
9209    }
  • PhoneWindowManager
    layoutWindowLw
    主要功能:根據LayoutParams 計算
    ParentFrame,DisplayFrame,OverscanFrame,ContentFrame,VisibleFrame,DecorFrame,StableFrame
    把這些作爲參數傳到computeFrameLw中

  • WindowState
    computeFrameLw
    主要功能:計算WindowState.mFrame以及WindowState其他參數
    (eg. mContentFrame, mContentInsets …)

534    public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf,
535            Rect osf) {

559        final int pw = mContainingFrame.width(); //父窗口的寬高
560        final int ph = mContainingFrame.height();
561
562        int w,h; //初步計算窗口寬高
563        if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) {
564            if (mAttrs.width < 0) {
565                w = pw;
566            } else if (mEnforceSizeCompat) {
567                w = (int)(mAttrs.width * mGlobalScale + .5f);
568            } else {
569                w = mAttrs.width;
570            }
571            if (mAttrs.height < 0)
               ...
578        } else {
               ...
593        }

607        mOverscanFrame.set(of); //給WindowState的其他屬性賦值
608        mContentFrame.set(cf);
609        mVisibleFrame.set(vf);
610        mDecorFrame.set(dcf);
611        mStableFrame.set(sf);

620        float x, y; //左上角
621        if (mEnforceSizeCompat) {
622            x = mAttrs.x * mGlobalScale;
623            y = mAttrs.y * mGlobalScale;
624        } else {
625            x = mAttrs.x;
626            y = mAttrs.y;
627        }

           //計算mFrame (根據父窗口區域mContainingFrame和gravity[gravity簡單的說是參考佈局(左對齊,居中...)])
636        Gravity.apply(mAttrs.gravity, w, h, mContainingFrame,
637                (int) (x + mAttrs.horizontalMargin * pw),
638                (int) (y + mAttrs.verticalMargin * ph), mFrame);
639
640        // Now make sure the window fits in the overall display frame.
           // 計算mFrame (根據顯示屏區域mDisplayFrame和gravity)
641        Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame);

653        // Make sure the content and visible frames are inside of the
654        // final window frame. mContentFrame必須包含在mFrame中
655        mContentFrame.set(Math.max(mContentFrame.left, mFrame.left),
656                Math.max(mContentFrame.top, mFrame.top),
657                Math.min(mContentFrame.right, mFrame.right),
658                Math.min(mContentFrame.bottom, mFrame.bottom));
           . . .
           //mContentInsets = mFrame - mContentFrame
675        mContentInsets.set(mContentFrame.left - mFrame.left,
676                mContentFrame.top - mFrame.top,
677                mFrame.right - mContentFrame.right,
678                mFrame.bottom – mContentFrame.bottom);
           ...
690        mCompatFrame.set(mFrame);
  • WindowStateAnimator
    • 官方說明:
      Keep track of animations and surface operations for a single WindowState.

這裏寫圖片描述

  • computeShownFrameLocked()
    1.根據Animation的Transformation,通過矩陣運算得出變換矩陣 這裏寫圖片描述 ;
    2.計算Rectf WindowState::mShownFrame(x,y=平移向量的值; w,h值=WindowState.mFrame width,height值) 和mShownAlpha。
1036    void computeShownFrameLocked() {
                ...
1076        if (selfTransformation || attachedTransformation != null
1077                || appTransformation != null || screenAnimation) {
1078            // cache often used attributes locally
1079            final Rect frame = mWin.mFrame; 
1080            final float tmpFloats[] = mService.mTmpFloats;
1081            final Matrix tmpMatrix = mWin.mTmpMatrix;
1082
1083            // Compute the desired transformation. 根據Animation的transformation計算變換矩陣的值
1084            if (screenAnimation && screenRotationAnimation.isRotating()) { //顯示屏是否有旋轉動畫
                        ...
1099            } else {
1100                tmpMatrix.reset();
1101            }
1102            tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
1103            if (selfTransformation) { //當前窗口是否有動畫
1104                tmpMatrix.postConcat(mTransformation.getMatrix());
1105            }
1106            tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
1107            if (attachedTransformation != null) { //父窗口是否有動畫
1108                tmpMatrix.postConcat(attachedTransformation.getMatrix());
1109            }
1110            if (appTransformation != null) { //Activity切換動畫
1111                tmpMatrix.postConcat(appTransformation.getMatrix());
1112            }
1113            if (screenAnimation) { //顯示屏是否有動畫
1114                tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
1115            }
1116
                     ...
1133            mHaveMatrix = true;
1134            tmpMatrix.getValues(tmpFloats);
1135            mDsDx = tmpFloats[Matrix.MSCALE_X]; //變換矩陣的賦值
1136            mDtDx = tmpFloats[Matrix.MSKEW_Y];
1137            mDsDy = tmpFloats[Matrix.MSKEW_X];
1138            mDtDy = tmpFloats[Matrix.MSCALE_Y];
1139            float x = tmpFloats[Matrix.MTRANS_X]; //mShowFrame的左上角
1140            float y = tmpFloats[Matrix.MTRANS_Y];
1141            int w = frame.width();
1142            int h = frame.height();
1143            mWin.mShownFrame.set(x, y, x+w, y+h);
                    ...
1150            mShownAlpha = mAlpha; //這個alpha變化效果因爲硬件不支持被關閉了,這個值現在是木有效果的
  • setSurfaceBoundariesLocked()
    根據WindowState::mShownFrame, mAttrs.sufaceinsets,設置position, size,matrix, crop
1356    void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
1357        final WindowState w = mWin;
1358
1359        int width;
1360        int height;
1361        if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
1362            // for a scaled surface, we always want the requested size.
1364            width  = w.mRequestedWidth;
1365            height = w.mRequestedHeight;
1366        } else {
1367            width = w.mCompatFrame.width();
1368            height = w.mCompatFrame.height();
1369        }
1370        ...
1380        float left = w.mShownFrame.left;
1381        float top = w.mShownFrame.top;
1382
1383        // Adjust for surface insets.
1384        final LayoutParams attrs = w.getAttrs();
1385        final int displayId = w.getDisplayId();
1386        float scale = 1.0f;
                . . .
1396        width += scale * (attrs.surfaceInsets.left + attrs.surfaceInsets.right); //後面會調用setSize(width,height)
1397        height += scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom);
1398        left -= scale * attrs.surfaceInsets.left;  //後面會調用 setPosition(l,r)
1399        top -= scale * attrs.surfaceInsets.top;

1409                mSurfaceControl.setPosition(left, top);

1428                mSurfaceControl.setSize(width, height);
1429                mSurfaceControl.setMatrix(
1430                        mDsDx * w.mHScale, mDtDx * w.mVScale,
1431                        mDsDy * w.mHScale, mDtDy * w.mVScale);

1452        updateSurfaceWindowCrop(recoveringMemory);
1453    }
  • setMatrix的值
    這裏寫圖片描述

  • setSize的值
    如果有縮放width = WindowState.mRequestWidth+scale * (attrs.surfaceInsets.left + attrs.surfaceInsets.right);
    height = WindowState.mRequestWidth+scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom);

根據上面兩項,縮放之後,寬高值是attrs.{width|height},這下wms.relayoutWindow計算的縮放因子的註釋就清楚了( requested{Width|Height} Surface’s physical size. attrs.{width|height} Size on screen)
這裏寫圖片描述

2. WindowState 和 WindowStateAnimator

這裏寫圖片描述

–>WindowState mWin是在WindowStateAnimator構造函數賦值
195 WindowStateAnimator(final WindowState win) {

212 mWin = win;

—>WindowStateAnimator 是在 WindowState 構造函數裏面創建
frameworks/base/services/core/java/com/android/server/wm/WindowState.java#501
mWinAnimator = new WindowStateAnimator(this); //把 WindowState 本身傳進去


WindowState
mRequestedWidth,mRequestedHeight :APP申請的寬高

frameworks/base/core/java/android/view/ViewRootImpl.java
WindowManager.LayoutParams attrs的值是由ViewRootImpl.java這邊傳下去的
(CALL performTraversals() relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); //params 是WindowManager.LayoutParams, 由mWindowAttributes賦值給它 )

mWindowAttributes的值在這兩處獲得(mWindowAttributes.copyFrom(attrs);)
frameworks/base/core/java/android/view/ViewRootImpl.java#461 setView()

frameworks/base/core/java/android/view/ViewRootImpl.java#797 setLayoutParams()

Cmd:

adb shell dumpsys window

frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
static final boolean DEBUG_SURFACE_TRACE = false; -> true

[frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java]
dumpAllSurfaces() 會執行

adb shell dumpsys window surfaces
Surface #3: #544e0ff SurfaceView
mLayerStack=0 mLayer=21025
mShown=true mAlpha=1.0 mIsOpaque=false
mPosition=0.0,0.0 mSize=1920x1080
mCrop=[0,0][1920,1080]
Transform: (0.5625, 0.0, 0.0, 1.7777778)

參考(圖片來源):
Android窗口管理服務WindowManagerService計算Activity窗口大小的過程分析

WindowManagerService動畫分析

Android變形(Transform) 之 Matrix

矩陣的座標變換

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章