swayfx-mosaic/tooling/probes/step20c-egl-fx/test_probe_mocks.c

158 lines
6 KiB
C

/* Offline harness: every native EGL/Wayland/wlroots entrypoint is replaced.
* This executable is NOT the real probe and links no EGL/FX/wlroots library. */
#define main probe_main
#define environ mock_environ
#define wl_event_loop_create mock_loop_create
#define wl_event_loop_destroy mock_loop_destroy
#define wlr_headless_backend_create mock_backend_create
#define wlr_backend_destroy mock_backend_destroy
#define wlr_backend_get_drm_fd mock_backend_fd
#define wlr_egl_create_with_drm_fd mock_egl_create
#define wlr_egl_destroy mock_egl_destroy
#define wlr_egl_get_display mock_egl_display
#define eglQueryString mock_query_string
#define eglGetProcAddress mock_get_proc
#define fx_renderer_create_egl mock_fx_create
#define wlr_renderer_destroy mock_renderer_destroy
#define wlr_renderer_get_drm_fd mock_renderer_fd
#define wlr_renderer_get_render_formats mock_render_formats
#define wlr_renderer_get_texture_formats mock_texture_formats
#include "probe.c"
#undef main
#include <assert.h>
static int mode, fx_calls, egl_destroyed, renderer_destroyed, order;
static unsigned texture_queries;
static struct wlr_backend backend_object;
static struct wlr_renderer renderer_object;
static struct wlr_drm_format format_object = {.format = 875713112};
static struct wlr_drm_format_set format_set = {.len = 1, .formats = &format_object};
static struct wlr_drm_format_set excessive_set = {.len = 257};
static const char *device_extensions;
static char *mock_environment[] = {
"PATH=/usr/bin", "PWD=/tmp", "LC_ALL=C", "WLR_RENDERER_FORCE_SOFTWARE=1",
"WLR_RENDERER_ALLOW_SOFTWARE=1", "LIBGL_ALWAYS_SOFTWARE=1", "LP_NUM_THREADS=2",
"__EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json", NULL,
};
char **mock_environ = mock_environment;
struct wl_event_loop *mock_loop_create(void) {
return (struct wl_event_loop *)(uintptr_t)1;
}
void mock_loop_destroy(struct wl_event_loop *loop) {
assert(loop == (struct wl_event_loop *)(uintptr_t)1 && order == 2);
order = 3;
}
struct wlr_backend *mock_backend_create(struct wl_event_loop *loop) {
assert(loop == (struct wl_event_loop *)(uintptr_t)1);
return &backend_object;
}
void mock_backend_destroy(struct wlr_backend *backend) {
assert(backend == &backend_object && order == 1);
order = 2;
}
int mock_backend_fd(struct wlr_backend *backend) {
assert(backend == &backend_object);
return -1;
}
struct wlr_egl *mock_egl_create(int fd) {
assert(fd == -1);
return (struct wlr_egl *)(uintptr_t)2;
}
void mock_egl_destroy(struct wlr_egl *egl) {
assert(egl == (struct wlr_egl *)(uintptr_t)2 && order == 0);
assert(renderer_destroyed == 0);
egl_destroyed++;
order = 1;
}
EGLDisplay mock_egl_display(struct wlr_egl *egl) {
assert(egl == (struct wlr_egl *)(uintptr_t)2);
return (EGLDisplay)(uintptr_t)3;
}
const char *mock_query_string(EGLDisplay display, EGLint name) {
if (display == EGL_NO_DISPLAY) {
return "EGL_EXT_device_query";
}
assert(display == (EGLDisplay)(uintptr_t)3);
return name == EGL_EXTENSIONS ? "EGL_EXT_image_dma_buf_import" : "mock";
}
static EGLBoolean mock_query_display(EGLDisplay display, EGLint attribute, EGLAttrib *value) {
assert(display == (EGLDisplay)(uintptr_t)3 && attribute == EGL_DEVICE_EXT);
*value = 4;
return mode != 5;
}
static const char *mock_query_device(EGLDeviceEXT device, EGLint name) {
/* An arbitrary enumerated device would violate this assertion. */
assert(device == (EGLDeviceEXT)(uintptr_t)4 && name == EGL_EXTENSIONS);
return device_extensions;
}
__eglMustCastToProperFunctionPointerType mock_get_proc(const char *name) {
if (strcmp(name, "eglQueryDisplayAttribEXT") == 0) {
return (__eglMustCastToProperFunctionPointerType)mock_query_display;
}
assert(strcmp(name, "eglQueryDeviceStringEXT") == 0);
return (__eglMustCastToProperFunctionPointerType)mock_query_device;
}
struct wlr_renderer *mock_fx_create(struct wlr_egl *egl) {
assert(egl == (struct wlr_egl *)(uintptr_t)2);
fx_calls++;
return mode == 1 ? NULL : &renderer_object;
}
void mock_renderer_destroy(struct wlr_renderer *renderer) {
assert(renderer == &renderer_object && order == 0 && egl_destroyed == 0);
renderer_destroyed++;
/* Mock renderer consumes the transferred EGL, without a second helper free. */
order = 1;
}
int mock_renderer_fd(struct wlr_renderer *renderer) {
assert(renderer == &renderer_object);
return mode == 7 ? 42 : -1;
}
const struct wlr_drm_format_set *mock_render_formats(struct wlr_renderer *renderer) {
assert(renderer == &renderer_object);
return mode == 6 ? &excessive_set : &format_set;
}
const struct wlr_drm_format_set *mock_texture_formats(struct wlr_renderer *renderer,
uint32_t caps) {
assert(renderer == &renderer_object);
assert(caps == WLR_BUFFER_CAP_DMABUF || caps == WLR_BUFFER_CAP_DATA_PTR ||
caps == WLR_BUFFER_CAP_SHM);
assert((texture_queries & caps) == 0);
texture_queries |= caps;
return caps == WLR_BUFFER_CAP_DMABUF ? &format_set : NULL;
}
int main(void) {
/* Keep bounded test output separate from simulated JSONL evidence. */
assert(freopen("/dev/null", "w", stdout) != NULL);
for (mode = 0; mode < 8; mode++) {
fx_calls = egl_destroyed = renderer_destroyed = order = 0;
texture_queries = 0;
device_extensions = "EGL_MESA_device_software";
if (mode == 2) {
device_extensions = "EGL_EXT_device_drm";
} else if (mode == 3) {
device_extensions = "EGL_MESA_device_software EGL_EXT_device_drm_render_node";
} else if (mode == 4) {
device_extensions = "EGL_MESA_device_software_suffix";
}
renderer_object.render_buffer_caps = WLR_BUFFER_CAP_DMABUF;
char *argv[] = {"inert-mock", NULL};
assert(probe_main(1, argv) == (mode == 0 ? 0 : 20));
assert(order == 3);
if (mode >= 2 && mode <= 5) {
assert(fx_calls == 0 && egl_destroyed == 1 && renderer_destroyed == 0);
} else if (mode == 1) {
assert(fx_calls == 1 && egl_destroyed == 1 && renderer_destroyed == 0);
} else {
assert(fx_calls == 1 && egl_destroyed == 0 && renderer_destroyed == 1);
}
if (mode == 0 || mode == 6) {
assert(texture_queries == (WLR_BUFFER_CAP_DMABUF | WLR_BUFFER_CAP_DATA_PTR |
WLR_BUFFER_CAP_SHM));
}
}
fputs("8 mock C scenarios passed; no EGL/FX library linked\n", stderr);
return 0;
}