Improved reference caching in AtlasGlyphManager for text changes in an existing Text... 15/40715/2
authorRichard Underhill <r.underhill@partner.samsung.com>
Wed, 10 Jun 2015 09:07:36 +0000 (10:07 +0100)
committerRichard Underhill <r.underhill@partner.samsung.com>
Wed, 10 Jun 2015 09:07:36 +0000 (10:07 +0100)
Change-Id: Ib56edfedee5fe9a8f71df8643116c20b19f95465
Signed-off-by: Richard Underhill <r.underhill@partner.samsung.com>
dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp
dali-toolkit/internal/atlas-manager/atlas-manager-impl.h
dali-toolkit/internal/atlas-manager/atlas-manager.cpp
dali-toolkit/internal/atlas-manager/atlas-manager.h
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp

index 853c0ae..266e8b9 100644 (file)
@@ -651,7 +651,8 @@ void AtlasManager::UploadImage( const BufferImage& image,
 
 void AtlasManager::GenerateMeshData( ImageId id,
                                      const Vector2& position,
-                                     MeshData& meshData )
+                                     MeshData& meshData,
+                                     bool addReference )
 {
   // Read the atlas Id to use for this image
   SizeType imageId = id - 1u;
@@ -672,8 +673,11 @@ void AtlasManager::GenerateMeshData( ImageId id,
 
   CreateMesh( atlas, width, height, position, widthInBlocks, heightInBlocks, meshData, mImageList[ imageId ] );
 
-  // Mesh created so increase the reference count
-  mImageList[ imageId ].mCount++;
+  // Mesh created so increase the reference count, if we're asked to
+  if ( addReference )
+  {
+    mImageList[ imageId ].mCount++;
+  }
 }
 
 Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const
@@ -826,7 +830,6 @@ void AtlasManager::GetMetrics( Toolkit::AtlasManager::Metrics& metrics )
   metrics.mTextureMemoryUsed = textureMemoryUsed;
 }
 
-
 } // namespace Internal
 
 } // namespace Toolkit
