framebuffer: Bind the framebuffer before querying the bits

The GL framebuffer driver now makes sure to bind the framebuffer
before counting the number of bits. Previously it would just query the
number of bits for whatever framebuffer happened to be used last.

In addition the virtual for querying the framebuffer bits has been
modified to take a pointer to a structure instead of a separate
pointer to each component. This should make it slightly more efficient
and easier to maintain.

Reviewed-by: Robert Bragg <robert@linux.intel.com>

(cherry picked from commit e9c58b2ba23a7cebcd4e633ea7c3191f02056fb5)
This commit is contained in:
Neil Roberts 2012-12-13 15:39:55 +00:00 committed by Robert Bragg
parent 41612bfc74
commit 0b01c91fc5
8 changed files with 70 additions and 91 deletions

View File

@ -75,10 +75,7 @@ struct _CoglDriverVtable
void void
(* framebuffer_query_bits) (CoglFramebuffer *framebuffer, (* framebuffer_query_bits) (CoglFramebuffer *framebuffer,
int *red, CoglFramebufferBits *bits);
int *green,
int *blue,
int *alpha);
void void
(* framebuffer_finish) (CoglFramebuffer *framebuffer); (* framebuffer_finish) (CoglFramebuffer *framebuffer);

View File

@ -105,6 +105,14 @@ typedef enum
COGL_READ_PIXELS_NO_FLIP = 1L << 30 COGL_READ_PIXELS_NO_FLIP = 1L << 30
} CoglPrivateReadPixelsFlags; } CoglPrivateReadPixelsFlags;
typedef struct
{
int red;
int blue;
int green;
int alpha;
} CoglFramebufferBits;
struct _CoglFramebuffer struct _CoglFramebuffer
{ {
CoglObject _parent; CoglObject _parent;
@ -162,10 +170,7 @@ struct _CoglFramebuffer
/* driver specific */ /* driver specific */
CoglBool dirty_bitmasks; CoglBool dirty_bitmasks;
int red_bits; CoglFramebufferBits bits;
int blue_bits;
int green_bits;
int alpha_bits;
int samples_per_pixel; int samples_per_pixel;
}; };

View File

@ -1093,47 +1093,44 @@ int
cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer) cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer)
{ {
CoglContext *ctx = framebuffer->context; CoglContext *ctx = framebuffer->context;
int red, green, blue, alpha; CoglFramebufferBits bits;
ctx->driver_vtable->framebuffer_query_bits (framebuffer, ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
&red, &green, &blue, &alpha);
return red; return bits.red;
} }
int int
cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer) cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer)
{ {
CoglContext *ctx = framebuffer->context; CoglContext *ctx = framebuffer->context;
int red, green, blue, alpha; CoglFramebufferBits bits;
ctx->driver_vtable->framebuffer_query_bits (framebuffer, ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
&red, &green, &blue, &alpha);
return green; return bits.green;
} }
int int
cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer) cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer)
{ {
CoglContext *ctx = framebuffer->context; CoglContext *ctx = framebuffer->context;
int red, green, blue, alpha; CoglFramebufferBits bits;
ctx->driver_vtable->framebuffer_query_bits (framebuffer, ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
&red, &green, &blue, &alpha);
return blue; return bits.blue;
} }
int int
cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer) cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer)
{ {
CoglContext *ctx = framebuffer->context; CoglContext *ctx = framebuffer->context;
int red, green, blue, alpha; CoglFramebufferBits bits;
ctx->driver_vtable->framebuffer_query_bits (framebuffer, ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
&red, &green, &blue, &alpha);
return alpha; return bits.alpha;
} }
CoglColorMask CoglColorMask

View File

@ -50,10 +50,7 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
void void
_cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer, _cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer,
int *red, CoglFramebufferBits *bits);
int *green,
int *blue,
int *alpha);
void void
_cogl_framebuffer_gl_finish (CoglFramebuffer *framebuffer); _cogl_framebuffer_gl_finish (CoglFramebuffer *framebuffer);

View File

