X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Frendering%2Fatlas%2Fatlas-manager-impl.cpp;h=ba07ceff330ee2dfbb9e94e6f59be7ee7c29b8f4;hb=6b0ebeb01bd36475054ec211311763cd82390dd1;hp=dacb141218e2b8e31e03e226f159c0465b73818d;hpb=aae67693a392087235a203195366691f2dc9f91f;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-manager-impl.cpp b/dali-toolkit/internal/text/rendering/atlas/atlas-manager-impl.cpp index dacb141..ba07cef 100644 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-manager-impl.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-manager-impl.cpp @@ -41,8 +41,12 @@ namespace const uint32_t DEFAULT_BLOCK_HEIGHT( 16u ); const uint32_t SINGLE_PIXEL_PADDING( 1u ); const uint32_t DOUBLE_PIXEL_PADDING( SINGLE_PIXEL_PADDING << 1 ); - const uint32_t FILLED_PIXEL( -1 ); Toolkit::AtlasManager::AtlasSize EMPTY_SIZE; + + bool IsBlockSizeSufficient( uint32_t width, uint32_t height, uint32_t requiredBlockWidth, uint32_t requiredBlockHeight ) + { + return ( width + DOUBLE_PIXEL_PADDING <= requiredBlockWidth ) && ( height + DOUBLE_PIXEL_PADDING <= requiredBlockHeight ); + } } AtlasManager::AtlasManager() @@ -79,8 +83,15 @@ Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( const Toolkit::AtlasMa return 0; } - Dali::Atlas atlas = Dali::Atlas::New( width, height, pixelformat ); - atlas.Clear( Vector4::ZERO ); + Dali::Texture atlas = Dali::Texture::New( TextureType::TEXTURE_2D, pixelformat, width, height ); + + // Clear the background + unsigned int bufferSize( width * height * Dali::Pixel::GetBytesPerPixel( pixelformat ) ); + unsigned char* background = new unsigned char[bufferSize]; + memset( background, 0, bufferSize ); + PixelData backgroundPixels = PixelData::New( background, bufferSize, width, height, pixelformat, PixelData::DELETE_ARRAY ); + atlas.Upload( backgroundPixels, 0u, 0u, 0u, 0u, width, height ); + AtlasDescriptor atlasDescriptor; atlasDescriptor.mAtlas = atlas; atlasDescriptor.mSize = size; @@ -88,35 +99,21 @@ Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( const Toolkit::AtlasMa atlasDescriptor.mTotalBlocks = ( ( width - 1u ) / blockWidth ) * ( ( height - 1u ) / blockHeight ); atlasDescriptor.mAvailableBlocks = atlasDescriptor.mTotalBlocks; - 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 ) - { - DALI_LOG_ERROR("atlasDescriptor.mHorizontalStrip.GetBuffer() returns NULL\n"); - return 0; - } - 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) - { - DALI_LOG_ERROR("filledPixelImage.GetBuffer() returns NULL\n"); - return 0; - } - - memset( buffer, 0xFF, filledPixelImage.GetBufferSize() ); - atlas.Upload( filledPixelImage, 0, 0 ); + bufferSize = blockWidth * SINGLE_PIXEL_PADDING * Dali::Pixel::GetBytesPerPixel(pixelformat); + unsigned char* bufferHorizontalStrip = new unsigned char[bufferSize]; + memset( bufferHorizontalStrip, 0, bufferSize ); + atlasDescriptor.mHorizontalStrip = PixelData::New( bufferHorizontalStrip, bufferSize, blockWidth, SINGLE_PIXEL_PADDING, pixelformat, PixelData::DELETE_ARRAY ); + + bufferSize = SINGLE_PIXEL_PADDING * (blockHeight - DOUBLE_PIXEL_PADDING) * Dali::Pixel::GetBytesPerPixel(pixelformat); + unsigned char* bufferVerticalStrip = new unsigned char[bufferSize]; + memset( bufferVerticalStrip, 0, bufferSize ); + atlasDescriptor.mVerticalStrip = PixelData::New( bufferVerticalStrip, bufferSize, SINGLE_PIXEL_PADDING, blockHeight - DOUBLE_PIXEL_PADDING, pixelformat, PixelData::DELETE_ARRAY ); + + bufferSize = Dali::Pixel::GetBytesPerPixel(pixelformat); + unsigned char* buffer = new unsigned char[bufferSize]; + memset( buffer, 0xFF, bufferSize ); + PixelData filledPixelImage = PixelData::New( buffer, bufferSize, 1u, 1u, pixelformat, PixelData::DELETE_ARRAY ); + atlas.Upload( filledPixelImage, 0u, 0u, 0u, 0u, 1u, 1u ); mAtlasList.push_back( atlasDescriptor ); return mAtlasList.size(); } @@ -126,7 +123,7 @@ void AtlasManager::SetAddPolicy( Toolkit::AtlasManager::AddFailPolicy policy ) mAddFailPolicy = policy; } -bool AtlasManager::Add( const BufferImage& image, +bool AtlasManager::Add( const PixelData& image, Toolkit::AtlasManager::AtlasSlot& slot, Toolkit::AtlasManager::AtlasId atlas ) { @@ -147,39 +144,46 @@ bool AtlasManager::Add( const BufferImage& image, } // Search current atlases to see if there is a good match - while( !foundAtlas && index < mAtlasList.size() ) + while( ( 0u == foundAtlas ) && ( index < mAtlasList.size() ) ) { foundAtlas = CheckAtlas( index, width, height, pixelFormat ); ++index; } // If we can't find a suitable atlas then check the policy to determine action - if ( !foundAtlas-- ) + if ( 0u == foundAtlas ) { if ( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES == mAddFailPolicy ) { - foundAtlas = CreateAtlas( mNewAtlasSize, pixelFormat ); - if ( !foundAtlas-- ) + if ( IsBlockSizeSufficient( width, height, mNewAtlasSize.mBlockWidth, mNewAtlasSize.mBlockHeight ) ) // Checks if image fits within the atlas blocks { - 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 created; + foundAtlas = CreateAtlas( mNewAtlasSize, pixelFormat ); // Creating atlas with mNewAtlasSize, may not be the needed size! + if ( 0u == 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 false; + } + else + { + created = true; + } } - created = true; - foundAtlas = CheckAtlas( foundAtlas, width, height, pixelFormat ); } - if ( !foundAtlas-- || Toolkit::AtlasManager::FAIL_ON_ADD_FAILS == mAddFailPolicy ) + if ( ( 0u == foundAtlas ) || Toolkit::AtlasManager::FAIL_ON_ADD_FAILS == mAddFailPolicy ) { - // Haven't found an atlas for this image!!!!!! + // Haven't found an atlas for this image ( may have failed to add image to atlas ) DALI_LOG_ERROR("Failed to create an atlas under current policy.\n"); - return created; + return false; } } + foundAtlas--; // Atlas created successfully, decrement by 1 to get index (starts at 0 not 1) + // Work out which the block we're going to use // Is there currently a next free block available ? if ( mAtlasList[ foundAtlas ].mAvailableBlocks ) @@ -196,7 +200,7 @@ bool AtlasManager::Add( const BufferImage& image, desc.mImageWidth = width; desc.mImageHeight = height; - desc.mAtlasId = foundAtlas + 1u; + desc.mAtlasId = foundAtlas + 1u; // Ids start from 1 not the 0 index desc.mCount = 1u; // See if there's a previously freed image ID that we can assign to this new image @@ -219,7 +223,7 @@ bool AtlasManager::Add( const BufferImage& image, mImageList[ imageId - 1u ] = desc; slot.mImageId = imageId; } - slot.mAtlasId = foundAtlas + 1u; + slot.mAtlasId = foundAtlas + 1u; // Ids start from 1 not the 0 index // Upload the buffer image into the atlas UploadImage( image, desc ); @@ -234,18 +238,19 @@ AtlasManager::SizeType AtlasManager::CheckAtlas( SizeType atlas, AtlasManager::SizeType result = 0u; if ( pixelFormat == mAtlasList[ atlas ].mPixelFormat ) { - // Check to see if the image will fit in these blocks, if not we'll need to create a new atlas - if ( ( mAtlasList[ atlas ].mAvailableBlocks + mAtlasList[ atlas ].mFreeBlocksList.Size() ) - && width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockWidth - && height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockHeight ) + // Check to see if the image will fit in these blocks + + const SizeType availableBlocks = mAtlasList[ atlas ].mAvailableBlocks + mAtlasList[ atlas ].mFreeBlocksList.Size(); + + if ( availableBlocks && IsBlockSizeSufficient( width, height,mAtlasList[ atlas ].mSize.mBlockWidth, mAtlasList[ atlas ].mSize.mBlockHeight ) ) { - result = atlas + 1u; + result = atlas + 1u; // Atlas ids start from 1 not 0 } } return result; } -void AtlasManager::UploadImage( const BufferImage& image, +void AtlasManager::UploadImage( const PixelData& image, const AtlasSlotDescriptor& desc ) { // Get the atlas to upload the image to @@ -271,25 +276,30 @@ void AtlasManager::UploadImage( const BufferImage& image, SizeType height = image.GetHeight(); // Blit image 1 pixel to the right and down into the block to compensate for texture filtering - if ( !mAtlasList[ atlas ].mAtlas.Upload( image, + if ( !mAtlasList[ atlas ].mAtlas.Upload( image, 0u, 0u, blockOffsetX + SINGLE_PIXEL_PADDING, - blockOffsetY + SINGLE_PIXEL_PADDING ) ) + blockOffsetY + SINGLE_PIXEL_PADDING, + width, height) ) { DALI_LOG_ERROR("Uploading image to Atlas Failed!.\n"); } // Blit top strip - if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mHorizontalStrip, + if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mHorizontalStrip, 0u, 0u, blockOffsetX, - blockOffsetY ) ) + blockOffsetY, + mAtlasList[ atlas ].mHorizontalStrip.GetWidth(), + mAtlasList[ atlas ].mHorizontalStrip.GetHeight()) ) { DALI_LOG_ERROR("Uploading top strip to Atlas Failed!\n"); } // Blit left strip - if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip, + if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip, 0u, 0u, blockOffsetX, - blockOffsetY + SINGLE_PIXEL_PADDING ) ) + blockOffsetY + SINGLE_PIXEL_PADDING, + mAtlasList[ atlas ].mVerticalStrip.GetWidth(), + mAtlasList[ atlas ].mVerticalStrip.GetHeight() ) ) { DALI_LOG_ERROR("Uploading left strip to Atlas Failed!\n"); } @@ -297,9 +307,11 @@ void AtlasManager::UploadImage( const BufferImage& image, // Blit bottom strip if ( blockOffsetY + height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mHeight ) { - if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mHorizontalStrip, + if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mHorizontalStrip, 0u, 0u, blockOffsetX, - blockOffsetY + height + SINGLE_PIXEL_PADDING ) ) + blockOffsetY + height + SINGLE_PIXEL_PADDING, + mAtlasList[ atlas ].mHorizontalStrip.GetWidth(), + mAtlasList[ atlas ].mHorizontalStrip.GetHeight() ) ) { DALI_LOG_ERROR("Uploading bottom strip to Atlas Failed!.\n"); } @@ -308,9 +320,11 @@ void AtlasManager::UploadImage( const BufferImage& image, // Blit right strip if ( blockOffsetX + width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mWidth ) { - if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip, + if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mVerticalStrip, 0u, 0u, blockOffsetX + width + SINGLE_PIXEL_PADDING, - blockOffsetY + SINGLE_PIXEL_PADDING ) ) + blockOffsetY + SINGLE_PIXEL_PADDING, + mAtlasList[ atlas ].mVerticalStrip.GetWidth(), + mAtlasList[ atlas ].mVerticalStrip.GetHeight() ) ) { DALI_LOG_ERROR("Uploading right strip to Atlas Failed!.\n"); } @@ -349,10 +363,10 @@ void AtlasManager::GenerateMeshData( ImageId id, } } -Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const +Dali::Texture AtlasManager::GetAtlasContainer( AtlasId atlas ) const { DALI_ASSERT_DEBUG( atlas && atlas <= mAtlasList.size() ); - Dali::Atlas atlasContainer; + Dali::Texture atlasContainer; if ( atlas && atlas-- <= mAtlasList.size() ) { atlasContainer = mAtlasList[ atlas ].mAtlas; @@ -436,7 +450,7 @@ AtlasManager::SizeType AtlasManager::GetAtlasCount() const return mAtlasList.size(); } -Pixel::Format AtlasManager::GetPixelFormat( AtlasId atlas ) +Pixel::Format AtlasManager::GetPixelFormat( AtlasId atlas ) const { DALI_ASSERT_DEBUG( atlas && atlas <= mAtlasList.size() ); Pixel::Format pixelFormat = Pixel::RGBA8888; @@ -476,23 +490,23 @@ void AtlasManager::GetMetrics( Toolkit::AtlasManager::Metrics& metrics ) metrics.mTextureMemoryUsed = textureMemoryUsed; } -Material AtlasManager::GetMaterial( AtlasId atlas ) const +TextureSet AtlasManager::GetTextures( AtlasId atlas ) const { DALI_ASSERT_DEBUG( atlas && atlas <= mAtlasList.size() ); - Material material; + TextureSet textureSet; if ( atlas && atlas-- <= mAtlasList.size() ) { - material = mAtlasList[ atlas ].mMaterial; + textureSet = mAtlasList[ atlas ].mTextureSet; } - return material; + return textureSet; } -void AtlasManager::SetMaterial( AtlasId atlas, Material& material ) +void AtlasManager::SetTextures( AtlasId atlas, TextureSet& textureSet ) { DALI_ASSERT_DEBUG( atlas && atlas <= mAtlasList.size() ); if ( atlas && atlas-- <= mAtlasList.size() ) { - mAtlasList[ atlas ].mMaterial = material; + mAtlasList[ atlas ].mTextureSet = textureSet; } }