android 绘制流程

来源:互联网 发布:苹果6为什么打不开淘宝 编辑:程序博客网 时间:2024/06/08 17:57

转自:http://blog.csdn.net/zdm20061984/article/details/5709438

启动每个Activity系统都会创建一个ViewRoot用于保存所有的view,通过viewRoot将窗体加载到 WindowManagerService并创建窗体的客户端,监控并处理相应事件。

界面的绘画是由相应事件调用函数scheduleTraversals()开始的:
1.函数scheduleTraversals()会分发消息 sendEmptyMessage(DO_TRAVERSAL);
2.消息由函数handleMessage(Message msg)处理:
    viewroot.java :: handleMessage(Message msg)
            case DO_TRAVERSAL:
                    ...
                   performTraversals();
                ...
3.在函数performTraversals()中会调用函数draw(fullRedrawNeeded)进行绘画;
    viewroot.java :: performTraversals()
        ...
        draw(fullRedrawNeeded);
        ...
-->    viewroot.java :: draw(boolean fullRedrawNeeded)
        ...
         mView.draw(canvas);
        ...
-->    view.java :: draw(Canvas canvas)
        ...
         onDraw(canvas)
        ...
(以imageview为例)
-->    imageview.java :: onDraw(Canvas canvas)
        ...
        mDrawable.draw(canvas)
        ...
 (以BitmapDrawable为例)
-->    bitmapdrawable.java :: draw(Canvas canvas)
        ...
        canvas.drawBitmap(bitmap, null, mDstRect, state.mPaint);
        ...
-->    canvas.java :: drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
        ...
        native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst,paint != null ? paint.mNativePaint : 0)
        ...
-->    canvas.cpp :: drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas,
                             SkBitmap* bitmap, jobject srcIRect,
                             jobject dstRectF, SkPaint* paint)
        ...
        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint);   
        ...
-->    canvas.cpp :: doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap,
                        jobject srcIRect, const SkRect& dst, SkPaint* paint)
        ...
        canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
        ...
-->    skcanvas.cpp :: drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
                              const SkRect& dst, const SkPaint* paint)
        ...
        this->internalDrawBitmap(*bitmapPtr, matrix, paint);
        ...
-->    skcanvas.cpp :: internalDrawBitmap(const SkBitmap& bitmap,
                                const SkMatrix& matrix, const SkPaint* paint)
        ...
        this->commonDrawBitmap(bitmap, matrix, tmpPaint);
        ...
-->    skcanvas.cpp :: commonDrawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
                                const SkPaint& paint)
        ...
        iter.fDevice->drawBitmap(iter, bitmap, matrix, paint);
        (注:iter为skdrawiter,其成员fdevice为skdevive)
        ...
-->    skdevice.cpp :: drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
                              const SkMatrix& matrix, const SkPaint& paint)
        ...
        draw.drawBitmap(bitmap, matrix, paint);
        ...
-->    SkDraw.cpp :: drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
                        const SkPaint& paint)
        ...
        blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap,
                                            ix, iy, storage, sizeof(storage));
            -- >        case SkBitmap::kARGB_8888_Config:
                            SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S32_BlitRowProc,storage, storageSize, (source));
        ...
        blitter->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
        ...
(在ChooseSprite选择时,返回的blitter为Sprite_D16_S32_BlitRowProc)
-->     SkSpriteBlitter_RGB16.cpp :: blitRect(int x, int y, int width, int height)
        ...
        SkBlitRow::Proc proc = fProc;
        ...
        proc(dst, src, width, alpha, x, y);
        ...   

(由于:
    SkRGB16_Shader_Blitter.cpp :: setup(const SkBitmap& device, int left, int top,
                       const SkPaint& paint)
        ...
            fProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config);
            -->     case SkBitmap::kRGB_565_Config:
                        return gProcs16[flags];
       
            skblitrow_d16.cpp :: SkBlitRow::Proc gProcs16[]
                ...
                S32A_D565_Blend,   
                ...
,则此处调用的 proc实际为S32A_D565_Blend)
-->     SkBlitRow_D16.cpp :: S32A_D565_Blend(uint16_t* SK_RESTRICT dst,
                              const SkPMColor* SK_RESTRICT src, int count,
                               U8CPU alpha, int /*x*/, int /*y*/)
        ...
                    unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale);
                    dr = (SkPacked32ToR16(sc) * src_scale + SkGetPackedR16(dc) * dst_scale) >> 8;
                    dg = (SkPacked32ToG16(sc) * src_scale + SkGetPackedG16(dc) * dst_scale) >> 8;
                    db = (SkPacked32ToB16(sc) * src_scale + SkGetPackedB16(dc) * dst_scale) >> 8;
               
                    *dst = SkPackRGB16(dr, dg, db);       
        ...
通过此流程可以确认 显示的混合部分是在skia中进行的,并且在调用opengl前完成。


补充实际上这个scheduleTraversals()

这个函数能够就是类似于浏览器里面的renderer中IfneedRender()

函数,那么就会间接的调用到frameview的绘制函数。

实际上如果进行2D加速的操作就是在这个流程之中






原创粉丝点击