Android GUI更新过程
来源:互联网 发布:天高云淡秒赞源码 编辑:程序博客网 时间:2024/05/11 17:03
转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静 <xianjimli@gmail.com>
Android GUI更新过程
相关组件
1.ViewRoot
在private void draw(boolean fullRedrawNeeded)中,会调用lockCanvas,从而获取一个Canvas对象,然后调用递归调用子窗口(View)的draw函数 去绘制自己,最后调用unlockCanvasAndPost让Surface把自己更新到屏幕上。
- canvas <span style="color: #339933;">=</span>
- surface.<span style="color: #202020;">lockCanvas</span>
- <span style="color: #009900;">(</span>
- dirty<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- mView.<span style="color: #202020;">draw</span>
- <span style="color: #009900;">(</span>
- canvas<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- surface.<span style="color: #202020;">unlockCanvasAndPost</span>
- <span style="color: #009900;">(</span>
- canvas<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
2.android/view/Surface
它主要对一些native函数的包装。
- private native Canvas lockCanvasNative<span style="color: #009900;">(</span>
- Rect dirty<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- public native <span style="color: #993333;">void</span>
- unlockCanvasAndPost<span style="color: #009900;">(</span>
- Canvas canvas<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
3.android_view_Surface.cpp
这是native函数的实现。
Surface_lockCanvas它先锁住Surface,从而获取Surface相关的信息,如果格式、宽度、高度和像素缓冲区。然后创建一个bitmap,这个bitmap和共享一个像素缓冲区,这样View就能直接把自己绘制到Surface上了。
- status_t err <span style="color: #339933;">=</span>
- surface<span style="color: #339933;">-></span>
- lock<span style="color: #009900;">(</span>
- <span style="color: #339933;">&</span>
- info<span style="color: #339933;">,</span>
- <span style="color: #339933;">&</span>
- dirtyRegion<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- bitmap.<span style="color: #202020;">setPixels</span>
- <span style="color: #009900;">(</span>
- info.<span style="color: #202020;">bits</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- nativeCanvas<span style="color: #339933;">-></span>
- setBitmapDevice<span style="color: #009900;">(</span>
- bitmap<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
Surface_unlockCanvasAndPost它断开SkCanvas与Surface之间的关系,然后调用Surface的unlockAndPost。
- nativeCanvas<span style="color: #339933;">-></span>
- setBitmapDevice<span style="color: #009900;">(</span>
- SkBitmap<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- status_t err <span style="color: #339933;">=</span>
- surface<span style="color: #339933;">-></span>
- unlockAndPost<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
4.surfaceflinger_client/Surface.cpp
Surface::lock调用dequeueBuffer获取一个可用的Buffer,dequeueBuffer会调用SharedBufferClient::dequeue等到backbuffer可用,然后锁住这个Buffer并填充相关信息。
- status_t err <span style="color: #339933;">=</span>
- dequeueBuffer<span style="color: #009900;">(</span>
- <span style="color: #339933;">&</span>
- backBuffer<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- err <span style="color: #339933;">=</span>
- lockBuffer<span style="color: #009900;">(</span>
- backBuffer.<span style="color: #202020;">get</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
Surface::unlockAndPost先unlock Buffer,然后调queueBuffer显示Buffer。
- status_t err <span style="color: #339933;">=</span>
- mLockedBuffer<span style="color: #339933;">-></span>
- unlock<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- err <span style="color: #339933;">=</span>
- queueBuffer<span style="color: #009900;">(</span>
- mLockedBuffer.<span style="color: #202020;">get</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
Surface::queueBuffer是比较有意思的,它设置更新的区域,然后通知服务端(SurfaceFlinger)。
- mSharedBufferClient<span style="color: #339933;">-></span>
- setDirtyRegion<span style="color: #009900;">(</span>
- bufIdx<span style="color: #339933;">,</span>
- mDirtyRegion<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- err <span style="color: #339933;">=</span>
- mSharedBufferClient<span style="color: #339933;">-></span>
- queue<span style="color: #009900;">(</span>
- bufIdx<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- client<span style="color: #339933;">-></span>
- signalServer<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
通过binder发送请求给服务:
- virtual <span style="color: #993333;">void</span>
- signal<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #993333;">const</span>
- <span style="color: #009900;">{</span>
- Parcel data<span style="color: #339933;">,</span>
- reply<span style="color: #339933;">;</span>
- data.<span style="color: #202020;">writeInterfaceToken</span>
- <span style="color: #009900;">(</span>
- ISurfaceComposer<span style="color: #339933;">::</span>
- <span style="color: #202020;">getInterfaceDescriptor</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- remote<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">-></span>
- transact<span style="color: #009900;">(</span>
- BnSurfaceComposer<span style="color: #339933;">::</span>
- <span style="color: #202020;">SIGNAL</span>
- <span style="color: #339933;">,</span>
- data<span style="color: #339933;">,</span>
- <span style="color: #339933;">&</span>
- reply<span style="color: #339933;">,</span>
- IBinder<span style="color: #339933;">::</span>
- <span style="color: #202020;">FLAG_ONEWAY</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <span style="color: #009900;">}</span>
5.SurfaceFlinger
- BnSurfaceComposer<span style="color: #339933;">::</span>
- <span style="color: #202020;">onTransact</span>
- <span style="color: #b1b100;">case</span>
- SIGNAL<span style="color: #339933;">:</span>
- <span style="color: #009900;">{</span>
- CHECK_INTERFACE<span style="color: #009900;">(</span>
- ISurfaceComposer<span style="color: #339933;">,</span>
- data<span style="color: #339933;">,</span>
- reply<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- signal<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <span style="color: #009900;">}</span>
- <span style="color: #000000; font-weight: bold;">break</span>
- <span style="color: #339933;">;</span>
这是SurfaceFlinger中处理SIGNAL的代码,它调用SurfaceFlinger::signal,再调用 SurfaceFlinger::signalEvent,最后调用MessageQueue::invalidate唤醒是 SurfaceFlinger的主循环。
在主循环中waitForEvent返回,再handleRepaint去合成个Layer/Surface。
- bool SurfaceFlinger<span style="color: #339933;">::</span>
- <span style="color: #202020;">threadLoop</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">{</span>
- waitForEvent<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- handleRepaint<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- postFramebuffer<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <span style="color: #009900;">}</span>
SurfaceFlinger::handleRepaint会调用composeSurfaces把需要绘制各个Surface合并起来,绘制到FrameBuffer的BackBuffer上。
- <span style="color: #b1b100;">for</span>
- <span style="color: #009900;">(</span>
- size_t i<span style="color: #339933;">=</span>
- <span style="color: #0000dd;">0</span>
- <span style="color: #339933;">;</span>
- i<span style="color: #339933;"><</span>
- count <span style="color: #339933;">;</span>
- <span style="color: #339933;">++</span>
- i<span style="color: #009900;">)</span>
- <span style="color: #009900;">{</span>
- <span style="color: #993333;">const</span>
- sp<span style="color: #339933;"><</span>
- LayerBase<span style="color: #339933;">>&</span>
- layer <span style="color: #339933;">=</span>
- layers<span style="color: #009900;">[</span>
- i<span style="color: #009900;">]</span>
- <span style="color: #339933;">;</span>
- <span style="color: #993333;">const</span>
- Region<span style="color: #339933;">&</span>
- visibleRegion<span style="color: #009900;">(</span>
- layer<span style="color: #339933;">-></span>
- visibleRegionScreen<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <span style="color: #b1b100;">if</span>
- <span style="color: #009900;">(</span>
- <span style="color: #339933;">!</span>
- visibleRegion.<span style="color: #202020;">isEmpty</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">{</span>
- <span style="color: #808080; font-style: italic;">/* broncho cy add */</span>
- <span style="color: #339933;">#ifdef USEOVERLAY</span>
- mToppest<span style="color: #009900;">[</span>
- <span style="color: #0000dd;">1</span>
- <span style="color: #009900;">]</span>
- <span style="color: #339933;">=</span>
- mToppest<span style="color: #009900;">[</span>
- <span style="color: #0000dd;">0</span>
- <span style="color: #009900;">]</span>
- <span style="color: #339933;">;</span>
- mToppest<span style="color: #009900;">[</span>
- <span style="color: #0000dd;">0</span>
- <span style="color: #009900;">]</span>
- <span style="color: #339933;">=</span>
- layer<span style="color: #339933;">-></span>
- getIdentity<span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <span style="color: #339933;">#endif</span>
- <span style="color: #808080; font-style: italic;">/* broncho end */</span>
- <span style="color: #993333;">const</span>
- Region clip<span style="color: #009900;">(</span>
- dirty.<span style="color: #202020;">intersect</span>
- <span style="color: #009900;">(</span>
- visibleRegion<span style="color: #009900;">)</span>
- <span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <span style="color: #b1b100;">if</span>
- <span style="color: #009900;">(</span>
- <span style="color: #339933;">!</span>
- clip.<span style="color: #202020;">isEmpty</span>
- <span style="color: #009900;">(</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">)</span>
- <span style="color: #009900;">{</span>
- layer<span style="color: #339933;">-></span>
- draw<span style="color: #009900;">(</span>
- clip<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <span style="color: #009900;">}</span>
- <span style="color: #009900;">}</span>
- <span style="color: #009900;">}</span>
SurfaceFlinger::postFramebuffer最后把FrameBuffer的BackBuffer显示到屏幕上:
- hw.<span style="color: #202020;">flip</span>
- <span style="color: #009900;">(</span>
- mInvalidRegion<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
- <span style="color: #339933;">--></span>
- eglSwapBuffers<span style="color: #009900;">(</span>
- dpy<span style="color: #339933;">,</span>
- surface<span style="color: #009900;">)</span>
- <span style="color: #339933;">;</span>
FrameBuffer具体的显示过程,下次再写吧。
- Android GUI更新过程
- Android GUI更新过程
- Android GUI更新过程
- Android GUI更新过程
- Android GUI 的更新过程
- Android GUI更新过程
- Android GUI更新过程
- Android GUI 的更新过程
- Android GUI更新过程
- Android GUI更新过程
- Android 中的 framebuffer 和SurFace的关系(GUI更新过程)
- 更新过程
- Android画布更新过程OnDraw调用过程
- Android sdk更新过程中出现问题 和导包问题
- Android源码分析之WindowManager.LayoutParams属性更新过程
- Android源码分析之WindowManager.LayoutParams属性更新过程
- Android源码分析之WindowManager.LayoutParams属性更新过程
- ANDROID GUI
- 字符串String
- How to install Adobe Reader on Ubuntu
- javascript获取select的值全解
- Qt中QTableWidget用法总结
- Unity3d的2D Toolkit中tk2dUISoundItem使用注意事项
- Android GUI更新过程
- C#制作无边框纸牌游戏
- SVN服务器搭建和使用(二)
- N的阶乘 C/C++ Java 实现
- logback 常用配置详解(二) <appender>
- (转)关于主函数:int main(int&nb…
- SVN服务器搭建和使用(三)
- HTC ONE(M7)免刷去除海苔条教程(国际版、台版通用)
- android:visibility||view.setVisibility(View.VISIBLE)