atlas: fix some journal flushing issues
authorRobert Bragg <robert@linux.intel.com>
Fri, 4 Jun 2010 15:42:30 +0000 (16:42 +0100)
committerRobert Bragg <robert@linux.intel.com>
Wed, 9 Jun 2010 14:19:31 +0000 (15:19 +0100)
1) Always flush when migrating textures out of an atlas because although
it's true that the original texture data will remain valid in the
original texture we can't assume that journal entries have resolved the
GL texture that will be used. This is only true if a layer0_override has
been used.

2) Don't flush at the point of creating a new atlas simply flush
immediately before reorganizing an atlas. This means we are now assuming
that we will never see recursion due to atlas textures being modified
during a journal flush. This means it's the responsibility of the
primitives code to _ensure_mipmaps for example not the responsibility of
_cogl_material_flush_gl_state.

clutter/cogl/cogl/cogl-atlas-texture.c

index 0835e73..6270269 100644 (file)
@@ -362,12 +362,14 @@ _cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex)
 
       COGL_NOTE (ATLAS, "Migrating texture out of the atlas");
 
-      /* Although this texture is being moved out of the atlas, we
-         don't need to flush the journal here because the contents of
-         the old image will still be left in the same position in the
-         atlas. The only way this would get overwritten would be if a
-         new texture was added, but in that case we flush the journal
-         anyway */
+      /* We don't know if any materials may currently be referenced in
+       * the journal that depend on the current underlying GL texture
+       * storage so we flush the journal before migrating.
+       *
+       * We are assuming that texture atlas migration never happens
+       * during a flush so we don't have to consider recursion here.
+       */
+      _cogl_journal_flush ();
 
       cogl_handle_unref (atlas_tex->sub_texture);
 
@@ -670,6 +672,15 @@ _cogl_atlas_texture_migrate (unsigned int                    n_textures,
 
   _cogl_atlas_texture_blit_begin (&blit_data, new_texture, old_texture);
 
+  /* We don't know if any materials may currently be referenced in the
+   * journal that depend on the current underlying GL texture storage
+   * so we flush the journal before migrating.
+   *
+   * We are assuming that texture atlas migration never happens during
+   * a flush so we don't have to consider recursion here.
+   */
+  _cogl_journal_flush ();
+
   for (i = 0; i < n_textures; i++)
     {
       /* Skip the texture that is being added because it doesn't contain
@@ -984,22 +995,6 @@ _cogl_atlas_texture_new_from_bitmap (CoglHandle       bmp_handle,
       return COGL_INVALID_HANDLE;
     }
 
-  /* We need to flush the journal when adding a new atlas texture for
-     two reasons:
-
-     1) If the atlas gets reorganized then any existing textures may
-        be moved so the coordinates in journal will be wrong.
-
-     2) We don't want to flush before migrating a texture out of the
-        atlas because we will potentially already be in the middle of
-        a flush to cause the migration. Therefore we rely on the old
-        contents of the texture still remaining in the atlas so that
-        any existing journal entries will still be valid. However once
-        the texture is migrated out the space would be free to be
-        reclaimed by this new texture. That won't matter if we flush
-        now */
-  _cogl_journal_flush ();
-
   /* We need to allocate the texture now because we need the pointer
      to set as the data for the rectangle in the atlas */
   atlas_tex = g_new (CoglAtlasTexture, 1);