xcb EGL GL#include xcb/xcb.h #include EGL/egl.h #include EGL/eglext.h #include GL/gl.h #include stdio.h #include stdlib.h #include string.h #include thorvg.h int main() { // 1. 创建 XCB 连接和窗口 int w 800; int h 600; xcb_connection_t *conn xcb_connect(NULL, NULL); const xcb_setup_t *setup xcb_get_setup(conn); xcb_screen_t *screen xcb_setup_roots_iterator(setup).data; xcb_window_t win xcb_generate_id(conn); uint32_t mask XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; uint32_t values[] { screen-black_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS }; xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, screen-root, 0, 0, w, h, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen-root_visual, mask, values); // 设置窗口标题 const char* title XCB Window Demo; xcb_change_property( conn, XCB_PROP_MODE_REPLACE, win, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, strlen(title),title ); xcb_map_window(conn, win); xcb_flush(conn); // 1. 初始化 EGL display // EGLDisplay egl_dpy eglGetDisplay(EGL_DEFAULT_DISPLAY); auto eglGetPlatformDisplayEXT (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress(eglGetPlatformDisplayEXT); EGLDisplay egl_dpy eglGetPlatformDisplayEXT(EGL_PLATFORM_XCB_EXT, (void*)conn, nullptr ); if (egl_dpy EGL_NO_DISPLAY) { fprintf(stderr, eglGetDisplay failed %p\n,egl_dpy); return -1; } EGLint major, minor; if (!eglInitialize(egl_dpy, major, minor)) { fprintf(stderr, eglInitialize failed\n); return -1; } printf(EGL version %d.%d\n, major, minor); // 1. choose OpenGL API for EGL, by default it uses OpenGL ES eglBindAPI(EGL_OPENGL_API); // 2. 选择 EGL 配置 const EGLint attribs[] { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_CONFORMANT, EGL_OPENGL_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_NONE }; EGLConfig config; EGLint num_configs1; if (!eglChooseConfig(egl_dpy, attribs, config, 1, num_configs) || num_configs 1) { fprintf(stderr, eglChooseConfig failed %d\n, num_configs); return -1; } // 3. 创建 EGL 表面 EGLint attr[] { EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR, // or use EGL_GL_COLORSPACE_SRGB for sRGB framebuffer EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE, }; EGLSurface egl_surf eglCreateWindowSurface(egl_dpy, config, (EGLNativeWindowType)win, attr); if (egl_surf EGL_NO_SURFACE) { fprintf(stderr, eglCreateWindowSurface failed\n); return -1; } // 4. 创建 EGL 上下文 const EGLint ctx_attribs[] { EGL_CONTEXT_MAJOR_VERSION, 4, EGL_CONTEXT_MINOR_VERSION, 1, EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, EGL_NONE }; EGLContext egl_ctx eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs); if (egl_ctx EGL_NO_CONTEXT) { fprintf(stderr, eglCreateContext failed\n); return -1; } // 7. 绑定上下文 if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { fprintf(stderr, eglMakeCurrent failed\n); return -1; } tvg::Initializer::init(0); tvg::GlCanvas* canvas{}; canvas tvg::GlCanvas::gen(); canvas-target(egl_dpy,egl_surf, egl_ctx,0,w,h, tvg::ColorSpace::ABGR8888S); eglSwapInterval(egl_dpy, 1); // 8. 渲染循环 xcb_generic_event_t *ev; int running 1; while (running) { // 处理 XCB 事件简单示例 while ((ev xcb_poll_for_event(conn))) { uint8_t type ev-response_type ~0x80; if (type XCB_KEY_PRESS) running 0; free(ev); } glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glFlush(); { auto shape tvg::Shape::gen(); shape-appendRect(10, 10, 100, 100); // 占位 shape-fill(255, 255, 255); canvas-add(shape); canvas-update(); canvas-draw(); canvas-sync(); } printf(eglSwapBuffer...\n); 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); xcb_destroy_window(conn, win); xcb_disconnect(conn); return 0; }