X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fatlas-manager%2Fatlas-manager-impl.cpp;h=832e5d9010d0e740af07f0fa6f699a65224de8aa;hp=9ef43a9d67a9a7a8e2d4fb13e1ae8194f7035f56;hb=3e39b3bd20678fc2aba9618f782a830014f2062a;hpb=5823a096131e0d581ca2a070f5da23bd7fc47337 diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp index 9ef43a9..832e5d9 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp +++ b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp @@ -50,13 +50,11 @@ namespace attribute mediump vec2 aPosition; attribute mediump vec2 aTexCoord; uniform mediump mat4 uMvpMatrix; - uniform mediump vec3 uSize; varying mediump vec2 vTexCoord; void main() { mediump vec4 position = vec4( aPosition, 0.0, 1.0 ); - position.xyz *= uSize; gl_Position = uMvpMatrix * position; vTexCoord = aTexCoord; } @@ -74,7 +72,7 @@ namespace } ); - const char* FRAGMENT_SHADER_BGRA = MAKE_SHADER( + const char* FRAGMENT_SHADER_RGBA = MAKE_SHADER( uniform sampler2D sTexture; varying mediump vec2 vTexCoord; @@ -87,13 +85,14 @@ namespace } AtlasManager::AtlasManager() -: mAddFailPolicy( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES ), - mFilledPixel( FILLED_PIXEL ) +: mAddFailPolicy( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES ) { mNewAtlasSize.mWidth = DEFAULT_ATLAS_WIDTH; 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,30 +103,6 @@ AtlasManagerPtr AtlasManager::New() AtlasManager::~AtlasManager() { - 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 ) @@ -138,51 +113,55 @@ Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( const Toolkit::AtlasMa SizeType blockHeight = size.mBlockHeight; // Check to see if the atlas is large enough to hold a single block even ? - if ( blockWidth > width || blockHeight > height ) + if ( blockWidth + DOUBLE_PIXEL_PADDING + 1u > width || blockHeight + DOUBLE_PIXEL_PADDING + 1u > height ) { DALI_LOG_ERROR("Atlas %i x %i too small. Dimensions need to be at least %ix%i\n", - width, height, blockWidth, blockHeight ); + width, height, blockWidth + DOUBLE_PIXEL_PADDING + 1u, blockHeight + DOUBLE_PIXEL_PADDING + 1u ); return 0; } Dali::Atlas atlas = Dali::Atlas::New( width, height, pixelformat ); + atlas.Clear( Vector4::ZERO ); AtlasDescriptor atlasDescriptor; atlasDescriptor.mAtlas = atlas; 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 )? - SizeType neededStripSize =( blockWidth > blockHeight - DOUBLE_PIXEL_PADDING ? blockWidth : blockHeight - DOUBLE_PIXEL_PADDING ) << 2; - atlasDescriptor.mStripBuffer = new PixelBuffer[ neededStripSize ]; - memset( atlasDescriptor.mStripBuffer, 0, neededStripSize ); - - atlasDescriptor.mHorizontalStrip = BufferImage::New( atlasDescriptor.mStripBuffer, - blockWidth, - SINGLE_PIXEL_PADDING, - pixelformat ); - - atlasDescriptor.mVerticalStrip = BufferImage::New( atlasDescriptor.mStripBuffer, - 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 ); + atlasDescriptor.mTotalBlocks = ( ( width - 1u ) / blockWidth ) * ( ( height - 1u ) / blockHeight ); + atlasDescriptor.mAvailableBlocks = atlasDescriptor.mTotalBlocks; - Sampler sampler = Sampler::New( atlas, "sTexture" ); - sampler.SetProperty( Sampler::Property::AFFECTS_TRANSPARENCY, true ); - Shader shader; - if ( pixelformat == Pixel::BGRA8888 ) + atlasDescriptor.mHorizontalStrip = BufferImage::New( blockWidth, SINGLE_PIXEL_PADDING, pixelformat ); + atlasDescriptor.mVerticalStrip = BufferImage::New( SINGLE_PIXEL_PADDING, blockHeight - DOUBLE_PIXEL_PADDING, pixelformat ); + + PixelBuffer* buffer = atlasDescriptor.mHorizontalStrip.GetBuffer(); + if( buffer == NULL ) { - shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_BGRA ); + DALI_LOG_ERROR("atlasDescriptor.mHorizontalStrip.GetBuffer() returns NULL\n"); + return 0; } - else + memset( buffer, 0, atlasDescriptor.mHorizontalStrip.GetBufferSize() ); + + buffer = atlasDescriptor.mVerticalStrip.GetBuffer(); + if( buffer == NULL ) + { + DALI_LOG_ERROR("atlasDescriptor.mVerticalStrip.GetBuffer() returns NULL\n"); + return 0; + } + memset( buffer, 0, atlasDescriptor.mVerticalStrip.GetBufferSize() ); + + BufferImage filledPixelImage = BufferImage::New( 1u, 1u, pixelformat ); + buffer = filledPixelImage.GetBuffer(); + if( buffer == NULL) { - shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_L8 ); + DALI_LOG_ERROR("filledPixelImage.GetBuffer() returns NULL\n"); + return 0; } - atlasDescriptor.mMaterial = Material::New( shader ); + + memset( buffer, 0xFF, filledPixelImage.GetBufferSize() ); + atlas.Upload( filledPixelImage, 0, 0 ); + + Sampler sampler = Sampler::New( atlas, "sTexture" ); + sampler.SetProperty( Sampler::Property::AFFECTS_TRANSPARENCY, true ); + atlasDescriptor.mMaterial = Material::New( pixelformat == Pixel::L8 ? mShaderL8 : mShaderRgba ); atlasDescriptor.mMaterial.AddSampler( sampler ); atlasDescriptor.mSampler = sampler; atlasDescriptor.mMaterial.SetBlendMode( BlendingMode::ON ); @@ -205,7 +184,6 @@ void AtlasManager::Add( const BufferImage& image, SizeType width = image.GetWidth(); SizeType height = image.GetHeight(); SizeType blockArea = 0; - SizeType totalBlocks = 0; SizeType foundAtlas = 0; SizeType index = 0; slot.mImageId = 0; @@ -215,14 +193,13 @@ void AtlasManager::Add( const BufferImage& image, // If there is a preferred atlas then check for room in that first if ( atlas-- ) { - foundAtlas = CheckAtlas( atlas, width, height, pixelFormat, blockArea, totalBlocks ); + foundAtlas = CheckAtlas( atlas, width, height, pixelFormat, blockArea ); } // Search current atlases to see if there is a good match - while( !foundAtlas && index < mAtlasList.size() ) { - foundAtlas = CheckAtlas( index, width, height, pixelFormat, blockArea, totalBlocks ); + foundAtlas = CheckAtlas( index, width, height, pixelFormat, blockArea ); ++index; } @@ -231,20 +208,24 @@ void AtlasManager::Add( const BufferImage& image, { if ( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES == mAddFailPolicy ) { - SizeType newAtlas = CreateAtlas( mNewAtlasSize, pixelFormat ); - if ( !newAtlas-- ) + foundAtlas = CreateAtlas( mNewAtlasSize, pixelFormat ); + if ( !foundAtlas-- ) { + DALI_LOG_ERROR("Failed to create an atlas of %i x %i blocksize: %i x %i.\n", + mNewAtlasSize.mWidth, + mNewAtlasSize.mHeight, + mNewAtlasSize.mBlockWidth, + mNewAtlasSize.mBlockHeight ); return; } - else - { - foundAtlas = CheckAtlas( newAtlas, width, height, pixelFormat, blockArea, totalBlocks ); - } + + foundAtlas = CheckAtlas( foundAtlas, width, height, pixelFormat, blockArea ); } - if ( Toolkit::AtlasManager::FAIL_ON_ADD_FAILS == mAddFailPolicy || !foundAtlas-- ) + if ( !foundAtlas-- || Toolkit::AtlasManager::FAIL_ON_ADD_FAILS == mAddFailPolicy ) { // Haven't found an atlas for this image!!!!!! + DALI_LOG_ERROR("Failed to create an atlas under current policy.\n"); return; } } @@ -253,21 +234,10 @@ void AtlasManager::Add( const BufferImage& image, for ( SizeType i = 0; i < blockArea; ++i ) { // Is there currently a next free block available ? - if ( mAtlasList[ foundAtlas ].mNextFreeBlock ) + if ( mAtlasList[ foundAtlas ].mAvailableBlocks ) { - // Yes, so use this for our next block - SizeType selectedBlock = mAtlasList[ foundAtlas ].mNextFreeBlock - 1u; - desc.mBlocksList.PushBack( selectedBlock ); - - // Any blocks going to be available after this one (adjust to store +1 )? - selectedBlock++; - selectedBlock++; - if ( selectedBlock > totalBlocks ) - { - // No so start trying to use free blocks list - selectedBlock = 0; - } - mAtlasList[ foundAtlas ].mNextFreeBlock = selectedBlock; + // Yes, so select our next block + desc.mBlocksList.PushBack( mAtlasList[ foundAtlas ].mTotalBlocks - mAtlasList[ foundAtlas ].mAvailableBlocks-- ); } else { @@ -283,8 +253,8 @@ void AtlasManager::Add( const BufferImage& image, desc.mCount = 1u; // See if there's a previously freed image ID that we can assign to this new image - uint32_t imageId = 0; - for ( uint32_t i = 0; i < mImageList.size(); ++i ) + uint32_t imageId = 0u; + for ( uint32_t i = 0u; i < mImageList.size(); ++i ) { if ( !mImageList[ i ].mCount ) { @@ -310,29 +280,20 @@ AtlasManager::SizeType AtlasManager::CheckAtlas( SizeType atlas, SizeType width, SizeType height, Pixel::Format pixelFormat, - SizeType& blockArea, - SizeType& totalBlocks ) + SizeType& blockArea ) { if ( pixelFormat == mAtlasList[ atlas ].mPixelFormat ) { - // Check to see if there are any unused blocks in this atlas to accomodate our image - SizeType blocksInX = mAtlasList[ atlas ].mSize.mWidth / mAtlasList[ atlas ].mSize.mBlockWidth; - SizeType blocksInY = mAtlasList[ atlas ].mSize.mHeight / mAtlasList[ atlas ].mSize.mBlockHeight; - totalBlocks = blocksInX * blocksInY; - SizeType blocksFree = mAtlasList[ atlas ].mNextFreeBlock ? - totalBlocks - mAtlasList[ atlas ].mNextFreeBlock + 1u : - mAtlasList[ atlas ].mFreeBlocksList.Size(); - // Check to see if the image will fit in these blocks, if not we'll need to create a new atlas - if ( blocksFree - && width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockWidth - && height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockHeight ) + if ( ( mAtlasList[ atlas ].mAvailableBlocks + mAtlasList[ atlas ].mFreeBlocksList.Size() ) + && width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockWidth + && height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockHeight ) { blockArea = 1u; return ( atlas + 1u ); } } - return 0; + return 0u; } void AtlasManager::CreateMesh( SizeType atlas, @@ -344,7 +305,6 @@ void AtlasManager::CreateMesh( SizeType atlas, Toolkit::AtlasManager::Mesh2D& mesh, AtlasSlotDescriptor& desc ) { - Toolkit::AtlasManager::Vertex2D vertex; uint32_t faceIndex = 0; // TODO change to unsigned short when property type is available @@ -357,7 +317,7 @@ void AtlasManager::CreateMesh( SizeType atlas, SizeType width = mAtlasList[ atlas ].mSize.mWidth; SizeType height = mAtlasList[ atlas ].mSize.mHeight; - SizeType atlasWidthInBlocks = width / blockWidth; + SizeType atlasWidthInBlocks = ( width - 1u ) / blockWidth; // Get the normalized size of a texel in both directions // TODO when texture resizing and passing texture size via uniforms is available, @@ -366,6 +326,9 @@ void AtlasManager::CreateMesh( SizeType atlas, float texelX = 1.0f / static_cast< float >( width ); float texelY = 1.0f / static_cast< float >( height ); + float oneAndAHalfTexelX = texelX + ( texelX * 0.5f ); + float oneAndAHalfTexelY = texelY + ( texelY * 0.5f ); + // Get the normalized size of a block in texels float texelBlockWidth = texelX * vertexBlockWidth; float texelBlockHeight = texelY * vertexBlockHeight; @@ -375,8 +338,14 @@ void AtlasManager::CreateMesh( SizeType atlas, float vertexEdgeHeight = static_cast< float >( imageHeight % blockHeight ); // And in texels - float texelEdgeWidth = vertexEdgeWidth * texelX; - float texelEdgeHeight = vertexEdgeHeight * texelY; + float texelEdgeWidth = texelX * vertexEdgeWidth; + float texelEdgeHeight = texelY * vertexEdgeHeight; + + // We're going to 'blit' half a pixel more on each edge + vertexBlockWidth++; + vertexEdgeWidth++; + vertexBlockHeight++; + vertexEdgeHeight++; // Block by block create the two triangles for the quad SizeType blockIndex = 0; @@ -385,7 +354,8 @@ void AtlasManager::CreateMesh( SizeType atlas, float ndcVWidth; float ndcVHeight; - Vector2 topLeft = position; + // Move back half a pixel + Vector2 topLeft = Vector2( position.x - 0.5f, position.y - 0.5f ); for ( SizeType y = 0; y < heightInBlocks; ++y ) { @@ -394,12 +364,12 @@ void AtlasManager::CreateMesh( SizeType atlas, if ( ( heightInBlocks - 1u ) == y && vertexEdgeHeight > 0.0f ) { - ndcHeight = texelEdgeHeight; + ndcHeight = texelEdgeHeight + texelY; ndcVHeight = vertexEdgeHeight; } else { - ndcHeight = texelBlockHeight; + ndcHeight = texelBlockHeight + texelY; ndcVHeight = vertexBlockHeight; } @@ -410,18 +380,18 @@ void AtlasManager::CreateMesh( SizeType atlas, float fBlockX = texelBlockWidth * static_cast< float >( block % atlasWidthInBlocks ); float fBlockY = texelBlockHeight * static_cast< float >( block / atlasWidthInBlocks ); - // Add on texture filtering compensation - fBlockX += texelX; - fBlockY += texelY; + // Add on texture filtering compensation ( half a texel plus compensation for filled pixel in top left corner ) + fBlockX += oneAndAHalfTexelX; + fBlockY += oneAndAHalfTexelY; if ( ( widthInBlocks - 1u ) == x && vertexEdgeWidth > 0.0f ) { - ndcWidth = texelEdgeWidth; + ndcWidth = texelEdgeWidth + texelX; ndcVWidth = vertexEdgeWidth; } else { - ndcWidth = texelBlockWidth; + ndcWidth = texelBlockWidth + texelX; ndcVWidth = vertexBlockWidth; } @@ -479,7 +449,6 @@ void AtlasManager::CreateMesh( SizeType atlas, Toolkit::AtlasManager::Mesh2D optimizedMesh; OptimizeMesh( mesh, optimizedMesh ); } - //PrintMeshData( mesh ); } void AtlasManager::PrintMeshData( const Toolkit::AtlasManager::Mesh2D& mesh ) @@ -518,8 +487,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 ); @@ -542,16 +513,22 @@ void AtlasManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first, const Toolkit::AtlasManager::Mesh2D& second, bool optimize ) { - uint32_t vc = first.mVertices.Size(); + const uint32_t verticesCount = first.mVertices.Size(); + first.mVertices.Insert( first.mVertices.End(), + second.mVertices.Begin(), + second.mVertices.End() ); - for ( uint32_t v = 0; v < second.mVertices.Size(); ++v ) - { - first.mVertices.PushBack( second.mVertices[ v ] ); - } + const uint32_t indicesCount = first.mIndices.Size(); + first.mIndices.Insert( first.mIndices.End(), + second.mIndices.Begin(), + second.mIndices.End() ); - for ( uint32_t i = 0; i < second.mIndices.Size(); ++i ) + for( Vector::Iterator it = first.mIndices.Begin() + indicesCount, + endIt = first.mIndices.End(); + it != endIt; + ++it ) { - first.mIndices.PushBack( second.mIndices[ i ] + vc ); + *it += verticesCount; } if ( optimize ) @@ -562,41 +539,6 @@ void AtlasManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first, } } -void AtlasManager::StitchMesh( const Toolkit::AtlasManager::Mesh2D& first, - const Toolkit::AtlasManager::Mesh2D& second, - Toolkit::AtlasManager::Mesh2D& out, - bool optimize ) -{ - uint32_t vc = first.mVertices.Size(); - - for ( uint32_t v = 0; v < vc; ++v ) - { - out.mVertices.PushBack( first.mVertices[ v ] ); - } - - for ( uint32_t v = 0; v < second.mVertices.Size(); ++v ) - { - out.mVertices.PushBack( second.mVertices[ v ] ); - } - - for ( uint32_t i = 0; i < first.mIndices.Size(); ++i ) - { - out.mIndices.PushBack( first.mIndices[ i ] ); - } - - for ( uint32_t i = 0; i < second.mIndices.Size(); ++i ) - { - out.mIndices.PushBack( second.mIndices[ i ] + vc ); - } - - if ( optimize ) - { - Toolkit::AtlasManager::Mesh2D optimizedMesh; - OptimizeMesh( out, optimizedMesh ); - out = optimizedMesh; - } -} - void AtlasManager::UploadImage( const BufferImage& image, const AtlasSlotDescriptor& desc ) { @@ -612,13 +554,13 @@ void AtlasManager::UploadImage( const BufferImage& image, SizeType atlasBlockWidth = mAtlasList[ atlas ].mSize.mBlockWidth; SizeType atlasBlockHeight = mAtlasList[ atlas ].mSize.mBlockHeight; - SizeType atlasWidthInBlocks = mAtlasList[ atlas ].mSize.mWidth / mAtlasList[ atlas ].mSize.mBlockWidth; + SizeType atlasWidthInBlocks = ( mAtlasList[ atlas ].mSize.mWidth - 1u ) / mAtlasList[ atlas ].mSize.mBlockWidth; SizeType block = desc.mBlocksList[ 0 ]; SizeType blockX = block % atlasWidthInBlocks; SizeType blockY = block / atlasWidthInBlocks; - SizeType blockOffsetX = blockX * atlasBlockWidth; - SizeType blockOffsetY = blockY * atlasBlockHeight; + SizeType blockOffsetX = ( blockX * atlasBlockWidth ) + 1u; + SizeType blockOffsetY = ( blockY * atlasBlockHeight) + 1u; SizeType width = image.GetWidth(); SizeType height = image.GetHeight(); @@ -630,38 +572,21 @@ void AtlasManager::UploadImage( const BufferImage& image, { DALI_LOG_ERROR("Uploading image to Atlas Failed!.\n"); } - else + + // Blit top strip + if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mHorizontalStrip, + blockOffsetX, + blockOffsetY ) ) { - mUploadedImages.PushBack( const_cast< BufferImage& >( image ).GetBuffer() ); + DALI_LOG_ERROR("Uploading top strip to Atlas Failed!\n"); } - // If this is the first block then we need to keep the first pixel free for underline texture - if ( block ) + // Blit left strip + if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip, + blockOffsetX, + blockOffsetY + SINGLE_PIXEL_PADDING ) ) { - - // Blit top strip - if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mHorizontalStrip, - blockOffsetX, - blockOffsetY ) ) - { - 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, - blockOffsetX, - blockOffsetY + SINGLE_PIXEL_PADDING ) ) - { - DALI_LOG_ERROR("Uploading left strip to Atlas Failed!\n"); - } - else - { - mUploadedImages.PushBack( NULL ); - } + DALI_LOG_ERROR("Uploading left strip to Atlas Failed!\n"); } // Blit bottom strip @@ -673,10 +598,6 @@ void AtlasManager::UploadImage( const BufferImage& image, { DALI_LOG_ERROR("Uploading bottom strip to Atlas Failed!.\n"); } - else - { - mUploadedImages.PushBack( NULL ); - } } // Blit right strip @@ -688,38 +609,45 @@ 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; - SizeType atlas = mImageList[ imageId ].mAtlasId - 1u; - SizeType width = mImageList[ imageId ].mImageWidth; - SizeType height = mImageList[ imageId ].mImageHeight; - - SizeType widthInBlocks = width / mAtlasList[ atlas ].mSize.mBlockWidth; - if ( width % mAtlasList[ atlas ].mSize.mBlockWidth ) + if ( id ) { - widthInBlocks++; + // Read the atlas Id to use for this image + SizeType imageId = id - 1u; + SizeType atlas = mImageList[ imageId ].mAtlasId - 1u; + SizeType width = mImageList[ imageId ].mImageWidth; + SizeType height = mImageList[ imageId ].mImageHeight; + + SizeType widthInBlocks = width / mAtlasList[ atlas ].mSize.mBlockWidth; + if ( width % mAtlasList[ atlas ].mSize.mBlockWidth ) + { + widthInBlocks++; + } + SizeType heightInBlocks = height / mAtlasList[ atlas ].mSize.mBlockHeight; + if ( height % mAtlasList[ atlas ].mSize.mBlockHeight ) + { + heightInBlocks++; + } + + CreateMesh( atlas, width, height, position, widthInBlocks, heightInBlocks, meshData, mImageList[ imageId ] ); + + // Mesh created so increase the reference count, if we're asked to + if ( addReference ) + { + mImageList[ imageId ].mCount++; + } } - SizeType heightInBlocks = height / mAtlasList[ atlas ].mSize.mBlockHeight; - if ( height % mAtlasList[ atlas ].mSize.mBlockHeight ) + else { - heightInBlocks++; + DALI_LOG_ERROR("Cannot generate mesh with invalid AtlasId\n"); } - - CreateMesh( atlas, width, height, position, widthInBlocks, heightInBlocks, meshData, mImageList[ imageId ] ); - - // Mesh created so increase the reference count - mImageList[ imageId ].mCount++; } Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const @@ -782,6 +710,8 @@ AtlasManager::AtlasId AtlasManager::GetAtlas( ImageId id ) const void AtlasManager::SetNewAtlasSize( const Toolkit::AtlasManager::AtlasSize& size ) { mNewAtlasSize = size; + + // Add on padding for borders around atlas entries mNewAtlasSize.mBlockWidth += DOUBLE_PIXEL_PADDING; mNewAtlasSize.mBlockHeight += DOUBLE_PIXEL_PADDING; } @@ -797,28 +727,9 @@ const Toolkit::AtlasManager::AtlasSize& AtlasManager::GetAtlasSize( AtlasId atla AtlasManager::SizeType AtlasManager::GetFreeBlocks( AtlasId atlas ) const { - if ( atlas && atlas <= mAtlasList.size() ) + if ( atlas && atlas-- <= mAtlasList.size() ) { - uint32_t index = atlas - 1u; - uint32_t width = mAtlasList[ index ].mSize.mWidth; - uint32_t height = mAtlasList[ index ].mSize.mHeight; - uint32_t blockWidth = mAtlasList[ index ].mSize.mBlockWidth; - uint32_t blockHeight = mAtlasList[ index ].mSize.mBlockHeight; - - SizeType widthInBlocks = width / blockWidth; - SizeType heightInBlocks = height / blockHeight; - uint32_t blockCount = widthInBlocks * heightInBlocks; - - // Check free previously unallocated blocks and any free blocks - if ( mAtlasList[ index ].mNextFreeBlock ) - { - blockCount -= mAtlasList[ index ].mNextFreeBlock -1u - mAtlasList[ index ].mFreeBlocksList.Size(); - } - else - { - blockCount = mAtlasList[ index ].mFreeBlocksList.Size(); - } - return blockCount; + return ( mAtlasList[ atlas ].mAvailableBlocks + mAtlasList[ atlas ].mFreeBlocksList.Size() ); } else { @@ -839,7 +750,7 @@ Pixel::Format AtlasManager::GetPixelFormat( AtlasId atlas ) DALI_LOG_ERROR("Cannot get Atlas from AtlasID ( doesn't exist ).\n"); return Pixel::L8; } - return mAtlasList[ atlas -1u ].mPixelFormat; + return mAtlasList[ --atlas].mPixelFormat; } void AtlasManager::GetMetrics( Toolkit::AtlasManager::Metrics& metrics ) @@ -853,12 +764,11 @@ void AtlasManager::GetMetrics( Toolkit::AtlasManager::Metrics& metrics ) for ( uint32_t i = 0; i < atlasCount; ++i ) { entry.mSize = mAtlasList[ i ].mSize; - entry.mTotalBlocks = ( entry.mSize.mWidth / entry.mSize.mBlockWidth ) * ( entry.mSize.mHeight / entry.mSize.mBlockHeight ); - uint32_t reuseBlocks = mAtlasList[ i ].mFreeBlocksList.Size(); - entry.mBlocksUsed = mAtlasList[ i ].mNextFreeBlock ? mAtlasList[ i ].mNextFreeBlock - reuseBlocks - 1u: entry.mTotalBlocks - reuseBlocks; + entry.mTotalBlocks = mAtlasList[ i ].mTotalBlocks; + entry.mBlocksUsed = entry.mTotalBlocks - mAtlasList[ i ].mAvailableBlocks + mAtlasList[ i ].mFreeBlocksList.Size(); entry.mPixelFormat = GetPixelFormat( i + 1 ); - metrics.mAtlasMetrics.PushBack( entry ); + metrics.mAtlasMetrics.PushBack( entry ); uint32_t size = entry.mSize.mWidth * entry.mSize.mHeight; if ( entry.mPixelFormat == Pixel::BGRA8888 ) @@ -874,9 +784,9 @@ void AtlasManager::GetMetrics( Toolkit::AtlasManager::Metrics& metrics ) Material AtlasManager::GetMaterial( AtlasId atlas ) const { - if ( atlas && atlas <= mAtlasList.size() ) + if ( atlas && atlas-- <= mAtlasList.size() ) { - return mAtlasList[ atlas -1u ].mMaterial; + return mAtlasList[ atlas ].mMaterial; } Material null; return null; @@ -884,9 +794,9 @@ Material AtlasManager::GetMaterial( AtlasId atlas ) const Sampler AtlasManager::GetSampler( AtlasId atlas ) const { - if ( atlas && atlas <= mAtlasList.size() ) + if ( atlas && atlas-- <= mAtlasList.size() ) { - return mAtlasList[ atlas -1u ].mSampler; + return mAtlasList[ atlas ].mSampler; } Sampler null; return null;