From 8b474798c4b5a53412ed526f6279d4d27b440fc9 Mon Sep 17 00:00:00 2001 From: Sunghyun kim Date: Tue, 23 Apr 2019 14:40:05 +0900 Subject: [PATCH 1/1] Move MultiplyColorByAlpha() from main thread to resource thread Change-Id: I61f8e9b1bb1711de98707aa21ec5325b62bd5b10 --- .../image-loader/async-image-loader-devel.cpp | 11 ++++++++ .../image-loader/async-image-loader-devel.h | 30 ++++++++++++++++++++++ .../image-loader/async-image-loader-impl.cpp | 6 ++--- .../image-loader/async-image-loader-impl.h | 5 ++-- .../internal/image-loader/image-atlas-impl.cpp | 2 +- .../internal/image-loader/image-load-thread.cpp | 13 ++++++++-- .../internal/image-loader/image-load-thread.h | 7 +++-- .../internal/visuals/texture-manager-impl.cpp | 18 ++++++------- .../internal/visuals/texture-manager-impl.h | 4 ++- .../public-api/image-loader/async-image-loader.cpp | 6 ++--- 10 files changed, 78 insertions(+), 24 deletions(-) diff --git a/dali-toolkit/devel-api/image-loader/async-image-loader-devel.cpp b/dali-toolkit/devel-api/image-loader/async-image-loader-devel.cpp index 690f078..451ace3 100644 --- a/dali-toolkit/devel-api/image-loader/async-image-loader-devel.cpp +++ b/dali-toolkit/devel-api/image-loader/async-image-loader-devel.cpp @@ -24,6 +24,17 @@ namespace Toolkit namespace DevelAsyncImageLoader { +uint32_t Load( AsyncImageLoader asyncImageLoader, + const std::string& url, + ImageDimensions dimensions, + FittingMode::Type fittingMode, + SamplingMode::Type samplingMode, + bool orientationCorrection, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad ) +{ + return GetImplementation( asyncImageLoader ).Load( Toolkit::Internal::VisualUrl(url), dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad); +} + PixelBufferLoadedSignalType& PixelBufferLoadedSignal( AsyncImageLoader asyncImageLoader ) { return GetImplementation( asyncImageLoader ).PixelBufferLoadedSignal(); diff --git a/dali-toolkit/devel-api/image-loader/async-image-loader-devel.h b/dali-toolkit/devel-api/image-loader/async-image-loader-devel.h index 7cb64c5..1208f0d 100644 --- a/dali-toolkit/devel-api/image-loader/async-image-loader-devel.h +++ b/dali-toolkit/devel-api/image-loader/async-image-loader-devel.h @@ -31,6 +31,36 @@ namespace DevelAsyncImageLoader typedef Signal< void ( uint32_t, Devel::PixelBuffer ) > PixelBufferLoadedSignalType; /** + * @brief Whether to multiply alpha into color channels on load + */ +enum class PreMultiplyOnLoad +{ + OFF = 0, ///< Don't modify the image + ON ///< Multiply alpha into color channels on load +}; + +/** + * @brief Starts an image loading task. + * @REMARK_INTERNET + * @REMARK_STORAGE + * @param[in] asyncImageLoader The ayncImageLoader + * @param[in] url The URL of the image file to load + * @param[in] dimensions The width and height to fit the loaded image to + * @param[in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter + * @param[in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size + * @param[in] orientationCorrection Reorient the image to respect any orientation metadata in its header + * @param[in] preMultiplyOnLoad ON if the image color should be multiplied by it's alpha. Set to OFF if there is no alpha + * @return The loading task id + */ +DALI_TOOLKIT_API uint32_t Load( AsyncImageLoader asyncImageLoader, + const std::string& url, + ImageDimensions dimensions, + FittingMode::Type fittingMode, + SamplingMode::Type samplingMode, + bool orientationCorrection, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad ); + +/** * Connect to this signal if you want to load a PixelBuffer instead of a PixelData. * @note Connecting to this signal prevents the emission of the ImageLoadedSignal. */ diff --git a/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp b/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp index 966da79..1b764cb 100644 --- a/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp +++ b/dali-toolkit/internal/image-loader/async-image-loader-impl.cpp @@ -53,15 +53,15 @@ uint32_t AsyncImageLoader::Load( const VisualUrl& url, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, - bool orientationCorrection ) + bool orientationCorrection, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad) { if( !mIsLoadThreadStarted ) { mLoadThread.Start(); mIsLoadThreadStarted = true; } - - mLoadThread.AddTask( new LoadingTask( ++mLoadTaskId, url, dimensions, fittingMode, samplingMode, orientationCorrection ) ); + mLoadThread.AddTask( new LoadingTask( ++mLoadTaskId, url, dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad ) ); return mLoadTaskId; } diff --git a/dali-toolkit/internal/image-loader/async-image-loader-impl.h b/dali-toolkit/internal/image-loader/async-image-loader-impl.h index ce40f5a..7810a8f 100644 --- a/dali-toolkit/internal/image-loader/async-image-loader-impl.h +++ b/dali-toolkit/internal/image-loader/async-image-loader-impl.h @@ -50,13 +50,14 @@ public: static IntrusivePtr New(); /** - * @copydoc Toolkit::AsyncImageLoader::Load( const std::string&, ImageDimensions, FittingMode::Type, SamplingMode::Type, bool ) + * @copydoc Toolkit::AsyncImageLoader::Load( const std::string&, ImageDimensions, FittingMode::Type, SamplingMode::Type, bool , DevelAsyncImageLoader::PreMultiplyOnLoad ) */ uint32_t Load( const VisualUrl& url, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, - bool orientationCorrection ); + bool orientationCorrection, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad ); /** * @copydoc Toolkit::AsyncImageLoader::ImageLoadedSignal diff --git a/dali-toolkit/internal/image-loader/image-atlas-impl.cpp b/dali-toolkit/internal/image-loader/image-atlas-impl.cpp index b69adbd..d167499 100644 --- a/dali-toolkit/internal/image-loader/image-atlas-impl.cpp +++ b/dali-toolkit/internal/image-loader/image-atlas-impl.cpp @@ -163,7 +163,7 @@ bool ImageAtlas::Upload( Vector4& textureRect, unsigned int packPositionY = 0; if( mPacker.Pack( dimensions.GetWidth(), dimensions.GetHeight(), packPositionX, packPositionY ) ) { - unsigned short loadId = mAsyncLoader.Load( url, size, fittingMode, SamplingMode::BOX_THEN_LINEAR, orientationCorrection ); + unsigned short loadId = mAsyncLoader.Load( url, size, fittingMode, SamplingMode::BOX_THEN_LINEAR, orientationCorrection); mLoadingTaskInfoContainer.PushBack( new LoadingTaskInfo( loadId, packPositionX, packPositionY, dimensions.GetWidth(), dimensions.GetHeight(), atlasUploadObserver ) ); // apply the half pixel correction textureRect.x = ( static_cast( packPositionX ) +0.5f ) / mWidth; // left diff --git a/dali-toolkit/internal/image-loader/image-load-thread.cpp b/dali-toolkit/internal/image-loader/image-load-thread.cpp index 74d3e39..320911d 100644 --- a/dali-toolkit/internal/image-loader/image-load-thread.cpp +++ b/dali-toolkit/internal/image-loader/image-load-thread.cpp @@ -33,14 +33,15 @@ namespace Internal { LoadingTask::LoadingTask( uint32_t id, const VisualUrl& url, ImageDimensions dimensions, - FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection ) + FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad ) : pixelBuffer(), url( url ), id( id ), dimensions( dimensions ), fittingMode( fittingMode ), samplingMode( samplingMode ), - orientationCorrection( orientationCorrection ) + orientationCorrection( orientationCorrection ), + preMultiplyOnLoad( preMultiplyOnLoad ) { } @@ -54,6 +55,14 @@ void LoadingTask::Load() { pixelBuffer = Dali::DownloadImageSynchronously ( url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection ); } + + if( pixelBuffer && Pixel::HasAlpha( pixelBuffer.GetPixelFormat() ) ) + { + if( preMultiplyOnLoad == DevelAsyncImageLoader::PreMultiplyOnLoad::ON ) + { + pixelBuffer.MultiplyColorByAlpha(); + } + } } diff --git a/dali-toolkit/internal/image-loader/image-load-thread.h b/dali-toolkit/internal/image-loader/image-load-thread.h index 4791a75..35fe216 100644 --- a/dali-toolkit/internal/image-loader/image-load-thread.h +++ b/dali-toolkit/internal/image-loader/image-load-thread.h @@ -28,6 +28,7 @@ #include #include #include +#include namespace Dali { @@ -51,10 +52,12 @@ struct LoadingTask * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter. * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size. * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header. + * @param [in] preMultiplyOnLoad ON if the image's color should be multiplied by it's alpha. */ LoadingTask( uint32_t id, const VisualUrl& url, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, - bool orientationCorrection ); + bool orientationCorrection, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad ); /** * Load the image @@ -78,7 +81,7 @@ public: FittingMode::Type fittingMode; ///< fitting options SamplingMode::Type samplingMode; ///< sampling options bool orientationCorrection:1; ///< if orientation correction is needed - + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad; //< if the image's color should be multiplied by it's alpha }; diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.cpp b/dali-toolkit/internal/visuals/texture-manager-impl.cpp index 3a32ddc..2be3aaa 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.cpp +++ b/dali-toolkit/internal/visuals/texture-manager-impl.cpp @@ -690,10 +690,12 @@ void TextureManager::LoadTexture( TextureInfo& textureInfo, TextureUploadObserve { auto& loadersContainer = textureInfo.url.IsLocalResource() ? mAsyncLocalLoaders : mAsyncRemoteLoaders; auto loadingHelperIt = loadersContainer.GetNext(); + auto premultiplyOnLoad = textureInfo.preMultiplyOnLoad? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF; DALI_ASSERT_ALWAYS(loadingHelperIt != loadersContainer.End()); loadingHelperIt->Load(textureInfo.textureId, textureInfo.url, textureInfo.desiredSize, textureInfo.fittingMode, - textureInfo.samplingMode, textureInfo.orientationCorrection ); + textureInfo.samplingMode, textureInfo.orientationCorrection, + premultiplyOnLoad ); } ObserveTexture( textureInfo, observer ); } @@ -873,13 +875,8 @@ void TextureManager::UploadTexture( Devel::PixelBuffer& pixelBuffer, TextureInfo { DALI_LOG_INFO( gTextureManagerLogFilter, Debug::General, " TextureManager::UploadTexture() New Texture for textureId:%d\n", textureInfo.textureId ); - // If the texture doesn't have an alpha channel, can't pre-multiply it. - // Ensure that we don't change the load parameter (it's used for hashing), and instead set - // the status for use in the observer. - auto preMultiply = textureInfo.preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : - TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; - PreMultiply( pixelBuffer, preMultiply ); - textureInfo.preMultiplied = (preMultiply == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ); + // Check if this pixelBuffer is premultiplied + textureInfo.preMultiplied = pixelBuffer.IsAlphaPreMultiplied(); Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight() ); @@ -1120,10 +1117,11 @@ void TextureManager::AsyncLoadingHelper::Load(TextureId textureId, ImageDimensions desiredSize, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, - bool orientationCorrection) + bool orientationCorrection, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad) { mLoadingInfoContainer.push_back(AsyncLoadingInfo(textureId)); - auto id = mLoader.Load(url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection); + auto id = DevelAsyncImageLoader::Load(mLoader, url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad); mLoadingInfoContainer.back().loadId = id; } diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.h b/dali-toolkit/internal/visuals/texture-manager-impl.h index c64b781..2cb06bd 100755 --- a/dali-toolkit/internal/visuals/texture-manager-impl.h +++ b/dali-toolkit/internal/visuals/texture-manager-impl.h @@ -713,13 +713,15 @@ private: * @param[in] samplingMode The SamplingMode to use * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image, * e.g., from portrait to landscape + * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. */ void Load(TextureId textureId, const VisualUrl& url, ImageDimensions desiredSize, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, - bool orientationCorrection); + bool orientationCorrection, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad); public: AsyncLoadingHelper(const AsyncLoadingHelper&) = delete; diff --git a/dali-toolkit/public-api/image-loader/async-image-loader.cpp b/dali-toolkit/public-api/image-loader/async-image-loader.cpp index b01134d..a1d21e7 100644 --- a/dali-toolkit/public-api/image-loader/async-image-loader.cpp +++ b/dali-toolkit/public-api/image-loader/async-image-loader.cpp @@ -64,12 +64,12 @@ AsyncImageLoader AsyncImageLoader::New() uint32_t AsyncImageLoader::Load( const std::string& url ) { - return GetImplementation( *this ).Load( Toolkit::Internal::VisualUrl(url), ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true ); + return GetImplementation( *this ).Load( Toolkit::Internal::VisualUrl(url), ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true, DevelAsyncImageLoader::PreMultiplyOnLoad::OFF ); } uint32_t AsyncImageLoader::Load( const std::string& url, ImageDimensions dimensions ) { - return GetImplementation( *this ).Load( Toolkit::Internal::VisualUrl(url), dimensions, FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true ); + return GetImplementation( *this ).Load( Toolkit::Internal::VisualUrl(url), dimensions, FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true , DevelAsyncImageLoader::PreMultiplyOnLoad::OFF ); } uint32_t AsyncImageLoader::Load( const std::string& url, @@ -78,7 +78,7 @@ uint32_t AsyncImageLoader::Load( const std::string& url, SamplingMode::Type samplingMode, bool orientationCorrection ) { - return GetImplementation(*this).Load( Toolkit::Internal::VisualUrl(url), dimensions, fittingMode, samplingMode, orientationCorrection ); + return GetImplementation(*this).Load( Toolkit::Internal::VisualUrl(url), dimensions, fittingMode, samplingMode, orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad::OFF ); } bool AsyncImageLoader::Cancel( uint32_t loadingTaskId ) -- 2.7.4