Android GUI更新过程

来源:互联网 发布:天高云淡秒赞源码 编辑:程序博客网 时间:2024/05/11 17:03

转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog 
作者联系方式:李先静 <xianjimli@gmail.com>

 

Android GUI更新过程

相关组件
android_gui 
1.ViewRoot
在private void draw(boolean fullRedrawNeeded)中,会调用lockCanvas,从而获取一个Canvas对象,然后调用递归调用子窗口(View)的draw函数 去绘制自己,最后调用unlockCanvasAndPost让Surface把自己更新到屏幕上。

[c] view plaincopy
  1. canvas <span style="color: #339933;">=</span>  
  2.  surface.<span style="color: #202020;">lockCanvas</span>  
  3. <span style="color: #009900;">(</span>  
  4. dirty<span style="color: #009900;">)</span>  
  5. <span style="color: #339933;">;</span>  
  6.   
  7. mView.<span style="color: #202020;">draw</span>  
  8. <span style="color: #009900;">(</span>  
  9. canvas<span style="color: #009900;">)</span>  
  10. <span style="color: #339933;">;</span>  
  11.   
  12. surface.<span style="color: #202020;">unlockCanvasAndPost</span>  
  13. <span style="color: #009900;">(</span>  
  14. canvas<span style="color: #009900;">)</span>  
  15. <span style="color: #339933;">;</span>  

2.android/view/Surface
它主要对一些native函数的包装。

[c] view plaincopy
  1.     private native Canvas lockCanvasNative<span style="color: #009900;">(</span>  
  2. Rect dirty<span style="color: #009900;">)</span>  
  3. <span style="color: #339933;">;</span>  
  4.   
  5.     public native   <span style="color: #993333;">void</span>  
  6.  unlockCanvasAndPost<span style="color: #009900;">(</span>  
  7. Canvas canvas<span style="color: #009900;">)</span>  
  8. <span style="color: #339933;">;</span>  

3.android_view_Surface.cpp
这是native函数的实现。
Surface_lockCanvas它先锁住Surface,从而获取Surface相关的信息,如果格式、宽度、高度和像素缓冲区。然后创建一个bitmap,这个bitmap和共享一个像素缓冲区,这样View就能直接把自己绘制到Surface上了。

[c] view plaincopy
  1. status_t err <span style="color: #339933;">=</span>  
  2.  surface<span style="color: #339933;">-></span>  
  3. lock<span style="color: #009900;">(</span>  
  4. <span style="color: #339933;">&</span>  
  5. info<span style="color: #339933;">,</span>  
  6.  <span style="color: #339933;">&</span>  
  7. dirtyRegion<span style="color: #009900;">)</span>  
  8. <span style="color: #339933;">;</span>  
  9.   
  10. bitmap.<span style="color: #202020;">setPixels</span>  
  11. <span style="color: #009900;">(</span>  
  12. info.<span style="color: #202020;">bits</span>  
  13. <span style="color: #009900;">)</span>  
  14. <span style="color: #339933;">;</span>  
  15.   
  16. nativeCanvas<span style="color: #339933;">-></span>  
  17. setBitmapDevice<span style="color: #009900;">(</span>  
  18. bitmap<span style="color: #009900;">)</span>  
  19. <span style="color: #339933;">;</span>  

Surface_unlockCanvasAndPost它断开SkCanvas与Surface之间的关系,然后调用Surface的unlockAndPost。

[c] view plaincopy
  1. nativeCanvas<span style="color: #339933;">-></span>  
  2. setBitmapDevice<span style="color: #009900;">(</span>  
  3. SkBitmap<span style="color: #009900;">(</span>  
  4. <span style="color: #009900;">)</span>  
  5. <span style="color: #009900;">)</span>  
  6. <span style="color: #339933;">;</span>  
  7.   
  8. status_t err <span style="color: #339933;">=</span>  
  9.  surface<span style="color: #339933;">-></span>  
  10. unlockAndPost<span style="color: #009900;">(</span>  
  11. <span style="color: #009900;">)</span>  
  12. <span style="color: #339933;">;</span>  

