[Cogl] [PATCH 04/13] framebuffer: defer calculating level size until allocation
Robert Bragg
robert at sixbynine.org
Wed Dec 11 10:31:25 PST 2013
From: Robert Bragg <robert at linux.intel.com>
The plan is to defer more of the work for creating a texture until
allocation time, but that means we won't be able to always assume
we can query the size of a texture when creating an offscreen
framebuffer from a texture (consider for example using
_texture_new_from_file() where the size isn't known until the file has
been loaded). This defers needing to know the size of the texture
underlying an offscreen framebuffer until calling
cogl_framebuffer_allocate().
---
cogl/cogl-framebuffer-private.h | 2 --
cogl/cogl-framebuffer.c | 28 +++++++++++------------
cogl/cogl-gles2-context.c | 13 +++++++++--
cogl/driver/gl/cogl-framebuffer-gl.c | 44 +++++++++++++++++++++++-------------
4 files changed, 53 insertions(+), 34 deletions(-)
diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
index 3b91771..6476611 100644
--- a/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl-framebuffer-private.h
@@ -205,8 +205,6 @@ struct _CoglOffscreen
CoglTexture *texture;
int texture_level;
- int texture_level_width;
- int texture_level_height;
CoglTexture *depth_texture;
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 340c8b2..bf4e5f4 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -604,34 +604,27 @@ _cogl_offscreen_new_with_texture_full (CoglTexture *texture,
CoglContext *ctx = texture->context;
CoglOffscreen *offscreen;
CoglFramebuffer *fb;
- int level_width;
- int level_height;
CoglOffscreen *ret;
_COGL_RETURN_VAL_IF_FAIL (cogl_is_texture (texture), NULL);
- _COGL_RETURN_VAL_IF_FAIL (level < _cogl_texture_get_n_levels (texture),
- NULL);
-
- _cogl_texture_get_level_size (texture,
- level,
- &level_width,
- &level_height,
- NULL);
offscreen = g_new0 (CoglOffscreen, 1);
offscreen->texture = cogl_object_ref (texture);
offscreen->texture_level = level;
- offscreen->texture_level_width = level_width;
- offscreen->texture_level_height = level_height;
offscreen->create_flags = create_flags;
fb = COGL_FRAMEBUFFER (offscreen);
+ /* NB: we can't assume we can query the texture's width yet, since
+ * it might not have been allocated yet and for example if the
+ * texture is being loaded from a file then the file might not
+ * have been read yet. */
+
_cogl_framebuffer_init (fb,
ctx,
COGL_FRAMEBUFFER_TYPE_OFFSCREEN,
- level_width,
- level_height);
+ -1, /* unknown width, until allocation */
+ -1); /* unknown height until allocation */
ret = _cogl_offscreen_object_new (offscreen);
@@ -724,6 +717,13 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
return FALSE;
}
+ /* Now that the texture has been allocated we can determine a
+ * size for the framebuffer... */
+ framebuffer->width = cogl_texture_get_width (offscreen->texture);
+ framebuffer->height = cogl_texture_get_height (offscreen->texture);
+ framebuffer->viewport_width = framebuffer->width;
+ framebuffer->viewport_height = framebuffer->height;
+
/* Forward the texture format as the internal format of the
* framebuffer */
framebuffer->internal_format =
diff --git a/cogl/cogl-gles2-context.c b/cogl/cogl-gles2-context.c
index 82ae324..ebe70e2 100644
--- a/cogl/cogl-gles2-context.c
+++ b/cogl/cogl-gles2-context.c
@@ -1688,6 +1688,8 @@ _cogl_gles2_offscreen_allocate (CoglOffscreen *offscreen,
const CoglWinsysVtable *winsys;
CoglError *internal_error = NULL;
CoglGLES2Offscreen *gles2_offscreen;
+ int level_width;
+ int level_height;
if (!framebuffer->allocated &&
!cogl_framebuffer_allocate (framebuffer, error))
@@ -1717,11 +1719,18 @@ _cogl_gles2_offscreen_allocate (CoglOffscreen *offscreen,
}
gles2_offscreen = g_slice_new0 (CoglGLES2Offscreen);
+
+ _cogl_texture_get_level_size (offscreen->texture,
+ offscreen->texture_level,
+ &level_width,
+ &level_height,
+ NULL);
+
if (!_cogl_framebuffer_try_creating_gl_fbo (gles2_context->context,
offscreen->texture,
offscreen->texture_level,
- offscreen->texture_level_width,
- offscreen->texture_level_height,
+ level_width,
+ level_height,
offscreen->depth_texture,
&COGL_FRAMEBUFFER (offscreen)->config,
offscreen->allocation_flags,
diff --git a/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/driver/gl/cogl-framebuffer-gl.c
index d1904a0..9c430ab 100644
--- a/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -734,14 +734,26 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
CoglContext *ctx = fb->context;
CoglOffscreenAllocateFlags flags;
CoglGLFramebuffer *gl_framebuffer = &offscreen->gl_framebuffer;
+ int level_width;
+ int level_height;
+
+ _COGL_RETURN_VAL_IF_FAIL (offscreen->texture_level <
+ _cogl_texture_get_n_levels (offscreen->texture),
+ NULL);
+
+ _cogl_texture_get_level_size (offscreen->texture,
+ offscreen->texture_level,
+ &level_width,
+ &level_height,
+ NULL);
if (fb->config.depth_texture_enabled &&
offscreen->depth_texture == NULL)
{
offscreen->depth_texture =
create_depth_texture (ctx,
- offscreen->texture_level_width,
- offscreen->texture_level_height);
+ level_width,
+ level_height);
if (!cogl_texture_allocate (offscreen->depth_texture, error))
{
@@ -770,8 +782,8 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
try_creating_fbo (ctx,
offscreen->texture,
offscreen->texture_level,
- offscreen->texture_level_width,
- offscreen->texture_level_height,
+ level_width,
+ level_height,
offscreen->depth_texture,
&fb->config,
flags = 0,
@@ -781,8 +793,8 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
try_creating_fbo (ctx,
offscreen->texture,
offscreen->texture_level,
- offscreen->texture_level_width,
- offscreen->texture_level_height,
+ level_width,
+ level_height,
offscreen->depth_texture,
&fb->config,
flags = ctx->last_offscreen_allocate_flags,
@@ -800,8 +812,8 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
try_creating_fbo (ctx,
offscreen->texture,
offscreen->texture_level,
- offscreen->texture_level_width,
- offscreen->texture_level_height,
+ level_width,
+ level_height,
offscreen->depth_texture,
&fb->config,
flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL,
@@ -810,8 +822,8 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
try_creating_fbo (ctx,
offscreen->texture,
offscreen->texture_level,
- offscreen->texture_level_width,
- offscreen->texture_level_height,
+ level_width,
+ level_height,
offscreen->depth_texture,
&fb->config,
flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH |
@@ -821,8 +833,8 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
try_creating_fbo (ctx,
offscreen->texture,
offscreen->texture_level,
- offscreen->texture_level_width,
- offscreen->texture_level_height,
+ level_width,
+ level_height,
offscreen->depth_texture,
&fb->config,
flags = COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL,
@@ -831,8 +843,8 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
try_creating_fbo (ctx,
offscreen->texture,
offscreen->texture_level,
- offscreen->texture_level_width,
- offscreen->texture_level_height,
+ level_width,
+ level_height,
offscreen->depth_texture,
&fb->config,
flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH,
@@ -841,8 +853,8 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
try_creating_fbo (ctx,
offscreen->texture,
offscreen->texture_level,
- offscreen->texture_level_width,
- offscreen->texture_level_height,
+ level_width,
+ level_height,
offscreen->depth_texture,
&fb->config,
flags = 0,
--
1.8.3.1
More information about the Cogl
mailing list