4k 是假的吗?

测试发现,即使android 选择4k 输出, android 系统运行状态还是1080p, 所谓的4k是不是把 1080p 的framebuffer scale输出到 4k 显示器(新下载的11月版本)?
请问如何修改 kernel 分辨率,让 android 运行在 4k分辨率下?

一般FB 是FHD, HDMI 会scale到4k。播放ideo的是时候video输出video buffer直接 4K。无 scale 。
FB直接4K 没试过。内存会紧张吧。楼主有啥需求要FB 4K?

那一張4k2k的bmp檔,顯示出來不就失真了?

好吧 ,FB改4K的地方在kernel/arch/arm/boot/dts/lcd-box.dtsi
disp_timings: display-timings {
native-mode = <&timing1>;

改成 native-mode = <&timing2>;

4K是一个分辨率标准,4K还包括解码能力,可以播放4K高清的视频,至于Android和HDMI的buffer也可以改大

把 kernel/arch/arm/boot/dts/lcd-box.dtsi 修改为 改成 native-mode = <&timing2>; 编译出 resource.img, 更新后不是4k, 变成1280x720,4k 失败自动回到720p ?

把 cat /sys/class/graphics/fb0/disp_info 信息贴上来。

电视是4K吗?

烧写4k resource.img 后显示 /sys/class/graphics/fb0/disp_info

z-order:
  layer3_sel_win[3]
  layer2_sel_win[2]
  layer1_sel_win[1]
  layer0_sel_win[0]
win0:
  state:0,   fmt:ARGB888,   y_vir:320,   uv_vir:320
  xact: 320,   yact: 240,   dsp_x: 320,   dsp_y: 240,   x_st:   0,   y_st:   0
  y_h_fac:    4096,   y_v_fac:    4096,   uv_h_fac:    4096,   uv_v_fac:    4096
  y_addr: 0x00000000,   uv_addr:0x00000000
win1:
  state:1,   fmt:ARGB888,   y_vir:3840,   uv_vir:0
  xact:1280,   yact: 720,   dsp_x:3840,   dsp_y:2160,   x_st:   0,   y_st:   0
  y_h_fac:   21825,   y_v_fac:   21809,   uv_h_fac:    4096,   uv_v_fac:    4096
  y_addr: 0x10000000,   uv_addr:0x00000000
win2:
  state:0
  fmt:ARGB888
  area0:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
  area1:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
  area2:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
  area3:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
win3:
  state:0
  fmt:ARGB888
  area0:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
  area1:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0   addr:0x00000000
  area2:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
  area3:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000

马上 reboot 后变成

z-order:
  layer3_sel_win[3]
  layer2_sel_win[2]
  layer1_sel_win[1]
  layer0_sel_win[0]
win0:
  state:0,   fmt:ARGB888,   y_vir:320,   uv_vir:320
  xact: 320,   yact: 240,   dsp_x: 320,   dsp_y: 240,   x_st:   0,   y_st:   0
  y_h_fac:    4096,   y_v_fac:    4096,   uv_h_fac:    4096,   uv_v_fac:    4096
  y_addr: 0x00000000,   uv_addr:0x00000000
win1:
  state:1,   fmt:ARGB888,   y_vir:3840,   uv_vir:0
  xact:1920,   yact:1080,   dsp_x:3840,   dsp_y:2160,   x_st:   0,   y_st:   0
  y_h_fac:   32750,   y_v_fac:   32737,   uv_h_fac:    4096,   uv_v_fac:    4096
  y_addr: 0x13f48000,   uv_addr:0x00000000
win2:
  state:0
  fmt:ARGB888
  area0:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
  area1:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
  area2:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
  area3:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
win3:
  state:0
  fmt:ARGB888
  area0:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
  area1:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0   addr:0x00000000
  area2:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000
  area3:  state:0,  y_vir: 320,  dsp_x: 320,  dsp_y: 240,  x_st:   0,  y_st:   0,  addr:0x00000000

重启过程可以看到 屏幕中央的 android 图标 明显变小很多, 似乎4k 有效了, 但是进入android 后,第一次是720p 分辨率, 之后重启都是1080p,貌似android 系统拒绝了4k模式?

依照你的描述 应该是kernel已经生效了。android做了限制。
我在ubuntu上试过了。FB 4K是没问题。
这个需要android上层修改。可能比较麻烦点。
我先找找有没有解决方案吧。

android 本身限制应该没有,2013 年开始 android 就支持高分辨率了。现在一些平板手机超过1080p.
贴上log

[root@victor ApiDemos]# adb logcat|egrep '(384|192|128)0'
D/Displaymanager(  138): [display_list_add] display 0 iface HDMI connect 1 enable 1 mode 3840x2160p-30
D/Displaymanager(  138): [display_list_add] display 0 iface VGA connect 1 enable 0 mode 1920x1080p-60
D/Displaymanager(  138): read cfg: display=0,iface=4,enable=1,mode=3840x2160p-25
D/Displaymanager(  138): [readConfig] display 0 iface 4 connect 1 enable 1 mode 3840x2160p-25
D/Displaymanager(  138): read cfg: display=0,iface=3,enable=0,mode=1920x1080p-60
D/Displaymanager(  138): [readConfig] display 0 iface 3 connect 1 enable 0 mode 1920x1080p-60
D/Displaymanager(  138): [operateIfaceMode] property 0 iface 4 type 1 mode 3840x2160p-25
I/[Gralloc](  142): xres         = 3840 px
I/[Gralloc](  142): xres_virtual = 3840 px
D/hwcomposer(  142): set default fake ui size 1280x720
D/hwcomposer(  142): hwc_getDisplayAttributes disp = 0, width = 3840
D/BootAnimation(  447): DISPLAY,W-H: 3840-2160, ori: 0
D/CameraHal(  145): ParserDVConfig(667):  DV_720P(720p) resolution(1280x720) fps(10) support(0)
D/CameraHal(  145): ParserDVConfig(679):  DV_1080P(1080p) resolution(1920x1080) fps(10) support(0)
D/CameraHal(  145): ParserDVConfig(667):  DV_720P(720p) resolution(1280x720) fps(10) support(1)
D/CameraHal(  145): ParserDVConfig(679):  DV_1080P(1080p) resolution(1920x1080) fps(10) support(1)
D/SensorService(  470): Max socket buffer size 163840
I/DisplayManagerService(  470): Display device added: DisplayDeviceInfo{"Built-in Screen": 3840 x 2160, 60.000004 fps, density 160, 159.895 x 159.953 dpi, touch INTERNAL, rotation 0, type BUILT_IN, FLAG_DEFAULT_DISPLAY, FLAG_ROTATES_WITH_CONTENT, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS}
D/Environment(  470): screen raw size:3840,2160
D/Environment(  470): screen raw size:3840,2160
D/Environment(  470): screen raw size:3840,2160
D/Environment(  470): screen raw size:3840,2160
D/Environment(  470): screen raw size:3840,2160
D/qiuen   (  470): >>>CURRENT DISPLAY SIZE: 1920x1080
I/qiuen   (  470): FORCED DISPLAY SIZE: 1920x1080
I/ActivityManager(  470): Config changes=1df8 {1.0 ?mcc?mnc en_US ldltr sw1080dp w1920dp h1080dp 160dpi xlrg long land ?uimode ?night -touch -keyb/v/h -nav/h s.2}
I/ActivityManager(  470): Config changes=400 {1.0 ?mcc?mnc en_US ldltr sw1080dp w1920dp h1007dp 160dpi xlrg long land ?uimode ?night -touch -keyb/v/h -nav/h s.3}
I/ActivityManager(  470): Config changes=200 {1.0 ?mcc?mnc en_US ldltr sw1080dp w1920dp h1007dp 160dpi xlrg long land -touch -keyb/v/h -nav/h s.4}
D/Environment(  470): screen raw size:1920,1080
I/ActivityManager(  470): Config changes=60 {1.0 ?mcc?mnc en_US ldltr sw1080dp w1920dp h1007dp 160dpi xlrg long land -touch -keyb/v/h dpad/v s.5}
D/Environment(  470): screen raw size:1920,1080
D/Environment(  470): screen raw size:1920,1080
D/DisplayOutputManager(  470): setDisplaySize 0 1920 1080
D/Displaymanager(  138): switchFramebuffer display 0 new res is x 1920 y 1080
D/DisplayDeviceManagementService(  470): send cmd utils switchfb 0 1920x1080

貌似是进入ui 后 才强制到1080p.

额,我的意思是这个sdk上的android上层displaymanager 做了限制。不是说android原生的限制。

试一下在frameworks/base/services/java/com/android/server/wm/WindowManagerService.java

public void displayReady() {
        displayReady(Display.DEFAULT_DISPLAY);

        synchronized(mWindowMap) {
            final DisplayContent displayContent = getDefaultDisplayContentLocked();
            readForcedDisplaySizeAndDensityLocked(displayContent);
            mDisplayReady = true;
        }

        try {
            mActivityManager.updateConfiguration(null);
        } catch (RemoteException e) {
        }

        synchronized(mWindowMap) {
            mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_TOUCHSCREEN);
            configureDisplayPolicyLocked(getDefaultDisplayContentLocked());
        }

        try {
            mActivityManager.updateConfiguration(null);
        } catch (RemoteException e) {
        }
    }

