[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