android GUI 记录(2)

/ android / 没有评论 / 532浏览

用到的代码文件

frameworks/native/services/surfaceflinger/SurfaceFlinger.h
frameworks/native/services/surfaceflinger/DisplayDevice.h

相关概念

下面的代码是以android N(api 24)为基础来进行流程分析。

系统层级(SurfaceFlinger)的合成(上屏)的次数。

在 Android 系统中,SurfaceFlinger 扮演了系统中所有 Surface 的管理者的角色,当应用程序所对应的 Surface 更新之后,绝大多数的 Surface 都将在 SurfaceFlinger 之中完成了合并的工作之后,最终才会在 Screen 上显示出来。

SurfaceFlinger 的执行是由 VSYNC 信号驱动的,这决定了每秒钟合成次数的上限就是 60 次。当SurfaceFlinger 接收到 Surface 更新通知的时候,将会由 SurfaceFlinger::handleMessageRefresh 函数进行处理,其中包含重建可见区域、初始化、合成等步骤。

void SurfaceFlinger::handleMessageRefresh() {
    ATRACE_CALL();

#ifdef ENABLE_FENCE_TRACKING
    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
#else
    nsecs_t refreshStartTime = 0;
#endif
    static nsecs_t previousExpectedPresent = 0;
    nsecs_t expectedPresent = mPrimaryDispSync.computeNextRefresh(0);
    static bool previousFrameMissed = false;
    bool frameMissed = (expectedPresent == previousExpectedPresent);
    if (frameMissed != previousFrameMissed) {
        ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
    }
    previousFrameMissed = frameMissed;

    if (CC_UNLIKELY(mDropMissedFrames && frameMissed)) {
        // Latch buffers, but don't send anything to HWC, then signal another
        // wakeup for the next vsync
        preComposition();
        repaintEverything();
    } else {
        preComposition();
        rebuildLayerStacks();
        setUpHWComposer();
        doDebugFlashRegions();
        /*
          * 进行合成
          */
        doComposition();
        postComposition(refreshStartTime);
    }

    // Release any buffers which were replaced this frame
    for (auto& layer : mLayersWithQueuedFrames) {
        layer->releasePendingBuffer();
    }
    mLayersWithQueuedFrames.clear();

    previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0);
}
void SurfaceFlinger::doComposition() {
    ATRACE_CALL();
    ALOGV("doComposition");

    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
        const sp<DisplayDevice>& hw(mDisplays[dpy]);
        if (hw->isDisplayOn()) {
            // transform the dirty region into this screen's coordinate space
            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));

            // repaint the framebuffer (if needed)
            doDisplayComposition(hw, dirtyRegion);

            hw->dirtyRegion.clear();
            /*
              * 调用的是DisplayDevice.cpp中的flip()方法
              */
            hw->flip(hw->swapRegion);
            hw->swapRegion.clear();
        }
    }
    postFramebuffer();
}
void DisplayDevice::flip(const Region& dirty) const
{
    mFlinger->getRenderEngine().checkErrors();

    if (kEGLAndroidSwapRectangle) {
        if (mFlags & SWAP_RECTANGLE) {
            const Region newDirty(dirty.intersect(bounds()));
            const Rect b(newDirty.getBounds());
            eglSetSwapRectangleANDROID(mDisplay, mSurface,
                    b.left, b.top, b.width(), b.height());
        }
    }
    /*
      * mPageFlipCount 记录了 SurfaceFlinger 一共进行了多少次合成,也可以
      * 简单理解为SurfaceFlinger 向屏幕提交了多少帧的数据。
      */
    mPageFlipCount++;
}

我们可以通过adb命令查看这个变量的值,需要root权限。
adb root
adb shell service call SurfaceFlinger 1013

执行结果:
Result: Parcel(00002338 '8#..')

FPS 的计算方法:
在 t1 时刻获取 mPageFlipCount 的数值 v1,在在 t2时刻获取 mPageFlipCount 的数值 v2。

FPS 的计算公式:FPS = (v2 - v1) / (t2 - t1);

上面adb命令实际调用过程:

status_t SurfaceFlinger::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    ......
    case 1013: {
        Mutex::Autolock _l(mStateLock);
        sp<const DisplayDevice> hw(getDefaultDisplayDevice());
        reply->writeInt32(hw->getPageFlipCount());
        return NO_ERROR;
    }
    ......
}

在onTransact方法中还包含有其他的case,比如adb shell service call SurfaceFlinger 1002:打开屏幕更新提示,对应着手机Developer options中的Show screen updates选项。 android N