我听说 EGL 是在 Wayland 窗口中渲染图形的不错选择。 我还没有被说服,我仍然不知道(除了 vulkan)这是否是唯一的方法 在 Wayland 窗口客户端中发挥一些 openGL 魔力。
我已经尝试过,但我在第一行就面临内存泄漏的欺骗。
这是 makefile :
WAYLAND_FLAGS = `pkg-config wayland-client wayland-egl --cflags --libs`
GL_FLAGS = `pkg-config egl glesv2 --cflags --libs`
CGLM_FLAGS = `pkg-config cglm --cflags --libs` -lm
WAYLAND_PROTOCOLS_DIR = `pkg-config wayland-protocols --variable=pkgdatadir`
WAYLAND_SCANNER = `pkg-config --variable=wayland_scanner wayland-scanner`
CFLAGS = -std=c11 -Wall -Werror -g
XDG_SHELL_PROTOCOL = $(WAYLAND_PROTOCOLS_DIR)/stable/xdg-shell/xdg-shell.xml
XDG_SHELL_FILES=xdg-shell-client-protocol.h xdg-shell-protocol.c
all: hello-wayland
hello-wayland: main.c $(XDG_SHELL_FILES)
$(CC) $(CFLAGS) -o hello-wayland $(WAYLAND_FLAGS) $(GL_FLAGS) $(CGLM_FLAGS) *.c
xdg-shell-client-protocol.h:
$(WAYLAND_SCANNER) client-header $(XDG_SHELL_PROTOCOL) xdg-shell-client-protocol.h
xdg-shell-protocol.c:
$(WAYLAND_SCANNER) code $(XDG_SHELL_PROTOCOL) xdg-shell-protocol.c
.PHONY: clean
clean:
$(RM) hello-wayland $(XDG_SHELL_FILES)
这是 EGL 之前的代码:
#include <cglm/cglm.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <wayland-client.h>
#include <wayland-client-protocol.h>
#include <wayland-egl.h>
#include "xdg-shell-client-protocol.h"
int main(int argc, char *argv[]) {
struct wl_display *display = wl_display_connect(0);
printf("Display : %p\n", display);
if(display) wl_display_disconnect(display);
printf("Display disconnected\n");
return 0;
}
没有内存泄漏:
==10344== Memcheck, a memory error detector
==10344== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==10344== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==10344== Command: ./hello-wayland
==10344==
Display : 0x4c31890
Display disconnected
==10344==
==10344== HEAP SUMMARY:
==10344== in use at exit: 0 bytes in 0 blocks
==10344== total heap usage: 61 allocs, 61 frees, 20,039 bytes allocated
==10344==
==10344== All heap blocks were freed -- no leaks are possible
==10344==
==10344== For lists of detected and suppressed errors, rerun with: -s
==10344== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
当我添加一些 EGL 时:
int main(int argc, char *argv[]) {
struct wl_display *display = wl_display_connect(0);
EGLDisplay egl_display;
printf("Display : %p\n", display);
egl_display = eglGetDisplay((EGLNativeDisplayType) display);
printf("EGL display : %p\n", egl_display);
if(egl_display != EGL_NO_DISPLAY) eglTerminate(egl_display);
printf("EGL disconnected\n");
if(display) wl_display_disconnect(display);
printf("Display disconnected\n");
return 0;
}
我明白了:
==10430== Memcheck, a memory error detector
==10430== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==10430== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==10430== Command: ./hello-wayland
==10430==
Display : 0x4c31890
EGL display : 0x4c508c0
EGL disconnected
Display disconnected
==10430==
==10430== HEAP SUMMARY:
==10430== in use at exit: 28,526 bytes in 68 blocks
==10430== total heap usage: 176 allocs, 108 frees, 125,398 bytes allocated
==10430==
==10430== 24 bytes in 1 blocks are still reachable in loss record 1 of 8
==10430== at 0x484282F: malloc (vg_replace_malloc.c:446)
==10430== by 0x402587F: malloc (rtld-malloc.h:56)
==10430== by 0x402587F: strdup (strdup.c:42)
==10430== by 0x4014B48: _dl_load_cache_lookup (dl-cache.c:515)
==10430== by 0x4008F1F: _dl_map_object (dl-load.c:2116)
==10430== by 0x400C9CB: dl_open_worker_begin (dl-open.c:578)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C10F: dl_open_worker (dl-open.c:803)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C563: _dl_open (dl-open.c:905)
==10430== by 0x4A49E23: dlopen_doit (dlopen.c:56)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x4001678: _dl_catch_error (dl-catch.c:256)
==10430==
==10430== 24 bytes in 1 blocks are still reachable in loss record 2 of 8
==10430== at 0x484282F: malloc (vg_replace_malloc.c:446)
==10430== by 0x400BE90: UnknownInlinedFun (rtld-malloc.h:56)
==10430== by 0x400BE90: _dl_new_object (dl-object.c:199)
==10430== by 0x4007299: _dl_map_object_from_fd (dl-load.c:1053)
==10430== by 0x4008CB7: _dl_map_object (dl-load.c:2249)
==10430== by 0x400C9CB: dl_open_worker_begin (dl-open.c:578)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C10F: dl_open_worker (dl-open.c:803)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C563: _dl_open (dl-open.c:905)
==10430== by 0x4A49E23: dlopen_doit (dlopen.c:56)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x4001678: _dl_catch_error (dl-catch.c:256)
==10430==
==10430== 367 bytes in 16 blocks are still reachable in loss record 3 of 8
==10430== at 0x484282F: malloc (vg_replace_malloc.c:446)
==10430== by 0x402587F: malloc (rtld-malloc.h:56)
==10430== by 0x402587F: strdup (strdup.c:42)
==10430== by 0x4014B48: _dl_load_cache_lookup (dl-cache.c:515)
==10430== by 0x4008F1F: _dl_map_object (dl-load.c:2116)
==10430== by 0x400287C: openaux (dl-deps.c:64)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x4002CDF: _dl_map_object_deps (dl-deps.c:232)
==10430== by 0x400CA34: dl_open_worker_begin (dl-open.c:638)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C10F: dl_open_worker (dl-open.c:803)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C563: _dl_open (dl-open.c:905)
==10430==
==10430== 367 bytes in 16 blocks are still reachable in loss record 4 of 8
==10430== at 0x484282F: malloc (vg_replace_malloc.c:446)
==10430== by 0x400BE90: UnknownInlinedFun (rtld-malloc.h:56)
==10430== by 0x400BE90: _dl_new_object (dl-object.c:199)
==10430== by 0x4007299: _dl_map_object_from_fd (dl-load.c:1053)
==10430== by 0x4008CB7: _dl_map_object (dl-load.c:2249)
==10430== by 0x400287C: openaux (dl-deps.c:64)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x4002CDF: _dl_map_object_deps (dl-deps.c:232)
==10430== by 0x400CA34: dl_open_worker_begin (dl-open.c:638)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C10F: dl_open_worker (dl-open.c:803)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C563: _dl_open (dl-open.c:905)
==10430==
==10430== 1,257 bytes in 1 blocks are still reachable in loss record 5 of 8
==10430== at 0x484A0FC: calloc (vg_replace_malloc.c:1675)
==10430== by 0x400BBAD: UnknownInlinedFun (rtld-malloc.h:44)
==10430== by 0x400BBAD: _dl_new_object (dl-object.c:92)
==10430== by 0x4007299: _dl_map_object_from_fd (dl-load.c:1053)
==10430== by 0x4008CB7: _dl_map_object (dl-load.c:2249)
==10430== by 0x400C9CB: dl_open_worker_begin (dl-open.c:578)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C10F: dl_open_worker (dl-open.c:803)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C563: _dl_open (dl-open.c:905)
==10430== by 0x4A49E23: dlopen_doit (dlopen.c:56)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x4001678: _dl_catch_error (dl-catch.c:256)
==10430==
==10430== 2,672 bytes in 1 blocks are still reachable in loss record 6 of 8
==10430== at 0x484A0FC: calloc (vg_replace_malloc.c:1675)
==10430== by 0x504635E: _eglFindDisplay (egldisplay.c:270)
==10430== by 0x5046A2F: _eglGetWaylandDisplay (egldisplay.c:632)
==10430== by 0x488EF6C: GetPlatformDisplayCommon (libegl.c:324)
==10430== by 0x4011B4: main (main.c:17)
==10430==
==10430== 3,720 bytes in 16 blocks are still reachable in loss record 7 of 8
==10430== at 0x484A0FC: calloc (vg_replace_malloc.c:1675)
==10430== by 0x4013D77: UnknownInlinedFun (rtld-malloc.h:44)
==10430== by 0x4013D77: _dl_check_map_versions (dl-version.c:280)
==10430== by 0x400CA7A: dl_open_worker_begin (dl-open.c:646)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C10F: dl_open_worker (dl-open.c:803)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C563: _dl_open (dl-open.c:905)
==10430== by 0x4A49E23: dlopen_doit (dlopen.c:56)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x4001678: _dl_catch_error (dl-catch.c:256)
==10430== by 0x4A49912: _dlerror_run (dlerror.c:138)
==10430== by 0x4A49EDE: dlopen_implementation (dlopen.c:71)
==10430== by 0x4A49EDE: dlopen@@GLIBC_2.34 (dlopen.c:81)
==10430==
==10430== 20,095 bytes in 16 blocks are still reachable in loss record 8 of 8
==10430== at 0x484A0FC: calloc (vg_replace_malloc.c:1675)
==10430== by 0x400BBAD: UnknownInlinedFun (rtld-malloc.h:44)
==10430== by 0x400BBAD: _dl_new_object (dl-object.c:92)
==10430== by 0x4007299: _dl_map_object_from_fd (dl-load.c:1053)
==10430== by 0x4008CB7: _dl_map_object (dl-load.c:2249)
==10430== by 0x400287C: openaux (dl-deps.c:64)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x4002CDF: _dl_map_object_deps (dl-deps.c:232)
==10430== by 0x400CA34: dl_open_worker_begin (dl-open.c:638)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C10F: dl_open_worker (dl-open.c:803)
==10430== by 0x4001522: _dl_catch_exception (dl-catch.c:237)
==10430== by 0x400C563: _dl_open (dl-open.c:905)
==10430==
==10430== LEAK SUMMARY:
==10430== definitely lost: 0 bytes in 0 blocks
==10430== indirectly lost: 0 bytes in 0 blocks
==10430== possibly lost: 0 bytes in 0 blocks
==10430== still reachable: 28,526 bytes in 68 blocks
==10430== suppressed: 0 bytes in 0 blocks
==10430==
==10430== For lists of detected and suppressed errors, rerun with: -s
==10430== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我做错了什么吗? Valgrind 越野车? EGL 泄漏? 这直接是我代码中的调用:
==10430== 2,672 bytes in 1 blocks are still reachable in loss record 6 of 8
==10430== at 0x484A0FC: calloc (vg_replace_malloc.c:1675)
==10430== by 0x504635E: _eglFindDisplay (egldisplay.c:270)
==10430== by 0x5046A2F: _eglGetWaylandDisplay (egldisplay.c:632)
==10430== by 0x488EF6C: GetPlatformDisplayCommon (libegl.c:324)
==10430== by 0x4011B4: main (main.c:17)
eglTerminate 不是eglGetDisplay 的直接对应部分吗? 我没有发现有医生说别的。难道是我搜错了?
谢谢。
我做错了什么吗?
可能不是。
Valgrind 越野车?
Valgrind 有很多问题(以及一些灰色区域),但这不是其中之一。我读过成百上千个妄想性确认偏差的案例,人们得出的结论是一定存在内存检查误报。
泄漏检查是 memcheck 所做的最简单的事情之一。只要 Valgrind 能够正确地重定向
malloc
和家人,那么就很难出错。泄漏的分类有点棘手 - 到处搜索指针来寻找潜在的泄漏有点繁琐。
EGL 泄漏?
Valgrind 使用 getaddrinfo 显示仍然可达内存泄漏
间接地,泄漏的是动态链接器。问题确实出在 GNU libc 中。
如上面的链接,我建议您对动态链接器分配的仍然可达的内存使用抑制机制。
剩下来自 _eglFindDisplay 的 calloc (ewwww retch 未定义的行为,带有前导下划线的全局符号)。您需要使用 EGL 源来确定是否有办法释放该内存,或者 EGL 开发人员是否懒得释放它。如果您不想这样做,您可以再次使用抑制。