11、数码相框编写程序之MainPage显存管理与页面规划

上一节:10、数码相框编写程序之图标显示

下一节:12、数码相框编写程序之效果演示与代码讲解

在上一小节中实现了图标的显示,基本工作就准备好了。现在要来做的是显示下面这些页面:
在这里插入图片描述
先做主页面的显示:
在这里插入图片描述
我们要在显示main_page.c页面的三个图标出来,其实完成的就是我们之前每个页面的框架中的第一步显示页面,即完成如下截图部分的代码。
在这里插入图片描述

1、显存的分配和获取

在写这个代码之前,我们先来了解一下硬件上面是怎么回事:不管你用的是什么开发板,在我们的板子上面,2440 也好或者其他单板也好,里面会有 LCD 控 制 器 或 者 称 为 显 卡 ,外 面 接 有LCDLCD 控制器或者显卡上面对应要有显存。我们写显示器的驱动程序的时候会在内存里面分配一块所谓的显存,在我们这里称为 framebuffer。而 LCD 控制器或者显卡会从 framebuffer 里把数据取出来,发给 LCD。当我们想显示图片的话,直接把图片写到 framebuffer 里就可以了。

那我们写应用程序时怎么做呢?可以先打开驱动程序,得到这块framebuffer,然后就可以在这块显存里面直接写数据了。但是这样有缺点,如果你的程序运行得很慢,当你在 LCD 上面描图片的时候就会发现是一行一行很慢地描。就是说内容更新的很慢。

那我们到底一般会这么做呢?会先 malloc 一块内存,这块内存和 framebuffer 的大小是一样的。我们事先将要显示的图片数据全部放到这块内存里,弄好之后再一股脑 memcpyframebuffer 里面。这样 LCD 的图片就一下子更新好了。就不会出现逐行逐行或者逐块逐块地显示了。
在这里插入图片描述
所以针对于每个页面我们要先获得分配好的内存,然后设置里面的内容(主要是RGB数据部分和一些flag),然后写到我们实际的FB的显存中。

代码见:第 1 个 项 目 数 码 相 框 全 部 源 码 _ 图 片 _ 文 档 \ 源 码 ( 含 讲 课 过 程 中 即 时 编 写 的 文 档 )\12. 数 码 相 框 项 目\14.digital_photo_frame_8.4.2_图片_源码\14.digital_photo_frame_8.4.2 节_图片_源码\14.digial_photo_frame

应用程序事先分配好多块内存,用于显存:
在这里插入图片描述

1.1、构造显存链表的结构体

但是要考虑由于我们是嵌入式系统,针对于某些型号可能内存不够用,所以分配多个显存并非对应每种型号都适用的,所以我们要兼容这些型号,我们在构造显存的链表的时候,应该在最头部加上设备实际分配的fb的显存,对应这些内存不够用的设备,我们可以只使用这个显存链表的第一个成员即可,那么对于每个显存链表中结构体的成员应该如何考虑呢?(实际上也就是每个显存里面除了要保存RGB数据供实际的设备显存fb使用,还需要哪些表示来表示和区分这些其余的显存的,比如我现在有5个页面,也就是要分配5个显存,外加一个fb的实际设备的显存,假如我要显示main_page这个页面,我们首先要把main_page页面对应的显存里面对应的数据给fb就可以显示,但是要解决几个问题:怎么从显存链表里面找到main_page的显存呢?main_page里面的显存里面的RGB数据有没有准备好呢?等等),从如上几点考虑,我们的显存链表结构体构造成员如下:

  • 1、由于我们的目的是为了让所有的页面都对应分配一个显存,那样对应每个页面都会有对应的显存保存它的数据,我们之后用户操作返回,或者前进时,在每个页面的显存就不用再次去设置里面的内容,所以我们需要一个ID来标识每个显存,当用户去返回,或者跳转到另外的页面时,就可以直接利用原来的对应的显存来进行显示里面的数据,所以需要以ID来辨别显存;
  • 2、我们之前有提到过,在用户点击触摸之后,会有一段时间的间隙,我们利用这段间隙,把可能下次要准备的页面通过多线程的方式准备好,所以我们还需要一个成员用来判断这个显存是给主线程使用,还是prepare线程使用的,另外给个初始状态是未被使用的,所以需要一个显存的进程使用状态eVideoMemState
  • 3、我们所分配的显存中主要还是用来存放要显示的每一页的数据,我们需要定义一个标志位来表示这个显存里面的对应的数据的情况,,是已经有了数据,还是正在产生数据,还是空的,成员为ePicState
  • 4、最开始我们说了我们要在链表的头部加上一个实际LCD设备的fb的显存,但是我们如何标识出链表中的成员是不是fb的实际设备显存呢,用标志位bDevFrameBuffer表示;
  • 5、最主要的还是给每个显存里面提供要现实页面的RGB数据,也就是我们之前有定义的T_PixelDatas tPixelDatas
  • 6、最后就是要提供链表的指向下一个链表的成员struct VideoMem *ptNext

最终的结构体定义如下:
在这里插入图片描述
构造完显存的链表的结构体之后,我们就要实现这个链表,我们肯定要提供一个分配显存的函数int AllocVideoMem(int iNum),其次我们最终是要把链表里面的某一个显存成员memcpyfb实际的显存,所以我们还需要一个从链表中提取显存的函数,我们分配显存肯定能是在应用层最开始就配分的,比如说我们要分配5块显存,里面的具体内容在最开始分配的时候基本上都是一样的,比如ID都设置为0,当具体的页面比如main_page去取显存的时候,发现5个的ID都是0,就会随机取一块然后再具体分配ID和对应的页面的RGB数据给显存,下次相同的页面只需要再取到同样的ID的显存就可以了。

1.2、显存分配函数

提供一个分配显存的函数给最顶层使用,我们先来看分配显存的函数如何实现。

1、将我们自己分配的显存加入显存链表

针对于我们要分配的显存,我们肯定是用malloc来分配,那么要分配多大呢?要注意的是并非sizeof(T_VideoMem)这么大,T_VideoMem这个结构体只是用来标识我们的分配的显存的,里面虽然有定义对应页面的数据的指针,但sizeof(T_VideoMem)并没有包含页面对应数据的大小,所以还要分配对应页面数据的大小,其实我们的数据也就是我们LCD的分辨率的大小:sizeof(T_VideoMem) + LCD的数据大小

  • 1、获取LCD的分辨率
    要获得我们LCD的数据大小,就是要获取我们LCD的分辨率来计算的,我们之前的代码有获取x、y值,但要知道要分配多少个字节,还需要知道bpp参数,所以修改代码:
    在这里插入图片描述
    然后我们就可以获取bpp了:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值