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