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=7fc344feb5b3074f6f00e6c13efd4d5448900ebc;hp=11e251a0d53942f5ce2e221d78aba771b073127c;hb=7018f61b640b6fcf9cb576b537bafcb6bb8240e8;hpb=fc829906bc88730e08c8d483a351bd1a1ffc563f diff --git a/dali-toolkit/internal/image-loader/image-load-thread.cpp b/dali-toolkit/internal/image-loader/image-load-thread.cpp index 11e251a..7fc344f 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) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -18,57 +18,169 @@ // CLASS HEADER #include "image-load-thread.h" +// EXTERNAL INCLUDES +#include +#include +#include +#include + namespace Dali { - namespace Toolkit { - namespace Internal { +LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLoading, uint32_t frameIndex) +: pixelBuffer(), + url(), + id(id), + dimensions(), + fittingMode(), + samplingMode(), + orientationCorrection(), + preMultiplyOnLoad(DevelAsyncImageLoader::PreMultiplyOnLoad::OFF), + isMaskTask(false), + maskPixelBuffer(), + contentScale(1.0f), + cropToMask(false), + animatedImageLoading(animatedImageLoading), + frameIndex(frameIndex) +{ +} + +LoadingTask::LoadingTask(uint32_t id, const VisualUrl& url, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad) +: pixelBuffer(), + url(url), + id(id), + dimensions(dimensions), + fittingMode(fittingMode), + samplingMode(samplingMode), + orientationCorrection(orientationCorrection), + preMultiplyOnLoad(preMultiplyOnLoad), + isMaskTask(false), + maskPixelBuffer(), + contentScale(1.0f), + cropToMask(false), + animatedImageLoading(), + frameIndex(0u) +{ +} + +LoadingTask::LoadingTask(uint32_t id, Devel::PixelBuffer pixelBuffer, Devel::PixelBuffer maskPixelBuffer, float contentScale, bool cropToMask, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad) +: pixelBuffer(pixelBuffer), + url(""), + id(id), + dimensions(), + fittingMode(), + samplingMode(), + orientationCorrection(), + preMultiplyOnLoad(preMultiplyOnLoad), + isMaskTask(true), + maskPixelBuffer(maskPixelBuffer), + contentScale(contentScale), + cropToMask(cropToMask), + animatedImageLoading(), + frameIndex(0u) +{ +} -LoadingTask::LoadingTask(uint32_t id, BitmapLoader loader ) -: loader( loader ), - id( id ) +void LoadingTask::Load() { + if(animatedImageLoading) + { + pixelBuffer = animatedImageLoading.LoadFrame(frameIndex); + } + else if(url.IsLocalResource()) + { + pixelBuffer = Dali::LoadImageFromFile(url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection); + } + else + { + pixelBuffer = Dali::DownloadImageSynchronously(url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection); + } + + if(!pixelBuffer) + { + DALI_LOG_ERROR("LoadingTask::Load: Loading is failed: %s\n", url.GetUrl().c_str()); + } } -ImageLoadThread::ImageLoadThread( EventThreadCallback* trigger ) -: mTrigger( trigger ) +void LoadingTask::ApplyMask() +{ + pixelBuffer.ApplyMask(maskPixelBuffer, contentScale, cropToMask); +} + +void LoadingTask::MultiplyAlpha() +{ + if(pixelBuffer && Pixel::HasAlpha(pixelBuffer.GetPixelFormat())) + { + if(preMultiplyOnLoad == DevelAsyncImageLoader::PreMultiplyOnLoad::ON) + { + pixelBuffer.MultiplyColorByAlpha(); + } + } +} + +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() { - while( LoadingTask* task = NextTaskToProcess() ) + SetThreadName("ImageLoadThread"); + mLogFactory.InstallLogFunction(); + + while(LoadingTask* task = NextTaskToProcess()) { - task->loader.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(); @@ -78,31 +190,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; } } @@ -110,15 +222,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(); } @@ -126,32 +237,30 @@ 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(); } - - } // namespace Internal } // namespace Toolkit