improve gbm demo supports connector selection
This commit is contained in:
parent
a6e5e145e3
commit
67d5b5737e
13
Makefile
13
Makefile
|
@ -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
|
38
README.md
38
README.md
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user