cogl-framebuffer: Try to track format of the framebuffer
Previously in cogl_read_pixels we assume the format of the framebuffer is always premultiplied because that is the most likely format with the default Cogl blend mode. However when the framebuffer is bound to a texture we should be able to make a better guess at the format because we know the texture keeps track of the premult status. This patch adds an internal format member to CoglFramebuffer. For onscreen framebuffers we still assume it is RGBA_8888_PRE but for offscreen to textures we copy the texture format. cogl_read_pixels uses this to determine whether the data returned by glReadPixels will be premultiplied. http://bugzilla.clutter-project.org/show_bug.cgi?id=2414
This commit is contained in:
parent
8fd47276b7
commit
47ccbf472e
@ -39,6 +39,9 @@ struct _CoglFramebuffer
|
||||
CoglFramebufferType type;
|
||||
int width;
|
||||
int height;
|
||||
/* Format of the pixels in the framebuffer (including the expected
|
||||
premult state) */
|
||||
CoglPixelFormat format;
|
||||
|
||||
CoglMatrixStack *modelview_stack;
|
||||
CoglMatrixStack *projection_stack;
|
||||
|
@ -139,12 +139,14 @@ _cogl_is_framebuffer (void *object)
|
||||
static void
|
||||
_cogl_framebuffer_init (CoglFramebuffer *framebuffer,
|
||||
CoglFramebufferType type,
|
||||
CoglPixelFormat format,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
framebuffer->type = type;
|
||||
framebuffer->width = width;
|
||||
framebuffer->height = height;
|
||||
framebuffer->format = format;
|
||||
framebuffer->viewport_x = 0;
|
||||
framebuffer->viewport_y = 0;
|
||||
framebuffer->viewport_width = width;
|
||||
@ -540,6 +542,7 @@ _cogl_offscreen_new_to_texture_full (CoglHandle texhandle,
|
||||
{
|
||||
_cogl_framebuffer_init (COGL_FRAMEBUFFER (offscreen),
|
||||
COGL_FRAMEBUFFER_TYPE_OFFSCREEN,
|
||||
cogl_texture_get_format (texhandle),
|
||||
data.level_width,
|
||||
data.level_height);
|
||||
|
||||
@ -594,9 +597,21 @@ _cogl_onscreen_new (void)
|
||||
* implement CoglOnscreen framebuffers, since we can't, e.g. keep track of
|
||||
* the window size. */
|
||||
|
||||
/* FIXME: We are assuming onscreen buffers will always be
|
||||
premultiplied so we'll set the premult flag on the bitmap
|
||||
format. This will usually be correct because the result of the
|
||||
default blending operations for Cogl ends up with premultiplied
|
||||
data in the framebuffer. However it is possible for the
|
||||
framebuffer to be in whatever format depending on what
|
||||
CoglPipeline is used to render to it. Eventually we may want to
|
||||
add a way for an application to inform Cogl that the framebuffer
|
||||
is not premultiplied in case it is being used for some special
|
||||
purpose. */
|
||||
|
||||
onscreen = g_new0 (CoglOnscreen, 1);
|
||||
_cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen),
|
||||
COGL_FRAMEBUFFER_TYPE_ONSCREEN,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
0xdeadbeef, /* width */
|
||||
0xdeadbeef); /* height */
|
||||
|
||||
|
22
cogl/cogl.c
22
cogl/cogl.c
@ -603,17 +603,14 @@ _cogl_read_pixels_with_rowstride (int x,
|
||||
|
||||
if ((format & COGL_A_BIT))
|
||||
{
|
||||
/* FIXME: We are assuming glReadPixels will always give us
|
||||
premultiplied data so we'll set the premult flag on the
|
||||
bitmap format. This will usually be correct because the
|
||||
result of the default blending operations for Cogl ends up
|
||||
with premultiplied data in the framebuffer. However it is
|
||||
possible for the framebuffer to be in whatever format
|
||||
depending on what CoglPipeline is used to render to
|
||||
it. Eventually we may want to add a way for an application to
|
||||
inform Cogl that the framebuffer is not premultiplied in case
|
||||
it is being used for some special purpose. */
|
||||
bmp_format |= COGL_PREMULT_BIT;
|
||||
/* We match the premultiplied state of the target buffer to the
|
||||
* premultiplied state of the framebuffer so that it will get
|
||||
* converted to the right format below */
|
||||
|
||||
if ((framebuffer->format & COGL_PREMULT_BIT))
|
||||
bmp_format |= COGL_PREMULT_BIT;
|
||||
else
|
||||
bmp_format &= ~COGL_PREMULT_BIT;
|
||||
}
|
||||
|
||||
bmp = _cogl_bitmap_new_from_data (pixels,
|
||||
@ -640,7 +637,8 @@ _cogl_read_pixels_with_rowstride (int x,
|
||||
guint8 *tmp_data = g_malloc (width * height * 4);
|
||||
|
||||
tmp_bmp = _cogl_bitmap_new_from_data (tmp_data,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888 |
|
||||
(bmp_format & COGL_PREMULT_BIT),
|
||||
width, height, 4 * width,
|
||||
(CoglBitmapDestroyNotify) g_free,
|
||||
NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user