improve gbm demo supports connector selection

This commit is contained in:
uziel 2024-11-05 11:33:01 +00:00
parent a6e5e145e3
commit 67d5b5737e
5 changed files with 288 additions and 150 deletions

View File

@ -6,9 +6,14 @@ build:
mkdir build
cmake -B build
t: compile
DISPLAY=:0 ./build/bin/TriangleEsDemo
x11: compile
sudo DISPLAY=:0 ./build/bin/TriangleEsX11Demo
gbm: compile
sudo ./build/bin/TriangleEsDemo
dt: compile
DISPLAY=:0 gdb ./build/bin/TriangleEsDemo
gbm-1: compile
sudo ./build/bin/TriangleEsDemo --conn=1
gbm-2: compile
sudo ./build/bin/TriangleEsDemo --conn=2

View File

@ -1,13 +1,47 @@
# 使用gpu opengles在drm上画图。
使用gbm实现opengles在drm上画图。
## 文件列表
| Syntax | Description |
| ----------- | ----------- |
| color_test.c | 直接刷写fb的像素值 |
| simple-es2.c | 使用GBM + pbuffer离屏渲染并写入文件 |
| triangle-es2.c | 使用GBM + surface渲染opengles到屏幕 |
| triangle-es2-x11.c | 使用X11 + xwin渲染opengles到屏幕 |
依赖
## 快捷指令
编译所有程序
```
make
```
编译并执行x11测试
```
make x11
```
编译并执行gbm测试
```
make gbm
```
编译并执行gbm测试,使用1号输出
```
make gbm-1
```
程序支持的参数:
```
Usage: ./build/bin/TriangleEsDemo --conn=[num] -w=[num] -h=[num] --help
Parameters:
--conn=[num] : choose connector index [num]
-w=[num] : choose a valid screen can set pixel width [num]
-w=[num] : choose a valid screen can set pixel height [num]
--help : show this message
```
## 依赖
libgbm-dev, libopengles-dev

View File