@ -892,54 +892,54 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
{ {
CoglContext *ctx = framebuffer->context; CoglContext *ctx = framebuffer->context;
cogl_framebuffer_allocate (framebuffer, NULL);
if (G_LIKELY (!framebuffer->dirty_bitmasks)) if (G_LIKELY (!framebuffer->dirty_bitmasks))
return; return;
cogl_framebuffer_allocate (framebuffer, NULL);
_cogl_framebuffer_flush_state (framebuffer,
framebuffer,
COGL_FRAMEBUFFER_STATE_BIND);
#ifdef HAVE_COGL_GL #ifdef HAVE_COGL_GL
if ((ctx->private_feature_flags & if ((ctx->private_feature_flags &
COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS) && COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS) &&
framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
{
static const struct
{ {
GLenum attachment, pname; GLenum attachment, pname;
size_t offset;
} params[] =
{
{ GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
offsetof (CoglFramebufferBits, red) },
{ GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
offsetof (CoglFramebufferBits, green) },
{ GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
offsetof (CoglFramebufferBits, blue) },
{ GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
offsetof (CoglFramebufferBits, alpha) },
};
int i;
attachment = GL_COLOR_ATTACHMENT0; for (i = 0; i < G_N_ELEMENTS (params); i++)
{
pname = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE; int *value =
(int *) ((uint8_t *) &framebuffer->bits + params[i].offset);
GE( ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GE( ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER,
attachment, params[i].attachment,
pname, params[i].pname,
&framebuffer->red_bits) ); value) );
}
pname = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
GE( ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER,
attachment,
pname,
&framebuffer->green_bits)
);
pname = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
GE( ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER,
attachment,
pname,
&framebuffer->blue_bits)
);
pname = GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE;
GE( ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER,
attachment,
pname,
&framebuffer->alpha_bits)
);
} }
else else
#endif /* HAVE_COGL_GL */ #endif /* HAVE_COGL_GL */
{ {
GE( ctx, glGetIntegerv (GL_RED_BITS, &framebuffer->red_bits) ); GE( ctx, glGetIntegerv (GL_RED_BITS, &framebuffer->bits.red) );
GE( ctx, glGetIntegerv (GL_GREEN_BITS, &framebuffer->green_bits) ); GE( ctx, glGetIntegerv (GL_GREEN_BITS, &framebuffer->bits.green) );
GE( ctx, glGetIntegerv (GL_BLUE_BITS, &framebuffer->blue_bits) ); GE( ctx, glGetIntegerv (GL_BLUE_BITS, &framebuffer->bits.blue) );
GE( ctx, glGetIntegerv (GL_ALPHA_BITS, &framebuffer->alpha_bits) ); GE( ctx, glGetIntegerv (GL_ALPHA_BITS, &framebuffer->bits.alpha) );
} }
@ -949,29 +949,23 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN
? "offscreen" ? "offscreen"
: "onscreen", : "onscreen",
framebuffer->red_bits, framebuffer->bits.red,
framebuffer->blue_bits, framebuffer->bits.blue,
framebuffer->green_bits, framebuffer->bits.green,
framebuffer->alpha_bits); framebuffer->bits.alpha);
framebuffer->dirty_bitmasks = FALSE; framebuffer->dirty_bitmasks = FALSE;
} }
void void
_cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer, _cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer,
int *red, CoglFramebufferBits *bits)
int *green,
int *blue,
int *alpha)
{ {
_cogl_framebuffer_init_bits (framebuffer); _cogl_framebuffer_init_bits (framebuffer);
/* TODO: cache these in some driver specific location not /* TODO: cache these in some driver specific location not
* directly as part of CoglFramebuffer. */ * directly as part of CoglFramebuffer. */
*red = framebuffer->red_bits; *bits = framebuffer->bits;
*green = framebuffer->green_bits;
*blue = framebuffer->blue_bits;
*alpha = framebuffer->alpha_bits;
} }
void void

View File

@ -53,10 +53,7 @@ _cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer,
void void
_cogl_framebuffer_nop_query_bits (CoglFramebuffer *framebuffer, _cogl_framebuffer_nop_query_bits (CoglFramebuffer *framebuffer,
int *red, CoglFramebufferBits *bits);
int *green,
int *blue,
int *alpha);
void void
_cogl_framebuffer_nop_finish (CoglFramebuffer *framebuffer); _cogl_framebuffer_nop_finish (CoglFramebuffer *framebuffer);

View File

@ -29,7 +29,7 @@
#include "cogl-framebuffer-nop-private.h" #include "cogl-framebuffer-nop-private.h"
#include <glib.h> #include <glib.h>
#include <string.h>
void void
_cogl_framebuffer_nop_flush_state (CoglFramebuffer *draw_buffer, _cogl_framebuffer_nop_flush_state (CoglFramebuffer *draw_buffer,
@ -62,15 +62,9 @@ _cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer,
void void
_cogl_framebuffer_nop_query_bits (CoglFramebuffer *framebuffer, _cogl_framebuffer_nop_query_bits (CoglFramebuffer *framebuffer,
int *red, CoglFramebufferBits *bits)
int *green,
int *blue,
int *alpha)
{ {
*red = 0; memset (bits, 0, sizeof (CoglFramebufferBits));
*green = 0;
*blue = 0;
*alpha = 0;
} }
void void

View File

@ -98,9 +98,7 @@ main (int argc, char **argv)
ADD_TEST (test_bitmask, 0, 0); ADD_TEST (test_bitmask, 0, 0);
ADD_TEST (test_offscreen, 0, 0); ADD_TEST (test_offscreen, 0, 0);
ADD_TEST (test_framebuffer_get_bits, ADD_TEST (test_framebuffer_get_bits, TEST_REQUIREMENT_OFFSCREEN, 0);
TEST_REQUIREMENT_OFFSCREEN,
TEST_KNOWN_FAILURE);
ADD_TEST (test_point_size, 0, 0); ADD_TEST (test_point_size, 0, 0);
ADD_TEST (test_point_sprite, ADD_TEST (test_point_sprite,