android屏幕旋转显示流程

PAD默认屏幕显示方向是竖着显示,改成默认横屏显示需要将屏幕的默认显示方向顺时针旋转90度.

android显示系统的核心是surfaceflinger,它为所有的应用程序提供显示服务,它能够将各种应用程序的2D,3D surface进行组合,合并最终得到的一个main surface数据送入framebuffer,显示的翻转和旋转也是由surfaceflinger完成的,我们大致分析下surfaceflinger的旋转流程:

1.surfaceflinger启动后首先进行初始化操作,设置surfaceflinger的相关属性并创建了DisplayDevice对象

[cpp]  view plain  copy
  1. void SurfaceFlinger::init() {  
  2. ...  
  3. #ifdef MTK_AOSP_ENHANCEMENT  
  4.     // make sure 3D init success  
  5.     if (mEGLContext == EGL_NO_CONTEXT)  
  6.     {  
  7.         ALOGE("FATAL: couldn't create EGLContext");  
  8.         delete mHwc;  
  9.         eglTerminate(mEGLDisplay);  
  10.         exit(0);  
  11.     }  
  12.   
  13.     // init properties setting first  
  14.     setMTKProperties();   //设置MTK相关属性  
  15. #else  
  16.     LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,  
  17.             "couldn't create EGLContext");  
  18. #endif  
  19. ...  
  20.     // initialize our non-virtual displays  
  21.     for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {  
  22.         DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);  
  23.         // set-up the displays that are already connected  
  24.         if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {  
  25.             // All non-virtual displays are currently considered secure.  
  26.             bool isSecure = true;  
  27.             createBuiltinDisplayLocked(type);  
  28.             wp<IBinder> token = mBuiltinDisplays[i];  
  29.   
  30.   
  31.             sp<IGraphicBufferProducer> producer;  
  32.             sp<IGraphicBufferConsumer> consumer;  
  33.             BufferQueue::createBufferQueue(&producer, &consumer,  
  34.                     new GraphicBufferAlloc());  
  35.   
  36.   
  37.             sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,  
  38.                     consumer);  
  39.             int32_t hwcId = allocateHwcDisplayId(type);  
  40.             sp<DisplayDevice> hw = new DisplayDevice(this,  //初始化各个DisplayDevice对象  
  41.                     type, hwcId, mHwc->getFormat(hwcId), isSecure, token,  
  42.                     fbs, producer,  
  43.                     mRenderEngine->getEGLConfig());  
  44.             if (i > DisplayDevice::DISPLAY_PRIMARY) {  
  45.                 // FIXME: currently we don't get blank/unblank requests  
  46.                 // for displays other than the main display, so we always  
  47.                 // assume a connected display is unblanked.  
  48.                 ALOGD("marking display %zu as acquired/unblanked", i);  
  49.                 hw->setPowerMode(HWC_POWER_MODE_NORMAL);  
  50.             }  
  51.             mDisplays.add(token, hw);  
  52.         }  
  53.     }  
  54. }  

setMTKProperties()中会设置surfaceflinger的相关属性:

[cpp]  view plain  copy
  1. void SurfaceFlinger::setMTKProperties(String8 &result) {  
  2. ...  
  3.     // get info for panel physical rotation  
  4.     property_get("ro.sf.hwrotation", value, "0");  
  5.     sPropertiesState.mHwRotation = atoi(value);  
  6.     snprintf(buffer, sizeof(buffer), "    ro.sf.hwrotation (mHwRotation): %d\n", sPropertiesState.mHwRotation);  
  7.     result.append(buffer);  
  8. ...  
  9. }  
此处会读取 ro.sf.hwrotation系统属性,这个系统属性决定了显示屏的初始旋转方向,并保存到全局变量sPropertiesState.mHwRotation中

2.DisplayDevice中会调用显示的旋转函数setProjection()

[cpp]  view plain  copy
  1. DisplayDevice::DisplayDevice(  
  2.         const sp<SurfaceFlinger>& flinger,  
  3.         DisplayType type,  
  4.         int32_t hwcId,  
  5.         int format,  
  6.         bool isSecure,  
  7.         const wp<IBinder>& displayToken,  
  8.         const sp<DisplaySurface>& displaySurface,  
  9.         const sp<IGraphicBufferProducer>& producer,  
  10.         EGLConfig config)(  
  11. <span style="font-family: Arial, Helvetica, sans-serif;">...  
  12. </span><pre code_snippet_id="1939821" snippet_file_name="blog_20161020_4_9852155" name="code" class="cpp">#ifdef MTK_AOSP_ENHANCEMENT  
  13.     mHwOrientation = DisplayState::eOrientationDefault;   //读取默认的显示屏方向  
  14.   
  15.   
  16.     // Name the display.  The name will be replaced shortly if the display  
  17.     // was created with createDisplay().  
  18.     switch (mType) {  
  19.         case DISPLAY_PRIMARY:  
  20.             mDisplayName = "Built-in Screen";  
  21. #ifdef MTK_AOSP_ENHANCEMENT  
  22.             switch (mFlinger->sPropertiesState.mHwRotation) {     //读取显示屏初始旋转方向  
  23.                 case 90:  
  24.                     mHwOrientation = DisplayState::eOrientation90;  
  25.                     break;  
  26.                 case 180:  
  27.                     mHwOrientation = DisplayState::eOrientation180;  
  28.                     break;  
  29.                 case 270:  
  30.                     mHwOrientation = DisplayState::eOrientation270;  
  31.                     break;  
  32.             }  
  33. #endif  
  34.             break;  
  35.         case DISPLAY_EXTERNAL:  
  36.             mDisplayName = "HDMI Screen";  
  37.             break;  
  38.         default:  
  39.             mDisplayName = "Virtual Screen";    // e.g. Overlay #n  
  40.             break;  
  41.     }  
  42.   
  43.     // initialize the display orientation transform.  
  44.     setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);  //设置显示屏初始旋转方向  
  45. }  
 
 

