Fix Klocwork issues.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / atlas-manager / atlas-manager-impl.cpp
index d1e2a6d..a3b9e86 100644 (file)
@@ -74,7 +74,7 @@ namespace
   }
   );
 
-  const char* FRAGMENT_SHADER_BGRA = MAKE_SHADER(
+  const char* FRAGMENT_SHADER_RGBA = MAKE_SHADER(
   uniform         sampler2D sTexture;
   varying mediump vec2      vTexCoord;
 
@@ -94,6 +94,8 @@ AtlasManager::AtlasManager()
   mNewAtlasSize.mHeight = DEFAULT_ATLAS_HEIGHT;
   mNewAtlasSize.mBlockWidth = DEFAULT_BLOCK_WIDTH;
   mNewAtlasSize.mBlockHeight = DEFAULT_BLOCK_HEIGHT;
+  mShaderL8 = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_L8 );
+  mShaderRgba = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_RGBA );
 }
 
 AtlasManagerPtr AtlasManager::New()
@@ -104,10 +106,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 +153,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,21 +169,13 @@ 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 );
 
   Sampler sampler = Sampler::New( atlas, "sTexture" );
   sampler.SetProperty( Sampler::Property::AFFECTS_TRANSPARENCY, true );
-  Shader shader;
-  if ( pixelformat == Pixel::BGRA8888 )
-  {
-    shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_BGRA );
-  }
-  else
-  {
-    shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_L8 );
-  }
-  atlasDescriptor.mMaterial = Material::New( shader );
+  atlasDescriptor.mMaterial = Material::New( pixelformat == Pixel::L8 ? mShaderL8 : mShaderRgba );
   atlasDescriptor.mMaterial.AddSampler( sampler );
   atlasDescriptor.mSampler = sampler;
   atlasDescriptor.mMaterial.SetBlendMode( BlendingMode::ON );
@@ -496,8 +511,10 @@ void AtlasManager::OptimizeMesh( const Toolkit::AtlasManager::Mesh2D& in,
     Toolkit::AtlasManager::Vertex2D v = in.mVertices[ in.mIndices[ i ] ];
     for ( SizeType j = 0; j < out.mVertices.Size(); ++j )
     {
-      if ( v.mPosition.x == out.mVertices[ j ].mPosition.x && v.mPosition.y == out.mVertices[ j ].mPosition.y &&
-           v.mTexCoords.x == out.mVertices[ j ].mTexCoords.x && v.mTexCoords.y == out.mVertices[ j ].mTexCoords.y )
+      if ( ( fabsf( v.mPosition.x - out.mVertices[ j ].mPosition.x ) < Math::MACHINE_EPSILON_1000 ) &&
+           ( fabsf( v.mPosition.y - out.mVertices[ j ].mPosition.y ) < Math::MACHINE_EPSILON_1000 ) &&
+           ( fabsf( v.mTexCoords.x - out.mVertices[ j ].mTexCoords.x ) < Math::MACHINE_EPSILON_1000 ) &&
+           ( fabsf( v.mTexCoords.y - out.mVertices[ j ].mTexCoords.y ) < Math::MACHINE_EPSILON_1000 ) )
       {
         // Yes, so store this down as the vertex to use
         out.mIndices.PushBack( j );
@@ -608,6 +625,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 +641,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 +653,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 +668,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,12 +683,17 @@ void AtlasManager::UploadImage( const BufferImage& image,
     {
       DALI_LOG_ERROR("Uploading right strip to Atlas Failed!.\n");
     }
+    else
+    {
+      mUploadedImages.PushBack( NULL );
+    }
   }
 }
 
 void AtlasManager::GenerateMeshData( ImageId id,
                                      const Vector2& position,
-                                     Toolkit::AtlasManager::Mesh2D& meshData )
+                                     Toolkit::AtlasManager::Mesh2D& meshData,
+                                     bool addReference )
 {
   // Read the atlas Id to use for this image
   SizeType imageId = id - 1u;
@@ -676,8 +714,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