调用流程如下: /frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java performSurfacePlacement -> performSurfacePlacementLoop -> isLayoutNeeded -> requestTraversal -> mAnimationHandler.post(runnable) -> 持wms锁 -> performSurfacePlacement() ->
如果一个window连续layout的次数超过6,打印log :WindowManager: Performed 6 layouts in a row. Skipping
/ WindowSurfacePlacer{ mPerformSurfacePlacement = () -> { synchronized (mService.mWindowMap) { performSurfacePlacement(); } }; } --->performSurfacePlacement--> { int loopCount = 6; do { mTraversalScheduled = false; performSurfacePlacementLoop(); mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement); loopCount--; } while (mTraversalScheduled && loopCount > 0); } --->performSurfacePlacementLoop--> { mService.mRoot.performSurfacePlacement(recoveringMemory);//处理relayout的核心方法 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout"); 1. if (mService.mRoot.isLayoutNeeded()) { if (++mLayoutRepeatCount < 6) { 2. requestTraversal(); } else { Slog.e(TAG, "Performed 6 layouts in a row. Skipping"); mLayoutRepeatCount = 0; } } else { mLayoutRepeatCount = 0; } Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); } 1.--->RootWindowContainer-->isLayoutNeeded{ final int numDisplays = mChildren.size(); for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { final DisplayContent displayContent = mChildren.get(displayNdx); 3. if (displayContent.isLayoutNeeded()) { return true; } } return false; } } /// 2-->requestTraversal void requestTraversal() { if (!mTraversalScheduled) { mTraversalScheduled = true; mService.mAnimationHandler.post(mPerformSurfacePlacement); } } private final Runnable mPerformSurfacePlacement; public WindowSurfacePlacer(WindowManagerService service) { mService = service; mPerformSurfacePlacement = () -> { synchronized (mService.mGlobalLock) { performSurfacePlacement();///循环操作 } }; } /// 3--->DisplayContent.isLayoutNeeded.mLayoutNeeded DisplayContent.setLayoutNeeded{ mLayoutNeeded = true; } /frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java performSurfacePlacement-->performSurfacePlacementNoTrace{ ..... 581 if (mWmService.mFocusMayChange) { 582 mWmService.mFocusMayChange = false; 583 mWmService.updateFocusedWindowLocked( 584 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/); 585 } .... .... 605 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 606 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); 607 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges"); //openTransaction和closeTransaction之间是对surface进行操作,建立和SurfaceFlinger通信, //如setSize,setLayer,setPosition等都不是及时生效的,而是要等到业务关闭之后才统一通知 //SurfaceFlinger,可以避免属性过快带来的画面不稳定 608 mWmService.openSurfaceTransaction(); 609 try { //计算窗口大小及完成窗口动画 610 applySurfaceChangesTransaction(recoveringMemory); 611 } catch (RuntimeException e) { 612 Slog.wtf(TAG, "Unhandled exception in Window Manager", e); 613 } finally { 614 mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces"); 615 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 616 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 617 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); 618 } 619 mWmService.mAnimator.executeAfterPrepareSurfacesRunnables(); .... 654 handleResizingWindows(); } RootWindowContainer.applySurfaceChangesTransaction---> private void applySurfaceChangesTransaction(boolean recoveringMemory) { .... //遍历mChildren 830 final int count = mChildren.size(); 831 for (int j = 0; j < count; ++j) { 832 final DisplayContent dc = mChildren.get(j); 833 dc.applySurfaceChangesTransaction(recoveringMemory); 834 } 835 836 // Give the display manager a chance to adjust properties like display rotation if it needs 837 // to. 838 mWmService.mDisplayManagerInternal.performTraversal(mDisplayTransaction); 839 SurfaceControl.mergeToGlobalTransaction(mDisplayTransaction); .... } /frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java 3715 // TODO: Super crazy long method that should be broken down... 3716 void applySurfaceChangesTransaction(boolean recoveringMemory) { 3721 int repeats = 0; 3722 do { 3723 repeats++; 3724 if (repeats > 6) { 3725 Slog.w(TAG, "Animation repeat aborted after too many iterations"); 3726 clearLayoutNeeded(); 3727 break; 3728 } 3730 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("On entry to LockedInner", 3731 pendingLayoutChanges); .... .... /// 3733 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) { 3734 mWallpaperController.adjustWallpaperWindows(); 3735 } 3736 3737 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) { 3738 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout"); 3739 if (updateOrientationFromAppTokens()) { 3740 setLayoutNeeded(); 3741 sendNewConfiguration(); 3742 } 3743 } 3744 3745 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) { 3746 setLayoutNeeded(); 3747 } 3749 // FIRST LOOP: Perform a layout, if needed. 3750 if (repeats < LAYOUT_REPEAT_THRESHOLD) { 3751 performLayout(repeats == 1, false /* updateInputWindows */); 3752 } else { 3753 Slog.w(TAG, "Layout repeat skipped after too many iterations"); 3754 } 3755 3756 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think it is animating. 3757 pendingLayoutChanges = 0; //pendingLayoutChanges赋值,判断是否需要下一次计算 3759 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy"); 3760 try { 3761 mDisplayPolicy.beginPostLayoutPolicyLw(); 3762 forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */); 3763 pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw(); 3764 } finally { 3765 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); 3766 } /// .... 3767 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats( 3768 "after finishPostLayoutPolicyLw", pendingLayoutChanges); 3769 mInsetsStateController.onPostLayout(); 3770 } while (pendingLayoutChanges != 0); ..... ..... Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyWindowSurfaceChanges"); try { //调用 winAnimator.computeShownFrameLocked(); 计算动画变换矩阵 包括转屏,平移等动画 forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } ...... } 基于pendingLayoutChanges 这个值是否跳出循环,关注pendingLayoutChanges的赋值 frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> { final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked; final boolean obscuredChanged = w.mObscured != mTmpApplySurfaceChangesTransactionState.obscured; final RootWindowContainer root = mWmService.mRoot; .... // Moved from updateWindowsAndWallpaperLocked(). if (w.mHasSurface) { ///commitFinishDrawingLocked中设置window转台为READY_TO_SHOW, //其方法中的方法中调用WindowState.performShowLocked更新窗口绘制状态 为HAS_DRAWN // Take care of the window being ready to display. final boolean committed = winAnimator.commitFinishDrawingLocked(); ....... } .... }