DirectFB 之 通过多Window实现多元素处理
图像
设计
采用多window的方式实现显示,因为每个window可以独立的属性,比如刷新频率,也是我们最关注的
示例
/**********************************************
* Author: younger.liucn@hotmail.com
* File name: dfbFont.c
* Description: dfbFont
* Version, Desc
* 1.1 Created
* 1.2 add config
**********************************************/ #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h> #include <time.h>
#include <sys/time.h>
#include <directfb.h> #include "dfbFont.h" /* config information */
#define DFB_LAYERID_USING 0
#define DFB_FONT_TYPE_1 "/home/younger/DFB/Font/data/decker.ttf" /*********************************************************
* log flags and func of debug and error infor.[Begin]
********************************************************/ #ifdef _DFB_DEBUG_
#define DFB_DEBUG(format, ...) do { \
printf("[BootAnimation:%4dL]DEBUG: "format, __LINE__, ##__VA_ARGS__); \
} while (0)
#else
#define DFB_DEBUG(format, ...) do {} while (0)
#endif #define DFB_NOTICE(format, ...) do { \
printf("[BootAnimation:%4dL]INFO: "format, __LINE__, ##__VA_ARGS__); \
} while (0) #define DFB_ERROR(format, ...) do { \
printf("[BootAnimation:%4dL]ERROR: "format, __LINE__, ##__VA_ARGS__); \
} while (0)
/*********************************************************
* log flags and func of debug and error infor.[End]
********************************************************/ /*********************************************************
* Data structure and Global variants [Begin]
********************************************************/
/* 使用directFB画图所需的DFB资源 */
struct DfbResDsc {
IDirectFB *dfb;
IDirectFBDisplayLayer *layer;
};
static struct DfbResDsc badsc; struct WinResDsc {
IDirectFBWindow *window;
IDirectFBSurface *surface;
};
static struct WinResDsc winText;
/* 如果位置值(OFFSET_X或OFFSET_Y)设置为-1,表示居中显示 */
#define WINDOW_TEXT_LEN_X (800)
#define WINDOW_TEXT_LEN_Y (100)
#define WINDOW_TEXT_OFFSET_X (-1)
#define WINDOW_TEXT_OFFSET_Y (500)
static char *testString = "Hello world! This is DirectFB!"; static struct WinResDsc winAnim;
/* 如果位置值(OFFSET_X或OFFSET_Y)设置为-1,表示居中显示 */
#define WINDOW_ANIM_LEN_X (200)
#define WINDOW_ANIM_LEN_Y (200)
#define WINDOW_ANIM_OFFSET_X (-1)
#define WINDOW_ANIM_OFFSET_Y (200) /* config information */
#define ANIM_IMAGES_COUNT 48
/* support png, jpg */
#define ANIM_IMAGE_FORMAT "png"
#define ANIM_FILE_NAME_MAX_SIZE 255
#define ANIM_IMG_DEFAULT_WIDTH 186
#define ANIM_IMG_DEFAULT_HEIGHT 186
#define ANIM_IMG_DEFAULT_FPS 10
#define ANIM_MAX_RUNNING_MTIME (20000) #define ANIM_DEFAULT_LOGO_PATH "/home/liuyiy/DFB/FontAnim/data/images" static IDirectFBSurface *imgSfc[ANIM_IMAGES_COUNT];
/*********************************************************
* Data structure and Global variants [End]
********************************************************/ /* 初始化/释放资源dfb/layer [Begin] */
void freeResources()
{
/* Release the layer. */
if (badsc.layer)
badsc.layer->Release(badsc.layer); badsc.dfb->Release(badsc.dfb); return ;
} static void initResources(int argc, char **argv)
{
DFBResult ret;
badsc.dfb = NULL;
IDirectFB *dfb = NULL; /* 初始化DirectFB */
DirectFBInit(&argc, &argv);
DirectFBCreate(&dfb);
if (!dfb) {
DFB_ERROR("directfb interface is NULL\n");
return ;
}
badsc.dfb = dfb; /* 初始化 display layer:其中DFB_LAYERID_USING设置为0.*/
ret = badsc.dfb->GetDisplayLayer(badsc.dfb, DFB_LAYERID_USING, &(badsc.layer));
if(ret != (DFBResult)DFB_OK) {
DFB_ERROR("Get layer(%d) failed!\n", DFB_LAYERID_USING);
goto fail;
} else {
DFB_DEBUG("Get layer(%d) independently.\n", DFB_LAYERID_USING);
} return ;
fail:
freeResources();
return ;
}
/* 初始化/释放资源dfb/layer [End] */ /* 初始化/释放资源WinResDsc [Begin] */
static void deinitWinRes(struct WinResDsc *winres)
{ winres->surface->SetColor(winres->surface, 0, 0, 0, 0);
winres->surface->Clear(winres->surface, 0, 0, 0, 0);
winres->surface->Flip(winres->surface, NULL, DSFLIP_WAITFORSYNC); /* Release the window's surface. */
if(winres->surface)
winres->surface->Release(winres->surface);
/* Release the window. */
if (winres->window)
winres->window->Release(winres->window); return ;
} static void initWinResPercent(struct WinResDsc *winres,
int window_offset_x,
int window_offset_y,
int window_len_x,
int window_len_y
)
{
DFBResult ret;
IDirectFBWindow *window = NULL;
IDirectFBSurface *surface = NULL;
DFBWindowDescription desc;
DFBDisplayLayerConfig config; /* 获取display layer的配置,. */
badsc.layer->GetConfiguration(badsc.layer, &config); /* 设置window参数,并创建Window */
desc.flags = (DFBWindowDescriptionFlags)(DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS | DWDESC_OPTIONS);
DFB_NOTICE("Layer Screen width %d, height %d !\n", config.width, config.height);
/* 固定window在layer的中位置 */
if (-1 == window_offset_x) {
desc.posx = (config.width - window_len_x) / 2;
} else {
desc.posx = window_offset_x;
}
if (-1 == window_offset_y) {
desc.posy = (config.height - window_len_y) / 2;
} else {
desc.posy = window_offset_y;
}
desc.width = window_len_x;
desc.height = window_len_y;
desc.caps = (DFBWindowCapabilities)(DWCAPS_NODECORATION);
desc.options = (DFBWindowOptions) (DWOP_GHOST);
ret = badsc.layer->CreateWindow(badsc.layer, &desc, &window);
if(ret != (DFBResult)DFB_OK) {
DFB_ERROR("Create window failed!\n");
return ;
} /* 设置透明度 */
ret = window->SetOpacity(window, 0xFF);
if(ret != (DFBResult)DFB_OK) {
DFB_ERROR("SetOpacity failed!\n");
window->Release(window);
return ;
} /* 获取window的surface. */
ret = window->GetSurface(window, &surface);
if(ret != (DFBResult)DFB_OK) {
DFB_ERROR("GetSurface failed!\n");
return ;
}
/*若不执行clear,则可能出现花屏*/
surface->SetColor(surface, 0, 0, 0, 0);
surface->Clear(surface, 0, 0, 0, 0);
surface->Flip(surface, NULL, DSFLIP_WAITFORSYNC);
winres->window = window;
winres->surface = surface;
return ;
}
/* 初始化/释放资源WinResDsc [End] */ /* 绘制字符串 */
static void flipText(char* str) {
int width = 0, height = 0;
IDirectFBFont* font = NULL;
DFBFontDescription font_desc;
IDirectFBSurface *surface = winText.surface; surface->GetSize(surface, &width, &height); /* font init */
font_desc.flags = DFDESC_HEIGHT;
font_desc.height = height / 2;
badsc.dfb->CreateFont(badsc.dfb, DFB_FONT_TYPE_1, &font_desc, &font); surface->Clear(surface, 0x0, 0x0, 0x0, 0xff);
surface->SetFont(surface, font);
/* 设置前景颜色 */
surface->SetColor(surface, 0x00, 0xFF, 0x00, 0xFF);
surface->DrawString(surface, str, strlen(str), width / 2, height / 2, DSTF_CENTER);
/* 变换、更新surface buffer */
surface->Flip(surface, NULL, DSFLIP_WAITFORSYNC);
return ;
} /* 绘制动画 [Begin] */
static inline int checkFileExist(const char *filename)
{
if((access(filename, R_OK)) != -1)
return 1; return 0;
}
static int doLoadImg(const char *filename,
IDirectFBSurface **surface,
unsigned int *width,
unsigned int *height)
{
int ret;
IDirectFB *dfb = badsc.dfb;
DFBSurfaceDescription img_dsc;
IDirectFBImageProvider *provider = NULL; if(NULL == surface || NULL == filename) {
DFB_ERROR("doLoadImg() failed for %d.\n", -EINVAL);
return -EINVAL;
} DFB_DEBUG("doLoadImg() entry:%s .\n", filename);
/* 检查图片是否存在 */
if(!checkFileExist(filename)) {
DFB_ERROR("file %s does not exist.\n", filename);
return -EINVAL;
} /* 将要显示的图片及其相关信息保存在一个image provider中 */
ret = dfb->CreateImageProvider(dfb, filename, &provider);
if(ret) {
DFB_ERROR("CreateImageProvider() for %s failed %d.\n", filename, ret);
return ret;
} /* 将保存在provider中的图片信息提取出来,存于surface description中 */
ret = provider->GetSurfaceDescription(provider, &img_dsc);
if(ret) {
DFB_ERROR("GetSurfaceDescription() for %s failed %d.\n",
filename, ret);
provider->Release(provider);
return ret;
} /* 根据surface description创建surface,尺寸与图片大小完全一致 */
ret = dfb->CreateSurface(dfb, &img_dsc, surface);
if(ret) {
DFB_ERROR("CreateSurface() for %s failed %d.\n", filename, ret);
provider->Release(provider);
return ret;
} /* 将图片呈递给刚才建立的logo平面,如果大小不一致,则进行缩放 */
ret = provider->RenderTo(provider, *surface, NULL);
if(ret) {
DFB_ERROR("RenderTo() for %s failed %d.\n", filename, ret);
(*surface)->Release(*surface);
provider->Release(provider);
return ret;
} /* Return width / height? */
if(width) {
*width = img_dsc.width;
}
if(height){
*height = img_dsc.height;
} /* release provider */
provider->Release(provider); DFB_DEBUG("doLoadImg() exit.\n");
return ret;
} /* 释放图片资源 */
static void deinitImages()
{
int i = 0;
for (i = 0; i < ANIM_IMAGES_COUNT; i++) {
if (imgSfc[i]) {
imgSfc[i]->Release(imgSfc[i]);
} else {
break;
}
}
return ;
}
/* 初始化图片资源 */
static int initImages()
{
int ret = 0, i = 0;
char filename[ANIM_FILE_NAME_MAX_SIZE];
IDirectFBSurface *tmp_sfc = NULL; for (i = 0; i < ANIM_IMAGES_COUNT; i++) {
imgSfc[i] = NULL;
} for (i = 0; i < ANIM_IMAGES_COUNT; i++) {
tmp_sfc = NULL;
memset(filename, 0x0, sizeof(filename));
snprintf(filename, ANIM_FILE_NAME_MAX_SIZE,
"%s/%02d.%s", ANIM_DEFAULT_LOGO_PATH, i, ANIM_IMAGE_FORMAT);
ret = doLoadImg(filename, &tmp_sfc, NULL, NULL);
if (ret != 0) {
goto bail;
}
imgSfc[i] = tmp_sfc;
} return 0;
bail:
deinitImages();
return -1;
} static void fillDFBSurface(
IDirectFBSurface *primary_sfc,
IDirectFBSurface *img_sfc,
int x, int y)
{
primary_sfc->Clear(primary_sfc, 0, 0, 0, 255);
/*
* blit即将两张位图(即thiz和source)按拉操作的方法组合成一张图片。
* 在DirectFB中,其定义的动作也是合理的:将img_sfc blit到primary_sfc上去,
* 两个平面上的内容会产生叠加
*/
primary_sfc->Blit(primary_sfc, img_sfc, NULL, x, y);
/* 变换、更新surface buffer */
primary_sfc->Flip(primary_sfc, NULL, DSFLIP_WAITFORSYNC); return ;
} /* 获取b与a的时间差,单位:毫秒 */
static unsigned long deltaMsecs(struct timespec *a,
struct timespec *b)
{
long delta_secs = 0, delta_msecs = 0; if(a->tv_sec < b->tv_sec ||
(a->tv_sec == b->tv_sec && a->tv_nsec < b->tv_nsec)) {
return 0;
} delta_secs = a->tv_sec - b->tv_sec;
delta_msecs = (a->tv_nsec - b->tv_nsec) / 1000000;
while(delta_msecs < 0) {
delta_secs--;
delta_msecs += 1000;
} return delta_secs * 1000 + delta_msecs;
} static void doAnimation()
{
int ret, i;
struct timespec before_draw, after_draw;
unsigned long elapsed_msec, total_msec;
IDirectFBSurface *primary = winAnim.surface;
unsigned long interval = (1000 / ANIM_IMG_DEFAULT_FPS); if (initImages()) {
DFB_ERROR("Init images failed!\n");
return ;
} DFB_NOTICE("Animation start ...\n");
total_msec = 0;
i = 0;
do {
if(i >= ANIM_IMAGES_COUNT) {
i = 0;
} clock_gettime(CLOCK_MONOTONIC, &before_draw);
fillDFBSurface(primary, imgSfc[i],
0,0);
clock_gettime(CLOCK_MONOTONIC, &after_draw);
/*
* 获取画图前后两次的时间差elapsed_msec
* 如果elapsed_msec>interval,则不再休眠
* 否则休眠interval-elapsed_msec
*/
elapsed_msec = deltaMsecs(&after_draw, &before_draw);
if(elapsed_msec < interval) {
usleep((interval - elapsed_msec) * 1000);
total_msec += interval;
} else {
total_msec += elapsed_msec;
}
DFB_DEBUG("elapsed %lu ms \n",
elapsed_msec < interval ? interval : elapsed_msec);
if(total_msec >= ANIM_MAX_RUNNING_MTIME) {
DFB_NOTICE("Stopped by Timeout(%lu).\n", total_msec);
break;
} i++;
} while(1); out:
DFB_NOTICE("Animation exit with black screen...\n");
deinitImages(); return ;
}
/* 绘制动画 [End] */ static void doShow()
{
DFB_NOTICE("Text start ...\n");
flipText(testString);
doAnimation(); return ;
} int main(int argc, char **argv)
{
DFB_NOTICE("Animation entry.\n");
initResources(argc, argv);
initWinResPercent(&winText,
WINDOW_TEXT_OFFSET_X, WINDOW_TEXT_OFFSET_Y,
WINDOW_TEXT_LEN_X, WINDOW_TEXT_LEN_Y);
initWinResPercent(&winAnim,
WINDOW_ANIM_OFFSET_X, WINDOW_ANIM_OFFSET_Y,
WINDOW_ANIM_LEN_X, WINDOW_ANIM_LEN_Y);
doShow();
deinitWinRes(&winText);
deinitWinRes(&winAnim);
freeResources(); DFB_NOTICE("Animation exit.\n");
return 0;
}
DirectFB 之 通过多Window实现多元素处理的更多相关文章
- WPF 远程显示原图 当前主页面 工具栏 一个Window页面的元素适用一个效果
http://www.jb51.net/article/98384.htm 1.wpf远程显示原图: Stretch="Fill" + ; 主要是因为那个950和650,据显示位置 ...
- DirectFB、Layer、Window、Surface之间关系
层(Layers) 表示一块儿独立的图像缓冲区.大多数的嵌入式设备都有多个层.他们由硬件使用合适的alpha值来blending,然后显示. 表面 (Surface) 用来保存像素数据的保留内存区域. ...
- C# 利用 DbUp 通过多个SQL Script文件完成对数据库的更新
详细流程请参考(本人测试过,很好用): http://dbup.github.io/ 配置截图: 程序如下: static int Main(string[] args) { var connecti ...
- SQL 存储过程 通过多个ID更新数据 分类: SQL Server 2014-12-08 16:08 299人阅读 评论(0) 收藏
下面举个例子说明: 我想让一部分品牌的名称(即Brand_Name)后面加上1,Brand_ID是主键,sql语句很容易实现,但是存储过程如何写呢? 错误写法如下: //*************** ...
- CSS设计模式之三权分立模式篇
分类: Html/CSS | 转载请注明: 出自 海玉的博客 本文地址: http://www.hicss.net/separation-of-powers-model-in-css-design-p ...
- 从div盒子模型谈如何写可维护的css代码(转)
市面上我们常常会看到各种各样的设计模式书籍,Java设计模式.C#设计模式.Ruby设计模式等等.在众多的语言设计模式中我唯独找不到关于CSS设计模式的资料,即使在网上找到类似内容,细细一看之下才发觉 ...
- CSS设计模式之三权分立模式篇 ( 转)
转自 海玉的博客 市面上我们常常会看到各种各样的设计模式书籍,Java设计模式.C#设计模式.Ruby设计模式等等.在众多的语言设计模式中我唯独找不到关于CSS设计模式的资料,即使在网上找到类似内容, ...
- Flink之Window Operation
目录 Configuring Time Characteristics Process Functions Window Operators Applying Functions on Windows ...
- 彻底搞清Flink中的Window
窗口 在流处理应用中,数据是连续不断的,因此我们不可能等到所有数据都到了才开始处理.当然我们可以每来一个消息就处理一次,但是有时我们需要做一些聚合类的处理,例如:在过去的1分钟内有多少用户点击了我们的 ...
随机推荐
- Servlet 与 Ajax 交互一直报status=parsererror
原因:servlet 返回的数据不是 Json 格式 1.JS代码为: var jsonStr = {'clusterNum':2,'iterationNum':3,'runTimes':4}; $. ...
- click和onclick本质的区别
原生javascript的click在w3c里边的阐述是DOM button对象,也是html DOM click() 方法,可模拟在按钮上的一次鼠标单击. button 对象代表 HTML 文档中的 ...
- NIO(二、Buffer)
目录 NIO(一.概述) NIO(二.Buffer) Buffer 前文讲了NIO与IO的区别,那么这一章开始讲述NIO下核心类 - Buffer类 上一章就说过,NIO的核心包括三个部分:通道(Ch ...
- SQL AlawaysOn 之二:添加组织和域用户
1.在管理工具打开Active Directory 用户和计算机 2.在域控制器名称下面右键 选择 新建--组织单位, 3.输入组织名定,点确定 4.在组织右键--新建--用户 5.输入用户信息,点 ...
- 实例PK(Vue服务端渲染 VS Vue浏览器端渲染)
Vue 2.0 开始支持服务端渲染的功能,所以本文章也是基于vue 2.0以上版本.网上对于服务端渲染的资料还是比较少,最经典的莫过于Vue作者尤雨溪大神的 vue-hacker-news.本人在公司 ...
- 10大支持移动“触摸操作”的JavaScript框架
摘要:移动开发行业的发展速度让人目不暇接,也在此大势之下,推出移动网站App成为开发者必经之路,如何让触屏设备 更易使用?如何让网站对触摸手势做出反应并使触摸更友好?所有这一切,皆因JavaScrip ...
- Linux中的sed命令
sed - stream editor for filtering and transforming text 流编辑器的过滤和转换文本 sed [-nerf] [动作] 参数: -i 修改源文件 危 ...
- swig编译GDAL的C#库时遇到的代码安全问题及解决方法
之前一直用的是别人编译好的gdal库开发,今天自己编译了gdal的2.0.0版本,踩了不少坑,但总算解决了. 编译方法主要参考http://blog.csdn.net/liminlu0314/arti ...
- API测试自动化——基于CDIF的SOA基本功能(实例篇)
今天我们通过一些实例来体验一下API的自动化测试,感受一下基于CDIF的SOA的一些基本功能. 传统的测试工具在测试一个API的时候,必须手动填写这个API所需要接收的所有信息,比如一个查询航班动态的 ...
- 【Egret】WebSocket 的使用说明
在Egret里可以使用WebSocket ,也可以使用socket.io 首先先深入了解一下 WebSocket 在Egret里的机制,看这篇文章: 主要讲解Egret里使用WebSocket和pro ...