index ef078f8..7c8470d 100644 (file)
@@ -111,7 +111,8 @@ public:
    */
   void GenerateMeshData( ImageId id,
                          const Vector2& position,
-                         MeshData& mesh );
+                         MeshData& mesh,
+                         bool addReference );
 
   /**
    * @copydoc Toolkit::AtlasManager::StitchMesh
index e46eb1d..6773416 100644 (file)
@@ -69,11 +69,13 @@ bool AtlasManager::Remove( ImageId id )
 
 void AtlasManager::GenerateMeshData( ImageId id,
                                      const Vector2& position,
-                                     MeshData& meshData)
+                                     MeshData& meshData,
+                                     bool addReference )
 {
   GetImplementation(*this).GenerateMeshData( id,
                                              position,
-                                             meshData );
+                                             meshData,
+                                             addReference );
 }
 
 void AtlasManager::StitchMesh( MeshData& first,
index 2bf79f0..2330647 100644 (file)
@@ -274,10 +274,12 @@ public:
    * @param[in] id Image Id returned in the AtlasSlot from the add operation
    * @param[in] position position of the resulting mesh in model space
    * @param[out] mesh Mesh Data Object to populate with mesh data
+   * @param[in] addReference Whether to increase the internal reference count for image or not
    */
   void GenerateMeshData( ImageId id,
                          const Vector2& position,
-                         MeshData& mesh );
+                         MeshData& mesh,
+                         bool addReference = true );
 
   /**
    * @brief Append second mesh to the first mesh
index 734b82a..d7fde4e 100644 (file)
@@ -40,6 +40,18 @@ AtlasGlyphManager::AtlasGlyphManager()
 
 AtlasGlyphManager::~AtlasGlyphManager()
 {
+  // Clear up any remaining references
+  for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+        fontGlyphRecordIt != mFontGlyphRecords.end();
+        ++fontGlyphRecordIt )
+  {
+    for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+          glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
+          ++glyphRecordEntryIt )
+    {
+      mAtlasManager.Remove( glyphRecordEntryIt->mImageId );
+    }
+  }
 }
 
 AtlasGlyphManagerPtr AtlasGlyphManager::New()
@@ -48,17 +60,39 @@ AtlasGlyphManagerPtr AtlasGlyphManager::New()
   return internal;
 }
 
-void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
+void AtlasGlyphManager::Add( Text::FontId fontId,
+                             const Text::GlyphInfo& glyph,
                              const BufferImage& bitmap,
                              Dali::Toolkit::AtlasManager::AtlasSlot& slot )
 {
-  GlyphRecord record;
-  record.mFontId = glyph.fontId;
-  record.mIndex = glyph.index;
-
   mAtlasManager.Add( bitmap, slot );
+
+  GlyphRecordEntry record;
+  record.mIndex = glyph.index;
   record.mImageId = slot.mImageId;
-  mGlyphRecords.PushBack( record );
+  record.mCount = 1;
+
+  // Have glyph records been created for this fontId ?
+  bool foundGlyph = false;
+  for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+        fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
+  {
+    if ( fontGlyphRecordIt->mFontId == fontId )
+    {
+      fontGlyphRecordIt->mGlyphRecords.PushBack( record );
+      foundGlyph = true;
+      break;
+    }
+  }
+
+  if ( !foundGlyph )
+  {
+    // We need to add a new font entry
+    FontGlyphRecord fontGlyphRecord;
+    fontGlyphRecord.mFontId = fontId;
+    fontGlyphRecord.mGlyphRecords.PushBack( record );
+    mFontGlyphRecords.push_back( fontGlyphRecord );
+  }
 
 #ifdef DISPLAY_ATLAS
   {
@@ -83,7 +117,8 @@ void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
                                           const Vector2& position,
                                           MeshData& meshData )
 {
-  mAtlasManager.GenerateMeshData( imageId, position, meshData );
+  // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
+  mAtlasManager.GenerateMeshData( imageId, position, meshData, false );
 }
 
 void AtlasGlyphManager::StitchMesh( MeshData& first,
@@ -92,20 +127,31 @@ void AtlasGlyphManager::StitchMesh( MeshData& first,
   mAtlasManager.StitchMesh( first, second );
 }
 
-void AtlasGlyphManager::Cached( Text::FontId fontId,
+bool AtlasGlyphManager::Cached( Text::FontId fontId,
                                 uint32_t index,
                                 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
 {
-  for ( uint32_t i = 0; i < mGlyphRecords.Size(); ++i )
+  for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+        fontGlyphRecordIt != mFontGlyphRecords.end();
+        ++fontGlyphRecordIt )
   {
-    if ( fontId == mGlyphRecords[ i ].mFontId && index == mGlyphRecords[ i ].mIndex )
+    if ( fontGlyphRecordIt->mFontId == fontId )
     {
-      slot.mImageId = mGlyphRecords[ i ].mImageId;
-      slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
-      return;
+      for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+            glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+            ++glyphRecordIt )
+      {
+        if ( glyphRecordIt->mIndex == index )
+        {
+          slot.mImageId = glyphRecordIt->mImageId;
+          slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
+          return true;
+        }
+      }
     }
   }
   slot.mImageId = 0;
+  return false;
 }
 
 Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
@@ -124,21 +170,6 @@ void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32
   mAtlasManager.SetNewAtlasSize( size );
 }
 
-void AtlasGlyphManager::Remove( uint32_t imageId )
-{
-  if ( mAtlasManager.Remove( imageId ) )
-  {
-    for ( uint32_t i = 0; i < mGlyphRecords.Size(); ++i )
-    {
-      if ( mGlyphRecords[ i ].mImageId == imageId )
-      {
-        mGlyphRecords.Remove( mGlyphRecords.Begin() + i );
-        return;
-      }
-    }
-  }
-}
-
 Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
 {
   return mAtlasManager.GetPixelFormat( atlasId );
@@ -146,11 +177,38 @@ Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
 
 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
 {
-  mMetrics.mGlyphCount = mGlyphRecords.Size();
+  mMetrics.mGlyphCount = mFontGlyphRecords.size();
   mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
   return mMetrics;
 }
 
+void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
+{
+  for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
+        fontGlyphRecordIt != mFontGlyphRecords.end();
+        ++fontGlyphRecordIt )
+  {
+    if ( fontGlyphRecordIt->mFontId == fontId )
+    {
+      for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
+            glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
+            ++glyphRecordIt )
+      {
+        if ( glyphRecordIt->mImageId == imageId )
+        {
+          glyphRecordIt->mCount += delta;
+          if ( !glyphRecordIt->mCount )
+          {
+            mAtlasManager.Remove( glyphRecordIt->mImageId );
+            fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
+          }
+          return;
+        }
+      }
+    }
+  }
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index cbbe732..5008106 100644 (file)
@@ -49,11 +49,17 @@ class AtlasGlyphManager : public Dali::BaseObject
 {
 public:
 
-  struct GlyphRecord
+  struct GlyphRecordEntry
   {
-    Text::FontId mFontId;
     Text::GlyphIndex mIndex;
     uint32_t mImageId;
+    int32_t mCount;
+  };
+
+  struct FontGlyphRecord
+  {
+    Text::FontId mFontId;
+    Vector< GlyphRecordEntry > mGlyphRecords;
   };
 
   AtlasGlyphManager();
@@ -68,7 +74,8 @@ public:
   /**
    * @copydoc Toolkit::AtlasGlyphManager::Add
    */
