Android硬件加速绘制过程源码分析(三)——DisplayList的绘制过程

上文我们分析了View Hierarchy录制绘制操作的过程,本文我们分析一下DisplayList的绘制过程。

      一、每个View的DisplayList对象之间有什么关系呢?

      我们先来解决上文的遗留问题,每个View的DisplayList对象之间有什么关系呢?还记得View的draw2函数吗:

boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
        ......
        
        useDisplayListProperties &= hasDisplayList;
        if (useDisplayListProperties) {
            displayList = getDisplayList();
            if (!displayList.isValid()) {
                // Uncommon, but possible. If a view is removed from the hierarchy during the call
                // to getDisplayList(), the display list will be marked invalid and we should not
                // try to use it again.
                displayList = null;
                hasDisplayList = false;
                useDisplayListProperties = false;
            }
        }

        ......

            if (!layerRendered) {
                if (!hasDisplayList) {
                    // Fast path for layouts with no backgrounds
                    if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
                        mPrivateFlags &= ~PFLAG_DIRTY_MASK;
                        dispatchDraw(canvas);
                    } else {
                        draw(canvas);
                    }
                } else {
                    mPrivateFlags &= ~PFLAG_DIRTY_MASK;
                    ((HardwareCanvas) canvas).drawDisplayList(displayList, null, flags);
                }
            }
       ......
    }

      draw2函数中的((HardwareCanvas) canvas).drawDisplayList(displayList, null, flags)我们还没分析。首先这里的canvas是父View传递给我们的,并且该canvas是一个GLES20RecordingCanvas对象。所以我们来看看GLES20RecordingCanvas的drawDisplayList函数:

@Override
    public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) {
        int status = super.drawDisplayList(displayList, dirty, flags);
        mDisplayList.getChildDisplayLists().add(displayList);
        return status;
    }

      我们看到mDisplayList.getChildDisplayLists().add(displayList)这句话,因为canvas是父View的canvas,所以canvas对应的mDisplayList对象就是父View的DisplayList对象,看一下getChildDisplayList()函数:

ArrayList<DisplayList> getChildDisplayLists() {
        if (mChildDisplayLists == null) mChildDisplayLists = new ArrayList<DisplayList>();
        return mChildDisplayLists;
    }

      所以每个父View的DisplayList都有一个ArrayList用来保存子View的DisplayList,这样每个View对应的DisplayList对象也组成了一棵树?但是千万别高兴的太早,我们之前讲过每个DisplayList的java对象都有一个对应的本地DIsplayList对象,本地DisplayList对象才是真正保存绘制操作的地方。照理说通过java层的DisplayList组成的树,本地DisplayList对象也可以联系在一起,但这会反复在java层和本地层之间进行切换,效率可能会比较低,所以Android也将本地DisplayList对象直接联系在一起了,我们来看是怎么联系的。我们回到GLES20RecordingCanvas的drawDisplayList函数,它其实先调用了super.drawDisplayList(displayList, dirty, flags)方法,GLES20RecordingCanvas的父类是GLES20Canvas,看一下GLES20Canvas的drawDisplayList方法:

@Override
    public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) {
        return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).getNativeDisplayList(),
                dirty, flags);
    }

      再看nDrawDisplayList方法,在core\jni\android_view_GLES20Canvas中:

static jint android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
        jobject clazz, jlong rendererHandle, jlong displayListHandle,
        jobject dirty, jint flags) {
    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
    Disp
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值