SurfaceFlinger旋转流程分析

chipset: MSM8X25Q

codebase: Android4.1

本文主要对SF(SurfaceFilnger)处理旋转事件的流程做个简单分析。GPU和mdp都可以用来旋转,文中对两者穿插说明。

 系统初始化会调用GraphicPlane::setDisplayHardware,此函数主要判断系统是否默认设置了rotation property值,如果有,则先保存下来。另外,SF是以transform其实就是以矩阵来作旋转计算的,计算方法以线性代数中的知识为依据:

void GraphicPlane::setDisplayHardware(DisplayHardware *hw)
{
    mHw = hw;

    // initialize the display orientation transform.
    // it's a constant that should come from the display driver.
    int displayOrientation = ISurfaceComposer::eOrientationDefault;
    char property[PROPERTY_VALUE_MAX];
	/*读取property*/
    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
        //displayOrientation
        switch (atoi(property)) {
		/*当然,你也可以仿照添加180°的旋转。*/
        case 90:
            displayOrientation = ISurfaceComposer::eOrientation90;
            break;
        case 270:
            displayOrientation = ISurfaceComposer::eOrientation270;
            break;
        }
    }


    const float w = hw->getWidth();
    const float h = hw->getHeight();
	/*根据宽和高以及orientation生成一个transform*/
    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
            &mDisplayTransform);
	/*90°或者270°时需要变换宽高。*/
    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
        mDisplayWidth = h;
        mDisplayHeight = w;
    } else {
        mDisplayWidth = w;
        mDisplayHeight = h;
    }

	/*保存当前全局旋转角度,意味着整个系统的显示都要根据整个值
来得出最后是否要旋转。如果为90°或者270°,那就是横屏,如果
是180°,画面就要反转180°。*/
    setOrientation(ISurfaceComposer::eOrientationDefault);
}

status_t GraphicPlane::setOrientation(int orientation)
{
    // If the rotation can be handled in hardware, this is where
    // the magic should happen.

    const DisplayHardware& hw(displayHardware());
    const float w = mDisplayWidth;
    const float h = mDisplayHeight;
    mWidth = int(w);
    mHeight = int(h);

    Transform orientationTransform;
    GraphicPlane::orientationToTransfrom(orientation, w, h,
            &orientationTransform);
    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
        mWidth = int(h);
        mHeight = int(w);
    }

    mOrientation = orientation;
	/*将orientation和h/w计算和得出一个全局的transform,这里的
相乘计算方法,就是利用矩阵来实现的。*/
    mGlobalTransform = mDisplayTransform * orientationTransform;
    return NO_ERROR;
}

由于整个系统一直默认旋转只是流程中一个坐标的特殊处理,不管系统上层是否请求旋转,如横屏游戏,sensor坐标变化,默认的旋转是一直会被处理的。

注意别把这两种旋转混淆了,默认旋转是一般情况下用户看到的显示效果,而上层apk

请求的旋转相对默认旋转是瞬间的。

         现在以上层发生旋转事件为例看下SF处理旋转的流程。

 上层调用SurfaceFlinger::setTransactionState设置当前角度变化了:

void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
        int orientation, uint32_t flags) {
    Mutex::Autolock _l(mStateLock);

uint32_t transactionFlags = 0;

/*当前坐标和要设置的坐标不相等表明要作旋转了!*/
    if (mCurrentState.orientation != orientation) {
        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
            mCurrentState.orientation = orientation;
            transactionFlags |= eTransactionNeeded;
        } else if (orientation != eOrientationUnchanged) {
            ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
                    orientation);
        }
    }

	/*设置旋转标志,SF处理的时候会用到。*/
    const size_t count = state.size();
    for (size_t i=0 ; i<count ; i++) {
        const Com
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值