-  void Add( const Text::GlyphInfo& glyph,
+  void Add( Text::FontId fontId,
+            const Text::GlyphInfo& glyph,
             const BufferImage& bitmap,
             Dali::Toolkit::AtlasManager::AtlasSlot& slot );
 
@@ -88,7 +95,7 @@ public:
   /**
    * @copydoc Toolkit::AtlasGlyphManager::Cached
    */
-  void Cached( Text::FontId fontId,
+  bool Cached( Text::FontId fontId,
                Text::GlyphIndex index,
                Dali::Toolkit::AtlasManager::AtlasSlot& slot );
 
@@ -103,11 +110,6 @@ public:
   void SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight );
 
   /**
-   * @copydoc Toolkit::AtlasGlyphManager::Remove
-   */
-  void Remove( uint32_t imageId );
-
-  /**
    * @copydoc toolkit::AtlasGlyphManager::GetPixelFormat
    */
   Pixel::Format GetPixelFormat( uint32_t atlasId );
@@ -117,10 +119,15 @@ public:
    */
   const Toolkit::AtlasGlyphManager::Metrics& GetMetrics();
 
+  /**
+   * @copydoc toolkit::AtlasGlyphManager::AdjustReferenceCount
+   */
+  void AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta );
+
 private:
 
   Dali::Toolkit::AtlasManager mAtlasManager;
-  Vector< GlyphRecord > mGlyphRecords;
+  std::vector< FontGlyphRecord > mFontGlyphRecords;
   uint32_t mCount;
   Toolkit::AtlasGlyphManager::Metrics mMetrics;
 };
index 37f7ee1..0438314 100644 (file)
@@ -69,11 +69,12 @@ AtlasGlyphManager::AtlasGlyphManager(Internal::AtlasGlyphManager *impl)
 {
 }
 
-void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
+void AtlasGlyphManager::Add( Text::FontId fontId,
+                             const Text::GlyphInfo& glyph,
                              const BufferImage& bitmap,
                              AtlasManager::AtlasSlot& slot )
 {
-  GetImplementation(*this).Add( glyph, bitmap, slot );
+  GetImplementation(*this).Add( fontId, glyph, bitmap, slot );
 }
 
 void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
@@ -91,11 +92,11 @@ void AtlasGlyphManager::StitchMesh( MeshData& first,
   GetImplementation(*this).StitchMesh( first, second );
 }
 
-void AtlasGlyphManager::Cached( Text::FontId fontId,
+bool AtlasGlyphManager::Cached( Text::FontId fontId,
                                 Text::GlyphIndex index,
                                 AtlasManager::AtlasSlot& slot )
 {
-  GetImplementation(*this).Cached( fontId, index, slot );
+  return GetImplementation(*this).Cached( fontId, index, slot );
 }
 
 void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
@@ -108,11 +109,6 @@ Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
   return GetImplementation(*this).GetAtlasSize( atlasId );
 }
 
-void AtlasGlyphManager::Remove( uint32_t imageId )
-{
-  GetImplementation(*this).Remove( imageId );
-}
-
 Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
 {
   return GetImplementation(*this).GetPixelFormat( atlasId );
@@ -123,6 +119,11 @@ const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
   return GetImplementation(*this).GetMetrics();
 }
 
+void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta )
+{
+  GetImplementation(*this).AdjustReferenceCount( fontId, imageId, delta );
+}
+
 } // namespace Toolkit
 
 } // namespace Dali
index ad2c5ea..fdc4141 100644 (file)
@@ -71,11 +71,13 @@ public:
   /**
    * @brief Ask Atlas Manager to add a glyph
    *
+   * @param[in] fontId fontId glyph comes from
    * @param[in] glyph glyph to add to an atlas
    * @param[in] bitmap bitmap to use for glyph addition
    * @param[out] slot information returned by atlas manager for addition
    */