4.surfaceflinger_client/Surface.cpp
Surface::lock调用dequeueBuffer获取一个可用的Buffer,dequeueBuffer会调用SharedBufferClient::dequeue等到backbuffer可用,然后锁住这个Buffer并填充相关信息。

[c] view plaincopy
  1. status_t err <span style="color: #339933;">=</span>  
  2.  dequeueBuffer<span style="color: #009900;">(</span>  
  3. <span style="color: #339933;">&</span>  
  4. backBuffer<span style="color: #009900;">)</span>  
  5. <span style="color: #339933;">;</span>  
  6.   
  7. err <span style="color: #339933;">=</span>  
  8.  lockBuffer<span style="color: #009900;">(</span>  
  9. backBuffer.<span style="color: #202020;">get</span>  
  10. <span style="color: #009900;">(</span>  
  11. <span style="color: #009900;">)</span>  
  12. <span style="color: #009900;">)</span>  
  13. <span style="color: #339933;">;</span>  

Surface::unlockAndPost先unlock Buffer,然后调queueBuffer显示Buffer。

[c] view plaincopy
  1. status_t err <span style="color: #339933;">=</span>  
  2.  mLockedBuffer<span style="color: #339933;">-></span>  
  3. unlock<span style="color: #009900;">(</span>  
  4. <span style="color: #009900;">)</span>  
  5. <span style="color: #339933;">;</span>  
  6.   
  7. err <span style="color: #339933;">=</span>  
  8.  queueBuffer<span style="color: #009900;">(</span>  
  9. mLockedBuffer.<span style="color: #202020;">get</span>  
  10. <span style="color: #009900;">(</span>  
  11. <span style="color: #009900;">)</span>  
  12. <span style="color: #009900;">)</span>  
  13. <span style="color: #339933;">;</span>  

Surface::queueBuffer是比较有意思的,它设置更新的区域,然后通知服务端(SurfaceFlinger)。

[c] view plaincopy
  1. mSharedBufferClient<span style="color: #339933;">-></span>  
  2. setDirtyRegion<span style="color: #009900;">(</span>  
  3. bufIdx<span style="color: #339933;">,</span>  
  4.  mDirtyRegion<span style="color: #009900;">)</span>  
  5. <span style="color: #339933;">;</span>  
  6.   
  7. err <span style="color: #339933;">=</span>  
  8.  mSharedBufferClient<span style="color: #339933;">-></span>  
  9. queue<span style="color: #009900;">(</span>  
  10. bufIdx<span style="color: #009900;">)</span>  
  11. <span style="color: #339933;">;</span>  
  12.   
  13. client<span style="color: #339933;">-></span>  
  14. signalServer<span style="color: #009900;">(</span>  
  15. <span style="color: #009900;">)</span>  
  16. <span style="color: #339933;">;</span>  

通过binder发送请求给服务:

[c] view plaincopy
  1.     virtual <span style="color: #993333;">void</span>  
  2.  signal<span style="color: #009900;">(</span>  
  3. <span style="color: #009900;">)</span>  
  4.  <span style="color: #993333;">const</span>  
  5.   
  6.     <span style="color: #009900;">{</span>  
  7.   
  8.        Parcel data<span style="color: #339933;">,</span>  
  9.  reply<span style="color: #339933;">;</span>  
  10.   
  11.        data.<span style="color: #202020;">writeInterfaceToken</span>  
  12. <span style="color: #009900;">(</span>  
  13. ISurfaceComposer<span style="color: #339933;">::</span>  
  14. <span style="color: #202020;">getInterfaceDescriptor</span>  
  15. <span style="color: #009900;">(</span>  
  16. <span style="color: #009900;">)</span>  
  17. <span style="color: #009900;">)</span>  
  18. <span style="color: #339933;">;</span>  
  19.   
  20.        remote<span style="color: #009900;">(</span>  
  21. <span style="color: #009900;">)</span>  
  22. <span style="color: #339933;">-></span>  
  23. transact<span style="color: #009900;">(</span>  
  24. BnSurfaceComposer<span style="color: #339933;">::</span>  
  25. <span style="color: #202020;">SIGNAL</span>  
  26. <span style="color: #339933;">,</span>  
  27.  data<span style="color: #339933;">,</span>  
  28.  <span style="color: #339933;">&</span>  
  29. reply<span style="color: #339933;">,</span>  
  30.  IBinder<span style="color: #339933;">::</span>  
  31. <span style="color: #202020;">FLAG_ONEWAY</span>  
  32. <span style="color: #009900;">)</span>  
  33. <span style="color: #339933;">;</span>  
  34.   
  35.     <span style="color: #009900;">}</span>  

