graphics层横屏竖屏切换

 

<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:黑体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimHei; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:1 135135232 16 0 262144 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@黑体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:1 135135232 16 0 262144 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} h1 {mso-style-next:正文; margin-top:17.0pt; margin-right:0cm; margin-bottom:16.5pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:240%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:1; font-size:22.0pt; font-family:"Times New Roman"; mso-font-kerning:22.0pt;} h2 {mso-style-next:正文; margin-top:13.0pt; margin-right:0cm; margin-bottom:13.0pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:173%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:2; font-size:16.0pt; font-family:Arial; mso-fareast-font-family:黑体; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:489178463; mso-list-type:hybrid; mso-list-template-ids:-1904288614 338594570 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 {mso-level-text:%1,; mso-level-tab-stop:39.0pt; mso-level-number-position:left; margin-left:39.0pt; text-indent:-18.0pt;} @list l1 {mso-list-id:734666112; mso-list-type:hybrid; mso-list-template-ids:-1866804122 1008655198 248933464 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l1:level1 {mso-level-text:%1,; mso-level-tab-stop:18.0pt; mso-level-number-position:left; margin-left:18.0pt; text-indent:-18.0pt;} @list l1:level2 {mso-level-number-format:alpha-lower; mso-level-text:"%2/)"; mso-level-tab-stop:39.0pt; mso-level-number-position:left; margin-left:39.0pt; text-indent:-18.0pt;} @list l2 {mso-list-id:1088306772; mso-list-type:hybrid; mso-list-template-ids:557996062 2070169818 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l2:level1 {mso-level-text:%1,; mso-level-tab-stop:39.0pt; mso-level-number-position:left; margin-left:39.0pt; text-indent:-18.0pt;} @list l3 {mso-list-id:1767262004; mso-list-type:hybrid; mso-list-template-ids:-2076174484 968550278 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l3:level1 {mso-level-text:%1,; mso-level-tab-stop:60.0pt; mso-level-number-position:left; margin-left:60.0pt; text-indent:-18.0pt;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->

                                      Marvel Pxa310 graphics 层横屏竖屏切换

前言

              Video 的切换做完后,又开始了 graphics 层的旋转,也就是 X server 的旋转,它和 video 层并没有多大区别,差别就在于 x server RGB 的数据,而 video 层是 YUV 的,另外一方面 x server 的架构要远复杂于 mplayer 的架构;

思路

1,  Marvel pxa310 没有自己的 DSP 不过有一个图形加速,也就是 M2D ,这玩意的意思就是 memory to device ,实际上,多数用法都是从内存的一个地方按照一定的算法移动到 framebuffer 或者一个中间的内存,所以旋转的操作就交给 M2D 了;

2,  寻找一个合适的地方进行初始化,比如 M2D 内存的分配,数据结构的初始化等等;

3,  寻找一个合适的地方进行旋转的操作;

 

步骤

      

1,  理解 X server 的架构;

       它的架构非常的复杂,我准备专门讨论,这里只是简单的介绍一下,我们用的 xserver 是基于 Kdrive 的,而 kdrive 下面的设备依赖层是由 omap 目录来提供相应的接口实现的,名字是源于 Nokia ,但是实际上的设备是 marvel pxa310

       简单的说作为 kdrive driver 必须要实现下面的结构体里面的函数指针:

       KdCardFuncs omap_funcs = {

    .cardinit         = omap_card_init,

    .cardfini         = omap_card_fini,

    .scrinit          = omap_screen_init,

    .scrfini          = omap_screen_fini,

    .initScreen       = omap_init_screen,

    .finishInitScreen = omap_finish_init_screen,

    .createRes        = omap_create_resources,

    .dpms             = omap_dpms,

       };

      

      

       omap_screen_init 的目的就是要初始化 KdScreenInfo 这个数据结构,并提供给设备独立层使用;而 screen 层本身的实现要依赖于不同的 fb 层,所以它需要调用 omap_plane_enable 来进行层本身的初始化;因为 gcu 本身的操作是针对特定的层的,所以我决定就把 gcu 的初始化放在这里了,这里重要的是源和目的 buffer 的分配,目的肯定是 fb0 的地址,而源的话是通过 m2d 分配的连续地址空间,并虚拟成 xserver 所要的 screen memory_base 。这样对 xserver 来说它所有的操作都是针对这个虚假的 framebuffer ,然后我再适当的时候再把这个内容旋转到真正的 framebuffer 就可以了,相关代码如下:

         gcu->format = FORMAT_RGB;

       gcu->src_buf[0] = m2d_alloc_buffer(gcu->context, gcu->src_width[0], gcu->src_height[0], GCU_PXLFMT_RGB565);

       gcu->dst_buf[0] = m2d_create_buffer(gcu->context, gcu->dst_width[0], gcu->dst_height[0], GCU_PXLFMT_RGB565, plane_info->fb);

       这三行代码提供了一些信息给驱动:

1,  数据的格式是 RGB 的而不是 YUV 的;

2,  源数据的格式为 RGB565 的;

3,  目的地的数据格式也是 RGB565 的;

4,  源的数据几何形状为 800X480 的;

5,  目的地的几何形状为 480X800 的;

 

2,  理解 omap_plane_flush 相关函数;

       这个函数的作用其实是需要在 LCD 本身有帧缓存的情况要才有用的,所以对于我们的平台这个函数基本没有用;但这里被我选来作为旋转的地方;

       它的调用逻辑如下:

       graphics层横屏竖屏切换_第1张图片

3,  新的输出实现;

              剩下的就和 video 的旋转没有多大的区别了:

1,  设置操作源和目的地;

       m2d_set_srcbuf0(gcu->context, gcu->src_buf[0]);

    m2d_set_dstbuf2(gcu->context, gcu->dst_buf[0]);

2,  取得操作子 ;

       SET_OP_REGION_SRC0(&opr[0][0], 0, 0, 0, 0, src_width[0]/2, src_height[0]);

       SET_OP_REGION_SRC0(&opr[0][1], src_width[0]/2, 0, 0, dst_height[0]/2, src_width[0]/2, src_height[0]);     

       这里的 src_width[0] 就是 800 src_height[0]=480,dst_height[0]=800,dst_width[0]=480;

       其实也就是定义了两个矩形,一个是,

       起点 0 0 ;目的地 0 0 ;宽高: 400 480

       第二个是:

       起点 400,0 ;目的地 0,400 ;宽高: 400 480

       每次旋转一半,分两次旋转;

3,  调用 M2D 提供的操作函数

       m2d_rotate_blt(gcu->context, &gcu->opr[0][0], gcu->rotate_degree);

m2d_rotate_blt(gcu->context, &gcu->opr[0][1], gcu->rotate_degree);

这里需要设置旋转度数,为 1 2 3 ,当然我觉得多半是 1 或者 3 吧。

m2d_submit(gcu->context);

经过这个函数后操作命令已经被放到了环形命令区,等待硬件的操作;

 

总结

              主要的难点就是如何填这些参数,特别是旋转的宽度和高度在大于 497 的时候的设置;

              另外的难点在于,驱动提供的接口必须要提供成 800X480 的假象,这样才不会导致 xserver 在它的 framebuffer 管理里面把图像布局成 480X800 的;另外这个旋转的动作是不能告诉其它客户端程序的,比如 matchbox ,否则布局都会搞错;

              还有一个地方需要注意就是:

              plane_info->fix.line_length = 1600;

              否则 xserver 的布局也会出错,因为驱动传上来的值有可能是 480X2 的,如果是这样就需要强制设成 800X2

问答

1, 屏幕漆黑一片,怎么回事?

       从本质上说是没有把数据写到 framebuffer ;那么出现这个原因就可能是旋转的参数设置错误,也有可能是源和目的地设置错误;

2 ,屏幕出现了内容但是显得很小,还有很多地方重叠;

       这个可能是 xserver 的布局从问题导致的;可以通过一个简单的测试证明:

找一个 800X480 的图片直接 cat fb0 ,如果结果是正确的现实,那么说明 LCD 本身就是 800X480 的;如果出现正确显示了图片,但是每一行的后半部分不见了,那么就说明 LCD 480X800 的,但是驱动把行同步设置成了 800 ;如果结果是图像都有重叠,也就是一行的后半部分出现在了下一行,这样的话,说明驱动是正确的,只是源数据出错了,也就是 xserver 布局错了,很有可能是 line_length 设置错误的结果;

 

备注

       如有其它疑问请参阅 video 横屏竖屏切换 .doc

 

       作者: wylhistory;

         联系方式: [email protected]

 

 

 

 

你可能感兴趣的:(graphics层横屏竖屏切换)