1. 简介
Android系统--视图绘制主要由以下几部分组成:
1) Canvas(画布)
提供画图所需要的所有工具,即各种draw函数;当前可用的画布对象有:具有硬件加速的GLES20Canvas和GLES20RecordingCanvas,不使用硬件加速的CompatibleCanvas)。
2) View(视图)
在具体画布对象上完成各种绘制图形的操作,可根据需要选择以上三种画布中的一种。
3) Gl20Renderer(把图直接绘制到屏幕上)
它是硬件加速视图绘制的引擎,负责整个与硬件加速相关的视图绘制过程,具体功能如下:
(1) 创建以下实例对象:
• GLES20Canvas (Canvas)
• GLES20DisplayList (DisplayList)
• GLES20TextureLayer (HardwareLayer)
• GLES20RenderLayer (HardwareLayer)
• SurfaceTexture
• Gl20Renderer (HardwareRenderer)
(2) 在GlRenderer.draw中调用View.getDisplayList()完成DisplayList命令的录制,并返回DisplayList
注:只有View被attach到硬件加速,才能创建DisplayList;
真正的命令录制工作在View.getDisplayList(DisplayList displayList, boolean isLayer)中完成。
(3) 在GlRenderer.draw中调用GLES20Canvas.drawDisplayList,把DisplayList中录制的命令回放在画布上。
(4) Gl20Renderer对象对应的画布为GLES20Canvas,Gl20Renderer对象在画布上的绘制实际上是绘制在OPENGL绘制上下文对应的主缓冲区。
4) GLES20DisplayList(把录制命令录制到Native的DiplayList中)
GLES20DisplayList对象创建具体的DisplayList对象及绘制用的画布(GLES20RecordingCanvas画布),完成视图绘制操作的DisplayList命令录制等工作。
5) GLES20RenderLayer(绘制到FOB Layer中,当作纹理)
负责创建硬件Layer层(GLES20Canvas.nCreateLayer)和绘制用到的画布(GLES20Canvas,使用Layer实例化GLES20Canvas(layer, trans))等工作。
为了有效支持视图的多层绘制,视图对象可以创建一个HardwareLayer层完成视图的图形在硬件纹理上的绘制操作或者其它特效操作,这就是GLES20RenderLayer对象的作用,创建独立的层并返回相应的画布供视图绘制使用。
1.1 View.draw(Canvas canvas)六步曲
此函数将把View自身及其所有的子子孙孙绘制到给定的画布上。其画图过程主要分为以下六步:
1) 画背景
2) 如果需要,保存画布的层为未来的淡入淡出做好准备
3) 画View本身的内容
4) 画它的孩子
5) 如果需要,画淡入淡出的边缘并恢复层
6) 画装饰部分(如:滚动条)
- /**
- * Manually render this view (and all of its children) to the given Canvas.
- * The view must have already done a full layout before this function is
- * called. When implementing a view, implement
- * {@link #onDraw(android.graphics.Canvas)} instead of overriding this method.
- * If you do need to override this method, call the superclass version.
- *
- * @param canvas The Canvas to which the View is rendered.
- */
- public void draw(Canvas canvas) {
- final int privateFlags = mPrivateFlags;
- final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
- (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
- mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
- /*
- * Draw traversal performs several drawing steps which must be executed
- * in the appropriate order:
- *
- * 1. Draw the background
- * 2. If necessary, save the canvas' layers to prepare for fading
- * 3. Draw view's content
- * 4. Draw children
- * 5. If necessary, draw the fading edges and restore layers
- * 6. Draw decorations (scrollbars for instance)
- */
- // Step 1, draw the background, if needed
- int saveCount;
- if (!dirtyOpaque) {
- final Drawable background = mBackground;
- if (background != null) {
- final int scrollX = mScrollX;
- final int scrollY = mScrollY;
- if (mBackgroundSizeChanged) {
- background.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
- mBackgroundSizeChanged = false;
- }
- if ((scrollX | scrollY) == 0) {
- background.draw(canvas);
- } else {
- canvas.translate(scrollX, scrollY);
- background.draw(canvas);
- canvas.translate(-scrollX, -scrollY);
- }
- }
- }
- // skip step 2 & 5 if possible (common case)
- final int viewFlags = mViewFlags;
- boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
- boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
- if (!verticalEdges && !horizontalEdges) {
- // Step 3, draw the content
- if (!dirtyOpaque) onDraw(canvas);
- // Step 4, draw the children
- dispatchDraw(canvas);
- // Step 6, draw decorations (scrollbars)
- onDrawScrollBars(canvas);
- // we're done...
- return;
- }
- }
2. 家族图谱
2.1 View家族图谱
2.2 Canvas和HardwareRenderer家族图谱
2.3 DisplayList和HardwareLayer家族图谱
2.4 Native OpenGLRenderer家族图谱
DisplayList.replay调用流程如下:
- //Java
- GlRenderer.draw((View view, View.AttachInfo attachInfo,...)
- GLES20Canvas.drawDisplayList(DisplayList displayList, Rect dirty, int flags)->
- //JNI
- nDrawDisplayList->
- android_view_GLES20Canvas_drawDisplayList(...,OpenGLRenderer* renderer,
- DisplayList* displayList,...)->
- //Native
- OpenGLRenderer.drawDisplayList(DisplayList* displayList,...)->
- DisplayList::replay(OpenGLRenderer& renderer,...)
2.5 Activity与Window家族图谱
• WindowManagerImpl:
允许把View子类增加到高级Window,应用不应该使用它,而是使用更高级的android.app.Activity或android.app.Dialog。
• PhoneWindow.mDecor(DecorView):窗口最高级的装饰View,即窗口的View树的树根,它包含:标准的Window框架、装饰、和放于窗口中的内容,可把它当作一个Window增加到Window Manager。
2.6 Activity与PhoneWindow的关系
每一个Activity都有一个关联的PhoneWindow对象,用来描述一个应用程序的窗口。每一个应用程序窗口(PhoneWindow)内部又包含有一个装饰View对象(mDecor:DecorView,View树的树根)和一个内容View对象(mContentParent: ViewGroup),用来描述应用程序窗口的视图。
1) mContentParent(ViewGroup):是Layout 资源描述的视图树的树根,它是mDecor的孩子
2) mDecor(DecorView):是PhoneWindow窗口中的视图树的树根
2.7 Activity实例化PhoneWindow流程
Activity在attach函数中实例化了PhoneWindow和WindowManagerImpl,以供后面绘制视图使用。
- Activity.attach(Context context, ActivityThread aThread,
- Instrumentation instr, IBinder token, int ident,
- Application application, Intent intent, ActivityInfo info,
- CharSequence title, Activity parent, String id,
- NonConfigurationInstances lastNonConfigurationInstances,
- Configuration config)->
- 1) PolicyManager.makeNewWindow(Context context)
- // 返回PhoneWindow实例并保存在mWindow中
- {
- Policy.makeNewWindow(Context context)->
- //new PhoneWindow(context)
- PhoneWindow(Context context)
- //获取LayoutInflater,它可以把Layout XML实例化为对应的View Objects
- }
- 2) Window.setWindowManager(
- (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
- mToken, mComponent.flattenToString(),
- (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0)->
- {
- WindowManagerImpl.createLocalWindowManager(Window parentWindow)
- // 返回WindowManagerImpl实例,并保存在Window.mWindowManager
- }
- 3)mWindow.setContainer(mParent.getWindow())
- 4)mWindowManager = mWindow.getWindowManager()
- //返回Window.mWindowManager
- //即Activity与Window中的mWindowManager为同一个
- //WindowManagerImpl实例
2.8 放置窗口内容setContentView
setContentView的功能是:把Layout XML资源文件实例化为一棵视图树,然后把它加入PhoneWindow.mContentParent中,即成为PhoneWindow.mContentParent的子女。
- Activity.setContentView(int layoutResID)->
- //设置Activity内容
- PhoneWindow.setContentView(int layoutResID)->
- LayoutInflater.inflate(layoutResID, mContentParent)->
- //把XML资源文件实例化为一棵视图树,并返回视图树的树根(root)
- //树根为ViewGroup实例
- LayoutInflater.inflate(layoutResID, root, root != null)->
- //根据资源生成XmlResourceParser
- LayoutInflater.inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)->
- ViewGroup.addView(View child, LayoutParams params)->
- {
- //把资源文件中的视图树加入PhoneWindow中的mContentParent中
- View.requestLayout()
- View.invalidate(true)->
- addViewInner(child, index, params, false)
- //它将调用child.requestLayout(),依次递归下去
- }
- ViewGroup.invalidateChild(View child, final Rect dirty)->
- ViewGroup.invalidateChildInParent(final int[] location, final Rect dirty)
- //更新dirty区域
3. FBO (Frame Buffer Object)和RBO (Render Buffer Object)
在了解下面的内容之前,需要了解一下FBO和RBO,除了使用窗口系统固有的Frame Buffer外,可以创建Frame Buffer Object,用于off-screen rendering(离线渲染:就是通过OpenGL将绘制结果渲染到显存中的一张图片上,通过gl接口函数可以从显存读取到内存中)。FBO是一种特殊的Buffer Object。
3.1 FBO
1) glGenFramebuffers: 生成FBO对象的名字
2) glBindFramebuffer: 绑定FBO并进行实始化
3) glDeleteFramebuffers: 删除FBO对象
FBO创建后,还不能绘图,必须为FBO提供绘图的目标buffer,也即Render Buffer Object。
3.2 RBO
Render Buffer Object包含具体的图像数据:
1) glGenRenderbuffers:生成对象的名字
2) glBindRenderbuffer: 绑定名字到RenderBuffer
3) glRenderbufferStorage: 为render buffer分配存储空间
3.3 把RBO连接到FBO上
glFramebufferRenderbuffer(GLenum target, GLenum attachment,GLenum renderbuffertarget, GLuint renderbuffer);
1) target:GL_DRAW_FRAMEBUFFER: 指定写入用途FBO
GL_READ_FRAMEBUFFER:指定读取用途FBO
GL_FRAMEBUFFER:指定两者
2) attachment:GL_COLOR_ATTACHMENT
GL_DEPTH_ATTACHMENT
GL_STENCIL_ATTACHMENT
GL_DEPTH_STENCIL_ATTACHMENT
3)renderbuffertarget: GL_RENDERBUFFER
4) renderbuffer: RBO名字
使用FBO可以创建出动态的texture,glFramebufferTexture可以绑定texture到FBO。
4. 各种各样的画布
从上面的家族图谱中可以看到,可用的画布有以下几种:
1) GLES20RecordingCanvas: 此GL画布用于录制画图操作
2) GLES20Canvas: 在OpenGL ES 2.0之上实现的画布
3) HardwareCanvas: 硬件加速的画布
3) Canvas: 实现画图操作的画布
4.1 Gl20Renderer使用的画布(直接绘制在屏幕上)
其相关代码如下:
Gl20Renderer.createCanvas()->
GLES20Canvas.GLES20Canvas(false, boolean translucent)->
nCreateRenderer()
- /**
- * Hardware renderer using OpenGL ES 2.0.
- */
- static class Gl20Renderer extends GlRenderer {
- private GLES20Canvas mGlCanvas;
- final boolean mTranslucent;
- //...
- @Override
- HardwareCanvas createCanvas() {
- //创建直接绘制到屏幕上的画布,而不会录制到DisplayList中
- return mGlCanvas = new GLES20Canvas(mTranslucent);
- }
- //...
- }
- /**
- * An implementation of Canvas on top of OpenGL ES 2.0.
- */
- class GLES20Canvas extends HardwareCanvas {
- private final boolean mOpaque;
- private int mRenderer;
- //...
- /**
- * Creates a canvas to render directly on screen.
- * 创建直接绘制到屏幕上的画布,而不会录制到DisplayList中
- * 由Gl20Renderer.createCanvas调用
- */
- GLES20Canvas(boolean translucent) {
- // 直接调用OpenGL函数把图画到屏幕上
- this(false, translucent);
- }
- /**
- * Creates a canvas to render into an FBO.
- * 创建离线绘制到FBO的画布
- */
- GLES20Canvas(int layer, boolean translucent) {
- mOpaque = !translucent;
- // mRenderer为Native中LayerRenderer类的实例
- mRenderer = nCreateLayerRenderer(layer);
- setupFinalizer();
- }
- protected GLES20Canvas(boolean record, boolean translucent) {
- mOpaque = !translucent;
- if (record) {
- // 把画图命令录制到DisplayListRenderer.mWriter中
- // mRender为Native中DisplayListRenderer类的实例
- mRenderer = nCreateDisplayListRenderer();
- } else {
- // 直接调用OpenGL函数把图画到屏幕上
- // mRenderer为Native中OpenGLRenderer类的实例
- mRenderer = nCreateRenderer();
- }
- setupFinalizer();
- }
- //...
- }
4.2 GLES20RenderLayer使用的画布(离线绘制到FBO Layer)
GLES20RenderLayer.GLES20RenderLayer(w,h,trans)->
GLES20Canvas.nCreateLayer(w,h,trans,layerInfo)
GLES20Canvas.GLES20Canvas(int layer, boolean translucent)->
nCreateLayerRenderer(layer)
- /**
- * An OpenGL ES 2.0 implementation of {@link HardwareLayer}. This
- * implementation can be used a rendering target. It generates a
- * {@link Canvas} that can be used to render into an FBO using OpenGL.
- */
- class GLES20RenderLayer extends GLES20Layer {
- private int mLayerWidth;
- private int mLayerHeight;
- private final GLES20Canvas mCanvas;
- GLES20RenderLayer(int width, int height, boolean isOpaque) {
- super(width, height, isOpaque);
- int[] layerInfo = new int[2];
- // 请求Native LayerRenderer创建一个FBO Layer,以用于离线Render
- mLayer = GLES20Canvas.nCreateLayer(width, height, isOpaque, layerInfo);
- if (mLayer != 0) {
- mLayerWidth = layerInfo[0];
- mLayerHeight = layerInfo[1];
- // 使用FBO Layer创建一个Native LayerRenderer,然后实例化画布
- mCanvas = new GLES20Canvas(mLayer, !isOpaque);
- mFinalizer = new Finalizer(mLayer);
- } else {
- mCanvas = null;
- mFinalizer = null;
- }
- }
- //...
- }
- /**
- * An implementation of Canvas on top of OpenGL ES 2.0.
- */
- class GLES20Canvas extends HardwareCanvas {
- private final boolean mOpaque;
- private int mRenderer;
- //...
- /**
- * Creates a canvas to render directly on screen.
- * 创建直接绘制到屏幕上的画布,而不会录制到DisplayList中
- * 由Gl20Renderer.createCanvas调用
- */
- GLES20Canvas(boolean translucent) {
- // 直接调用OpenGL函数把图画到屏幕上
- this(false, translucent);
- }
- /**
- * Creates a canvas to render into an FBO.
- * 创建离线绘制到FBO的画布
- */
- GLES20Canvas(int layer, boolean translucent) {
- mOpaque = !translucent;
- // mRenderer为Native中LayerRenderer类的实例
- mRenderer = nCreateLayerRenderer(layer);
- setupFinalizer();
- }
- protected GLES20Canvas(boolean record, boolean translucent) {
- mOpaque = !translucent;
- if (record) {
- // 把画图命令录制到DisplayListRenderer.mWriter中
- // mRender为Native中DisplayListRenderer类的实例
- mRenderer = nCreateDisplayListRenderer();
- } else {
- // 直接调用OpenGL函数把图画到屏幕上
- // mRenderer为Native中OpenGLRenderer类的实例
- mRenderer = nCreateRenderer();
- }
- setupFinalizer();
- }
- //...
- }
4.3 GLES20RecordingCanvas使用的画布 (绘制到DisplayList)
GLES20DisplayList.start->
GLES20RecordingCanvas.obtain(GLES20DisplayList displayList)-> (static)
GLES20RecordingCanvas.GLES20RecordingCanvas()->
GLES20Canvas(true /*record*/, true /*translucent*/)->
nCreateDisplayListRenderer()
- /**
- * An implementation of display list for OpenGL ES 2.0.
- */
- class GLES20DisplayList extends DisplayList {
- // These lists ensure that any Bitmaps and DisplayLists recorded by a DisplayList are kept
- // alive as long as the DisplayList is alive. The Bitmap and DisplayList lists
- // are populated by the GLES20RecordingCanvas during appropriate drawing calls and are
- // cleared at the start of a new drawing frame or when the view is detached from the window.
- final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(5);
- final ArrayList<DisplayList> mChildDisplayLists = new ArrayList<DisplayList>();
- private GLES20RecordingCanvas mCanvas;
- // Used for debugging
- private final String mName;
- // The native display list will be destroyed when this object dies.
- // DO NOT overwrite this reference once it is set.
- private DisplayListFinalizer mFinalizer;
- GLES20DisplayList(String name) {
- mName = name;
- }
- @Override
- public HardwareCanvas start() {
- if (mCanvas != null) {
- throw new IllegalStateException("Recording has already started");
- }
- mValid = false;
- // 使用GLES20DisplayList创建GLES20RecordingCanvas
- mCanvas = GLES20RecordingCanvas.obtain(this);
- mCanvas.start();
- return mCanvas;
- }
- //...
- }
- /**
- * An implementation of a GL canvas that records drawing operations.
- * This is intended for use with a DisplayList. This class keeps a list of all the Paint and
- * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
- * the DisplayList is still holding a native reference to the memory.
- */
- class GLES20RecordingCanvas extends GLES20Canvas implements Poolable<GLES20RecordingCanvas> {
- // The recording canvas pool should be large enough to handle a deeply nested
- // view hierarchy because display lists are generated recursively.
- private static final int POOL_LIMIT = 25;
- private static final Pool<GLES20RecordingCanvas> sPool = Pools.synchronizedPool(
- Pools.finitePool(new PoolableManager<GLES20RecordingCanvas>() {
- public GLES20RecordingCanvas newInstance() {
- return new GLES20RecordingCanvas();
- }
- @Override
- public void onAcquired(GLES20RecordingCanvas element) {
- }
- @Override
- public void onReleased(GLES20RecordingCanvas element) {
- }
- }, POOL_LIMIT));
- private GLES20DisplayList mDisplayList;
- private GLES20RecordingCanvas() {
- //实例化DisplayListRender
- super(true /*record*/, true /*translucent*/);
- }
- static GLES20RecordingCanvas obtain(GLES20DisplayList displayList) {
- GLES20RecordingCanvas canvas = sPool.acquire();
- canvas.mDisplayList = displayList;
- return canvas;
- }
- // ...
- }
- /**
- * An implementation of Canvas on top of OpenGL ES 2.0.
- */
- class GLES20Canvas extends HardwareCanvas {
- private final boolean mOpaque;
- private int mRenderer;
- //...
- /**
- * Creates a canvas to render directly on screen.
- * 创建直接绘制到屏幕上的画布,而不会录制到DisplayList中
- * 由Gl20Renderer.createCanvas调用
- */
- GLES20Canvas(boolean translucent) {
- // 直接调用OpenGL函数把图画到屏幕上
- this(false, translucent);
- }
- /**
- * Creates a canvas to render into an FBO.
- * 创建离线绘制到FBO的画布
- */
- GLES20Canvas(int layer, boolean translucent) {
- mOpaque = !translucent;
- // mRenderer为Native中LayerRenderer类的实例
- mRenderer = nCreateLayerRenderer(layer);
- setupFinalizer();
- }
- protected GLES20Canvas(boolean record, boolean translucent) {
- mOpaque = !translucent;
- if (record) {
- // 把画图命令录制到DisplayListRenderer.mWriter中
- // mRender为Native中DisplayListRenderer类的实例
- mRenderer = nCreateDisplayListRenderer();
- } else {
- // 直接调用OpenGL函数把图画到屏幕上
- // mRenderer为Native中OpenGLRenderer类的实例
- mRenderer = nCreateRenderer();
- }
- setupFinalizer();
- }
- //...
- }
5. 绘制(Render)元素小结
为了把图形绘制到屏幕上,必须使用Native Render,其最本质的东东是OpenGL,为了方便管理,其Native Render分为三类,其相关信息如下表所示:
Native Render类名 | OpenGLRenderer | DisplayListRenderer | LayerRenderer |
绘制到哪儿? | 直接绘制到屏幕上 | 录制到SkWriter32 | 离线绘制到FBO Layer |
JNI创建函数 | nCreateRenderer | nCreateDisplayListRenderer | nCreateLayerRenderer |
由谁管理? | GLES20Canvas | GLES20Canvas | GLES20Canvas |
由谁使用? | Gl20Renderer | GLES20DisplayList | GLES20RenderLayer |
使用者类别 | HardwareRenderer | DisplayList | HardwareLayer |
画图五元素间的暧昧关系如下图所示:
6. 创建窗口(Window)流程
其基本流程如下所示:
- ActivityThread.handleResumeActivity->
- {
- ActivityClientRecord.window = ActivityClientRecord.activity.getWindow();
- View decor = ActivityClientRecord.window.getDecorView();
- //实际调用PhoneWindow.getDecorView();
- decor.setVisibility(View.INVISIBLE);
- ViewManager wm = Activity.getWindowManager();
- //wm是WindowManagerImpl实例
- Activity.mDecor = decor;
- WindowManager.LayoutParams l = r.window.getAttributes();
- l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
- l.softInputMode |= forwardBit;
- if (a.mVisibleFromClient) {
- a.mWindowAdded = true;
- wm.addView(decor, l);--->
- //即调用WindowManagerImpl.addView,
- //把PhoneWindow.mDecor加入WindowManager中
- }
- }
- WindowManagerImpl.addView(View view, ViewGroup.LayoutParams params)->
- WindowManagerGlobal.addView(View view, ViewGroup.LayoutParams params,
- Display display, Window parentWindow)->
- (root = new ViewRootImpl(view.getContext(), display))
- ViewRootImpl.setView(View view, WindowManager.LayoutParams attrs, View panelParentView)->
- requestLayout()
- mWindowSession.addToDisplay(mWindow,...) --> //to Window Manager Server
- Session.addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
- int viewVisibility, int displayId, Rect outContentInsets,
- InputChannel outInputChannel)->
- WindowManagerService.addWindow(Session session, IWindow client, int seq,
- WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
- Rect outContentInsets, InputChannel outInputChannel)->
- new WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
- WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
- int viewVisibility, final DisplayContent displayContent)
- // WindowState实例即为Window Manager中刚创建的窗口
在以上过程中,ViewRootImpl为客户端,通过IWindowSession接口把创建窗口的请求发送给Server端(Session),然后调用WindowManagerService中对应的功能函数。同时把IWindow.Stub (W extends IWindow.Stub)的实现实例发送给服务器端,以便WindowMangerService通过IWindow接口向ViewRootImpl发送命令。其相互关系如下图所示:
Activity<-->PhoneWindow<-->ViewRootImpl<-->WindowManagerService
在以上关系中,WindowManagerService系统中仅一个实例,其它三个实例一一对应,即一个Activity实例有一个唯一的PhoneWindow和ViewRootImpl实例与之一一对应。
7. 硬件绘制(Hardware Render)窗口流程
- WMS.performLayoutAndPlaceSurfacesLocked->
- WMS.performLayoutAndPlaceSurfacesLockedLoop->
- WMS.performLayoutAndPlaceSurfacesLockedInner->
- mRelayoutWhileAnimating.get(j).mClient.doneAnimating()->
- //即IWindow.doneAnimating()
- ViewRootImpl.W.doneAnimating()->
- ViewRootImpl.dispatchDoneAnimating()->
- ViewRootImpl.handleDispatchDoneAnimating()->
- ViewRootImpl.scheduleTraversals()->
- ViewRootImpl.mTraversalRunnable.run()->
- ViewRootImpl.doTraversal()->
- ViewRootImpl.performTraversals() ->
- ViewRootImpl.performDraw()->
- ViewRootImpl.draw()->
- // ViewRootImpl.drawSoftware(..),软件render,暂且不讲,以下为硬件Render
- attachInfo.mHardwareRenderer.draw(mView,...)->
- // attachInfo.mHardwareRenderer实际为Gl20Renderer实例,
- // 在enableHardwareAcceleration中实例化
- // Gl20Renderer.createDisplayList: 实例化GLES20DisplayList
- // Gl20Renderer.createHardwareLayer(w,h):实例化GLES20RenderLayer
- // Gl20Renderer.create:实例化Gl20Renderer
- GlRenderer.draw(View view, View.AttachInfo attachInfo,...)->
- // 其mCanvas为GLES20Canvas,其对应的Native Render为OpenGLRenderer
- GLES20Canvas.onPreDraw(dirty)
- View.getDisplayList(mDisplayList, false)
- // 如果mDisplayList为null, 则调用
- mAttachInfo.mHardwareRenderer.createDisplayList
- // 返回的DisplayList为GLES20DisplayList实例
- GLES20DisplayList.start()
- // 返回GLES20RecordingCanvas实例
- //如果mLayerType为LAYER_TYPE_HARDWARE,则调用
- mAttachInfo.mHardwareRenderer.createHardwareLayer(w,h,..)
- //返回GLES20RenderLayer实例到mHardwareLayer中
- GLES20RecordingCanvas.drawHardwareLayer(mHardwareLayer,...)
- GLES20Canvas.drawDisplayList(displayList,...)
- GLES20Canvas.onPostDraw()
- EGL10.eglSwapBuffers(sEglDisplay, mEglSurface)
版权声明:本文为博主原创文章,未经博主允许不得转载。
-
顶
- 1
-
踩
- 0
-
主题推荐
- android
-
猜你在找
核心技术类目
- 个人资料
-
- 访问:1532616次
- 积分:17356
- 等级:
- 排名:第246名
- 原创:229篇
- 转载:174篇
- 译文:4篇
- 评论:280条
- 文章搜索
- 文章分类
- Linux驱动(29)
- Android OpenGL(0)
- Android应用(44)
- Linux Kernel(48)
- Android Media(10)
- Android Framework(27)
- Stagefright(8)
- DisplaySystem(8)
- HAL(2)
- CPU&GPU(18)
- HW(21)
- Android系统(50)
- Android调试(8)
- 基础知识(56)
- OpenGL ES(12)
- 项目管理(4)
- 测试(4)
- Google Play Store(2)
- 工作规范(1)
- Audio(3)
- 无线通信(1)
- Android基础知识(21)
- 认证(7)
- 商品管理(1)
- Android OTA(6)
- Android WiFi(12)
- Android待机唤醒(8)
- ALSA(13)
- V4L2&USB(14)
- 内存管理(4)
- Linux API(2)
- Linux安全(9)
- 云计算(1)
- 异构计算(1)
- cocos2d-x(17)
- Unity3D(24)
- H.265/HEVC(4)
- 3DS Max(3)
- Photoshop(1)
- 阅读排行
- WiFi基本知识(44912)
- Android 4.0 事件输入(Event Input)系统(34487)
- Linux pipe函数(33288)
- Android4.0.3 显示系统深入理解(26355)
- Android4.x 如何处理Power按键(22345)
- Android WiFi--系统架构(19674)
- Linux inotify功能及实现原理(18757)
- USB枚举过程(17931)
- USB协通讯议--深入理解(14960)
- Android App 隐藏标题栏+状态栏+导航栏(13950)
- 评论排行
- 最新评论
- Linux内存管理--基本概念
my0929my:@duanlove:MMU 配置,其实就是将物理地址偏移和虚拟地址的偏移,以及对应的符号表的映射关系...
- Android中statfs使用注意事项
maple516615:请问为什么说是这句问题?uint32_t到uint64_t数据转换是小数据到大数据的转换吧?这样会造...
- Unity5.0与Android交互
qq_27432207:谢谢,昨天实验成功了。之前看了一个别的教程只能在4.6使用,一直尝试想在5.0使用,正好解决了。非常...
- Unity5.0与Android交互
qq_27432207:谢谢,昨天实验成功了。之前看了一个别的教程只能在4.6使用,一直尝试想在5.0使用,正好解决了。非常...
- Unity5.0与Android交互
qq_27432207:谢谢,昨天实验成功了。之前看了一个别的教程只能在4.6使用,一直尝试想在5.0使用,正好解决了。非常...
- APK扩展文件及使用
eieihihi:写得非常详细!顶一下!
- Unity5.0与Android交互
kaitiren:写的不对!
- OpenGL ES 2.0基本概念
coblan:写的好,比较清晰。
- Android系统--事件读取及分发
凡成:竟然没人评论,好文章
- Apk文件破解可见源码
muzi1314_:反编译成java文件如果混绕之后有没有好的方法来看原代码?
4楼 sinat_19635357 2014-10-28 10:34发表 [回复]-
-
看了你画的2.1 View家族图谱,想问下博主有没有搞清楚基类和子类的关系,既然你说的很清楚了view是一个基类,那么箭头的方向是不是搞错了。
3楼 zhu85564043 2014-10-02 17:11发表 [回复]-
-
写的非常好! 看了你的文章收获很多! 感谢博主的分享!
2楼 duanlove 2013-12-15 21:10发表 [回复]-
-
写的挺细的。
1楼 talking 2013-11-23 17:12发表 [回复]-
-
深入浅出,博主博客对我帮组挺大,感谢啊