X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fsvg%2Fsvg-rasterize-thread.cpp;h=c5f055564f7af8c9c1216432ce9bc508f21f3015;hp=13140a7e60a41dbc0b8e1d508c67edc88f37a64a;hb=f3e45e41c5f16ccc2538b283897ed6efb07e4ea9;hpb=2dd55c62173e94588e4bb45e263a32b3d77af65a diff --git a/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp b/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp index 13140a7..c5f0555 100644 --- a/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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,10 +18,14 @@ // CLASS HEADER #include "svg-rasterize-thread.h" +// EXTERNAL INCLUDES +#include +#include +#include +#include + // INTERNAL INCLUDES -#include #include -#include namespace Dali { @@ -31,32 +35,83 @@ namespace Toolkit namespace Internal { +RasterizingTask::RasterizingTask(SvgVisual* svgRenderer, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height) +: mSvgVisual(svgRenderer), + mVectorRenderer(vectorRenderer), + mUrl(url), + mDpi(dpi), + mWidth(width), + mHeight(height), + mLoadSuccess(false) +{ -RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, unsigned int width, unsigned int height ) -: mSvgVisual( svgRenderer ), - mParsedSvg( parsedSvg ), - mWidth( width ), - mHeight( height ) +} + +RasterizingTask::~RasterizingTask() { } -void RasterizingTask::Rasterize( NSVGrasterizer* rasterizer ) +void RasterizingTask::Load() { - if( mWidth > 0u && mHeight > 0u ) + if(!mUrl.IsLocalResource()) { - float scaleX = static_cast( mWidth ) / mParsedSvg->width; - float scaleY = static_cast( mHeight ) / mParsedSvg->height; - float scale = scaleX < scaleY ? scaleX : scaleY; - unsigned int bufferStride = mWidth*Pixel::GetBytesPerPixel( Pixel::RGBA8888 ); - unsigned int bufferSize = bufferStride * mHeight; + Dali::Vector remoteBuffer; + if(!Dali::FileLoader::DownloadFileSynchronously(mUrl.GetUrl(), remoteBuffer)) + { + DALI_LOG_ERROR("RasterizingTask::Load: Failed to download file! [%s]\n", mUrl.GetUrl().c_str()); + return; + } - unsigned char* buffer = new unsigned char [bufferSize]; - nsvgRasterize(rasterizer, mParsedSvg, 0.f,0.f,scale, - buffer, mWidth, mHeight, - bufferStride ); + remoteBuffer.PushBack('\0'); - mPixelData = Dali::PixelData::New( buffer, bufferSize, mWidth, mHeight, Pixel::RGBA8888, Dali::PixelData::DELETE_ARRAY ); + if(!mVectorRenderer.Load(remoteBuffer, mDpi)) + { + DALI_LOG_ERROR("RasterizingTask::Load:Failed to load data! [%s]\n", mUrl.GetUrl().c_str()); + return; + } + + mLoadSuccess = true; } + else + { + mLoadSuccess = true; + } +} + +void RasterizingTask::Rasterize() +{ + if(mWidth <= 0u || mHeight <= 0u) + { + DALI_LOG_ERROR("RasterizingTask::Rasterize: Size is zero!\n"); + return; + } + + Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New(mWidth, mHeight, Dali::Pixel::RGBA8888); + + uint32_t defaultWidth, defaultHeight; + mVectorRenderer.GetDefaultSize(defaultWidth, defaultHeight); + + float scaleX = static_cast(mWidth) / static_cast(defaultWidth); + float scaleY = static_cast(mHeight) / static_cast(defaultHeight); + float scale = scaleX < scaleY ? scaleX : scaleY; + + if(!mVectorRenderer.Rasterize(pixelBuffer, scale)) + { + DALI_LOG_ERROR("RasterizingTask::Rasterize: Rasterize is failed! [%s]\n", mUrl.GetUrl().c_str()); + return; + } + + mPixelData = Devel::PixelBuffer::Convert(pixelBuffer); +} + +VectorImageRenderer RasterizingTask::GetVectorRenderer() const +{ + return mVectorRenderer; +} + +bool RasterizingTask::IsLoaded() const +{ + return mLoadSuccess; } SvgVisual* RasterizingTask::GetSvgVisual() const @@ -69,18 +124,20 @@ PixelData RasterizingTask::GetPixelData() const return mPixelData; } -SvgRasterizeThread::SvgRasterizeThread( EventThreadCallback* trigger ) -: mTrigger( trigger ), - mIsThreadWaiting( false ) +SvgRasterizeThread::SvgRasterizeThread() +: mTrigger( new EventThreadCallback( MakeCallback( this, &SvgRasterizeThread::ApplyRasterizedSVGToSampler ) ) ), + mLogFactory( Dali::Adaptor::Get().GetLogFactory() ), + mIsThreadWaiting( false ), + mProcessorRegistered( false ) { - mRasterizer = nsvgCreateRasterizer(); } SvgRasterizeThread::~SvgRasterizeThread() { - - nsvgDeleteRasterizer( mRasterizer ); - delete mTrigger; + if( mProcessorRegistered ) + { + Adaptor::Get().UnregisterProcessor( *this ); + } } void SvgRasterizeThread::TerminateThread( SvgRasterizeThread*& thread ) @@ -119,6 +176,12 @@ void SvgRasterizeThread::AddTask( RasterizingTaskPtr task ) } } mRasterizeTasks.push_back( task ); + + if( !mProcessorRegistered ) + { + Adaptor::Get().RegisterProcessor( *this ); + mProcessorRegistered = true; + } } if( wasEmpty) @@ -160,20 +223,22 @@ void SvgRasterizeThread::RemoveTask( SvgVisual* visual ) } } } + + UnregisterProcessor(); } -void SvgRasterizeThread::DeleteImage( NSVGimage* parsedSvg ) +void SvgRasterizeThread::DeleteImage( VectorImageRenderer vectorRenderer ) { // Lock while adding image to the delete queue ConditionalWait::ScopedLock lock( mConditionalWait ); if( mIsThreadWaiting ) // no rasterization is ongoing, save to delete { - nsvgDelete( parsedSvg ); + // TODO: what? } else // wait to delete until current rasterization completed. { - mDeleteSvg.PushBack( parsedSvg ); + mDeleteSvg.PushBack( &vectorRenderer ); } } @@ -185,12 +250,6 @@ RasterizingTaskPtr SvgRasterizeThread::NextTaskToProcess() // Delete the image here to make sure that it is not used in the nsvgRasterize() if( !mDeleteSvg.Empty() ) { - for( Vector< NSVGimage* >::Iterator it = mDeleteSvg.Begin(), endIt = mDeleteSvg.End(); - it != endIt; - ++it ) - { - nsvgDelete( *it ); - } mDeleteSvg.Clear(); } @@ -223,13 +282,44 @@ void SvgRasterizeThread::AddCompletedTask( RasterizingTaskPtr task ) void SvgRasterizeThread::Run() { SetThreadName( "SVGThread" ); + mLogFactory.InstallLogFunction(); + while( RasterizingTaskPtr task = NextTaskToProcess() ) { - task->Rasterize( mRasterizer ); + task->Load( ); + task->Rasterize( ); AddCompletedTask( task ); } } +void SvgRasterizeThread::ApplyRasterizedSVGToSampler() +{ + while( RasterizingTaskPtr task = NextCompletedTask() ) + { + task->GetSvgVisual()->ApplyRasterizedImage(task->GetVectorRenderer(), task->GetPixelData(), task->IsLoaded()); + } + + UnregisterProcessor(); +} + +void SvgRasterizeThread::Process() +{ + ApplyRasterizedSVGToSampler(); +} + +void SvgRasterizeThread::UnregisterProcessor() +{ + if ( mProcessorRegistered ) + { + if( mRasterizeTasks.empty() && mCompletedTasks.empty() ) + { + Adaptor::Get().UnregisterProcessor( *this ); + mProcessorRegistered = false; + } + } +} + + } // namespace Internal } // namespace Toolkit