注释掉
readForcedDisplaySizeAndDensityLocked(displayContent);
貌似就是这里强制成1080p了。

private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
      //$_rbox_$_modify_$_qiuen begin,add switch framebuffer size
	String displaypolicy = SystemProperties.get("persist.sys.display.policy", "manual");
    	if (displaypolicy.equals("auto") == true) {
    		Point ssize= new Point();
    		synchronized(displayContent.mDisplaySizeLock) {
    			ssize.x = displayContent.mBaseDisplayWidth;
    			ssize.y = displayContent.mBaseDisplayHeight;
    		}
            getCurScreenSize(Display.DEFAULT_DISPLAY, ssize);
	        Slog.d("qiuen", ">>>CURRENT DISPLAY SIZE: " + ssize.x + "x" + ssize.y);
	        synchronized(displayContent.mDisplaySizeLock) {
	        	if (displayContent.mBaseDisplayWidth != ssize.x
	                || displayContent.mBaseDisplayHeight != ssize.y) {
	                Slog.i("qiuen", "FORCED DISPLAY SIZE: " + ssize.x + "x" + ssize.y);
	                displayContent.mBaseDisplayWidth = ssize.x;
	                displayContent.mBaseDisplayHeight = ssize.y;
	        	}
	    	}
      //$_rbox_$_modify_$_end
        }else{
        String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
                Settings.Global.DISPLAY_SIZE_FORCED);
        if (sizeStr == null || sizeStr.length() == 0) {
            sizeStr = SystemProperties.get(SIZE_OVERRIDE, null);
        }
        if (sizeStr != null && sizeStr.length() > 0) {
            final int pos = sizeStr.indexOf(',');
            if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
                int width, height;
                try {
                    width = Integer.parseInt(sizeStr.substring(0, pos));
                    height = Integer.parseInt(sizeStr.substring(pos+1));
                    synchronized(displayContent.mDisplaySizeLock) {
                        if (displayContent.mBaseDisplayWidth != width
                                || displayContent.mBaseDisplayHeight != height) {
                            Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
                            displayContent.mBaseDisplayWidth = width;
                            displayContent.mBaseDisplayHeight = height;
                        }
                    }
                } catch (NumberFormatException ex) {
                }
            }
        }
	}

        String densityStr = Settings.Global.getString(mContext.getContentResolver(),
                Settings.Global.DISPLAY_DENSITY_FORCED);
        if (densityStr == null || densityStr.length() == 0) {
            densityStr = SystemProperties.get(DENSITY_OVERRIDE, null);
        }
        if (densityStr != null && densityStr.length() > 0) {
            int density;
            try {
                density = Integer.parseInt(densityStr);
                synchronized(displayContent.mDisplaySizeLock) {
                    if (displayContent.mBaseDisplayDensity != density) {
                        Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
                        displayContent.mBaseDisplayDensity = density;
                    }
                }
            } catch (NumberFormatException ex) {
            }
        }
    }