[cpp]  view plain  copy
  1. void DisplayDevice::setProjection(int orientation,  
  2.         const Rect& newViewport, const Rect& newFrame) {  
  3.     Rect viewport(newViewport);  
  4.     Rect frame(newFrame);  
  5.   
  6.     const int w = mDisplayWidth;  
  7.     const int h = mDisplayHeight;  
  8.   
  9.     Transform R;  
  10.     DisplayDevice::orientationToTransfrom(orientation, w, h, &R);  
  11.   
  12.     if (!frame.isValid()) {  
  13.         // the destination frame can be invalid if it has never been set,  
  14.         // in that case we assume the whole display frame.  
  15.         frame = Rect(w, h);  
  16.     }  
  17.   
  18.     if (viewport.isEmpty()) {  
  19.         // viewport can be invalid if it has never been set, in that case  
  20.         // we assume the whole display size.  
  21.         // it's also invalid to have an empty viewport, so we handle that  
  22.         // case in the same way.  
  23.         viewport = Rect(w, h);  
  24.         if (R.getOrientation() & Transform::ROT_90) {  
  25.             // viewport is always specified in the logical orientation  
  26.             // of the display (ie: post-rotation).  
  27.             swap(viewport.right, viewport.bottom);  
  28.         }  
  29.     }  
  30.   
  31.     dirtyRegion.set(getBounds());  
  32.   
  33.   
  34. #ifdef MTK_AOSP_ENHANCEMENT  
  35.     // for boot animation black screen issue  
  36.     if ((false == mFlinger->getBootFinished()) && (DISPLAY_PRIMARY == mType)) {  
  37.         ALOGI("[%s] clear DisplayDevice(type:%d) dirty region while booting",  
  38.             __FUNCTION__, mType);  
  39.   
  40.         dirtyRegion.clear();  
  41.     }  
  42. #endif  
  43.   
  44.     Transform TL, TP, S;  
  45.     float src_width  = viewport.width();  
  46.     float src_height = viewport.height();  
  47.     float dst_width  = frame.width();  
  48.     float dst_height = frame.height();  
  49.     if (src_width != dst_width || src_height != dst_height) {  
  50.         float sx = dst_width  / src_width;  
  51.         float sy = dst_height / src_height;  
  52.         S.set(sx, 0, 0, sy);  
  53.     }  
  54.   
  55.     float src_x = viewport.left;  
  56.     float src_y = viewport.top;  
  57.     float dst_x = frame.left;  
  58.     float dst_y = frame.top;  
  59.     TL.set(-src_x, -src_y);  
  60.     TP.set(dst_x, dst_y);  
  61.   
  62. #ifdef MTK_AOSP_ENHANCEMENT  
  63.     // need to take care of HW rotation for mGlobalTransform  
  64.     // for case if the panel is not installed align with device orientation  
  65.     if (DisplayState::eOrientationDefault != mHwOrientation) {      
  66.         DisplayDevice::orientationToTransfrom(  
  67.             (orientation + mHwOrientation) % (DisplayState::eOrientation270 + 1),  
  68.             w, h, &R);  
  69.     }  
  70. #endif  
  71.   
  72.     // The viewport and frame are both in the logical orientation.  
  73.     // Apply the logical translation, scale to physical size, apply the  
  74.     // physical translation and finally rotate to the physical orientation.  
  75.     mGlobalTransform = R * TP * S * TL;  
  76.   
  77.     const uint8_t type = mGlobalTransform.getType();  
  78.     mNeedsFiltering = (!mGlobalTransform.preserveRects() ||  
  79.             (type >= Transform::SCALE));  
  80.   
  81.     mScissor = mGlobalTransform.transform(viewport);  
  82.     if (mScissor.isEmpty()) {  
  83.         mScissor = getBounds();  
  84.     }  
  85.   
  86.     mOrientation = orientation;  
  87.     mViewport = viewport;  
  88.     mFrame = frame;  
  89. }  

接着调用DisplayDevice类的orientationToTransfrom()方法构造成一个变换矩阵R,然后得到mGlobalTransform这个全局变换矩阵,最后通过mGlobalTransform.transform()这个方法进行显示的旋转

[cpp]  view plain  copy
  1. status_t DisplayDevice::orientationToTransfrom(  
  2.         int orientation, int w, int h, Transform* tr)  
  3. {  
  4.     uint32_t flags = 0;  
  5.     switch (orientation) {  
  6.     case DisplayState::eOrientationDefault:  
  7.         flags = Transform::ROT_0;  
  8.         break;  
  9.     case DisplayState::eOrientation90:  
  10.         flags = Transform::ROT_90;  
  11.         break;  
  12.     case DisplayState::eOrientation180:  
  13.         flags = Transform::ROT_180;  
  14.         break;  
  15.     case DisplayState::eOrientation270:  
  16.         flags = Transform::ROT_270;  
  17.         break;  
  18.     default:  
  19.         return BAD_VALUE;  
  20.     }  
  21.     tr->set(flags, w, h);  
  22.     return NO_ERROR;  
  23. }  

这里调用Transform::set()方法设置矩阵,有兴趣可以深入分析


转自:https://blog.csdn.net/zqh2007/article/details/52873903

发布了129 篇原创文章 · 获赞 322 · 访问量 49万+

猜你喜欢

转载自blog.csdn.net/seek_0380/article/details/80537994