Added metrics logging to TextAtlasRenderer
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / atlas / text-atlas-renderer.cpp
index 0ed74bd..41dfac9 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/dali.h>
+#include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/atlas-manager/atlas-manager.h>
 #include <dali-toolkit/internal/text/rendering/shaders/text-basic-shader.h>
 #include <dali-toolkit/internal/text/rendering/shaders/text-bgra-shader.h>
 
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_ATLAS_RENDERER");
+#endif
+
 using namespace Dali;
 using namespace Dali::Toolkit;
 using namespace Dali::Toolkit::Text;
@@ -35,7 +40,7 @@ namespace
 {
   const Vector2 DEFAULT_ATLAS_SIZE( 512.0f, 512.0f );
   const Vector2 DEFAULT_BLOCK_SIZE( 16.0f, 16.0f );
-  const Vector2 PADDING( 2.0f, 2.0f );
+  const Vector2 PADDING( 4.0f, 4.0f ); // Allow for variation in font glyphs
 }
 
 struct AtlasRenderer::Impl
@@ -53,12 +58,18 @@ struct AtlasRenderer::Impl
     Text::GlyphIndex mIndex;
   };
 
+  struct MaxBlockSize
+  {
+    FontId mFontId;
+    Vector2 mNeededBlockSize;
+  };
+
   Impl()
   : mSlotDelegate( this )
   {
     mGlyphManager = AtlasGlyphManager::Get();
     mFontClient = TextAbstraction::FontClient::Get();
-    mGlyphManager.SetAtlasSize( DEFAULT_ATLAS_SIZE, DEFAULT_BLOCK_SIZE );
+    mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_SIZE, DEFAULT_BLOCK_SIZE );
     mBasicShader = BasicShader::New();
     mBGRAShader = BgraShader::New();
   }
@@ -67,6 +78,7 @@ struct AtlasRenderer::Impl
   {
     AtlasManager::AtlasSlot slot;
     std::vector< MeshRecord > meshContainer;
+    FontId lastFontId = 0;
 
     if (mImageIds.Size() )
     {
@@ -74,8 +86,7 @@ struct AtlasRenderer::Impl
       RemoveText();
     }
 
-    // Set the block size to use, if an atlas is created
-    mGlyphManager.SetAtlasSize( DEFAULT_ATLAS_SIZE, CalculateBlockSize( glyphs ) );
+    CalculateBlocksSize( glyphs );
 
     for ( uint32_t i = 0; i < glyphs.Size(); ++i )
     {
@@ -96,6 +107,20 @@ struct AtlasRenderer::Impl
         }
         else
         {
+
+          // Select correct size for new atlas if needed....?
+          if ( lastFontId != glyph.fontId )
+          {
+            for ( uint32_t j = 0; j < mBlockSizes.size(); ++j )
+            {
+              if ( mBlockSizes[ j ].mFontId == glyph.fontId )
+              {
+                mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_SIZE, mBlockSizes[ j ].mNeededBlockSize );
+              }
+            }
+            lastFontId = glyph.fontId;
+          }
+
           // Glyph doesn't currently exist in atlas so upload
           BufferImage bitmap = mFontClient.CreateBitmap( glyph.fontId, glyph.index );
 
@@ -145,6 +170,25 @@ struct AtlasRenderer::Impl
       }
       mActor.OffStageSignal().Connect( mSlotDelegate, &AtlasRenderer::Impl::OffStageDisconnect );
     }
