From b4770c1e9b27f7816572342b3899b117e5a91adb Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Wed, 21 Oct 2009 23:24:49 +0100 Subject: [PATCH] [cogl] Make sure Cogl always knows the current window geometry Because Cogl defines the origin of viewport and window coordinates to be top-left it always needs to know the size of the current window so that Cogl window/viewport coordinates can be transformed into OpenGL coordinates. This also fixes cogl_read_pixels to use the current draw buffer height instead of the viewport height to determine the OpenGL y coordinate to use for glReadPixels. --- cogl/cogl-context.c | 2 +- cogl/cogl-context.h | 2 +- cogl/cogl-draw-buffer.c | 36 +++++++++++++++++++++++++++++++----- cogl/cogl.h.in | 3 +++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c index ccd71c7d0..d50ec6cf9 100644 --- a/cogl/cogl-context.c +++ b/cogl/cogl-context.c @@ -102,7 +102,7 @@ cogl_create_context (void) _context->window_buffer = window_buffer; cogl_set_draw_buffer (COGL_WINDOW_BUFFER, 0/* ignored */); _context->dirty_bound_framebuffer = TRUE; - _context->dirty_viewport = TRUE; + _context->dirty_gl_viewport = TRUE; _context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode)); _context->last_path = 0; diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h index 1d3f9ecf3..aa2045456 100644 --- a/cogl/cogl-context.h +++ b/cogl/cogl-context.h @@ -90,7 +90,7 @@ typedef struct GSList *draw_buffer_stack; CoglHandle window_buffer; gboolean dirty_bound_framebuffer; - gboolean dirty_viewport; + gboolean dirty_gl_viewport; /* Primitives */ floatVec2 path_start; diff --git a/cogl/cogl-draw-buffer.c b/cogl/cogl-draw-buffer.c index 41f0a5f91..76077627a 100644 --- a/cogl/cogl-draw-buffer.c +++ b/cogl/cogl-draw-buffer.c @@ -163,7 +163,7 @@ _cogl_draw_buffer_set_viewport (CoglHandle handle, draw_buffer->viewport_height = height; if (_cogl_get_draw_buffer () == draw_buffer) - ctx->dirty_viewport = TRUE; + ctx->dirty_gl_viewport = TRUE; } int @@ -377,6 +377,26 @@ _cogl_onscreen_free (CoglOnscreen *onscreen) g_free (onscreen); } +void +_cogl_onscreen_clutter_backend_set_size (int width, int height) +{ + CoglDrawBuffer *draw_buffer; + + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + draw_buffer = COGL_DRAW_BUFFER (ctx->window_buffer); + + if (draw_buffer->width == width && draw_buffer->height == height) + return; + + draw_buffer->width = width; + draw_buffer->height = height; + + /* We'll need to recalculate the GL viewport state derived + * from the Cogl viewport */ + ctx->dirty_gl_viewport = 1; +} + GSList * _cogl_create_draw_buffer_stack (void) { @@ -434,7 +454,7 @@ cogl_set_draw_buffer (CoglBufferTarget target, CoglHandle handle) entry->target = target; ctx->dirty_bound_framebuffer = 1; - ctx->dirty_viewport = 1; + ctx->dirty_gl_viewport = 1; if (draw_buffer != COGL_INVALID_HANDLE) cogl_handle_ref (draw_buffer); @@ -531,13 +551,19 @@ _cogl_draw_buffer_flush_state (CoglHandle handle, ctx->dirty_bound_framebuffer = FALSE; } - if (ctx->dirty_viewport) + if (ctx->dirty_gl_viewport) { + /* Convert the Cogl viewport y offset to an OpenGL viewport y offset + * (NB: OpenGL defines its window and viewport origins to be bottom + * left, while Cogl defines them to be top left.) */ + int gl_viewport_y = draw_buffer->height - + (draw_buffer->viewport_y + draw_buffer->viewport_height); + GE (glViewport (draw_buffer->viewport_x, - draw_buffer->viewport_y, + gl_viewport_y, draw_buffer->viewport_width, draw_buffer->viewport_height)); - ctx->dirty_viewport = FALSE; + ctx->dirty_gl_viewport = FALSE; } /* XXX: Flushing clip state may trash the modelview and projection diff --git a/cogl/cogl.h.in b/cogl/cogl.h.in index 23e417a29..9ce95ba35 100644 --- a/cogl/cogl.h.in +++ b/cogl/cogl.h.in @@ -869,6 +869,9 @@ void cogl_flush_gl_state (int flags); void _cogl_set_indirect_context (gboolean indirect); void _cogl_set_viewport (int x, int y, int width, int height); +void +_cogl_onscreen_clutter_backend_set_size (int width, int height); + G_END_DECLS #undef __COGL_H_INSIDE__