Use MESA_pack_invert to avoid read_pixels flip
cogl_read_pixels returns image data in a top-down memory order, but because OpenGL normally returns pixel data in a bottom-up order we have to flip the data before returning it to the user. If the OpenGL driver supports the GL_MESA_pack_invert extension though we can ask the driver to return the data in a top-down order in the first place. Signed-off-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
parent
1527b017c5
commit
6f79eb8a5a
@ -138,6 +138,7 @@ typedef enum
|
|||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0,
|
COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0,
|
||||||
|
COGL_PRIVATE_FEATURE_MESA_PACK_INVERT = 1L<<1
|
||||||
} CoglPrivateFeatureFlags;
|
} CoglPrivateFeatureFlags;
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
27
cogl/cogl.c
27
cogl/cogl.c
@ -47,6 +47,10 @@
|
|||||||
#include "cogl-attribute-private.h"
|
#include "cogl-attribute-private.h"
|
||||||
#include "cogl-framebuffer-private.h"
|
#include "cogl-framebuffer-private.h"
|
||||||
|
|
||||||
|
#ifndef GL_PACK_INVERT_MESA
|
||||||
|
#define GL_PACK_INVERT_MESA 0x8758
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef COGL_GL_DEBUG
|
#ifdef COGL_GL_DEBUG
|
||||||
/* GL error to string conversion */
|
/* GL error to string conversion */
|
||||||
static const struct {
|
static const struct {
|
||||||
@ -474,6 +478,7 @@ _cogl_read_pixels_with_rowstride (int x,
|
|||||||
GLenum gl_format;
|
GLenum gl_format;
|
||||||
GLenum gl_type;
|
GLenum gl_type;
|
||||||
CoglPixelFormat bmp_format;
|
CoglPixelFormat bmp_format;
|
||||||
|
gboolean pack_invert_set;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
@ -546,6 +551,17 @@ _cogl_read_pixels_with_rowstride (int x,
|
|||||||
&gl_format,
|
&gl_format,
|
||||||
&gl_type);
|
&gl_type);
|
||||||
|
|
||||||
|
/* NB: All offscreen rendering is done upside down so there is no need
|
||||||
|
* to flip in this case... */
|
||||||
|
if ((ctx->private_feature_flags & COGL_PRIVATE_FEATURE_MESA_PACK_INVERT) &&
|
||||||
|
!cogl_is_offscreen (framebuffer))
|
||||||
|
{
|
||||||
|
GE (ctx, glPixelStorei (GL_PACK_INVERT_MESA, TRUE));
|
||||||
|
pack_invert_set = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pack_invert_set = FALSE;
|
||||||
|
|
||||||
/* Under GLES only GL_RGBA with GL_UNSIGNED_BYTE as well as an
|
/* Under GLES only GL_RGBA with GL_UNSIGNED_BYTE as well as an
|
||||||
implementation specific format under
|
implementation specific format under
|
||||||
GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES and
|
GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES and
|
||||||
@ -609,15 +625,18 @@ _cogl_read_pixels_with_rowstride (int x,
|
|||||||
_cogl_bitmap_convert_premult_status (bmp, format);
|
_cogl_bitmap_convert_premult_status (bmp, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Currently this function owns the pack_invert state and we don't want this
|
||||||
|
* to interfere with other Cogl components so all other code can assume that
|
||||||
|
* we leave the pack_invert state off. */
|
||||||
|
if (pack_invert_set)
|
||||||
|
GE (ctx, glPixelStorei (GL_PACK_INVERT_MESA, FALSE));
|
||||||
|
|
||||||
/* NB: All offscreen rendering is done upside down so there is no need
|
/* NB: All offscreen rendering is done upside down so there is no need
|
||||||
* to flip in this case... */
|
* to flip in this case... */
|
||||||
if (!cogl_is_offscreen (framebuffer))
|
if (!cogl_is_offscreen (framebuffer) && !pack_invert_set)
|
||||||
{
|
{
|
||||||
guint8 *temprow = g_alloca (rowstride * sizeof (guint8));
|
guint8 *temprow = g_alloca (rowstride * sizeof (guint8));
|
||||||
|
|
||||||
/* TODO: consider using the GL_MESA_pack_invert extension in the future
|
|
||||||
* to avoid this flip... */
|
|
||||||
|
|
||||||
/* vertically flip the buffer in-place */
|
/* vertically flip the buffer in-place */
|
||||||
for (y = 0; y < height / 2; y++)
|
for (y = 0; y < height / 2; y++)
|
||||||
{
|
{
|
||||||
|
@ -183,6 +183,9 @@ _cogl_gl_update_features (CoglContext *context)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (_cogl_check_extension ("GL_MESA_pack_invert", gl_extensions))
|
||||||
|
private_flags |= COGL_PRIVATE_FEATURE_MESA_PACK_INVERT;
|
||||||
|
|
||||||
GE( ctx, glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) );
|
GE( ctx, glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) );
|
||||||
/* We need at least three stencil bits to combine clips */
|
/* We need at least three stencil bits to combine clips */
|
||||||
if (num_stencil_bits > 2)
|
if (num_stencil_bits > 2)
|
||||||
|
Loading…
Reference in New Issue
Block a user