X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fimage-loader%2Fimage-load-thread.cpp;h=deb01781ed5cab893d3546ab88b1500f9a2eeb10;hp=74d3e3972f186f3a1b73c84a601c6858eac762f7;hb=11e1ee5bb1a33525dd3016a0fd145a6a3ee2c133;hpb=2dd55c62173e94588e4bb45e263a32b3d77af65a diff --git a/dali-toolkit/internal/image-loader/image-load-thread.cpp b/dali-toolkit/internal/image-loader/image-load-thread.cpp index 74d3e39..deb0178 100644 --- a/dali-toolkit/internal/image-loader/image-load-thread.cpp +++ b/dali-toolkit/internal/image-loader/image-load-thread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,83 +20,211 @@ // EXTERNAL INCLUDES #include -#include #include +#include +#include +#include namespace Dali { - namespace Toolkit { - namespace Internal { +LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLoading, uint32_t frameIndex, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad) +: url(), + encodedImageBuffer(), + id(id), + dimensions(), + fittingMode(), + samplingMode(), + preMultiplyOnLoad(preMultiplyOnLoad), + maskPixelBuffer(), + contentScale(1.0f), + animatedImageLoading(animatedImageLoading), + frameIndex(frameIndex), + orientationCorrection(), + isMaskTask(false), + cropToMask(false), + loadPlanes(false) +{ +} + +LoadingTask::LoadingTask(uint32_t id, const VisualUrl& url, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, bool loadPlanes) +: url(url), + encodedImageBuffer(), + id(id), + dimensions(dimensions), + fittingMode(fittingMode), + samplingMode(samplingMode), + preMultiplyOnLoad(preMultiplyOnLoad), + maskPixelBuffer(), + contentScale(1.0f), + animatedImageLoading(), + frameIndex(0u), + orientationCorrection(orientationCorrection), + isMaskTask(false), + cropToMask(false), + loadPlanes(loadPlanes) +{ +} -LoadingTask::LoadingTask( uint32_t id, const VisualUrl& url, ImageDimensions dimensions, - FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection ) -: pixelBuffer(), - url( url ), - id( id ), - dimensions( dimensions ), - fittingMode( fittingMode ), - samplingMode( samplingMode ), - orientationCorrection( orientationCorrection ) +LoadingTask::LoadingTask(uint32_t id, const EncodedImageBuffer& encodedImageBuffer, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad) +: url(), + encodedImageBuffer(encodedImageBuffer), + id(id), + dimensions(dimensions), + fittingMode(fittingMode), + samplingMode(samplingMode), + preMultiplyOnLoad(preMultiplyOnLoad), + maskPixelBuffer(), + contentScale(1.0f), + animatedImageLoading(), + frameIndex(0u), + orientationCorrection(orientationCorrection), + isMaskTask(false), + cropToMask(false), + loadPlanes(false) { } +LoadingTask::LoadingTask(uint32_t id, Devel::PixelBuffer pixelBuffer, Devel::PixelBuffer maskPixelBuffer, float contentScale, bool cropToMask, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad) +: url(""), + encodedImageBuffer(), + id(id), + dimensions(), + fittingMode(), + samplingMode(), + preMultiplyOnLoad(preMultiplyOnLoad), + maskPixelBuffer(maskPixelBuffer), + contentScale(contentScale), + animatedImageLoading(), + frameIndex(0u), + orientationCorrection(), + isMaskTask(true), + cropToMask(cropToMask), + loadPlanes(false) +{ + pixelBuffers.push_back(pixelBuffer); +} + void LoadingTask::Load() { - if( url.IsLocalResource() ) + Devel::PixelBuffer pixelBuffer; + if(animatedImageLoading) { - pixelBuffer = Dali::LoadImageFromFile( url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection ); + pixelBuffer = animatedImageLoading.LoadFrame(frameIndex); } - else + else if(encodedImageBuffer) { - pixelBuffer = Dali::DownloadImageSynchronously ( url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection ); + pixelBuffer = Dali::LoadImageFromBuffer(encodedImageBuffer.GetRawBuffer(), dimensions, fittingMode, samplingMode, orientationCorrection); + } + else if(url.IsValid() && url.IsLocalResource()) + { + if(loadPlanes) + { + Dali::LoadImagePlanesFromFile(url.GetUrl(), pixelBuffers, dimensions, fittingMode, samplingMode, orientationCorrection); + } + else + { + pixelBuffer = Dali::LoadImageFromFile(url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection); + } + } + else if(url.IsValid()) + { + pixelBuffer = Dali::DownloadImageSynchronously(url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection); + } + + if(pixelBuffer) + { + pixelBuffers.push_back(pixelBuffer); + } + + if(pixelBuffers.empty()) + { + DALI_LOG_ERROR("LoadingTask::Load: Loading is failed: %s\n", url.GetUrl().c_str()); } } +void LoadingTask::ApplyMask() +{ + if(!pixelBuffers.empty()) + { + pixelBuffers[0].ApplyMask(maskPixelBuffer, contentScale, cropToMask); + } +} + +void LoadingTask::MultiplyAlpha() +{ + if(!pixelBuffers.empty() && Pixel::HasAlpha(pixelBuffers[0].GetPixelFormat())) + { + if(preMultiplyOnLoad == DevelAsyncImageLoader::PreMultiplyOnLoad::ON) + { + pixelBuffers[0].MultiplyColorByAlpha(); + } + } +} -ImageLoadThread::ImageLoadThread( EventThreadCallback* trigger ) -: mTrigger( trigger ), - mLogFactory( Dali::Adaptor::Get().GetLogFactory() ) +ImageLoadThread::ImageLoadThread(EventThreadCallback* trigger) +: mTrigger(trigger), + mLogFactory(Dali::Adaptor::Get().GetLogFactory()) { } ImageLoadThread::~ImageLoadThread() { // add an empty task would stop the thread from conditional wait. - AddTask( NULL ); + AddTask(NULL); // stop the thread Join(); delete mTrigger; + + for(auto&& iter : mLoadQueue) + { + delete iter; + } + mLoadQueue.Clear(); + + for(auto&& iter : mCompleteQueue) + { + delete iter; + } + mCompleteQueue.Clear(); } void ImageLoadThread::Run() { - SetThreadName( "ImageLoadThread" ); + SetThreadName("ImageLoadThread"); mLogFactory.InstallLogFunction(); - while( LoadingTask* task = NextTaskToProcess() ) + while(LoadingTask* task = NextTaskToProcess()) { - task->Load(); - AddCompletedTask( task ); + if(!task->isMaskTask) + { + task->Load(); + } + else + { + task->ApplyMask(); + } + task->MultiplyAlpha(); + + AddCompletedTask(task); } } -void ImageLoadThread::AddTask( LoadingTask* task ) +void ImageLoadThread::AddTask(LoadingTask* task) { bool wasEmpty = false; - { // Lock while adding task to the queue - ConditionalWait::ScopedLock lock( mConditionalWait ); + ConditionalWait::ScopedLock lock(mConditionalWait); wasEmpty = mLoadQueue.Empty(); - mLoadQueue.PushBack( task ); + mLoadQueue.PushBack(task); } - if( wasEmpty ) + if(wasEmpty) { // wake up the image loading thread mConditionalWait.Notify(); @@ -106,31 +234,31 @@ void ImageLoadThread::AddTask( LoadingTask* task ) LoadingTask* ImageLoadThread::NextCompletedTask() { // Lock while popping task out from the queue - Mutex::ScopedLock lock( mMutex ); + Mutex::ScopedLock lock(mMutex); - if( mCompleteQueue.Empty() ) + if(mCompleteQueue.Empty()) { return NULL; } - Vector< LoadingTask* >::Iterator next = mCompleteQueue.Begin(); - LoadingTask* nextTask = *next; - mCompleteQueue.Erase( next ); + Vector::Iterator next = mCompleteQueue.Begin(); + LoadingTask* nextTask = *next; + mCompleteQueue.Erase(next); return nextTask; } -bool ImageLoadThread::CancelTask( uint32_t loadingTaskId ) +bool ImageLoadThread::CancelTask(uint32_t loadingTaskId) { // Lock while remove task from the queue - ConditionalWait::ScopedLock lock( mConditionalWait ); + ConditionalWait::ScopedLock lock(mConditionalWait); - for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); ++iter ) + for(Vector::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); ++iter) { - if( (*iter)->id == loadingTaskId ) + if((*iter)->id == loadingTaskId) { - delete (*iter); - mLoadQueue.Erase( iter ); + delete(*iter); + mLoadQueue.Erase(iter); return true; } } @@ -138,15 +266,14 @@ bool ImageLoadThread::CancelTask( uint32_t loadingTaskId ) return false; } - void ImageLoadThread::CancelAll() { // Lock while remove task from the queue - ConditionalWait::ScopedLock lock( mConditionalWait ); + ConditionalWait::ScopedLock lock(mConditionalWait); - for( Vector< LoadingTask* >::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); ++iter ) + for(Vector::Iterator iter = mLoadQueue.Begin(); iter != mLoadQueue.End(); ++iter) { - delete ( *iter ); + delete(*iter); } mLoadQueue.Clear(); } @@ -154,25 +281,25 @@ void ImageLoadThread::CancelAll() LoadingTask* ImageLoadThread::NextTaskToProcess() { // Lock while popping task out from the queue - ConditionalWait::ScopedLock lock( mConditionalWait ); + ConditionalWait::ScopedLock lock(mConditionalWait); - while( mLoadQueue.Empty() ) + while(mLoadQueue.Empty()) { - mConditionalWait.Wait( lock ); + mConditionalWait.Wait(lock); } - Vector< LoadingTask* >::Iterator next = mLoadQueue.Begin(); - LoadingTask* nextTask = *next; - mLoadQueue.Erase( next ); + Vector::Iterator next = mLoadQueue.Begin(); + LoadingTask* nextTask = *next; + mLoadQueue.Erase(next); return nextTask; } -void ImageLoadThread::AddCompletedTask( LoadingTask* task ) +void ImageLoadThread::AddCompletedTask(LoadingTask* task) { // Lock while adding task to the queue - Mutex::ScopedLock lock( mMutex ); - mCompleteQueue.PushBack( task ); + Mutex::ScopedLock lock(mMutex); + mCompleteQueue.PushBack(task); // wake up the main thread mTrigger->Trigger();