From 93432175cbf2b56cfc7138b26d7b6e19c4cb0510 Mon Sep 17 00:00:00 2001 From: "zhimin.liu" Date: Tue, 12 May 2026 18:49:07 +0800 Subject: [PATCH] feat(Ubuntu):Add Ubuntu compile and run/debug logic. --- clusterApp/Makefile_Ubuntu | 4 +- clusterApp/src/lib/InsGL.c | 209 +++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 2 deletions(-) diff --git a/clusterApp/Makefile_Ubuntu b/clusterApp/Makefile_Ubuntu index 1e7f762..ef6c49e 100644 --- a/clusterApp/Makefile_Ubuntu +++ b/clusterApp/Makefile_Ubuntu @@ -16,7 +16,7 @@ else CFLAGS += -O3 -fexpensive-optimizations endif -DEPS = -lpthread -lEGL -lGLESv2 -ldrm -lgbm -lfreetype -lcjson -ljpeg -lm -ldl -Wl,--library-path=$(TARGET_PATH_LIB),-rpath-link=$(TARGET_PATH_LIB) +DEPS = -lX11 -lpthread -lEGL -lGLESv2 -ldrm -lgbm -lfreetype -lcjson -ljpeg -lm -ldl -Wl,--library-path=$(TARGET_PATH_LIB),-rpath-link=$(TARGET_PATH_LIB) ## DEPS += /home/lst/workspace/jpeg/jpeg-9c/install/lib/libjpeg.a #DEPS += /home/user/zhimin/clusterApp/3psw/jpegsr9c/jpeg-9c/libjpeg.a #DEPS += /home/user/zhimin/packages/install/lib/libcjson.a @@ -42,7 +42,7 @@ CFLAGS += -Iinclude \ -I/home/lst/workspace/zlib/zlib_build/ \ -I/home/lst/workspace/libpng/libpng_build/ \ -I/home/user/zhimin/clusterApp/3psw/source_packages/build_install/ \ - -I/home/huaxu/develop/cluster/clusterApp_ubuntu/3psw/lpng1634 \ + -I/home/huaxu/develop/cluster/clusterAppUbuntu/3psw/lpng1634 \ -I/home/user/zhimin/clusterApp/3psw/source_packages/freetype-2.13.2/ \ -I/home/huaxu/develop/ICM-SOFT/D20/icm-code/cpu/app/insDavi2.0/3psw/freetype-2.9_MinGW/include/freetype2/ \ -I/usr/include/GL/ \ diff --git a/clusterApp/src/lib/InsGL.c b/clusterApp/src/lib/InsGL.c index bfd646b..b1db93e 100644 --- a/clusterApp/src/lib/InsGL.c +++ b/clusterApp/src/lib/InsGL.c @@ -1,3 +1,5 @@ +#ifndef COMPILE_IN_UBUNTU + #include #include @@ -867,3 +869,210 @@ void DeInitGL() } #endif // COMPILE_IN_WINDOWS } + +#else // UBUNUT 平台,使用 X11 + EGL + +#include +#include +#include +#include +#include +#include +#include +#include +#include "BaseTypes.h" + +static Display *x_display = NULL; +static Window x_window; +static EGLDisplay egl_dpy = EGL_NO_DISPLAY; +static EGLSurface egl_surf = EGL_NO_SURFACE; +static EGLContext egl_ctx = EGL_NO_CONTEXT; +static Bool egl_init_flg = INS_FALSE; +static int win_width = 0, win_height = 0; + +// 用于 FB1(第二屏,若不需要可保留为空实现) +static EGLDisplay egl_display_1 = EGL_NO_DISPLAY; +static EGLSurface eglsurface_fb1 = EGL_NO_SURFACE; +static EGLContext eglcontext_fb1 = EGL_NO_CONTEXT; +static Bool egl_init_flg_fb1 = INS_FALSE; + +Bool InitGL(Int32 x, Int32 y, Int32 w, Int32 h, Int32 *rtw, Int32 *rth) +{ + printf("InitGL: X11+EGL, request window %dx%d at (%d,%d)\n", w, h, x, y); + + // 1. 连接 X server + x_display = XOpenDisplay(NULL); + if (!x_display) { + fprintf(stderr, "Cannot open X display\n"); + return INS_FALSE; + } + int screen = DefaultScreen(x_display); + Window root = RootWindow(x_display, screen); + + // 2. 创建窗口 + win_width = w; + win_height = h; + x_window = XCreateSimpleWindow(x_display, root, x, y, win_width, win_height, 1, + BlackPixel(x_display, screen), + WhitePixel(x_display, screen)); + // 注册感兴趣的事件(至少需要窗口关闭事件,但我们可以在主循环外部处理) + XSelectInput(x_display, x_window, StructureNotifyMask | KeyPressMask); + XMapWindow(x_display, x_window); + // 等待窗口映射完成 + XEvent ev; + do { XNextEvent(x_display, &ev); } while (ev.type != MapNotify); + printf("X11 window created: %dx%d\n", win_width, win_height); + + // 3. 初始化 EGL + egl_dpy = eglGetDisplay((EGLNativeDisplayType)x_display); + if (egl_dpy == EGL_NO_DISPLAY) { + fprintf(stderr, "eglGetDisplay failed\n"); + XDestroyWindow(x_display, x_window); + XCloseDisplay(x_display); + return INS_FALSE; + } + + EGLint major, minor; + if (!eglInitialize(egl_dpy, &major, &minor)) { + fprintf(stderr, "eglInitialize failed\n"); + eglTerminate(egl_dpy); + XDestroyWindow(x_display, x_window); + XCloseDisplay(x_display); + return INS_FALSE; + } + printf("EGL version %d.%d\n", major, minor); + + // 确保 EGL 使用 OpenGL ES API + eglBindAPI(EGL_OPENGL_ES_API); + + // 选择配置 + const EGLint config_attribs[] = { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 0, + EGL_DEPTH_SIZE, 16, + EGL_STENCIL_SIZE, 0, + EGL_SAMPLES, 0, + EGL_SAMPLE_BUFFERS, 0, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + EGLConfig config; + EGLint num_configs; + if (!eglChooseConfig(egl_dpy, config_attribs, &config, 1, &num_configs) || num_configs == 0) { + fprintf(stderr, "eglChooseConfig failed\n"); + eglTerminate(egl_dpy); + XDestroyWindow(x_display, x_window); + XCloseDisplay(x_display); + return INS_FALSE; + } + + // 创建窗口表面 + egl_surf = eglCreateWindowSurface(egl_dpy, config, (EGLNativeWindowType)x_window, NULL); + if (egl_surf == EGL_NO_SURFACE) { + fprintf(stderr, "eglCreateWindowSurface failed: 0x%x\n", eglGetError()); + eglTerminate(egl_dpy); + XDestroyWindow(x_display, x_window); + XCloseDisplay(x_display); + return INS_FALSE; + } + + // 创建 OpenGL ES 2.0 上下文 + const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + egl_ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, context_attribs); + if (egl_ctx == EGL_NO_CONTEXT) { + fprintf(stderr, "eglCreateContext failed\n"); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + XDestroyWindow(x_display, x_window); + XCloseDisplay(x_display); + return INS_FALSE; + } + + // 激活上下文 + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + fprintf(stderr, "eglMakeCurrent failed\n"); + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + XDestroyWindow(x_display, x_window); + XCloseDisplay(x_display); + return INS_FALSE; + } + + // 设置视口 + glViewport(0, 0, win_width, win_height); + printf("OpenGL ES %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION)); + + // 返回实际窗口大小(与请求一致) + if (rtw) *rtw = win_width; + if (rth) *rth = win_height; + + egl_init_flg = INS_TRUE; + printf("InitGL success (X11+EGL)\n"); + return INS_TRUE; +} + +// 第二屏(FB1)的交换缓冲,若不需要可留空或简单实现 +Bool SwapGLBuffer_FB1() +{ + if (egl_display_1 != EGL_NO_DISPLAY && eglsurface_fb1 != EGL_NO_SURFACE) { + glFinish(); + eglSwapBuffers(egl_display_1, eglsurface_fb1); + } + return INS_TRUE; +} + +// 第二屏(FB1)的释放 +void DeInitGL_FB1() +{ + if (egl_init_flg_fb1 == INS_FALSE) { + if (egl_display_1 != EGL_NO_DISPLAY) { + eglMakeCurrent(egl_display_1, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (eglcontext_fb1 != EGL_NO_CONTEXT) + eglDestroyContext(egl_display_1, eglcontext_fb1); + if (eglsurface_fb1 != EGL_NO_SURFACE) + eglDestroySurface(egl_display_1, eglsurface_fb1); + eglTerminate(egl_display_1); + } + egl_init_flg_fb1 = INS_TRUE; + } +} + +// 主屏幕交换缓冲 +Bool SwapGLBuffer() +{ + glFinish(); // 确保所有绘制命令完成 + if (egl_surf != EGL_NO_SURFACE) { + eglSwapBuffers(egl_dpy, egl_surf); + } + return INS_TRUE; +} + +// 释放所有资源 +void DeInitGL() +{ + if (egl_init_flg == INS_FALSE) { + // 清屏并交换一次,避免残留(可选) + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + eglSwapBuffers(egl_dpy, egl_surf); + + eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + if (x_display) { + XDestroyWindow(x_display, x_window); + XCloseDisplay(x_display); + x_display = NULL; + } + + egl_init_flg = INS_TRUE; + printf("DeInitGL done.\n"); + } +} + +#endif // COMPILE_IN_UBUNTU \ No newline at end of file