5.SurfaceFlinger

[c] view plaincopy
  1. BnSurfaceComposer<span style="color: #339933;">::</span>  
  2. <span style="color: #202020;">onTransact</span>  
  3.   
  4.        <span style="color: #b1b100;">case</span>  
  5.  SIGNAL<span style="color: #339933;">:</span>  
  6.  <span style="color: #009900;">{</span>  
  7.   
  8.            CHECK_INTERFACE<span style="color: #009900;">(</span>  
  9. ISurfaceComposer<span style="color: #339933;">,</span>  
  10.  data<span style="color: #339933;">,</span>  
  11.  reply<span style="color: #009900;">)</span>  
  12. <span style="color: #339933;">;</span>  
  13.   
  14.            signal<span style="color: #009900;">(</span>  
  15. <span style="color: #009900;">)</span>  
  16. <span style="color: #339933;">;</span>  
  17.   
  18.        <span style="color: #009900;">}</span>  
  19.  <span style="color: #000000; font-weight: bold;">break</span>  
  20. <span style="color: #339933;">;</span>  

这是SurfaceFlinger中处理SIGNAL的代码,它调用SurfaceFlinger::signal,再调用 SurfaceFlinger::signalEvent,最后调用MessageQueue::invalidate唤醒是 SurfaceFlinger的主循环。

在主循环中waitForEvent返回,再handleRepaint去合成个Layer/Surface。

[c] view plaincopy
  1. bool SurfaceFlinger<span style="color: #339933;">::</span>  
  2. <span style="color: #202020;">threadLoop</span>  
  3. <span style="color: #009900;">(</span>  
  4. <span style="color: #009900;">)</span>  
  5.   
  6. <span style="color: #009900;">{</span>  
  7.   
  8.     waitForEvent<span style="color: #009900;">(</span>  
  9. <span style="color: #009900;">)</span>  
  10. <span style="color: #339933;">;</span>  
  11.   
  12.        handleRepaint<span style="color: #009900;">(</span>  
  13. <span style="color: #009900;">)</span>  
  14. <span style="color: #339933;">;</span>  
  15.   
  16.        postFramebuffer<span style="color: #009900;">(</span>  
  17. <span style="color: #009900;">)</span>  
  18. <span style="color: #339933;">;</span>  
  19.   
  20. <span style="color: #009900;">}</span>  

SurfaceFlinger::handleRepaint会调用composeSurfaces把需要绘制各个Surface合并起来,绘制到FrameBuffer的BackBuffer上。

