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 <neil@linux.intel.com>
This commit is contained in:
Robert Bragg 2011-07-22 12:23:40 +01:00
parent 8e8690a562
commit 3a2f94045e
5 changed files with 32 additions and 5 deletions

View File

@ -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! */

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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