win1:
  state:1,   fmt:ARGB888,   y_vir:3840,   uv_vir:0
  xact:3840,   yact:2160,   dsp_x:3840,   dsp_y:2160,   x_st:   0,   y_st:   0
  y_h_fac:    4096,   y_v_fac:    4096,   uv_h_fac:    4096,   uv_v_fac:    4096
  y_addr: 0x13f48000,   uv_addr:0x00000000

楼上正解。亲测有效!

确实如此,那个 里面那个 getCurScreenSize 读 /sys/class/graphic/fb0/disp_info 过滤了 1080 以上的

测试发现只修改 getCurScreenSize 还不够,切换分辨率之后回不到4k,原来
frameworks/base/core/java/android/os/DisplayOutputManager.java 中 setMode 也限制了1080p
修改后切换分辨率回4k正常

                if (n <= 720){
                  m = 1280;
                  n = 720;
                } else if (n > 2160) {
                  m = 1920;
                  n = 1080;
                } else if ( (m==3840&&n==2160)|| (m==1920&&n==1080)||(m == 1680 && n == 1050) ||(m == 1600 && n == 900) || (m == 1440 && n == 900) || (m == 1366 && n == 768)|| (m == 1024 && n == 768)|| (m == 800 && n == 600)) {
                    //Oh no
                    ;
                } else {
                  m = 1280;
                  n = 720;
                }

有人试过Linux下HDMI输出2560x1080分辨率么?

ubuntu上hdmi输出4K (38402160)都没问题的。25601080应该也没问题的。改下驱动就可以的。楼上可以自己试下。

connet 发表于 2014-11-24 17:36
测试发现只修改 getCurScreenSize 还不够,切换分辨率之后回不到4k,原来
frameworks/base/core/java/andr …

前辈,我想在安卓系统里增加25601440的分辨率跟14402560分辨率,我有个VR眼镜必须指定这个分辨率才能点亮,我刚刚接触开发板这个东西,对安卓以前是一窍不通,能否指点一下增加以上两个分辨率的具体办法?感激不尽。

本帖最后由 萧瑶 于 2015-9-18 06:07 编辑

connet 发表于 2014-11-24 17:36
测试发现只修改 getCurScreenSize 还不够,切换分辨率之后回不到4k,原来
frameworks/base/core/java/andr …

cht2能否直接帮忙把原系统必须修改的两个地方的代码直接修改后提供一下我自己研究怎么去替换。因为以我现在的水平要直接自己编译代码的话距离还很遥远。