RK3288 6.0 双屏异显,横屏+竖屏

RK3288 6.0 双屏异显,横屏+竖屏

由于是横屏+竖屏的组合,目前考虑两种实现方案。1.副屏存在黑边 2.对副屏内容进行拉伸。

默认情况下,我们设置的双屏初始rotation都为Surface.ROTATION_0,因此需将WSM中的updateRotationUncheckedLocked方法的该语句进行屏蔽。

        if (mRotateOnBoot) {
             mRotation = Surface.ROTATION_0;
             rotation = Surface.ROTATION_90;
        }     
                /* display portrait, force android rotation according to 90 */
        if("true".equals(SystemProperties.get("persist.display.portrait","false"))){
             rotation = Surface.ROTATION_90;
        }     
        //LQH 
        // rotation = Surface.ROTATION_0;
        /* display portrait end */

        // if("vr".equals(SystemProperties.get("ro.target.product","tablet")))
          // rotation = Surface.ROTATION_0;
        if (mRotation == rotation && mAltOrientation == altOrientation) {
            // No change.
            return false;
        }     


同时在该工程中集成了对于主屏和副屏初始角度控制的补丁,通过build.prop文件进行配置即可。

ro.sf.hwrotation=0                   主屏初始方向 (在./native/services/surfaceflinger/SurfaceFlinger.cpp进行赋值)
ro.orientation.einit=90             副屏初始方向
ro.same.orientation=false       主副屏orientaion是否相同
ro.rotation.external=false        副屏是否随主屏旋转

参考http://blog.csdn.net/ljp1205/article/details/53405641,了解Display框架及其初始化过程,主要对Display初始化时的参数进行调整。

该部分的代码在base/services/core/java/com/android/server/display/LocalDisplayAdapter.java的getDisplayDeviceInfoLocked()方法下完成:

 @Override
        public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
            if (mInfo == null) {
                SurfaceControl.PhysicalDisplayInfo phys = mDisplayInfos[mActivePhysIndex];
                mInfo = new DisplayDeviceInfo();
                mInfo.width = phys.width;
                mInfo.height = phys.height;
                mInfo.modeId = mActiveModeId;
                mInfo.defaultModeId = mDefaultModeId;
                mInfo.supportedModes = new Display.Mode[mSupportedModes.size()];
                for (int i = 0; i < mSupportedModes.size(); i++) {
                    DisplayModeRecord record = mSupportedModes.valueAt(i);
                    mInfo.supportedModes[i] = record.mMode;
                }
                mInfo.colorTransformId = mActiveColorTransformId;
                mInfo.defaultColorTransformId = mDefaultColorTransformId;
                mInfo.supportedColorTransforms =
                        new Display.ColorTransform[mSupportedColorTransforms.size()];
                for (int i = 0; i < mSupportedColorTransforms.size(); i++) {
                    mInfo.supportedColorTransforms[i] = mSupportedColorTransforms.valueAt(i);
                }
                mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos;
                mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos;
                mInfo.state = mState;
                mInfo.uniqueId = getUniqueId();

                // Assume that all built-in displays that have secure output (eg. HDCP) also
                // support compositing from gralloc protected buffers.
                if (phys.secure) {
                    mInfo.flags = DisplayDeviceInfo.FLAG_SECURE
                            | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
                }

                if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
                    final Resources res = getContext().getResources();
                    mInfo.name = res.getString(
                            com.android.internal.R.string.display_manager_built_in_display_name);
                    mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
                            | DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
                    if (res.getBoolean(com.android.internal.R.bool.config_mainBuiltInDisplayIsRound)
                            || (Build.HARDWARE.contains("goldfish")
                            && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
                        mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND;
                    }
                    mInfo.type = Display.TYPE_BUILT_IN;
                    mInfo.densityDpi = (int)(phys.density * 160 + 0.5f);
                    mInfo.xDpi = phys.xDpi;
                    mInfo.yDpi = phys.yDpi;
                    mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
                } else {
                    mInfo.type = Display.TYPE_HDMI;
                    mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
                    boolean noRotate = "0".equals(SystemProperties.get("ro.sf.hwrotation"));
                    if(noRotate && mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI){
                        if (SystemProperties.getBoolean("ro.rotation.external", false)) {
                            mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
                        }
                        String value = SystemProperties.get("ro.orientation.einit");
                        if ("0".equals(value)) {
                            mInfo.rotation = Surface.ROTATION_0;
                        } else if ("90".equals(value)) {
                            mInfo.rotation = Surface.ROTATION_90;
                        } else if ("180".equals(value)) {
                            mInfo.rotation = Surface.ROTATION_180;
                        } else if ("270".equals(value)) {
                            mInfo.rotation = Surface.ROTATION_270;
                        }
                    }
                    mInfo.name = getContext().getResources().getString(
                            com.android.internal.R.string.display_manager_hdmi_display_name);
                    mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
                    mInfo.setAssumedDensityForExternalDisplay(phys.width, phys.height);

                    // For demonstration purposes, allow rotation of the external display.
                    // In the future we might allow the user to configure this directly.
                    if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
                        mInfo.rotation = Surface.ROTATION_270;
                    }

                    // For demonstration purposes, allow rotation of the external display
                    // to follow the built-in display.
                    if (SystemProperties.getBoolean("persist.demo.hdmirotates", false)) {
                        mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
                    }
                }
            }
            return mInfo;
        }


