Fix for memory leak with BufferImages from FontClient and AtlasManager. 14/42114/4
authorRichard Underhill <r.underhill@partner.samsung.com>
Tue, 23 Jun 2015 10:34:26 +0000 (11:34 +0100)
committerFrancisco Santos <f1.santos@samsung.com>
Wed, 24 Jun 2015 14:07:00 +0000 (15:07 +0100)
Needs: https://review.tizen.org/gerrit/#/c/42095

Change-Id: I263ac4fede71da91c5f71cbb07a843e6a6fac41a
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

index d1e2a6d..9ef43a9 100644 (file)
@@ -104,10 +104,30 @@ AtlasManagerPtr AtlasManager::New()
 
 AtlasManager::~AtlasManager()
 {
-  for ( uint32_t i = 0; i < mAtlasList.size(); ++i )
+  for ( SizeType i = 0; i < mAtlasList.size(); ++i )
   {
+    mAtlasList[ i ].mAtlas.UploadedSignal().Disconnect( this, &AtlasManager::OnUpload );
     delete[] mAtlasList[ i ].mStripBuffer;
   }
+
+  // Are there any upload signals pending? Free up those buffer images now.
+  for ( SizeType i = 0; i < mUploadedImages.Size(); ++i )
+  {
+    delete[] mUploadedImages[ i ];
+  }
+}
+
+void AtlasManager::OnUpload( Image image )
+{
+  if ( mUploadedImages.Size() )
+  {
+    delete[] mUploadedImages[ 0 ];
+    mUploadedImages.Erase( mUploadedImages.Begin() );
+  }
+  else
+  {
+    DALI_LOG_ERROR("Atlas Image Upload List should not be empty\n");
+  }
 }
 
 Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( const Toolkit::AtlasManager::AtlasSize& size, Pixel::Format pixelformat )
@@ -131,9 +151,10 @@ Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( const Toolkit::AtlasMa
   atlasDescriptor.mSize = size;
   atlasDescriptor.mPixelFormat = pixelformat;
   atlasDescriptor.mNextFreeBlock = 1u; // indicate next free block will be the first ( +1 )
+  atlas.UploadedSignal().Connect( this, &AtlasManager::OnUpload );
 
   // What size do we need for this atlas' strip buffer ( assume 32bit pixel format )?
-  uint32_t neededStripSize =( blockWidth > blockHeight - DOUBLE_PIXEL_PADDING ? blockWidth : blockHeight - DOUBLE_PIXEL_PADDING ) << 2;
+  SizeType neededStripSize =( blockWidth > blockHeight - DOUBLE_PIXEL_PADDING ? blockWidth : blockHeight - DOUBLE_PIXEL_PADDING ) << 2;
   atlasDescriptor.mStripBuffer = new PixelBuffer[ neededStripSize ];
   memset( atlasDescriptor.mStripBuffer, 0, neededStripSize );
 
@@ -146,6 +167,7 @@ Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( const Toolkit::AtlasMa
                                                      SINGLE_PIXEL_PADDING,
                                                      blockHeight - DOUBLE_PIXEL_PADDING,
                                                      pixelformat );
+  mUploadedImages.PushBack( NULL );
   atlasDescriptor.mFilledPixelImage = BufferImage::New( reinterpret_cast< PixelBuffer* >( &mFilledPixel ), 1, 1, pixelformat );
   atlas.Upload( atlasDescriptor.mFilledPixelImage, 0, 0 );
 
@@ -608,6 +630,10 @@ void AtlasManager::UploadImage( const BufferImage& image,
   {
     DALI_LOG_ERROR("Uploading image to Atlas Failed!.\n");
   }
+  else
+  {
+     mUploadedImages.PushBack( const_cast< BufferImage& >( image ).GetBuffer() );
+  }
 
   // If this is the first block then we need to keep the first pixel free for underline texture
   if ( block )
@@ -620,6 +646,10 @@ void AtlasManager::UploadImage( const BufferImage& image,
     {
       DALI_LOG_ERROR("Uploading top strip to Atlas Failed!\n");
     }
+    else
+    {
+      mUploadedImages.PushBack( NULL );
+    }
 
     // Blit left strip
     if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip,
@@ -628,6 +658,10 @@ void AtlasManager::UploadImage( const BufferImage& image,
     {
       DALI_LOG_ERROR("Uploading left strip to Atlas Failed!\n");
     }
+    else
+    {
+      mUploadedImages.PushBack( NULL );
+    }
   }
 
   // Blit bottom strip
@@ -639,6 +673,10 @@ void AtlasManager::UploadImage( const BufferImage& image,
     {
       DALI_LOG_ERROR("Uploading bottom strip to Atlas Failed!.\n");
     }
+    else
+    {
+     mUploadedImages.PushBack( NULL );
+    }
   }
 
   // Blit right strip
@@ -650,6 +688,10 @@ void AtlasManager::UploadImage( const BufferImage& image,
     {
       DALI_LOG_ERROR("Uploading right strip to Atlas Failed!.\n");
     }
+    else
+    {
+      mUploadedImages.PushBack( NULL );
+    }
   }
 }
 
index 8046f71..a24bba0 100644 (file)
@@ -46,7 +46,7 @@ typedef Dali::Vector< Toolkit::AtlasManager::AtlasSlot > slotContainer;
 class AtlasManager;
 typedef IntrusivePtr<AtlasManager> AtlasManagerPtr;
 
-class AtlasManager : public Dali::BaseObject
+class AtlasManager : public Dali::BaseObject, public ConnectionTracker
 {
 public:
 
@@ -191,8 +191,12 @@ public:
 
 private:
 
-  std::vector< AtlasDescriptor > mAtlasList;        // List of atlases created
-  std::vector< AtlasSlotDescriptor > mImageList;  // List of bitmaps store in atlases
+  std::vector< AtlasDescriptor > mAtlasList;            // List of atlases created
+  std::vector< AtlasSlotDescriptor > mImageList;        // List of bitmaps store in atlases
+  Vector< PixelBuffer* > mUploadedImages;               // List of PixelBuffers passed to UploadedSignal
+  Toolkit::AtlasManager::AtlasSize mNewAtlasSize;       // Atlas size to use in next creation
+  Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy;  // Policy for faling to add an Image
+  SizeType mFilledPixel;                                // 32Bit pixel image for underlining
 
   SizeType CheckAtlas( SizeType atlas,
                        SizeType width,
@@ -218,9 +222,8 @@ private:
 
   void PrintMeshData( const Toolkit::AtlasManager::Mesh2D& mesh );
 
-  Toolkit::AtlasManager::AtlasSize mNewAtlasSize;
-  Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy;
-  uint32_t mFilledPixel;
+  void OnUpload( Image image );
+
 };
 
 } // namespace Internal