From 6dc418e4592f487e7f614f4f681d04de04e48341 Mon Sep 17 00:00:00 2001 From: Ferran Sole Date: Wed, 15 Jun 2016 09:26:00 +0100 Subject: [PATCH] Implemented Upload methods in Texture to upload data from PixelData objects Change-Id: I5d451dcf4a8a28bf3561e56b4280f352392c3c65 --- .../src/dali-devel/utc-Dali-Texture.cpp | 66 ++++++++++----------- dali/devel-api/rendering/texture.cpp | 16 ++--- dali/devel-api/rendering/texture.h | 33 ++++------- dali/internal/event/rendering/texture-impl.cpp | 69 ++++++++++++---------- dali/internal/event/rendering/texture-impl.h | 12 +--- dali/internal/render/common/render-manager.cpp | 4 +- dali/internal/render/common/render-manager.h | 4 +- dali/internal/render/renderers/render-texture.cpp | 52 ++++++++++++---- dali/internal/render/renderers/render-texture.h | 4 +- dali/internal/update/manager/update-manager.cpp | 6 +- dali/internal/update/manager/update-manager.h | 51 ++-------------- 11 files changed, 142 insertions(+), 175 deletions(-) diff --git a/automated-tests/src/dali-devel/utc-Dali-Texture.cpp b/automated-tests/src/dali-devel/utc-Dali-Texture.cpp index 7dcea18..fe3f396 100644 --- a/automated-tests/src/dali-devel/utc-Dali-Texture.cpp +++ b/automated-tests/src/dali-devel/utc-Dali-Texture.cpp @@ -132,9 +132,10 @@ int UtcDaliTextureUpload01(void) //Upload data to the texture callStack.Reset(); - Vector data; - data.Resize( width * height * 4 ); - texture.Upload( data ); + + unsigned char* buffer= reinterpret_cast( malloc( width * height * 4 ) ); + PixelData pixelData = PixelData::New( buffer, width, height, Pixel::RGBA8888, PixelData::FREE ); + texture.Upload( pixelData ); application.SendNotification(); application.Render(); @@ -147,9 +148,9 @@ int UtcDaliTextureUpload01(void) //Upload part of the texture callStack.Reset(); - Vector subImage; - subImage.Resize( width * height * 2 ); - texture.Upload( subImage, 0u, 0u, width/2, height/2, width/2, height/2 ); + buffer = reinterpret_cast( malloc( width * height * 2 ) ); + PixelData pixelDataSubImage = PixelData::New( buffer, width, height, Pixel::RGBA8888, PixelData::FREE ); + texture.Upload( pixelDataSubImage, 0u, 0u, width/2, height/2, width/2, height/2 ); application.SendNotification(); application.Render(); @@ -188,12 +189,14 @@ int UtcDaliTextureUpload02(void) DALI_TEST_CHECK( callStack.FindMethodAndParams("TexImage2D", out.str().c_str() ) ); } + unsigned char* buffer= reinterpret_cast( malloc( width * height * 4 ) ); + PixelData pixelData = PixelData::New( buffer, width, height, Pixel::RGBA8888, PixelData::FREE ); + //Upload data to the POSITIVE_X face of the texture { callStack.Reset(); - Vector data; - data.Resize( width * height * 4 ); - texture.Upload( data, CubeMap::POSITIVE_X, 0u, 0u, 0u, width, height ); + + texture.Upload( pixelData, CubeMap::POSITIVE_X, 0u, 0u, 0u, width, height ); application.SendNotification(); application.Render(); @@ -208,9 +211,8 @@ int UtcDaliTextureUpload02(void) //Upload data to the NEGATIVE_X face of the texture { callStack.Reset(); - Vector data; - data.Resize( width * height * 4 ); - texture.Upload( data, CubeMap::NEGATIVE_X, 0u, 0u, 0u, width, height ); + + texture.Upload( pixelData, CubeMap::NEGATIVE_X, 0u, 0u, 0u, width, height ); application.SendNotification(); application.Render(); @@ -225,9 +227,7 @@ int UtcDaliTextureUpload02(void) //Upload data to the POSITIVE_Y face of the texture { callStack.Reset(); - Vector data; - data.Resize( width * height * 4 ); - texture.Upload( data, CubeMap::POSITIVE_Y, 0u, 0u, 0u, width, height ); + texture.Upload( pixelData, CubeMap::POSITIVE_Y, 0u, 0u, 0u, width, height ); application.SendNotification(); application.Render(); @@ -242,9 +242,7 @@ int UtcDaliTextureUpload02(void) //Upload data to the NEGATIVE_Y face of the texture { callStack.Reset(); - Vector data; - data.Resize( width * height * 4 ); - texture.Upload( data, CubeMap::NEGATIVE_Y, 0u, 0u, 0u, width, height ); + texture.Upload( pixelData, CubeMap::NEGATIVE_Y, 0u, 0u, 0u, width, height ); application.SendNotification(); application.Render(); @@ -259,9 +257,7 @@ int UtcDaliTextureUpload02(void) //Upload data to the POSITIVE_Z face of the texture { callStack.Reset(); - Vector data; - data.Resize( width * height * 4 ); - texture.Upload( data, CubeMap::POSITIVE_Z, 0u, 0u, 0u, width, height ); + texture.Upload( pixelData, CubeMap::POSITIVE_Z, 0u, 0u, 0u, width, height ); application.SendNotification(); application.Render(); @@ -276,9 +272,7 @@ int UtcDaliTextureUpload02(void) //Upload data to the NEGATIVE_Z face of the texture { callStack.Reset(); - Vector data; - data.Resize( width * height * 4 ); - texture.Upload( data, CubeMap::NEGATIVE_Z, 0u, 0u, 0u, width, height ); + texture.Upload( pixelData, CubeMap::NEGATIVE_Z, 0u, 0u, 0u, width, height ); application.SendNotification(); application.Render(); @@ -321,13 +315,13 @@ int UtcDaliTextureUpload03(void) //Upload data to the texture mipmap 0 and mipmap 1 callStack.Reset(); - Vector data; - data.Resize( width * height * 4 ); - texture.Upload( data, 0u, 0u, 0u, 0u, width, height ); + unsigned char* buffer= reinterpret_cast( malloc( width * height * 4 ) ); + PixelData pixelData = PixelData::New( buffer, width, height, Pixel::RGBA8888, PixelData::FREE ); + texture.Upload( pixelData, 0u, 0u, 0u, 0u, width, height ); - Vector dataMipmap1; - dataMipmap1.Resize( widthMipmap1 * heightMipmap1 * 4 ); - texture.Upload( dataMipmap1, 0u, 1u, 0u, 0u, widthMipmap1, heightMipmap1 ); + buffer = reinterpret_cast( malloc( widthMipmap1 * heightMipmap1 * 4 ) ); + PixelData pixelDataMipmap1 = PixelData::New( buffer, width, height, Pixel::RGBA8888, PixelData::FREE ); + texture.Upload( pixelDataMipmap1, 0u, 1u, 0u, 0u, widthMipmap1, heightMipmap1 ); application.SendNotification(); application.Render(); @@ -362,13 +356,13 @@ int UtcDaliTextureUpload04(void) TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); //Upload data to the NEGATIVE_X face mipmap 0 and mipmap 1 - Vector data; - data.Resize( width * height * 4 ); - texture.Upload( data, CubeMap::NEGATIVE_X, 0u, 0u, 0u, width, height ); + unsigned char* buffer= reinterpret_cast( malloc( width * height * 4 ) ); + PixelData pixelData = PixelData::New( buffer, width, height, Pixel::RGBA8888, PixelData::FREE ); + texture.Upload( pixelData, CubeMap::NEGATIVE_X, 0u, 0u, 0u, width, height ); - Vector dataMipmap1; - dataMipmap1.Resize( widthMipmap1 * widthMipmap1 * 4 ); - texture.Upload( dataMipmap1, CubeMap::NEGATIVE_X, 1u, 0u, 0u, widthMipmap1, heightMipmap1 ); + buffer= reinterpret_cast( malloc( widthMipmap1 * heightMipmap1 * 4 ) ); + PixelData pixelDataMipmap1 = PixelData::New( buffer, width, height, Pixel::RGBA8888, PixelData::FREE ); + texture.Upload( pixelDataMipmap1, CubeMap::NEGATIVE_X, 1u, 0u, 0u, widthMipmap1, heightMipmap1 ); application.SendNotification(); application.Render(); diff --git a/dali/devel-api/rendering/texture.cpp b/dali/devel-api/rendering/texture.cpp index 6959544..99ced3c 100644 --- a/dali/devel-api/rendering/texture.cpp +++ b/dali/devel-api/rendering/texture.cpp @@ -61,23 +61,19 @@ Texture& Texture::operator=( const Texture& handle ) return *this; } -void Texture::Upload( Vector& buffer ) +void Texture::Upload( PixelData pixelData ) { - return GetImplementation(*this).Upload( buffer ); + Internal::PixelData& internalPixelData = GetImplementation( pixelData ); + return GetImplementation(*this).Upload( &internalPixelData ); } -void Texture::Upload( Vector& buffer, +void Texture::Upload( PixelData pixelData, unsigned int layer, unsigned int mipmap, unsigned int xOffset, unsigned int yOffset, unsigned int width, unsigned int height ) { - return GetImplementation(*this).Upload( buffer, layer, mipmap, xOffset, yOffset, width, height ); -} - -void Texture::Upload( PixelData pixelData ) -{ - //TODO: Implement this method once PixelData uses handle/body pattern - DALI_ASSERT_ALWAYS( false && "Not implemented yet"); + Internal::PixelData& internalPixelData = GetImplementation( pixelData ); + return GetImplementation(*this).Upload( &internalPixelData, layer, mipmap, xOffset, yOffset, width, height ); } void Texture::GenerateMipmaps() diff --git a/dali/devel-api/rendering/texture.h b/dali/devel-api/rendering/texture.h index 072897a..85ee5ea 100644 --- a/dali/devel-api/rendering/texture.h +++ b/dali/devel-api/rendering/texture.h @@ -120,39 +120,28 @@ public: Texture& operator=( const Texture& handle ); /** - * @brief Upload data to the texture - * @param[in] buffer A vector with the data to be uploaded - * @note buffer data will be moved after this call. If the application needs to keep the data, - * it will have to pass a copy of the original buffer into this function, otherwise the data - * will be lost + * @brief Upload data to the texture from a PixelData object + * @param[in] pixelData The pixelData object */ - void Upload( Vector& buffer ); + void Upload( PixelData pixelData ); /** - * @brief Upload data to the texture - * @param[in] buffer A vector with the data to be uploaded + * @brief Upload data to the texture from a PixelData object + * @param[in] pixelData The pixelData object * @param[in] layer Specifies the layer of a cube map or array texture. (Unused for 2D textures) * @param[in] mipmap Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image - * @param[in] xOffset Specifies a texel offset in the x direction within the texture array - * @param[in] yOffset Specifies a texel offset in the y direction within the texture array - * @param[in] width Specifies the width of the texture subimage - * @param[in] height Specifies the height of the texture subimage - * @note buffer data will be moved after this call. If the application needs to keep the data, - * it will have to pass a copy of the original buffer into this function, otherwise the data - * will be lost + * @param[in] xOffset Specifies an horizontal offset of the rectangular area in the texture that will be updated + * @param[in] yOffset Specifies a vertical offset of the rectangular area in the texture that will be updated + * @param[in] width Specifies the width of the rectangular area in the texture that will be updated + * @param[in] height Specifies the height of the rectangular area in the texture that will be updated + * @note Upload does not upsample or downsample pixel data to fit the specified rectangular area in the texture. */ - void Upload( Vector& buffer, + void Upload( PixelData pixelData, unsigned int layer, unsigned int mipmap, unsigned int xOffset, unsigned int yOffset, unsigned int width, unsigned int height ); /** - * @brief Upload data to the texture from a PixelData object - * @param[in] pixelData The pixelData object - */ - void Upload( PixelData pixelData ); - - /** * @brief Generate mipmaps for the texture * This will auto generate all the mipmaps for the texture based on the data in the base level */ diff --git a/dali/internal/event/rendering/texture-impl.cpp b/dali/internal/event/rendering/texture-impl.cpp index 1fe7657..5f8d4ee 100644 --- a/dali/internal/event/rendering/texture-impl.cpp +++ b/dali/internal/event/rendering/texture-impl.cpp @@ -90,48 +90,53 @@ NewTexture::~NewTexture() } } -bool NewTexture::CheckUploadParametres( const Vector& buffer, const UploadParams& parameters ) const +void NewTexture::Upload( PixelDataPtr pixelData ) { - if( mNativeImage ) - { - DALI_LOG_ERROR( "Error: Uploading data to a native texture"); - return false; - } - else if( buffer.Size() < GetBytesPerPixel( mFormat ) * parameters.width * parameters.height ) - { - DALI_LOG_ERROR( "Error: Buffer of an incorrect size when trying to update texture"); - return false; - } - else if( ( parameters.xOffset + parameters.width > static_cast( mWidth/(1< static_cast( mHeight/(1<& buffer, +void NewTexture::Upload( PixelDataPtr pixelData, unsigned int layer, unsigned int mipmap, unsigned int xOffset, unsigned int yOffset, unsigned int width, unsigned int height ) { - UploadParams params = { layer, mipmap, xOffset, yOffset, width, height }; - if( CheckUploadParametres( buffer, params ) ) + if( mNativeImage ) { - UploadTextureMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject, buffer, params ); + DALI_LOG_ERROR( "OpenGLES does not support uploading data to native texture"); } -} - -void NewTexture::Upload( Vector& buffer ) -{ - UploadParams params = {0u,0u,0u,0u,mWidth,mHeight}; - if( CheckUploadParametres( buffer, params ) ) + else { - UploadTextureMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject, buffer, params ); + unsigned int pixelDataSize = pixelData->GetWidth()*pixelData->GetHeight(); + if( pixelData->GetBuffer() == NULL || pixelDataSize == 0 ) + { + DALI_LOG_ERROR( "PixelData is empty"); + } + else + { + Pixel::Format pixelDataFormat = pixelData->GetPixelFormat(); + if( ( pixelDataFormat == mFormat ) || ( (pixelDataFormat == Pixel::RGB888 ) && ( mFormat == Pixel::RGBA8888 ) ) ) + { + if( pixelDataSize < width * height ) + { + DALI_LOG_ERROR( "Pixel data of an incorrect size when trying to update texture"); + } + else if( ( xOffset + width > static_cast( mWidth / (1< static_cast( mHeight / (1< #include // Dali::Internal::Render::Texture #include +#include namespace Dali { @@ -83,12 +84,12 @@ public: /** * @copydoc Dali::Texture::Upload() */ - void Upload( Vector& buffer ); + void Upload( PixelDataPtr pixelData ); /** * @copydoc Dali::Texture::Upload() */ - void Upload( Vector& buffer, + void Upload( PixelDataPtr pixelData, unsigned int layer, unsigned int mipmap, unsigned int xOffset, unsigned int yOffset, unsigned int width, unsigned int height ); @@ -144,13 +145,6 @@ private: // unimplemented methods private: // data - /** - * @brief Helper method to check that upload parameters are correct - * @param[in] buffer A vector with the data to be uploaded - * @param[in] parameters The uploading parameters - */ - bool CheckUploadParametres( const Vector& buffer, const UploadParams& parameters) const; - Internal::EventThreadServices& mEventThreadServices; ///& buffer, const NewTexture::UploadParams& params ) +void RenderManager::UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params ) { - texture->Upload( mImpl->context, buffer, params ); + texture->Upload( mImpl->context, pixelData, params ); } void RenderManager::GenerateMipmaps( Render::NewTexture* texture ) diff --git a/dali/internal/render/common/render-manager.h b/dali/internal/render/common/render-manager.h index 70c8116..93b9661 100644 --- a/dali/internal/render/common/render-manager.h +++ b/dali/internal/render/common/render-manager.h @@ -280,10 +280,10 @@ public: /** * Uploads data to an existing texture * @param[in] texture The texture - * @param[in] buffer Vector with the data to be uploaded + * @param[in] pixelData The pixel data object * @param[in] params The parameters for the upload */ - void UploadTexture( Render::NewTexture* texture, Vector& buffer, const NewTexture::UploadParams& params ); + void UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params ); /** * Generates mipmaps for a given texture diff --git a/dali/internal/render/renderers/render-texture.cpp b/dali/internal/render/renderers/render-texture.cpp index 3c87296..faa7c74 100644 --- a/dali/internal/render/renderers/render-texture.cpp +++ b/dali/internal/render/renderers/render-texture.cpp @@ -608,26 +608,56 @@ void NewTexture::Initialize(Context& context) } } -void NewTexture::Upload( Context& context, Vector& buffer, const Internal::NewTexture::UploadParams& params ) +void NewTexture::Upload( Context& context, PixelDataPtr pixelData, const Internal::NewTexture::UploadParams& params ) { DALI_ASSERT_ALWAYS( mNativeImage == NULL ); + //Get pointer to the data of the PixelData object + unsigned char* buffer( pixelData->GetBuffer() ); + + //This buffer is only used if manually converting from RGB to RGBA + unsigned char* tempBuffer(0); + + //Get pixel format and data type of the data contained in the PixelData object + GLenum pixelDataFormat, pixelDataElementType; + PixelFormatToGl( pixelData->GetPixelFormat(), pixelDataElementType, pixelDataFormat ); + +#if DALI_GLES_VERSION < 30 + if( pixelDataFormat == GL_RGB && mInternalFormat == GL_RGBA ) + { + //Convert manually from RGB to RGBA if GLES < 3 ( GLES 3 can do the conversion automatically when uploading ) + size_t dataSize = params.width * params.height; + tempBuffer = new unsigned char[dataSize*4u]; + for( size_t i(0u); i(mWidth / (1<(mHeight / (1<& buffer, const //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer, params.mipmap, mInternalFormat, params.width, params.height, 0, - mInternalFormat, mPixelDataType, &buffer[0] ); + pixelDataFormat, pixelDataElementType, buffer ); } else { //Specifying part of the image for the mipmap context.TexSubImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer, params.mipmap, params.xOffset, params.yOffset, params.width, params.height, - mInternalFormat, mPixelDataType, &buffer[0] ); + pixelDataFormat, pixelDataElementType, buffer ); } } + + //Destroy temp buffer used for conversion RGB->RGBA + delete[] tempBuffer; } bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler ) @@ -680,10 +713,7 @@ bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampl void NewTexture::ApplySampler( Context& context, Render::Sampler* sampler ) { Render::Sampler oldSampler = mSampler; - if( sampler ) - { - mSampler = *sampler; - } + mSampler = sampler ? *sampler : Sampler(); if( mSampler.mBitfield != oldSampler.mBitfield ) { diff --git a/dali/internal/render/renderers/render-texture.h b/dali/internal/render/renderers/render-texture.h index bdf9d2f..b117a14 100644 --- a/dali/internal/render/renderers/render-texture.h +++ b/dali/internal/render/renderers/render-texture.h @@ -146,10 +146,10 @@ public: /** * Uploads data to the texture. * @param[in] context The GL context - * @param[in] buffer A vector with the data to be uploaded + * @param[in] pixelData A pixel data object * @param[in] params Upload parameters. See UploadParams */ - void Upload( Context& context, Vector& buffer, const Internal::NewTexture::UploadParams& params ); + void Upload( Context& context, PixelDataPtr pixelData, const Internal::NewTexture::UploadParams& params ); /** * Bind the texture to the given texture unit and applies the given sampler diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index df573cf..957062b 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -1312,15 +1312,15 @@ void UpdateManager::RemoveTexture( Render::NewTexture* texture) new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture ); } -void UpdateManager::UploadTexture( Render::NewTexture* texture, Vector& buffer, const NewTexture::UploadParams& params ) +void UpdateManager::UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params ) { - typedef UploadTextureDataMessage< RenderManager > DerivedType; + typedef MessageValue3< RenderManager, Render::NewTexture*, PixelDataPtr, NewTexture::UploadParams > DerivedType; // Reserve some memory inside the message queue unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the message queue memory; note that delete should not be called on the return value - new (slot) DerivedType( &mImpl->renderManager, texture, buffer, params ); + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params ); } void UpdateManager::GenerateMipmaps( Render::NewTexture* texture ) diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 1c8f2a9..e90ab9d 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -491,10 +491,10 @@ public: /** * Uploads data to a texture owned by the RenderManager * @param[in] texture The texture - * @param[in] buffer Vector with the data to be uploaded + * @param[in] pixelData The pixel data object * @param[in] params The parameters for the upload */ - void UploadTexture( Render::NewTexture* texture, Vector& buffer, const NewTexture::UploadParams& params ); + void UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params ); /** * Generates mipmaps for a texture owned by the RenderManager @@ -1222,56 +1222,15 @@ inline void RemoveTexture( UpdateManager& manager, Render::NewTexture& texture ) new (slot) LocalType( &manager, &UpdateManager::RemoveTexture, &texture ); } -template< typename T > -class UploadTextureDataMessage : public MessageBase -{ -public: - - /** - * Constructor which does a Vector::Swap() - */ - UploadTextureDataMessage( T* manager, Render::NewTexture* texture, Dali::Vector& data, const NewTexture::UploadParams& params ) - : MessageBase(), - mManager( manager ), - mRenderTexture( texture ), - mParams( params ) - { - mData.Swap( data ); - } - - /** - * Virtual destructor - */ - virtual ~UploadTextureDataMessage() - { - } - - /** - * @copydoc MessageBase::Process - */ - virtual void Process( BufferIndex /*bufferIndex*/ ) - { - DALI_ASSERT_DEBUG( mManager && "Message does not have an object" ); - mManager->UploadTexture( mRenderTexture, mData, mParams ); - } - -private: - - T* mManager; - Render::NewTexture* mRenderTexture; - Dali::Vector mData; - NewTexture::UploadParams mParams; -}; - -inline void UploadTextureMessage( UpdateManager& manager, Render::NewTexture& texture, Dali::Vector& data, const NewTexture::UploadParams& params ) +inline void UploadTextureMessage( UpdateManager& manager, Render::NewTexture& texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params ) { - typedef UploadTextureDataMessage< UpdateManager > LocalType; + typedef MessageValue3< UpdateManager, Render::NewTexture*, PixelDataPtr, NewTexture::UploadParams > LocalType; // Reserve some memory inside the message queue unsigned int* slot = manager.ReserveMessageSlot( sizeof( LocalType ) ); // Construct message in the message queue memory; note that delete should not be called on the return value - new (slot) LocalType( &manager, &texture, data, params ); + new (slot) LocalType( &manager, &UpdateManager::UploadTexture, &texture, pixelData, params ); } inline void GenerateMipmapsMessage( UpdateManager& manager, Render::NewTexture& texture ) -- 2.7.4