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=151eda857d6e029651dfe75f717412c755c45bc8;hp=13140a7e60a41dbc0b8e1d508c67edc88f37a64a;hb=8bb92d7d1170f2ddf59da60bd3588be601ef8cd2;hpb=e671e53804ba5d0c87cbac89db4a6dc60114318c diff --git a/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp b/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp index 13140a7..151eda8 100644 --- a/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp @@ -18,10 +18,16 @@ // CLASS HEADER #include "svg-rasterize-thread.h" +// EXTERNAL INCLUDES +#include +#include +#include + // INTERNAL INCLUDES +#ifdef NO_THORVG #include +#endif /* NO_THORVG */ #include -#include namespace Dali { @@ -32,33 +38,155 @@ namespace Toolkit namespace Internal { -RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, unsigned int width, unsigned int height ) +namespace +{ +const char * const UNITS("px"); +} + +#ifdef NO_THORVG +RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, NSVGimage* parsedSvg, const VisualUrl& url, float dpi, unsigned int width, unsigned int height) : mSvgVisual( svgRenderer ), mParsedSvg( parsedSvg ), + mUrl( url ), + mDpi( dpi ), mWidth( width ), mHeight( height ) { + mRasterizer = nsvgCreateRasterizer(); +} +#else /* NO_THORVG */ +RasterizingTask::RasterizingTask( SvgVisual* svgRenderer, VectorImageRenderer vectorRenderer, const VisualUrl& url, float dpi, unsigned int width, unsigned int height, bool loaded) +: mSvgVisual( svgRenderer ), + mVectorRenderer( vectorRenderer ), + mUrl( url ), + mDpi( dpi ), + mWidth( width ), + mHeight( height ), + mLoaded( loaded ) +{ + +} +#endif /* NO_THORVG */ + +RasterizingTask::~RasterizingTask() +{ +#ifdef NO_THORVG + nsvgDeleteRasterizer( mRasterizer ); +#endif /* NO_THORVG */ +} + +void RasterizingTask::Load() +{ +#ifdef NO_THORVG + if( mParsedSvg != NULL) + { + return; + } + + if( !mUrl.IsLocalResource() ) + { + Dali::Vector remoteBuffer; + + if( !Dali::FileLoader::DownloadFileSynchronously( mUrl.GetUrl(), remoteBuffer )) + { + DALI_LOG_ERROR("Failed to download file!\n"); + return; + } + + remoteBuffer.PushBack( '\0' ); + mParsedSvg = nsvgParse( reinterpret_cast(remoteBuffer.begin()), UNITS, mDpi ); + } +#else /* NO_THORVG */ + if( !mLoaded && !mUrl.IsLocalResource() ) + { + Dali::Vector remoteBuffer; + + if( !Dali::FileLoader::DownloadFileSynchronously( mUrl.GetUrl(), remoteBuffer )) + { + DALI_LOG_ERROR("Failed to download file!\n"); + return; + } + + remoteBuffer.PushBack( '\0' ); + char *data = reinterpret_cast(remoteBuffer.begin()); + if ( !mVectorRenderer.Load( data, remoteBuffer.Size())) + { + DALI_LOG_ERROR( "Failed to load data!\n" ); + return; + } + + mLoaded = true; + } +#endif /* NO_THORVG */ } -void RasterizingTask::Rasterize( NSVGrasterizer* rasterizer ) +void RasterizingTask::Rasterize( ) { - if( mWidth > 0u && mHeight > 0u ) +#ifdef NO_THORVG + if( mParsedSvg != NULL && mWidth > 0u && mHeight > 0u ) { - float scaleX = static_cast( mWidth ) / mParsedSvg->width; - float scaleY = static_cast( mHeight ) / mParsedSvg->height; + 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; unsigned char* buffer = new unsigned char [bufferSize]; - nsvgRasterize(rasterizer, mParsedSvg, 0.f,0.f,scale, + nsvgRasterize(mRasterizer, mParsedSvg, 0.f,0.f,scale, buffer, mWidth, mHeight, bufferStride ); mPixelData = Dali::PixelData::New( buffer, bufferSize, mWidth, mHeight, Pixel::RGBA8888, Dali::PixelData::DELETE_ARRAY ); } +#else /* NO_THORVG */ + if ( mWidth <= 0u || mHeight <= 0u ) + { + DALI_LOG_ERROR( "Size is zero!\n" ); + return; + } + + Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New( mWidth, mHeight, Dali::Pixel::RGBA8888 ); + mVectorRenderer.SetBuffer( pixelBuffer ); + { + 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.Render( scale ) ) + { + DALI_LOG_ERROR( "SVG Render Fail!\n" ); + return; + } + + mPixelData = Devel::PixelBuffer::Convert( pixelBuffer ); + if ( !mPixelData ) + { + DALI_LOG_ERROR( "Pixel Data is null\n" ); + } + } +#endif /* NO_THORVG */ +} + +#ifdef NO_THORVG +NSVGimage* RasterizingTask::GetParsedImage() const +{ + return mParsedSvg; +} +#else /* NO_THORVG */ +VectorImageRenderer RasterizingTask::GetVectorRenderer() const +{ + return mVectorRenderer; } +bool RasterizingTask::IsLoaded() const +{ + return mLoaded; +} +#endif /* NO_THORVG */ + SvgVisual* RasterizingTask::GetSvgVisual() const { return mSvgVisual.Get(); @@ -73,13 +201,10 @@ SvgRasterizeThread::SvgRasterizeThread( EventThreadCallback* trigger ) : mTrigger( trigger ), mIsThreadWaiting( false ) { - mRasterizer = nsvgCreateRasterizer(); } SvgRasterizeThread::~SvgRasterizeThread() { - - nsvgDeleteRasterizer( mRasterizer ); delete mTrigger; } @@ -162,6 +287,7 @@ void SvgRasterizeThread::RemoveTask( SvgVisual* visual ) } } +#ifdef NO_THORVG void SvgRasterizeThread::DeleteImage( NSVGimage* parsedSvg ) { // Lock while adding image to the delete queue @@ -176,6 +302,22 @@ void SvgRasterizeThread::DeleteImage( NSVGimage* parsedSvg ) mDeleteSvg.PushBack( parsedSvg ); } } +#else /* NO_THORVG */ +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 + { + // TODO: what? + } + else // wait to delete until current rasterization completed. + { + mDeleteSvg.PushBack( &vectorRenderer ); + } +} +#endif /* NO_THORVG */ RasterizingTaskPtr SvgRasterizeThread::NextTaskToProcess() { @@ -185,12 +327,14 @@ RasterizingTaskPtr SvgRasterizeThread::NextTaskToProcess() // Delete the image here to make sure that it is not used in the nsvgRasterize() if( !mDeleteSvg.Empty() ) { +#ifdef NO_THORVG for( Vector< NSVGimage* >::Iterator it = mDeleteSvg.Begin(), endIt = mDeleteSvg.End(); it != endIt; ++it ) { nsvgDelete( *it ); } +#endif /* NO_THORVG */ mDeleteSvg.Clear(); } @@ -225,7 +369,8 @@ void SvgRasterizeThread::Run() SetThreadName( "SVGThread" ); while( RasterizingTaskPtr task = NextTaskToProcess() ) { - task->Rasterize( mRasterizer ); + task->Load( ); + task->Rasterize( ); AddCompletedTask( task ); } }