@ -46,18 +46,24 @@ int framebuffer_init(void) {
void full_screen(color_t color) {
printf("test write fb: 0x%08x\n", color);
int i;
int i, k;
int bpp = __g_vinfo.bits_per_pixel / 8;
unsigned char *p = __gp_frame;
for (i = 0; i < __g_vinfo.xres_virtual * __g_vinfo.yres_virtual; i++) {
for (i = 0; i < __g_vinfo.yres_virtual; i++) {
for (size_t j = 0; j < bpp; j++)
for (size_t k = 0; k < __g_vinfo.xres_virtual; k++)
{
p[j] = BYTE(color, j);
for (size_t j = 0; j < bpp; j++)
{
if ((i/20) & 0x1) {
p[j] = BYTE(color, j);
} else {
p[j] = 0;
}
}
p += bpp;
}
p += bpp;
}
}

View File

@ -175,17 +175,17 @@ static int matchConfigToVisual(EGLDisplay display, EGLint visualId, EGLConfig* c
{
EGLint id = 0;
EGLint suf_type;
int retId = -1;
int retId = 0;
for (int i = 0; i < count; ++i)
{
if (!eglGetConfigAttrib(display, configs[i], EGL_NATIVE_VISUAL_ID, &id))
continue;
// PRINT_CONFIG(display, configs[i], EGL_SURFACE_TYPE);
// PRINT_CONFIG(display, configs[i], EGL_MAX_SWAP_INTERVAL);
// PRINT_CONFIG(display, configs[i], EGL_MIN_SWAP_INTERVAL);
// printf("visualid: 0x%x, str:%.*s\n=====================\n", id, 4, &id);
// PRINT_CONFIG(display, configs[i], EGL_SURFACE_TYPE);
// PRINT_CONFIG(display, configs[i], EGL_MAX_SWAP_INTERVAL);
// PRINT_CONFIG(display, configs[i], EGL_MIN_SWAP_INTERVAL);
// printf("visualid: 0x%x, str:%.*s, 0x%x\n=====================\n", id, 4, &id);
if (id == visualId) {
retId = i;
break;
@ -195,6 +195,18 @@ static int matchConfigToVisual(EGLDisplay display, EGLint visualId, EGLConfig* c
return retId;
}
EGLDisplay x11_init() {
PFNEGLGETPLATFORMDISPLAYPROC egl_get_platform_display = eglGetProcAddress("eglGetPlatformDisplayEXT");
if (egl_get_platform_display) {
EGLDisplay disp = egl_get_platform_display(EGL_PLATFORM_X11_KHR, x_display, NULL);
if (disp) {
return disp;
}
}
printf("use eglGetDisplay instead of eglGetPlatformDisplay\n");
return eglGetDisplay((EGLNativeDisplayType)x_display);
}
int init(void)
{
EGLint count = 0;
@ -214,7 +226,7 @@ int init(void)
// 创建窗口
win = XCreateWindow ( // create a window with the provided parameters
x_display, root,
0, 0, 1000, 1000, 0,
0, 0, 1920, 1080, 0,
CopyFromParent, InputOutput,
CopyFromParent,
CWEventMask | CWOverrideRedirect,
@ -224,7 +236,8 @@ int init(void)
XStoreName ( x_display , win , "GL test"); // give the window a name
XSelectInput(x_display, win, StructureNotifyMask);
egldisplay = eglGetDisplay((EGLNativeDisplayType)x_display);
egldisplay = x11_init();
int majo, mino;
eglInitialize(egldisplay, &majo, &mino);
@ -386,20 +399,6 @@ void deinit(void)
eglReleaseThread();
}
int event_handle(void* arg) {
printf("start event loop\n");
while (1) {
XEvent xevent;
// XWindowEvent(x_display, win, StructureNotifyMask, &xevent);
XNextEvent(x_display, &xevent);
if (xevent.type == DestroyNotify) {
printf("DestroyNotify \n");
break;
}
}
return 0;
}
void handle_sig(int sig) {
printf("recieve sig: %d\n", sig);
g_stop = 1;
@ -432,9 +431,6 @@ int main (void)
eglQuerySurface(egldisplay, eglsurface, EGL_HEIGHT, &height);
printf("w=%d h=%d\n",width,height);
thrd_t thr;
thrd_create(&thr, event_handle, NULL);
long lastTime = GetNowMillis();
unsigned int framenum = 0;

View File

@ -14,6 +14,7 @@
#include <math.h>
#include <stdbool.h>
#include <threads.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
@ -41,19 +42,31 @@ Display *x_display;
Window win;
int device;
struct gbm_device *gbmDevice;
struct gbm_surface *gbmSurface;
struct gbm_bo * gbmBo;
int choose_conn_idx = -1;
int choose_w = -1;
int choose_h = -1;
int choose_conn_id = -1;
int choose_crtc_id = -1;
struct drm_mode_modeinfo choose_mod;
int fb_id;
int dumb_handle;
int g_stop;
#ifdef XORG_SHOW
#define USE_FORMAT 0x34325258
#else
#define USE_GBM_FORMAT GBM_FORMAT_XRGB8888
#define USE_GBM_FORMAT GBM_FORMAT_ARGB8888
#define USE_FORMAT USE_GBM_FORMAT
#endif
@ -71,13 +84,15 @@ GLuint g_hVertexLoc = 0;
GLuint g_hColorLoc = 1;
GLuint g_hVColor = 0;
#define MIN(x, y) ((x)>(y))?(y):(x)
#define ASSERT_EQ(exp1, exp2) do { auto e1 = (exp1);auto e2 = (exp2);\
if((e1) != (e2)) { \
printf("assert value: %p, %p\n", e1, e2); \
__assert_fail (#exp1 "==" #exp2, __FILE__, __LINE__, __ASSERT_FUNCTION); \
}}while(0)
//--------------------------------------------------------------------------------------
// Name: g_strVertexShader / g_strFragmentShader
// Desc: The vertex and fragment shader programs
@ -209,32 +224,109 @@ int modeset_import_fd(int dumb, int fd) {
}
int modeset_fd(int fd) {
int width = 1280;
int height = 1024;
int bpp = 32;
int buffer_v = mode_get_cap(fd, DRM_CAP_DUMB_BUFFER);
printf("buffer_v :0x%x\n", buffer_v);
int prime_v = mode_get_cap(fd, DRM_CAP_PRIME);
printf("prime_v :0x%x\n", prime_v);
int i;
// struct drm_mode_create_dumb create_dumb;
// memzero(&create_dumb);
// create_dumb.width = width;
// create_dumb.height = height;
// create_dumb.bpp = bpp;
// create_dumb.pitch = width * bpp/8;
// create_dumb.size = create_dumb.pitch * height;
// drm_ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
// dumb_handle = create_dumb.handle;
// printf("create_dumb handle:0x%x\n", dumb_handle);
struct drm_mode_card_res drm_mode_card_res;
memzero(&drm_mode_card_res);
drm_ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &drm_mode_card_res);
drm_mode_card_res.connector_id_ptr = calloc(drm_mode_card_res.count_connectors, sizeof(uint32_t));
drm_mode_card_res.crtc_id_ptr = calloc(drm_mode_card_res.count_crtcs, sizeof(uint32_t));
drm_mode_card_res.fb_id_ptr = calloc(drm_mode_card_res.count_fbs, sizeof(uint32_t));
drm_mode_card_res.count_encoders = 0;
// drm_mode_card_res.encoder_id_ptr = calloc(1, sizeof(uint32_t));
drm_ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &drm_mode_card_res);
// struct drm_mode_map_dumb map_dumb;
// map_dumb.handle = dumb_handle;
// drm_ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
printf("res count_connectors:%d, count_crtcs:%d, count_fbs:%d, crtc_ptr:0x%x\n",
drm_mode_card_res.count_connectors, drm_mode_card_res.count_crtcs, drm_mode_card_res.count_fbs, drm_mode_card_res.crtc_id_ptr);
for (i = 0; i < drm_mode_card_res.count_crtcs; i++) {
printf("crtc[%d]: %d\n", i, ((uint32_t*)drm_mode_card_res.crtc_id_ptr)[i]);
}
// int crtc_id = 0;
// if (choose_crtc_id != -1) {
// crtc_id = choose_crtc_id;
// printf("choose crtc[%d]: %d\n", choose_crtc_id, ((uint32_t*)drm_mode_card_res.connector_id_ptr)[crtc_id]);
// }
for (i = 0; i < drm_mode_card_res.count_connectors; i++) {
printf("conn[%d]: %d\n", i, ((uint32_t*)drm_mode_card_res.connector_id_ptr)[i]);
}
// printf("crtc data:[ %d]\n", ((uint32_t*)drm_mode_card_res.crtc_id_ptr)[crtc_id]);
// uint32_t crtc_id = ((uint32_t*)drm_mode_card_res.crtc_id_ptr)[crtc_id];
// uint32_t conn_id = ((uint32_t*)drm_mode_card_res.connector_id_ptr)[0];
uint32_t conn_id = 0;
if (choose_conn_idx == -1) {
choose_conn_idx = 0;
}
conn_id = ((uint32_t*)drm_mode_card_res.connector_id_ptr)[choose_conn_idx];
printf("choose conn[%d]: %d\n", choose_conn_idx, conn_id);
struct drm_mode_get_connector get_connector;
memzero(&get_connector);
get_connector.connector_id = conn_id;
drm_ioctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &get_connector);
printf("get_connector modes count: %d, encoder_id:%d\n", get_connector.count_modes, get_connector.encoder_id);
get_connector.connector_id = conn_id;
get_connector.count_encoders = 0;
get_connector.count_props = 0;
struct drm_mode_modeinfo *modes = calloc(get_connector.count_modes, sizeof(struct drm_mode_modeinfo));
get_connector.modes_ptr = modes;
drm_ioctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &get_connector);
if (get_connector.count_modes == 0) {
printf("conn[%d] has no any modes avalible!\n", conn_id);
return -1;
}
int take = 0;
for (i = 0; i < get_connector.count_modes; i++) {
printf("get_connector mode[%d] : '%s' -> (%d, %d, %d)\n", i, modes[i].name, modes[i].hdisplay, modes[i].vdisplay, modes[i].vrefresh);
// if (modes[i].hdisplay == width && modes[i].vdisplay == height) {
// printf("match gbm size (%d, %d)\n", width, height);
// break;
// }
if (choose_w != -1 && choose_h != -1 ) {
if (modes[i].hdisplay == choose_w && modes[i].vdisplay == choose_h)
take = 1;
} else if (choose_w != -1) {
if (modes[i].hdisplay == choose_w) {
choose_h = modes[i].vdisplay;
take = 1;
}
} else if (choose_h != -1) {
if (modes[i].vdisplay == choose_h) {
choose_w = modes[i].hdisplay;
take = 1;
}
} else {
choose_w = modes[i].hdisplay;
choose_h = modes[i].vdisplay;
take = 1;
}
if (take) {
memcpy(&choose_mod, &modes[i], sizeof(choose_mod));
break;
}
}
if (!take) {
printf("conn[%d] has no any modes avalible!", conn_id);
return -1;
}
// if (i == get_connector.count_modes) {
// printf("nothing match gbm size (%d, %d)\n", width, height);
// return -1;
// }
struct drm_mode_get_encoder get_encoder;
get_encoder.encoder_id = get_connector.encoder_id;
drm_ioctl(fd, DRM_IOCTL_MODE_GETENCODER, &get_encoder);
choose_conn_id = conn_id;
choose_crtc_id = get_encoder.crtc_id;
return 0;
}
@ -265,6 +357,7 @@ int gbm_mode_set() {
int width = gbm_bo_get_width(gbmBo);
int height = gbm_bo_get_height(gbmBo);
int bpp = gbm_bo_get_bpp(gbmBo);
int stride = gbm_bo_get_stride(gbmBo);
int i;
struct drm_mode_fb_cmd fb_cmd;
@ -273,67 +366,22 @@ int gbm_mode_set() {
fb_cmd.height = height;
fb_cmd.bpp = bpp;
fb_cmd.depth = 24;
fb_cmd.pitch = width * bpp/8;
fb_cmd.pitch = stride;
fb_cmd.handle = dumb_handle;
drm_ioctl(fd, DRM_IOCTL_MODE_ADDFB, &fb_cmd);
fb_id = fb_cmd.fb_id;
printf("add_fb fb_id: %d\n", fb_id);
printf("add_fb fb_id: %d, pitch: %d, stride:%d\n", fb_id, fb_cmd.pitch, stride);
struct drm_mode_card_res drm_mode_card_res;
memzero(&drm_mode_card_res);
drm_ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &drm_mode_card_res);
drm_mode_card_res.connector_id_ptr = calloc(1, sizeof(uint32_t));
drm_mode_card_res.crtc_id_ptr = calloc(1, sizeof(uint32_t));
drm_mode_card_res.fb_id_ptr = calloc(1, sizeof(uint32_t));
drm_mode_card_res.count_encoders = 0;
// drm_mode_card_res.encoder_id_ptr = calloc(1, sizeof(uint32_t));
drm_ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &drm_mode_card_res);
printf("res count_connectors:%d, count_crtcs:%d, count_fbs:%d, crtc_ptr:0x%x\n",
drm_mode_card_res.count_connectors, drm_mode_card_res.count_crtcs, drm_mode_card_res.count_fbs, drm_mode_card_res.crtc_id_ptr);
printf("crtc data:[ %d]\n", ((uint32_t*)drm_mode_card_res.crtc_id_ptr)[0]);
uint32_t crtc_id = ((uint32_t*)drm_mode_card_res.crtc_id_ptr)[0];
uint32_t conn_id = ((uint32_t*)drm_mode_card_res.connector_id_ptr)[0];
struct drm_mode_get_connector get_connector;
memzero(&get_connector);
get_connector.connector_id = conn_id;
drm_ioctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &get_connector);
printf("get_connector modes count: %d\n", get_connector.count_modes);
get_connector.connector_id = conn_id;
get_connector.count_encoders = 0;
get_connector.count_props = 0;
struct drm_mode_modeinfo *modes = calloc(get_connector.count_modes, sizeof(struct drm_mode_modeinfo));
get_connector.modes_ptr = modes;
drm_ioctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &get_connector);
for (i = 0; i < get_connector.count_modes; i++) {
printf("get_connector mode[%d] : '%s' -> (%d, %d, %d)\n", i, modes[i].name, modes[i].hdisplay, modes[i].vdisplay, modes[i].vrefresh);
if (modes[i].hdisplay == width && modes[i].vdisplay == height) {
printf("match gbm size (%d, %d)\n", width, height);
break;
}
}
if (i == get_connector.count_modes) {
printf("nothing match gbm size (%d, %d)\n", width, height);
return -1;
}
ioctl(fd, DRM_IOCTL_SET_MASTER);
struct drm_mode_crtc mode_crtc;
memzero(&mode_crtc);
mode_crtc.count_connectors = drm_mode_card_res.count_connectors;
mode_crtc.set_connectors_ptr = drm_mode_card_res.connector_id_ptr;
mode_crtc.crtc_id = crtc_id;
mode_crtc.count_connectors = 1;
mode_crtc.set_connectors_ptr = &choose_conn_id;
mode_crtc.crtc_id = choose_crtc_id;
mode_crtc.fb_id = fb_id;
mode_crtc.mode_valid = 1;
memcpy(&mode_crtc.mode, modes+i, sizeof(struct drm_mode_modeinfo));
memcpy(&mode_crtc.mode, &choose_mod, sizeof(struct drm_mode_modeinfo));
drm_ioctl(fd, DRM_IOCTL_MODE_SETCRTC, &mode_crtc);
// EGLImageKHR eglImage = eglCreateImageKHR(egldisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, gbmBo, NULL);
@ -348,19 +396,28 @@ int gbm_mode_set() {
EGLDisplay gbm_init(const char* devicePath) {
device = open(devicePath, O_RDWR | O_CLOEXEC);
modeset_fd(device);
if (modeset_fd(device)) {
return NULL;
}
gbmDevice = gbm_create_device(device);
if (!gbmDevice) {
printf("gbm device is null!\n");
}
// int gbm_fd = gbm_device_get_fd(gbmDevice);
// printf("gbm_fd: %d, card0 fd:%d\n", gbm_fd, device);
gbmSurface = gbm_surface_create(gbmDevice, 1280, 1024, USE_GBM_FORMAT, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
printf("init gbm with (%d,%d)\n", choose_w, choose_h);
gbmSurface = gbm_surface_create(gbmDevice, choose_w, choose_h, USE_GBM_FORMAT, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
if (!gbmSurface) {
printf("gbm surface is null!\n");
}
PFNEGLGETPLATFORMDISPLAYPROC egl_get_platform_display = eglGetProcAddress("eglGetPlatformDisplayEXT");
if (egl_get_platform_display) {
EGLDisplay disp = egl_get_platform_display(EGL_PLATFORM_GBM_KHR, gbmDevice, NULL);
if (disp) {
return disp;
}
}
printf("use eglGetDisplay instead of eglGetPlatformDisplay\n");
return eglGetDisplay(gbmDevice);
}
@ -401,10 +458,11 @@ static int matchConfigToVisual(EGLDisplay display, EGLint visualId, EGLConfig* c
if (!eglGetConfigAttrib(display, configs[i], EGL_NATIVE_VISUAL_ID, &id))
continue;
// PRINT_CONFIG(display, configs[i], EGL_SURFACE_TYPE);
// PRINT_CONFIG(display, configs[i], EGL_MAX_SWAP_INTERVAL);
// PRINT_CONFIG(display, configs[i], EGL_BUFFER_SIZE);
// PRINT_CONFIG(display, configs[i], EGL_STENCIL_SIZE);
// PRINT_CONFIG(display, configs[i], EGL_SAMPLE_BUFFERS);
// PRINT_CONFIG(display, configs[i], EGL_MIN_SWAP_INTERVAL);
// printf("visualid: 0x%x, str:%.*s\n=====================\n", id, 4, &id);
printf("visualid: 0x%x, str:%.*s\n=====================\n", id, 4, &id);
if (id == visualId) {
retId = i;
break;
@ -446,6 +504,11 @@ int init(void)
#else
egldisplay = gbm_init("/dev/dri/card0");
if (!egldisplay) {
printf("display init failed\n");
return -1;
}
printf("gbm init finish\n");
#endif
int majo, mino;
eglInitialize(egldisplay, &majo, &mino);
@ -459,8 +522,9 @@ int init(void)
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
// EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};
@ -474,7 +538,7 @@ int init(void)
int indexCfg = matchConfigToVisual(egldisplay, USE_FORMAT, configs, numConfigs);
printf("configs indexCfg: %d\n", indexCfg);
if (indexCfg < 0) {
indexCfg = 1;
indexCfg = 0;
}
eglconfig = configs[indexCfg];
@ -507,9 +571,9 @@ int init(void)
ASSERT_EQ(eglGetError(), EGL_SUCCESS);
// disable refresh rate limit
if (!eglSwapInterval || !eglSwapInterval(egldisplay, 0)) {
printf("Failed to set swap interval. Results may be bounded above by refresh rate.\n");
}
// if (!eglSwapInterval || !eglSwapInterval(egldisplay, 1)) {
// printf("Failed to set swap interval. Results may be bounded above by refresh rate.\n");
// }
print_glinfo();
@ -616,22 +680,6 @@ void deinit(void)
#endif
}
int event_handle(void* arg) {
printf("start event loop\n");
#ifdef XORG_SHOW
while (1) {
XEvent xevent;
// XWindowEvent(x_display, win, StructureNotifyMask, &xevent);
XNextEvent(x_display, &xevent);
if (xevent.type == DestroyNotify) {
printf("DestroyNotify \n");
break;
}
}
#endif
return 0;
}
void handle_sig(int sig) {
printf("recieve sig: %d\n", sig);
g_stop = 1;
@ -649,10 +697,60 @@ long GetNowMillis() {
return t.tv_sec*1000 + t.tv_usec/1000;
}
int main (void)
int parse_args(int argc, char* argv[]) {
int i=0;
char key[64];
char value[64];
int help=0;
for (i = 1; i < argc; i++) {
memset(key, 0, 64);
memset(value, 0, 64);
char* hyp = strchr(argv[i], '=');
if (hyp) {
strncpy(key, argv[i], MIN(hyp - argv[i], 63));
strncpy(value, hyp+1, 63);
} else {
strncpy(key, argv[i], 63);
}
// printf("key='%s', val='%s'\n", key, value);
if (!strcmp(key, "--conn")) {
choose_conn_idx = atoi(value);
}
if (!strcmp(key, "-w")) {
choose_w = atoi(value);
}
if (!strcmp(key, "-h")) {
choose_h = atoi(value);
}
if (!strcmp(key, "--help")) {
help = 1;
}
}
if (help) {
printf("Usage: %s --conn=[num] -w=[num] -h=[num] --help\n", argv[0]);
printf("Parameters:\n");
printf("\t--conn=[num] : choose connector index [num]\n");
printf("\t-w=[num] : choose a valid screen can set pixel width [num]\n");
printf("\t-w=[num] : choose a valid screen can set pixel height [num]\n");
printf("\t--help : show this message\n");
return 1;
}
return 0;
}
int main(int argc, char* argv[])
{
EGLint width = 600;
EGLint height = 600;
if (parse_args(argc, argv)) {
return 0;
}
EGLint width = 0;
EGLint height = 0;
int ret;
ret = init();
if (ret) {
@ -664,9 +762,6 @@ int main (void)
eglQuerySurface(egldisplay, eglsurface, EGL_HEIGHT, &height);
printf("w=%d h=%d\n",width,height);
thrd_t thr;
thrd_create(&thr, event_handle, NULL);
long lastTime = GetNowMillis();
unsigned int framenum = 0;
@ -675,15 +770,17 @@ int main (void)
eglSwapBuffers(egldisplay, eglsurface);
#ifndef XORG_SHOW
gbm_mode_set();
if (gbm_mode_set()) {
break;
}
#endif
//usleep(1*1000);
// usleep(1*1000);
framenum++;
if (!(framenum%100)) {
if (!(framenum%1000)) {
long now = GetNowMillis();
printf("frame num:%d, fps: %.1f\n", framenum, 100/((now-lastTime)/1000.0));
printf("frame num:%d, fps: %.1f, avg: %.1fms/p\n", framenum, 1000/((now-lastTime)/1000.0), (now-lastTime)/1000.0);
lastTime = now;
}
if (framenum > 100000) {