屏幕旋转180°调试过程

环境:

OS: Android4.1

Chipset:MSM8X25Q

mdp:3.03


背景:

屏幕反着打,需要显示旋转180°。

旋转方案:

1.   通过lcd driver ic直接让屏幕旋转。

2.   通过mdp旋转。

3.   Framework旋转。

 

调试过程:

方案1:

由于玻璃是单扫描方向,如果直接将driver IC反着扫,也就是说从IC

的memory里反着取数据,而玻璃还是正着扫描的话,结果就会产生

Tearing。此方案理论上直接行不通。

 

方案2:

       在mdp_ppp.c传参数flip_v+flip_h给mdp register,告诉ppp模块

在使用mdp composition旋转180°。

       考虑到GPU的composition会绕过mdp的ppp模块,因此将debug.composition.type

改成mdp,也就是想让系统全部用mdp去做composition.

       事实上,有些特殊情况,mdp是无法处理的,像alpha不是完全透明的,

旋转太复杂的等。这也可以从framework中的代码里的注释看到:

voidLayer::setGeometry(hwc_layer_t* hwcl)

{

~~snip

    //we can't do alpha-fade with the hwc HAL

    const State& s(drawingState());

    if (s.alpha < 0xFF) {

        hwcl->flags = HWC_SKIP_LAYER;         //表示用GPU做composition

    }

~~snip

    //we can only handle simple transformation

    if (finalTransform &Transform::ROT_INVALID) {

        hwcl->flags = HWC_SKIP_LAYER;

    } else {

        hwcl->transform = finalTransform;

}

~~snip

}

 因此,走GPU的时候又恢复成0°画面了,此方案也行不通了。


方案3:

       SF中提供了一个property来设置orientation,如90°,270°,

设置了180°之后,竖屏画面ok,不幸的是当进入横屏或者退出横屏的

时候,会瞬间显示成0°的画面。就是这个问题,花了我一周工作日时间才

搞定。下面是调试过程,中间省略N步…

a)   在进入或者退出横屏前过滤掉N帧。测试发现有时候进入横屏游戏卡的时候

这种方法是行不通的。

b)   设置debug.composition.type为GPU,无效。设置成mdp,然后将HWC_SKIP_LAYER

类型的都改成用mdp来处理,发现瞬间的画面虽然还是有,但是已经不是0°了,说明

跟这个flag有关啊!

c)   另外发现HWC_SKIP_LAYER和transform(坐标矩阵变换),也就是orientation有关联,

接着只能要细看SF的处理流程了,中间就是看一段觉得可疑就修改下加log,看和改参数之类的,无效。

d)   再者在composeSurfaces()中发现旋转的时候,要处理的layer其中总有一个的orientation和

另外的值不一样,比较了和不旋转180°的log,似乎也这样,就没太怀疑。

e)   从b)的过程能看出和GPU的处理有关,另外,网上有篇blog提到当旋转的时候,系统会先将屏幕

恢复成0°,然后再作旋转。可是它的codebase是GB,我使用的JB中并没有这部分,没办法,

继续往opengl中追。一直看到送给/dev/graphics/fb0也没发现有处理transform的地方。所以应该不是这个问题了。

f)    从log中发现LayerBase::setGeometry有不被Layer::setGeometry调用的状况,看来还有其他类型的layer创建了呀!

g) 跟踪发现,在旋转的时候居然创建了layerscrenshot这种Layer,而这种layer的纹理处理和一般的layer是不一样的,终于找到问题了!

 

改动如下:

LayerScreenshot.cpp

 

void LayerScreenshot::initTexture(GLfloat u, GLfloat v) {
	ALOGE("LayerScreenshot::initTexture");
    glBindTexture(GL_TEXTURE_2D, mTextureName);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

#ifndef  SF_ROTATION_180
    mTexCoords[0] = 0;         mTexCoords[1] = v;
    mTexCoords[2] = 0;         mTexCoords[3] = 0;
    mTexCoords[4] = u;         mTexCoords[5] = 0;
    mTexCoords[6] = u;         mTexCoords[7] = v;
#else
    mTexCoords[0] = u;         mTexCoords[1] = 0;
    mTexCoords[2] = u;         mTexCoords[3] = v;
    mTexCoords[4] = 0;         mTexCoords[5] = v;
    mTexCoords[6] = 0;         mTexCoords[7] = 0;
#endif
	
}

你可能感兴趣的:(子类_Display)