详解Android Surface系统

  1. public void scheduleTraversals() {

  2. if (!mTraversalScheduled) {

  3. mTraversalScheduled = true;

  4. sendEmptyMessage(DO_TRAVERSAL);

  5. }

  6. }

我们看看跨进程的那个调用。sWindowSession.add。它的最终实现在WindowManagerService中。

[—>WindowSession::add()]

  1. public int add(IWindow window, WindowManager.LayoutParams attrs,

  2. int viewVisibility, Rect outContentInsets) {

  3. return addWindow(this, window, attrs, viewVisibility, outContentInsets);

  4. }

WindowSession是个内部类,会调用外部类的addWindow。

这个函数巨复杂无比,但是我们的核心目标是找到创建显示相关的部分。所以,最后精简的话就简单了。

[—>WindowManagerService:: addWindow]

  1. public int addWindow(Session session, IWindow client,

  2. WindowManager.LayoutParams attrs, int viewVisibility,

  3. Rect outContentInsets) {

  4. //创建一个WindowState,这个又是什么玩意儿呢?

  5. win = new WindowState(session, client, token,

  6. attachedWindow, attrs, viewVisibility);

  7. win.attach();

  8. return res;

  9. }

WindowState类中有一个和Surface相关的成员变量,叫SurfaceSession。它会在attach函数中被创建。SurfaceSession嘛,就和SurfaceFlinger有关系了。我们待会看。

好,我们知道ViewRoot创建及调用add后,我们客户端的View系统就和WindowManagerService建立了牢不可破的关系。

另外,我们知道ViewRoot是一个handler,而且刚才我们调用了requestLayout,所以接下来消息循环下一个将调用的就是ViewRoot的handleMessage。

  1. public void handleMessage(Message msg) {

  2. switch (msg.what) {

  3. case DO_TRAVERSAL:

  4. performTraversals();

performTraversals更加复杂无比,经过我仔细挑选,目标锁定为下面几个函数。当然,后面我们还会回到performTraversals,不过我们现在更感兴趣的是Surface是如何创建的。

  1. private void performTraversals() {

  2. // cache mView since it is used so much below…

  3. final View host = mView;

  4. boolean initialized = false;

  5. boolean contentInsetsChanged = false;

  6. boolean visibleInsetsChanged;

  7. try {

  8. //ViewRoot也有一个Surface成员变量,叫mSurface,这个就是代表SurfaceFlinger的客户端

  9. //ViewRoot在这个Surface上作画,最后将由SurfaceFlinger来合成显示。刚才说了mSurface还没有什么内容。

  10. relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);

[---->ViewRoot:: relayoutWindow()]

  1. private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,

  2. boolean insetsPending) throws RemoteException {

  3. //relayOut是跨进程调用,mSurface做为参数传进去了,看来离真相越来越近了呀!

  4. int relayoutResult = sWindowSession.relayout(

  5. mWindow, params,

  6. (int) (mView.mMeasuredWidth * appScale + 0.5f),

  7. (int) (mView.mMeasuredHeight * appScale + 0.5f),

  8. viewVisibility, insetsPending, mWinFrame,

  9. mPendingContentInsets, mPendingVisibleInsets,

  10. mPendingConfiguration, mSurface); mSurface做为参数传进去了。

  11. }

我们赶紧转到WindowManagerService去看看吧。

  1. public int relayoutWindow(Session session, IWindow client,

  2. WindowManager.LayoutParams attrs, int requestedWidth,

  3. int requestedHeight, int viewVisibility, boolean insetsPending,

  4. Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,

  5. Configuration outConfig, Surface outSurface){

  6. try {

  7. //看到这里,我内心一阵狂喜,有戏,太有戏了!

  8. //其中win是我们最初创建的WindowState!

  9. Surface surface = win.createSurfaceLocked();

  10. if (surface != null) {

  11. //先创建一个本地surface,然后把传入的参数outSurface copyFrom一下

  12. outSurface.copyFrom(surface);

  13. win.mReportDestroySurface = false;

  14. win.mSurfacePendingDestroy = false;

  15. } else {

  16. outSurface.release();

  17. }

  18. }

  19. }

[—>WindowState::createSurfaceLocked]

  1. Surface createSurfaceLocked() {

  2. try {

  3. mSurface = new Surface(

  4. mSession.mSurfaceSession, mSession.mPid,

  5. mAttrs.getTitle().toString(),

  6. 0, w, h, mAttrs.format, flags);

  7. }

  8. Surface.openTransaction();

这里

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值