From 2834ffdeb2f24bcea9d6321e524af0877977545d Mon Sep 17 00:00:00 2001 From: Richard Underhill Date: Mon, 16 Mar 2015 14:21:30 +0000 Subject: [PATCH] Added pixel padding to image upload through Atlas manager Change-Id: I5af112017044aa12d466736df7aface1720aa337 Signed-off-by: Richard Underhill --- .../internal/atlas-manager/atlas-manager-impl.cpp | 63 +++++++++++++++------- .../internal/atlas-manager/atlas-manager-impl.h | 4 ++ 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp index da6ae94..15e9684 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp +++ b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp @@ -17,8 +17,9 @@ // CLASS HEADER #include -// EXTERNAL INCLUDES +// EXTERNAL INCLUDE #include +#include #include namespace Dali @@ -34,12 +35,15 @@ namespace { const Vector2 DEFAULT_ATLAS_SIZE( 512.0f, 512.0f ); const Vector2 DEFAULT_BLOCK_SIZE( 32.0f, 32.0f ); + const uint32_t PIXEL_PADDING( 2u ); } AtlasManager::AtlasManager() : mNewAtlasSize( DEFAULT_ATLAS_SIZE ), mNewBlockSize( DEFAULT_BLOCK_SIZE ), - mAddFailPolicy( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES ) + mAddFailPolicy( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES ), + mEdgeBuffer( NULL ), + mEdgeBufferSize( 0 ) { } @@ -51,6 +55,7 @@ AtlasManagerPtr AtlasManager::New() AtlasManager::~AtlasManager() { + delete[] mEdgeBuffer; } Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( SizeType width, @@ -81,6 +86,22 @@ Toolkit::AtlasManager::AtlasId AtlasManager::CreateAtlas( SizeType width, atlasDescriptor.mMaterial = Material::New( materialLabel.str() ); atlasDescriptor.mMaterial.SetDiffuseTexture( atlas ); atlasDescriptor.mNextFreeBlock = 1u; // indicate next free block will be the first ( +1 ) + + // What size do we need for this atlas' edge buffer ( assume RGBA pixel format )? + uint32_t neededEdgeSize = ( blockWidth > blockHeight ? blockWidth : blockHeight ) << 2; + + // Is the current edge buffer large enough? + if ( neededEdgeSize > mEdgeBufferSize ) + { + delete[] mEdgeBuffer; + mEdgeBuffer = new PixelBuffer[ neededEdgeSize ]; + memset( mEdgeBuffer, 0, neededEdgeSize ); + mEdgeBufferSize = neededEdgeSize; + } + + atlasDescriptor.mEdgeX = BufferImage::New( mEdgeBuffer, blockWidth, PIXEL_PADDING, pixelformat ); + atlasDescriptor.mEdgeY = BufferImage::New( mEdgeBuffer, PIXEL_PADDING, blockHeight, pixelformat ); + mAtlasList.push_back( atlasDescriptor ); return mAtlasList.size(); } @@ -210,29 +231,18 @@ AtlasManager::SizeType AtlasManager::CheckAtlas( SizeType atlas, { if ( pixelFormat == mAtlasList[ atlas ].mPixelFormat ) { - // Work out how many blocks wide and high our bitmap is in the atlas' block size - SizeType widthInBlocks = width / mAtlasList[ atlas ].mBlockWidth; - if ( width % mAtlasList[ atlas ].mBlockWidth ) - { - widthInBlocks++; - } - SizeType heightInBlocks = height / mAtlasList[ atlas ].mBlockHeight; - if ( height % mAtlasList[ atlas ].mBlockHeight ) - { - heightInBlocks++; - } - blockArea = widthInBlocks * heightInBlocks; - // Check to see if there are any unused blocks in this atlas to accomodate our image SizeType blocksInX = mAtlasList[ atlas ].mWidth / mAtlasList[ atlas ].mBlockWidth; SizeType blocksInY = mAtlasList[ atlas ].mHeight / mAtlasList[ atlas ].mBlockHeight; totalBlocks = blocksInX * blocksInY; SizeType blocksFree = mAtlasList[ atlas ].mNextFreeBlock ? totalBlocks - mAtlasList[ atlas ].mNextFreeBlock + 1u : 0; - // Check to see if there are enough blocks to accomodate our sliced image ? - if ( blockArea <= ( mAtlasList[ atlas ].mFreeBlocksList.Size() + blocksFree ) ) + // Check to see if the image will fit in these blocks, if not we'll need to create a new atlas + if ( blocksFree + && width + PIXEL_PADDING <= mAtlasList[ atlas ].mBlockWidth + && height + PIXEL_PADDING <= mAtlasList[ atlas ].mBlockHeight ) { - // Yes, we've found room + blockArea = 1u; return ( atlas + 1u ); } } @@ -576,10 +586,27 @@ void AtlasManager::UploadImage( const BufferImage& image, SizeType blockOffsetX = blockX * atlasBlockWidth; SizeType blockOffsetY = blockY * atlasBlockHeight; + SizeType width = image.GetWidth(); + SizeType height = image.GetHeight(); + if ( !mAtlasList[ atlas ].mAtlas.Upload( image, blockOffsetX, blockOffsetY ) ) { DALI_LOG_ERROR("Uploading block to Atlas Failed!.\n"); } + if ( blockOffsetY + height + PIXEL_PADDING <= mAtlasList[ atlas ].mHeight ) + { + if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mEdgeX, blockOffsetX, blockOffsetY + height ) ) + { + DALI_LOG_ERROR("Uploading edgeX to Atlas Failed!.\n"); + } + } + if ( blockOffsetX + width + PIXEL_PADDING <= mAtlasList[ atlas ].mWidth ) + { + if ( !mAtlasList[ atlas ].mAtlas.Upload( mAtlasList[ atlas ].mEdgeY, blockOffsetX + width, blockOffsetY ) ) + { + DALI_LOG_ERROR("Uploading edgeY to Atlas Failed!.\n"); + } + } } void AtlasManager::GenerateMeshData( ImageId id, diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h index 14f6c72..6393762 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h +++ b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h @@ -65,6 +65,8 @@ public: SizeType mBlockWidth; // width of a block in atlas SizeType mBlockHeight; // height of a block in atlas Pixel::Format mPixelFormat; // pixel format used by atlas + BufferImage mEdgeX; // Image used to pad upload + BufferImage mEdgeY; // Image used to pad upload Material mMaterial; // material used for atlas texture SizeType mNextFreeBlock; // next free block will be placed here ( actually +1 ) Dali::Vector< SizeType > mFreeBlocksList; // unless there are any previously freed blocks @@ -204,6 +206,8 @@ private: Vector2 mNewAtlasSize; Vector2 mNewBlockSize; Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy; + PixelBuffer* mEdgeBuffer; + uint32_t mEdgeBufferSize; }; } // namespace Internal -- 2.7.4