// Check to see if the atlas is large enough to hold a single block even ?
if ( blockWidth > width || blockHeight > height )
{
- DALI_LOG_ERROR("Atlas %i x %i too small. Dimensions need to be at least %i x %i\n",
+ DALI_LOG_ERROR("Atlas %i x %i too small. Dimensions need to be at least %ix%i\n",
width, height, blockWidth, blockHeight );
return 0;
}
}
}
-void AtlasManager::SetAtlasSize( const Vector2& size,
- const Vector2& blockSize )
+void AtlasManager::SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize )
{
mNewAtlasSize = size;
mNewBlockSize = blockSize;
}
}
+Vector2 AtlasManager::GetAtlasSize( AtlasId atlas )
+{
+ if ( atlas && atlas <= mAtlasList.size() )
+ {
+ return Vector2( static_cast< float >( mAtlasList[ atlas - 1u ].mWidth ),
+ static_cast< float >( mAtlasList[ atlas - 1u ].mHeight ) );
+ }
+ else
+ {
+ return Vector2( 0.0f, 0.0f );
+ }
+}
+
AtlasManager::SizeType AtlasManager::GetFreeBlocks( AtlasId atlas ) const
{
if ( atlas && atlas <= mAtlasList.size() )
uint32_t blockWidth = mAtlasList[ index ].mBlockWidth;
uint32_t blockHeight = mAtlasList[ index ].mBlockHeight;
- //Work out how many blocks wide and high our bitmap is in the atlas' block size
SizeType widthInBlocks = width / blockWidth;
- if ( width % blockWidth )
- {
- widthInBlocks++;
- }
SizeType heightInBlocks = height / blockHeight;
- if ( height % blockHeight )
- {
- heightInBlocks++;
- }
-
uint32_t blockCount = widthInBlocks * heightInBlocks;
// Check free previously unallocated blocks and any free blocks
return mAtlasList[ atlas -1u ].mPixelFormat;
}
+void AtlasManager::GetMetrics( Toolkit::AtlasManager::Metrics& metrics )
+{
+ Toolkit::AtlasManager::AtlasMetricsEntry entry;
+ uint32_t textureMemoryUsed = 0;
+ uint32_t atlasCount = mAtlasList.size();
+ metrics.mAtlasCount = atlasCount;
+ metrics.mAtlasMetrics.Resize(0);
+
+ for ( uint32_t i = 0; i < atlasCount; ++i )
+ {
+ SizeType width = mAtlasList[ i ].mWidth;
+ SizeType height = mAtlasList[ i ].mHeight;
+ SizeType blockWidth = mAtlasList[ i ].mBlockWidth;
+ SizeType blockHeight = mAtlasList[ i ].mBlockHeight;
+
+ entry.mWidth = width;
+ entry.mHeight = height;
+ entry.mBlockWidth = blockWidth;
+ entry.mBlockHeight = blockHeight;
+ entry.mTotalBlocks = ( width / blockWidth ) * ( height / blockHeight );
+ entry.mBlocksUsed = mAtlasList[ i ].mNextFreeBlock ? mAtlasList[ i ].mNextFreeBlock : entry.mTotalBlocks - mAtlasList[ i ].mFreeBlocksList.Size();
+ entry.mPixelFormat = GetPixelFormat( i + 1 );
+
+ metrics.mAtlasMetrics.PushBack( entry );
+
+ uint32_t size = width * height;
+ if ( entry.mPixelFormat == Pixel::BGRA8888 )
+ {
+ size <<= 2;
+ }
+
+ textureMemoryUsed += size;
+
+ }
+ metrics.mTextureMemoryUsed = textureMemoryUsed;
+}
+
} // namespace Internal
AtlasId GetAtlas( ImageId id ) const;
/**
- * @copydoc Toolkit::AtlasManager::SetAtlasSize
+ * @copydoc Toolkit::AtlasManager::SetNewAtlasSize
*/
- void SetAtlasSize( const Vector2& size,
- const Vector2& blockSize );
+ void SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize );
+
+ /**
+ * @copydoc Toolkit::AtlasManager::GetAtlasSize
+ */
+ Vector2 GetAtlasSize( AtlasId atlas );
/**
* @copydoc Toolkit::AtlasManager::GetBlockSize
*/
Pixel::Format GetPixelFormat( AtlasId atlas );
+ /**
+ * @copydoc Toolkit::AtlasManager::GetMetrics
+ */
+ void GetMetrics( Toolkit::AtlasManager::Metrics& metrics );
+
private:
std::vector< AtlasDescriptor > mAtlasList; // List of atlases created
return GetImplementation(*this).GetBlockSize( atlas );
}
+Vector2 AtlasManager::GetAtlasSize( AtlasId atlas )
+{
+ return GetImplementation(*this).GetAtlasSize( atlas );
+}
+
AtlasManager::SizeType AtlasManager::GetFreeBlocks( AtlasId atlas )
{
return GetImplementation(*this).GetFreeBlocks( atlas );
}
-void AtlasManager::SetAtlasSize( const Vector2& size,
- const Vector2& blockSize )
+void AtlasManager::SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize )
{
- GetImplementation(*this).SetAtlasSize( size, blockSize );
+ GetImplementation(*this).SetNewAtlasSize( size, blockSize );
}
AtlasManager::SizeType AtlasManager::GetAtlasCount() const
return GetImplementation(*this).GetPixelFormat( atlas );
}
+void AtlasManager::GetMetrics( Metrics& metrics )
+{
+ return GetImplementation(*this).GetMetrics( metrics );
+}
+
} // namespace Toolkit
} // namespace Dali
static const bool MESH_OPTIMIZE = true;
/**
+ * Metrics structures to describe Atlas Manager state
+ *
+ */
+ struct AtlasMetricsEntry
+ {
+ SizeType mWidth; // width of the atlas in pixels
+ SizeType mHeight;; // height of the atlas in pixels
+ SizeType mBlockWidth; // width of a block in pixels
+ SizeType mBlockHeight; // height of a block in pixels
+ SizeType mBlocksUsed; // number of blocks used in the atlas
+ SizeType mTotalBlocks; // total blocks used by atlas
+ Pixel::Format mPixelFormat; // pixel format of the atlas
+ };
+
+ struct Metrics
+ {
+ SizeType mAtlasCount; // number of atlases
+ SizeType mTextureMemoryUsed; // texture memory used by atlases
+ Dali::Vector< AtlasMetricsEntry > mAtlasMetrics; // container of atlas information
+ };
+
+ /**
* Create an AtlasManager handle; this can be initialised with AtlasManager::New()
* Calling member functions with an uninitialised handle is not allowed.
*/
/**
* @brief Create a blank atlas of specific dimensions and pixel format with a certain block size
*
- * @param width desired atlas width in pixels
- * @param height desired atlas height in pixels
- * @param blockWidth block width to use in atlas in pixels
- * @param blockHeight block height to use in atlas in pixels
- * @param pixelformat format of a pixel in atlas
+ * @param[in] width desired atlas width in pixels
+ * @param[in] height desired atlas height in pixels
+ * @param[in] blockWidth block width to use in atlas in pixels
+ * @param[in] blockHeight block height to use in atlas in pixels
+ * @param[in] pixelformat format of a pixel in atlas
*
* @return atlas Id
*/
/**
* @brief Get the BufferImage containing an atlas
*
- * @param atlas AtlasId returned when atlas was created
+ * @param[in] atlas AtlasId returned when atlas was created
+ *
* @return Atlas Handle
*/
Dali::Atlas GetAtlasContainer( AtlasId atlas ) const;
/**
* @brief Get the Id of the atlas containing an image
*
- * @param id ImageId
+ * @param[in] id ImageId
+ *
* @return Atlas Id
*/
AtlasId GetAtlas( ImageId id );
/**
* @brief Get the size of the blocks used in an atlas
*
- * @param atlas AtlasId
+ * @param[in] atlas AtlasId
+ *
* @return width and height of the blocks used
*/
Vector2 GetBlockSize( AtlasId atlas );
/**
+ * @brief Get the current size of an atlas
+ *
+ * @param[in] atlas AtlasId
+ *
+ * @return width and height of the atlas
+ */
+ Vector2 GetAtlasSize( AtlasId atlas );
+
+ /**
* @brief Get the number of blocks available in an atlas
*
- * @param atlas AtlasId
+ * @param[in] atlas AtlasId
+ *
* @return Number of blocks free in this atlas
*/
SizeType GetFreeBlocks( AtlasId atlas );
/**
* @brief Sets the pixel area of any new atlas and also the individual block size
*
- * @param size pixel area of atlas
+ * @param[in] size pixel area of atlas
+ *
* @param blockSize pixel area in atlas for a block
*/
- void SetAtlasSize( const Vector2& size,
- const Vector2& blockSize );
+ void SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize );
/**
* @brief Get the number of atlases created
/**
* @brief Get the pixel format used by an atlas
*
- * @param atlas AtlasId
+ * @param[in] atlas AtlasId
+ *
* @return Pixel format used by this atlas
*/
Pixel::Format GetPixelFormat( AtlasId atlas );
+ /**
+ * @brief Fill in a metrics structure showing current status of this Atlas Manager
+ *
+ * @param[in] metrics metrics structure to be filled
+ */
+ void GetMetrics( Metrics& metrics );
+
private:
explicit DALI_INTERNAL AtlasManager(Internal::AtlasManager *impl);
slot.mImageId = 0;
}
-void AtlasGlyphManager::SetAtlasSize( const Vector2& size,
- const Vector2& blockSize )
+void AtlasGlyphManager::SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize )
{
- mAtlasManager.SetAtlasSize( size, blockSize );
+ mAtlasManager.SetNewAtlasSize( size, blockSize );
}
void AtlasGlyphManager::Remove( uint32_t imageId )
return mAtlasManager.GetPixelFormat( atlasId );
}
+const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
+{
+ mMetrics.mGlyphCount = mGlyphRecords.Size();
+ mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
+ return mMetrics;
+}
+
} // namespace Internal
} // namespace Toolkit
Dali::Toolkit::AtlasManager::AtlasSlot& slot );
/**
- * @copydoc Toolkit::AtlasGlyphManager::SetAtlasSize
+ * @copydoc Toolkit::AtlasGlyphManager::SetNewAtlasSize
*/
- void SetAtlasSize( const Vector2& size,
- const Vector2& blockSize );
+ void SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize );
/**
* @copydoc Toolkit::AtlasGlyphManager::Remove
*/
Pixel::Format GetPixelFormat( uint32_t atlasId );
+ /**
+ * @copydoc toolkit::AtlasGlyphManager::GetMetrics
+ */
+ const Toolkit::AtlasGlyphManager::Metrics& GetMetrics();
+
private:
Dali::Toolkit::AtlasManager mAtlasManager;
Vector< GlyphRecord > mGlyphRecords;
uint32_t mCount;
+ Toolkit::AtlasGlyphManager::Metrics mMetrics;
};
} // namespace Internal
GetImplementation(*this).Cached( fontId, index, slot );
}
-void AtlasGlyphManager::SetAtlasSize( const Vector2& size,
- const Vector2& blockSize )
+void AtlasGlyphManager::SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize )
{
- GetImplementation(*this).SetAtlasSize( size, blockSize );
+ GetImplementation(*this).SetNewAtlasSize( size, blockSize );
}
void AtlasGlyphManager::Remove( uint32_t imageId )
return GetImplementation(*this).GetPixelFormat( atlasId );
}
+const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
+{
+ return GetImplementation(*this).GetMetrics();
+}
+
} // namespace Toolkit
} // namespace Dali
public:
/**
+ * Description of GlyphManager state
+ */
+ struct Metrics
+ {
+ uint32_t mGlyphCount; // number of glyphs being managed
+ AtlasManager::Metrics mAtlasMetrics; // metrics from the Atlas Manager
+ };
+
+ /**
* @brief Create a AtlasGlyphManager handle.
*
* Calling member functions with an uninitialised handle is not allowed.
* @param[in] size size of the atlas in pixels
* @param[in] blockSize size of a block in this atlas in pixels
*/
- void SetAtlasSize( const Vector2& size,
- const Vector2& blockSize );
+ void SetNewAtlasSize( const Vector2& size,
+ const Vector2& blockSize );
/**
* @brief Unreference an image from the atlas and remove from cache if no longer needed
/**
* @brief Get the Pixel Format used by an atlas
*
- * @param atlasId Id of atlas to check
+ * @param[in] atlasId Id of atlas to check
+ *
* @return The pixel format of the atlas
*/
Pixel::Format GetPixelFormat( uint32_t atlasId );
+ /**
+ * @brief Get Glyph Manager metrics
+ *
+ * @return const reference to glyph manager metrics
+ */
+ const Metrics& GetMetrics();
+
private:
explicit DALI_INTERNAL AtlasGlyphManager(Internal::AtlasGlyphManager *impl);
// 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;
{
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
{
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();
}
{
if ( mBlockSizes[ j ].mFontId == glyph.fontId )
{
- mGlyphManager.SetAtlasSize( DEFAULT_ATLAS_SIZE, mBlockSizes[ j ].mNeededBlockSize );
+ mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_SIZE, mBlockSizes[ j ].mNeededBlockSize );
}
}
lastFontId = glyph.fontId;
}
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,