From 3a2f94045e0c4e423e14b8823535512271f2d9bf Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Fri, 22 Jul 2011 12:23:40 +0100 Subject: [PATCH] framebuffer: make _swap_region coords top-left relative Cogl aims to consistently put the origin of 2D objects at the top-left instead of the bottom left as OpenGL does, but there was an oversight and the experimental cogl_framebuffer_swap_region API was accepting coordinates relative to the bottom left. Cogl will now flip the user's given rectangles to be relative to the bottom of the framebufffer before sending them to APIs like glXCopySubBuffer and glBlitFramebuffer. Reviewed-by: Neil Roberts --- cogl/cogl-framebuffer.c | 2 +- cogl/cogl-framebuffer.h | 2 +- cogl/winsys/cogl-winsys-egl.c | 16 +++++++++++++++- cogl/winsys/cogl-winsys-glx.c | 15 ++++++++++++++- cogl/winsys/cogl-winsys-private.h | 2 +- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c index a7a442c1e..4a45e7566 100644 --- a/cogl/cogl-framebuffer.c +++ b/cogl/cogl-framebuffer.c @@ -1666,7 +1666,7 @@ cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer) void cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer, - int *rectangles, + const int *rectangles, int n_rectangles) { /* FIXME: we shouldn't need to flush *all* journals here! */ diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h index 9619f01db..fb69da4e8 100644 --- a/cogl/cogl-framebuffer.h +++ b/cogl/cogl-framebuffer.h @@ -333,7 +333,7 @@ cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer); #define cogl_framebuffer_swap_region cogl_framebuffer_swap_region_EXP void cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer, - int *rectangles, + const int *rectangles, int n_rectangles); diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c index 08cd354a9..35230fc8b 100644 --- a/cogl/winsys/cogl-winsys-egl.c +++ b/cogl/winsys/cogl-winsys-egl.c @@ -1512,12 +1512,26 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen) static void _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, - int *rectangles, + const int *user_rectangles, int n_rectangles) { CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context; CoglRendererEGL *egl_renderer = context->display->renderer->winsys; CoglOnscreenEGL *egl_onscreen = onscreen->winsys; + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + int framebuffer_height = cogl_framebuffer_get_height (framebuffer); + int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4); + int i; + + /* eglSwapBuffersRegion expects rectangles relative to the bottom left corner + * but we are given rectangles relative to the top left so we need to flip + * them... */ + memcpy (rectangles, user_rectangles, sizeof (int) * n_rectangles * 4); + for (i = 0; i < n_rectangles; i++) + { + int *rect = &rectangles[4 * i]; + rect[1] = framebuffer_height - rect[1] - rect[3]; + } if (egl_renderer->pf_eglSwapBuffersRegion (egl_renderer->edpy, egl_onscreen->egl_surface, diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c index 0a2fe00be..b50af5562 100644 --- a/cogl/winsys/cogl-winsys-glx.c +++ b/cogl/winsys/cogl-winsys-glx.c @@ -1114,7 +1114,7 @@ _cogl_winsys_get_vsync_counter (void) static void _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, - int *rectangles, + const int *user_rectangles, int n_rectangles) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); @@ -1128,6 +1128,19 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen, guint32 end_frame_vsync_counter = 0; gboolean have_counter; gboolean can_wait; + int framebuffer_height = cogl_framebuffer_get_height (framebuffer); + int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4); + int i; + + /* glXCopySubBuffer expects rectangles relative to the bottom left corner but + * we are given rectangles relative to the top left so we need to flip + * them... */ + memcpy (rectangles, user_rectangles, sizeof (int) * n_rectangles * 4); + for (i = 0; i < n_rectangles; i++) + { + int *rect = &rectangles[4 * i]; + rect[1] = framebuffer_height - rect[1] - rect[3]; + } _cogl_framebuffer_flush_state (framebuffer, framebuffer, diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h index 88df22d48..dbc409775 100644 --- a/cogl/winsys/cogl-winsys-private.h +++ b/cogl/winsys/cogl-winsys-private.h @@ -107,7 +107,7 @@ typedef struct _CoglWinsysVtable void (*onscreen_swap_region) (CoglOnscreen *onscreen, - int *rectangles, + const int *rectangles, int n_rectangles); #ifdef COGL_HAS_EGL_SUPPORT