-  void Add( const Text::GlyphInfo& glyph,
+  void Add( Text::FontId fontId,
+            const Text::GlyphInfo& glyph,
             const BufferImage& bitmap,
             AtlasManager::AtlasSlot& slot );
 
@@ -105,8 +107,10 @@ public:
    * @param[in] fontId The font that this glyph comes from
    * @param[in] index The GlyphIndex of this glyph
    * @param[out] slot container holding information about the glyph( mImage = 0 indicates not being cached )
+   *
+   * @return Whether glyph is cached or not ?
    */
-  void Cached( Text::FontId fontId,
+  bool Cached( Text::FontId fontId,
                Text::GlyphIndex index,
                AtlasManager::AtlasSlot& slot );
 
@@ -130,13 +134,6 @@ public:
   void SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight );
 
   /**
-   * @brief Unreference an image from the atlas and remove from cache if no longer needed
-   *
-   * @param[in] imageId ID of the image
-   */
-  void Remove( uint32_t imageId );
-
-  /**
    * @brief Get the Pixel Format used by an atlas
    *
    * @param[in] atlasId Id of atlas to check
@@ -152,6 +149,15 @@ public:
    */
   const Metrics& GetMetrics();
 
+  /**
+   * @brief Adjust the reference count for an imageId and remove cache entry if it becomes free
+   *
+   * @param[in] fontId the font this image came from
+   * @param[in] imageId The imageId
+   * @param[in] delta adjustment to make to reference count
+   */
+  void AdjustReferenceCount( Text::FontId fontId, uint32_t imageId, int32_t delta );
+
 private:
 
   explicit DALI_INTERNAL AtlasGlyphManager(Internal::AtlasGlyphManager *impl);
index 58f7fc1..5eca29d 100644 (file)
@@ -80,17 +80,24 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     uint32_t mMeshRecordIndex;
   };
 
-  struct AtlasRecord
+  struct MaxBlockSize
   {
-    uint32_t mImageId;
+    FontId mFontId;
+    uint32_t mNeededBlockWidth;
+    uint32_t mNeededBlockHeight;
+  };
+
+  struct CheckEntry
+  {
+    FontId mFontId;
     Text::GlyphIndex mIndex;
   };
 
-  struct MaxBlockSize
+  struct TextCacheEntry
   {
     FontId mFontId;
-    uint32_t mNeededBlockWidth;
-    uint32_t mNeededBlockHeight;
+    Text::GlyphIndex mIndex;
+    uint32_t mImageId;
   };
 
   Impl()
@@ -118,6 +125,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     AtlasManager::AtlasSlot slot;
     std::vector< MeshRecord > meshContainer;
     Vector< Extent > extents;
+    TextCacheEntry textCacheEntry;
 
     float currentUnderlinePosition = ZERO;
     float currentUnderlineThickness = underlineHeight;
@@ -130,10 +138,10 @@ struct AtlasRenderer::Impl : public ConnectionTracker
       style = STYLE_DROP_SHADOW;
     }
 
-    if ( mImageIds.Size() )
+    if ( mTextCache.Size() )
     {
-      // Unreference any currently used glyphs
-      RemoveText();
+      // Update the glyph cache with any changes to current text
+      RemoveText( glyphs );
     }
 
     CalculateBlocksSize( glyphs );
@@ -183,17 +191,9 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 
         const Vector2& position = positions[ i ];
         MeshData newMeshData;
-        mGlyphManager.Cached( glyph.fontId, glyph.index, slot );
 
-        if ( slot.mImageId )
-        {
-          // This glyph already exists so generate mesh data plugging in our supplied position
-          mGlyphManager.GenerateMeshData( slot.mImageId, position, newMeshData );
-          mImageIds.PushBack( slot.mImageId );
-        }
-        else
+        if ( !mGlyphManager.Cached( glyph.fontId, glyph.index, slot ) )
         {
-
           // Select correct size for new atlas if needed....?
           if ( lastFontId != glyph.fontId )
           {
@@ -236,16 +236,17 @@ struct AtlasRenderer::Impl : public ConnectionTracker
             }
 
             // Locate a new slot for our glyph
-            mGlyphManager.Add( glyph, bitmap, slot );
-
-            // Generate mesh data for this quad, plugging in our supplied position
-            if ( slot.mImageId )
-            {
-              mGlyphManager.GenerateMeshData( slot.mImageId, position, newMeshData );
-              mImageIds.PushBack( slot.mImageId );
-            }
+            mGlyphManager.Add( glyph.fontId, glyph, bitmap, slot );
           }
         }