最终显示的frame大小确定,在framework/native/service/surfaceflinger/DisplayDevice.cpp中

bool isHdmiScreen = mType == DisplayDevice::DISPLAY_EXTERNAL;
    if (isHdmiScreen) {
        int eInitOrientation = 0;
        bool isSfHwrotated = false;
        bool isSupportRotation = false;
        bool isPrimaryExternalSameOrientation = false;
        Rect newFrame = Rect(0,0,getWidth(),getHeight());
        Rect newFrameRotated = Rect(0,0,getHeight(),getWidth());
        float frameRatio = (float)frame.getWidth() / frame.getHeight();
        char value[PROPERTY_VALUE_MAX];
        property_get("ro.sf.hwrotation", value, "0");
        isSfHwrotated = atoi(value) != 0;
        property_get("ro.same.orientation", value, "false");
        isPrimaryExternalSameOrientation = !strcmp(value,"true");
        if(!isSfHwrotated) {
            property_get("ro.orientation.einit", value, "0");
            eInitOrientation = atoi(value) / 90;
            property_get("ro.rotation.external", value, "false");
            isSupportRotation = !strcmp(value,"true");
        }
        if (isSupportRotation && !isPrimaryExternalSameOrientation) {
            mClientOrientation = orientation;
            if (eInitOrientation % 2 == 1) {
                frame = frameRatio > 1.0 ? frame : newFrameRotated;
                ALOGE("%d,[%d,%d]",__LINE__,frame.getWidth(),frame.getHeight());
            } else {
                frame = frameRatio > 1.0 ? newFrame : frame;
                ALOGE("%d,[%d,%d]",__LINE__,frame.getWidth(),frame.getHeight());
            }
        } else if (isSupportRotation) {
            mClientOrientation = orientation;
            if (eInitOrientation % 2 == 1) {
                //frame = frameRatio > 1.0 ? frame : frame;
                ALOGE("%d,[%d,%d]",__LINE__,frame.getWidth(),frame.getHeight());
            } else {
                frame = frameRatio > 1.0 ? newFrame : newFrameRotated;
                ALOGE("%d,[%d,%d]",__LINE__,frame.getWidth(),frame.getHeight());
            }
        } else if (eInitOrientation % 2 != 0) {
            if (isPrimaryExternalSameOrientation) {
                //frame = frameRatio > 1.0 ? frame : frame;
                ALOGE("%d,[%d,%d]",__LINE__,frame.getWidth(),frame.getHeight());
            } else {
                //应该走的这里
                frame = frameRatio > 1.0 ? frame : newFrameRotated;
                ALOGE("%d,[%d,%d]",__LINE__,frame.getWidth(),frame.getHeight());
            }
        } else if (eInitOrientation % 2 == 0) {
            if (isPrimaryExternalSameOrientation) {
                frame = frameRatio > 1.0 ? newFrame : frame;
                ALOGE("%d,[%d,%d]",__LINE__,frame.getWidth(),frame.getHeight());
            } else {
                frame = frameRatio > 1.0 ? newFrame : frame;
                ALOGE("%d,[%d,%d]",__LINE__,frame.getWidth(),frame.getHeight());
            }
        } else {
            frame = frameRatio > 1.0 ? newFrame : frame;
            ALOGE("%d,[%d,%d]",__LINE__,frame.getWidth(),frame.getHeight());
        }
       
        ALOGE("update frame [%d,%d]",frame.getWidth(),frame.getHeight());
    }

根据具体情况进行配置,即可实现 双屏异显,横屏+竖屏,竖屏存在黑边的效果。在上面的补丁中,可对frame进行强制定义为副屏大小,则可以实现拉伸效果,填充黑边。

frame=Rect(0,0,getHeight(),getWidth());

但两块屏幕比例相差较大的情况下,拉伸显示的效果较差。

注:在设置中将g-sensor的旋转功能关闭,旋转对上述实现存在一定影响。


 
  






你可能感兴趣的:(RK3288 6.0 双屏异显,横屏+竖屏)