From 198dcdb987a8fc734dd6e9f246ddd4728fcc0e0e Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Mon, 28 Jan 2019 01:14:36 +0000 Subject: [PATCH] gl_common: fix coordinate mismatch Xorg uses top left as origin, OpenGL uses lower left. So we need to flip the y axis, and make sure we are using the right points as origin of windows. Signed-off-by: Yuxuan Shui --- src/backend/gl/glx.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/backend/gl/glx.c b/src/backend/gl/glx.c index cb54e21..7d1d1b0 100644 --- a/src/backend/gl/glx.c +++ b/src/backend/gl/glx.c @@ -611,12 +611,31 @@ static int glx_buffer_age(void *backend_data, session_t *ps) { } static void glx_compose(void *backend_data, session_t *ps, win *w, void *win_data, - int dst_x, int dst_y, const region_t *region) { + int dst_x, int dst_y, const region_t *region) { struct _glx_data *gd = backend_data; struct _glx_win_data *wd = win_data; - gl_compose(&wd->texture, 0, 0, dst_x, dst_y, w->widthb, w->heightb, 0, 1, true, - false, region, &gd->win_shader); + // OpenGL and Xorg uses different coordinate systems. + // First, We need to flip the y axis of the paint region + region_t region_yflipped; + pixman_region32_init(®ion_yflipped); + pixman_region32_copy(®ion_yflipped, (region_t *)region); + + int nrects; + auto rect = pixman_region32_rectangles(®ion_yflipped, &nrects); + for (int i = 0; i < nrects; i++) { + auto tmp = rect[i].y1; + rect[i].y1 = ps->root_height - rect[i].y2; + rect[i].y2 = ps->root_height - tmp; + } + dump_region(®ion_yflipped); + + // Then, we still need to convert the origin of painting. + // Note, in GL coordinates, we need to specified the bottom left corner of the + // rectangle, while what we get from the arguments are the top left corner. + gl_compose(&wd->texture, 0, 0, dst_x, ps->root_height - dst_y - w->heightb, w->widthb, + w->heightb, 0, 1, true, false, ®ion_yflipped, &gd->win_shader); + pixman_region32_fini(®ion_yflipped); } backend_info_t glx_backend = {