+
+        // Generate mesh data for this quad, plugging in our supplied position
+        mGlyphManager.GenerateMeshData( slot.mImageId, position, newMeshData );
+        textCacheEntry.mFontId = glyph.fontId;
+        textCacheEntry.mImageId = slot.mImageId;
+        textCacheEntry.mIndex = glyph.index;
+        mTextCache.PushBack( textCacheEntry );
+
         // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
         StitchTextMesh( meshContainer,
                         newMeshData,
@@ -308,7 +309,6 @@ struct AtlasRenderer::Impl : public ConnectionTracker
           mActor = actor;
         }
       }
-      mActor.OffStageSignal().Connect( this, &AtlasRenderer::Impl::OffStageDisconnect );
     }
 #if defined(DEBUG_ENABLED)
     Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics();
@@ -434,19 +434,56 @@ struct AtlasRenderer::Impl : public ConnectionTracker
     }
   }
 
-  // Unreference any glyphs that were used with this actor
-  void OffStageDisconnect( Dali::Actor actor )
+  void RemoveText( const Vector<GlyphInfo>& glyphs )
   {
-    RemoveText();
-  }
+    Vector< CheckEntry > checked;
+    CheckEntry checkEntry;
 
-  void RemoveText()
-  {
-    for ( uint32_t i = 0; i < mImageIds.Size(); ++i )
+    for ( Vector< TextCacheEntry >::Iterator tCit = mTextCache.Begin(); tCit != mTextCache.End(); ++tCit )
     {
-      mGlyphManager.Remove( mImageIds[ i ] );
+      uint32_t index = tCit->mIndex;
+      uint32_t fontId = tCit->mFontId;
+
+      // Check that this character has not already been checked...
+      bool wasChecked = false;
+      for ( Vector< CheckEntry >::Iterator cEit = checked.Begin(); cEit != checked.End(); ++cEit )
+      {
+        if ( fontId == cEit->mFontId && index == cEit->mIndex )
+        {
+          wasChecked = true;
+        }
+      }
+
+      if ( !wasChecked )
+      {
+
+        int32_t newCount = 0;
+        int32_t oldCount = 0;
+
+        // How many times does this character occur in the old text ?
+        for ( Vector< TextCacheEntry >::Iterator oTcit = mTextCache.Begin(); oTcit != mTextCache.End(); ++oTcit )
+        {
+          if ( fontId == oTcit->mFontId && index == oTcit->mIndex )
+          {
+            oldCount++;
+          }
+        }
+
+        // And how many times in the new ?
+        for ( Vector< GlyphInfo >::Iterator cGit = glyphs.Begin(); cGit != glyphs.End(); ++cGit )
+        {
+          if ( fontId == cGit->fontId && index == cGit->index )
+          {
+            newCount++;
+          }
+        }
+        mGlyphManager.AdjustReferenceCount( fontId, tCit->mImageId, newCount - oldCount );
+        checkEntry.mIndex = index;
+        checkEntry.mFontId = fontId;
+        checked.PushBack( checkEntry );
+      }
     }
-    mImageIds.Resize( 0 );
+    mTextCache.Resize( 0 );
   }
 
   void CalculateBlocksSize( const Vector<GlyphInfo>& glyphs )
@@ -678,13 +715,13 @@ struct AtlasRenderer::Impl : public ConnectionTracker
 
   RenderableActor mActor;                             ///< The actor parent which renders the text
   AtlasGlyphManager mGlyphManager;                    ///< Glyph Manager to handle upload and caching
-  Vector< uint32_t > mImageIds;                       ///< A list of imageIDs used by the renderer
   TextAbstraction::FontClient mFontClient;            ///> The font client used to supply glyph information
   ShaderEffect mBasicShader;                          ///> Shader used to render L8 glyphs
   ShaderEffect mBgraShader;                           ///> Shader used to render BGRA glyphs
   ShaderEffect mBasicShadowShader;                    ///> Shader used to render drop shadow into buffer
   std::vector< MaxBlockSize > mBlockSizes;            ///> Maximum size needed to contain a glyph in a block within a new atlas
   std::vector< MeshData::FaceIndex > mFace;           ///> Face indices for a quad
+  Vector< TextCacheEntry > mTextCache;
 };
 
 Text::RendererPtr AtlasRenderer::New()
@@ -736,5 +773,7 @@ AtlasRenderer::AtlasRenderer()
 
 AtlasRenderer::~AtlasRenderer()
 {
+  Vector< GlyphInfo > emptyGlyphs;
+  mImpl->RemoveText( emptyGlyphs );
   delete mImpl;
 }