+#if defined(DEBUG_ENABLED)
+    Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics();
+    DALI_LOG_INFO( gLogFilter, Debug::Concise, "TextAtlasRenderer::GlyphManager::GlyphCount: %i, AtlasCount: %i, TextureMemoryUse: %iK\n",
+                                                metrics.mGlyphCount,
+                                                metrics.mAtlasMetrics.mAtlasCount,
+                                                metrics.mAtlasMetrics.mTextureMemoryUsed / 1024 );
+    for ( uint32_t i = 0; i < metrics.mAtlasMetrics.mAtlasCount; ++i )
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n",
+                                                 i + 1, i > 8 ? "" : " ",
+                                                 metrics.mAtlasMetrics.mAtlasMetrics[ i ].mPixelFormat == Pixel::L8 ? "L8  " : "BGRA",
+                                                 metrics.mAtlasMetrics.mAtlasMetrics[ i ].mWidth,
+                                                 metrics.mAtlasMetrics.mAtlasMetrics[ i ].mHeight,
+                                                 metrics.mAtlasMetrics.mAtlasMetrics[ i ].mBlockWidth,
+                                                 metrics.mAtlasMetrics.mAtlasMetrics[ i ].mBlockHeight,
+                                                 metrics.mAtlasMetrics.mAtlasMetrics[ i ].mBlocksUsed,
+                                                 metrics.mAtlasMetrics.mAtlasMetrics[ i ].mTotalBlocks );
+    }
+#endif
   }
 
   void StitchTextMesh( std::vector< MeshRecord >& meshContainer,
@@ -187,23 +231,40 @@ struct AtlasRenderer::Impl
     mImageIds.Resize( 0 );
   }
 
-  Vector2 CalculateBlockSize( const Vector<GlyphInfo>& glyphs )
+  void CalculateBlocksSize( const Vector<GlyphInfo>& glyphs )
   {
-    float maxWidth = glyphs[ 0 ].width;
-    float maxHeight = glyphs[ 0 ].height;
-
-    for ( uint32_t i = 1u; i < glyphs.Size(); ++i )
+    MaxBlockSize maxBlockSize;
+    for ( uint32_t i = 0; i < glyphs.Size(); ++i )
     {
-      if ( maxWidth < glyphs[ i ].width )
+      // Get the fontId of this glyph and check to see if a max size exists?
+      FontId fontId = glyphs[ i ].fontId;
+      float paddedWidth = glyphs[ i ].width + PADDING.x;
+      float paddedHeight = glyphs[ i ].height + PADDING.y;
+      bool foundFont = false;
+
+      for ( uint32_t j = 0; j < mBlockSizes.size(); ++j )
       {
-        maxWidth = glyphs[ i ].width;
+        if ( mBlockSizes[ j ].mFontId == fontId )
+        {
+          foundFont = true;
+          if ( mBlockSizes[ j ].mNeededBlockSize.x < paddedWidth )
+          {
+            mBlockSizes[ j ].mNeededBlockSize.x = paddedWidth;
+          }
+          if ( mBlockSizes[ j ].mNeededBlockSize.y < paddedHeight )
+          {
+            mBlockSizes[ j ].mNeededBlockSize.y = paddedHeight;
+          }
+        }
       }
-      if ( maxHeight < glyphs[ i ].height )
+
+      if ( !foundFont )
       {
-        maxHeight = glyphs[ i ].height;
+        maxBlockSize.mNeededBlockSize = Vector2( paddedWidth, paddedHeight );
+        maxBlockSize.mFontId = fontId;
+        mBlockSizes.push_back( maxBlockSize );
       }
     }
-    return Vector2( maxWidth + PADDING.x, maxHeight + PADDING.y );
   }
 
   RenderableActor mActor;                             ///< The actor parent which renders the text
@@ -213,6 +274,7 @@ struct AtlasRenderer::Impl
   SlotDelegate< AtlasRenderer::Impl > mSlotDelegate;  ///> Signal generated to unreference glyphs when renderable actor is removed
   ShaderEffect mBasicShader;                          ///> Shader to render L8 glyphs
   ShaderEffect mBGRAShader;                           ///> Shader to render BGRA glyphs
+  std::vector< MaxBlockSize > mBlockSizes;            ///> Maximum size needed to contain a glyph in a block within a new atlas
 };
 
 Text::RendererPtr AtlasRenderer::New()