[c] view plaincopy
  1.     <span style="color: #b1b100;">for</span>  
  2.  <span style="color: #009900;">(</span>  
  3. size_t i<span style="color: #339933;">=</span>  
  4. <span style="color: #0000dd;">0</span>  
  5.  <span style="color: #339933;">;</span>  
  6.  i<span style="color: #339933;"><</span>  
  7. count <span style="color: #339933;">;</span>  
  8.  <span style="color: #339933;">++</span>  
  9. i<span style="color: #009900;">)</span>  
  10.  <span style="color: #009900;">{</span>  
  11.   
  12.        <span style="color: #993333;">const</span>  
  13.  sp<span style="color: #339933;"><</span>  
  14. LayerBase<span style="color: #339933;">>&</span>  
  15.  layer <span style="color: #339933;">=</span>  
  16.  layers<span style="color: #009900;">[</span>  
  17. i<span style="color: #009900;">]</span>  
  18. <span style="color: #339933;">;</span>  
  19.   
  20.        <span style="color: #993333;">const</span>  
  21.  Region<span style="color: #339933;">&</span>  
  22.  visibleRegion<span style="color: #009900;">(</span>  
  23. layer<span style="color: #339933;">-></span>  
  24. visibleRegionScreen<span style="color: #009900;">)</span>  
  25. <span style="color: #339933;">;</span>  
  26.   
  27.        <span style="color: #b1b100;">if</span>  
  28.  <span style="color: #009900;">(</span>  
  29. <span style="color: #339933;">!</span>  
  30. visibleRegion.<span style="color: #202020;">isEmpty</span>  
  31. <span style="color: #009900;">(</span>  
  32. <span style="color: #009900;">)</span>  
  33. <span style="color: #009900;">)</span>  
  34.   <span style="color: #009900;">{</span>  
  35.   
  36.            <span style="color: #808080; font-style: italic;">/* broncho cy add */</span>  
  37.   
  38. <span style="color: #339933;">#ifdef USEOVERLAY</span>  
  39.   
  40.            mToppest<span style="color: #009900;">[</span>  
  41. <span style="color: #0000dd;">1</span>  
  42. <span style="color: #009900;">]</span>  
  43.  <span style="color: #339933;">=</span>  
  44.  mToppest<span style="color: #009900;">[</span>  
  45. <span style="color: #0000dd;">0</span>  
  46. <span style="color: #009900;">]</span>  
  47. <span style="color: #339933;">;</span>  
  48.   
  49.            mToppest<span style="color: #009900;">[</span>  
  50. <span style="color: #0000dd;">0</span>  
  51. <span style="color: #009900;">]</span>  
  52.  <span style="color: #339933;">=</span>  
  53.  layer<span style="color: #339933;">-></span>  
  54. getIdentity<span style="color: #009900;">(</span>  
  55. <span style="color: #009900;">)</span>  
  56. <span style="color: #339933;">;</span>  
  57.   
  58. <span style="color: #339933;">#endif</span>  
  59.   
  60.            <span style="color: #808080; font-style: italic;">/* broncho end */</span>  
  61.   
  62.            <span style="color: #993333;">const</span>  
  63.  Region clip<span style="color: #009900;">(</span>  
  64. dirty.<span style="color: #202020;">intersect</span>  
  65. <span style="color: #009900;">(</span>  
  66. visibleRegion<span style="color: #009900;">)</span>  
  67. <span style="color: #009900;">)</span>  
  68. <span style="color: #339933;">;</span>  
  69.   
  70.            <span style="color: #b1b100;">if</span>  
  71.  <span style="color: #009900;">(</span>  
  72. <span style="color: #339933;">!</span>  
  73. clip.<span style="color: #202020;">isEmpty</span>  
  74. <span style="color: #009900;">(</span>  
  75. <span style="color: #009900;">)</span>  
  76. <span style="color: #009900;">)</span>  
  77.  <span style="color: #009900;">{</span>  
  78.   
  79.                layer<span style="color: #339933;">-></span>  
  80. draw<span style="color: #009900;">(</span>  
  81. clip<span style="color: #009900;">)</span>  
  82. <span style="color: #339933;">;</span>  
  83.   
  84.            <span style="color: #009900;">}</span>  
  85.   
  86.        <span style="color: #009900;">}</span>  
  87.   
  88.     <span style="color: #009900;">}</span>  

SurfaceFlinger::postFramebuffer最后把FrameBuffer的BackBuffer显示到屏幕上:

[c] view plaincopy
  1. hw.<span style="color: #202020;">flip</span>  
  2. <span style="color: #009900;">(</span>  
  3. mInvalidRegion<span style="color: #009900;">)</span>  
  4. <span style="color: #339933;">;</span>  
  5.  <span style="color: #339933;">--></span>  
  6. eglSwapBuffers<span style="color: #009900;">(</span>  
  7. dpy<span style="color: #339933;">,</span>  
  8.  surface<span style="color: #009900;">)</span>  
  9. <span style="color: #339933;">;</span>  

FrameBuffer具体的显示过程,下次再写吧。

0 0