X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=dali%2Finternal%2Fcanvas-renderer%2Ftizen%2Fcanvas-renderer-impl-tizen.cpp;h=bc4583717e9aae6110bc1e3a925e06fbe2905255;hb=21f8be59ca7d18faa05d1a4b49f65ca33c2a9af6;hp=b1b043c691b5ad03ada207caa13a50c9eeaeb4f9;hpb=921e04e8b21578f2698d60e152d2003767a46616;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/canvas-renderer/tizen/canvas-renderer-impl-tizen.cpp b/dali/internal/canvas-renderer/tizen/canvas-renderer-impl-tizen.cpp index b1b043c..bc45837 100644 --- a/dali/internal/canvas-renderer/tizen/canvas-renderer-impl-tizen.cpp +++ b/dali/internal/canvas-renderer/tizen/canvas-renderer-impl-tizen.cpp @@ -24,7 +24,10 @@ // INTERNAL INCLUDES #include +#include #include +#include +#include #include namespace Dali @@ -51,13 +54,16 @@ CanvasRendererTizen* CanvasRendererTizen::New(const Vector2& viewBox) } CanvasRendererTizen::CanvasRendererTizen(const Vector2& viewBox) -: mPixelBuffer(nullptr), +: #ifdef THORVG_SUPPORT + mPixelBuffer(nullptr), + mRasterizedTexture(), + mMutex(), mTvgCanvas(nullptr), mTvgRoot(nullptr), #endif - mSize(0, 0), - mViewBox(0, 0), + mSize(Vector2::ZERO), + mViewBox(Vector2::ZERO), mChanged(false) { Initialize(viewBox); @@ -66,19 +72,8 @@ CanvasRendererTizen::CanvasRendererTizen(const Vector2& viewBox) CanvasRendererTizen::~CanvasRendererTizen() { #ifdef THORVG_SUPPORT - for(DrawableVectorIterator it = mDrawables.begin(), - endIt = mDrawables.end(); - it != endIt; - ++it) - { - Dali::CanvasRenderer::Drawable drawable = (*it).GetHandle(); - if(DALI_UNLIKELY(!drawable)) - { - continue; - } - Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable); - drawableImpl.SetObject(nullptr); - } + mDrawables.clear(); + //Terminate ThorVG Engine tvg::Initializer::term(tvg::CanvasEngine::Sw); #endif @@ -100,34 +95,28 @@ void CanvasRendererTizen::Initialize(const Vector2& viewBox) } MakeTargetBuffer(mSize); - - auto scene = tvg::Scene::gen(); - mTvgRoot = scene.get(); - mTvgCanvas->push(move(scene)); #endif } bool CanvasRendererTizen::Commit() { #ifdef THORVG_SUPPORT + Mutex::ScopedLock lock(mMutex); + + if(mSize.width < 1.0f || mSize.height < 1.0f) + { + DALI_LOG_ERROR("Size is zero [%p]\n", this); + return false; + } + bool changed = false; - for(DrawableVectorIterator it = mDrawables.begin(), - endIt = mDrawables.end(); - it != endIt; - ++it) + for(auto& it : mDrawables) { - Dali::CanvasRenderer::Drawable drawable = (*it).GetHandle(); - if(DALI_UNLIKELY(!drawable)) - { - continue; - } - Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable); - if(drawableImpl.GetChanged()) + if(HaveDrawablesChanged(it)) { + UpdateDrawablesChanged(it, false); changed = true; - drawableImpl.SetChanged(false); - break; } } @@ -137,85 +126,259 @@ bool CanvasRendererTizen::Commit() } else { - if(!mPixelBuffer.GetBuffer()) + if(!mPixelBuffer || !mPixelBuffer.GetBuffer()) { MakeTargetBuffer(mSize); mChanged = false; } } - if(mSize.width < 1.0f || mSize.height < 1.0f) + if(mTvgCanvas->clear() != tvg::Result::Success) { - DALI_LOG_ERROR("Size is zero [%p]\n", this); + DALI_LOG_ERROR("ThorVG canvas clear fail [%p]\n", this); return false; } - if(mViewBox != mSize) + auto scene = tvg::Scene::gen(); + mTvgRoot = scene.get(); + for(auto& it : mDrawables) + { + PushDrawableToGroup(it, mTvgRoot); + } + + if(mViewBox != mSize && mViewBox.width > 0 && mViewBox.height > 0) { auto scaleX = mSize.width / mViewBox.width; auto scaleY = mSize.height / mViewBox.height; mTvgRoot->scale(scaleX < scaleY ? scaleX : scaleY); } - mTvgCanvas->update(mTvgRoot); - if(mTvgCanvas->draw() != tvg::Result::Success) + if(mTvgCanvas->push(move(scene)) != tvg::Result::Success) { - DALI_LOG_ERROR("ThorVG Draw fail [%p]\n", this); + DALI_LOG_ERROR("ThorVG canvas push fail [%p]\n", this); return false; } + return true; #else return false; #endif } -Devel::PixelBuffer CanvasRendererTizen::GetPixelBuffer() +Dali::Texture CanvasRendererTizen::GetRasterizedTexture() { - return mPixelBuffer; +#ifdef THORVG_SUPPORT + if(mPixelBuffer) + { + auto width = mPixelBuffer.GetWidth(); + auto height = mPixelBuffer.GetHeight(); + if(width <= 0 || height <= 0) + { + return Dali::Texture(); + } + + Dali::PixelData pixelData = Devel::PixelBuffer::Convert(mPixelBuffer); + + if(!mRasterizedTexture || mRasterizedTexture.GetWidth() != width || mRasterizedTexture.GetHeight() != height) + { + mRasterizedTexture = Dali::Texture::New(Dali::TextureType::TEXTURE_2D, Dali::Pixel::BGRA8888, width, height); + } + + mRasterizedTexture.Upload(pixelData); + } + return mRasterizedTexture; +#else + return Dali::Texture(); +#endif } bool CanvasRendererTizen::AddDrawable(Dali::CanvasRenderer::Drawable& drawable) { #ifdef THORVG_SUPPORT - bool exist = false; - for(DrawableVectorIterator it = mDrawables.begin(), - endIt = mDrawables.end(); - it != endIt; - ++it) + Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable); + if(drawableImpl.IsAdded()) + { + DALI_LOG_ERROR("Already added [%p][%p]\n", this, &drawable); + return false; + } + + drawableImpl.SetAdded(true); + mDrawables.push_back(drawable); + mChanged = true; + + return true; +#else + return false; +#endif +} + +#ifdef THORVG_SUPPORT +bool CanvasRendererTizen::HaveDrawablesChanged(const Dali::CanvasRenderer::Drawable& drawable) const +{ + const Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable); + if(drawableImpl.GetChanged()) + { + return true; + } + Dali::CanvasRenderer::Drawable compositeDrawable = drawableImpl.GetCompositionDrawable(); + if(DALI_UNLIKELY(compositeDrawable)) { - if((*it) == drawable) + Internal::Adaptor::Drawable& compositeDrawableImpl = Dali::GetImplementation(compositeDrawable); + if(compositeDrawableImpl.GetChanged()) { - exist = true; - break; + return true; } } - if(exist) + + if(drawableImpl.GetType() == Drawable::Types::DRAWABLE_GROUP) { - DALI_LOG_ERROR("Already added [%p]\n", this); - return false; + const Dali::CanvasRenderer::DrawableGroup& group = static_cast(drawable); + const Internal::Adaptor::DrawableGroup& drawableGroupImpl = Dali::GetImplementation(group); + DrawableGroup::DrawableVector drawables = drawableGroupImpl.GetDrawables(); + for(auto& it : drawables) + { + if(HaveDrawablesChanged(it)) + { + return true; + } + } + } + else if(drawableImpl.GetType() == Drawable::Types::SHAPE) + { + const Dali::CanvasRenderer::Shape& shape = static_cast(drawable); + Dali::CanvasRenderer::Gradient fillGradient = shape.GetFillGradient(); + if(DALI_UNLIKELY(fillGradient)) + { + Internal::Adaptor::Gradient& fillGradientImpl = Dali::GetImplementation(fillGradient); + if(fillGradientImpl.GetChanged()) + { + return true; + } + } + + Dali::CanvasRenderer::Gradient strokeGradient = shape.GetStrokeGradient(); + if(DALI_UNLIKELY(strokeGradient)) + { + Internal::Adaptor::Gradient& strokeGradientImpl = Dali::GetImplementation(strokeGradient); + if(strokeGradientImpl.GetChanged()) + { + return true; + } + } } + return false; +} + +void CanvasRendererTizen::UpdateDrawablesChanged(Dali::CanvasRenderer::Drawable& drawable, bool changed) +{ Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable); - tvg::Paint* pDrawable = static_cast(drawableImpl.GetObject()); - if(!pDrawable) + drawableImpl.SetChanged(changed); + + Dali::CanvasRenderer::Drawable compositeDrawable = drawableImpl.GetCompositionDrawable(); + if(DALI_UNLIKELY(compositeDrawable)) { - DALI_LOG_ERROR("Invalid drawable object [%p]\n", this); - return false; + Internal::Adaptor::Drawable& compositeDrawableImpl = Dali::GetImplementation(compositeDrawable); + compositeDrawableImpl.SetChanged(changed); } - if(mSize.width < 1.0f || mSize.height < 1.0f) + + if(drawableImpl.GetType() == Drawable::Types::DRAWABLE_GROUP) { - DALI_LOG_ERROR("Size is zero [%p]\n", this); - return false; + Dali::CanvasRenderer::DrawableGroup& group = static_cast(drawable); + Internal::Adaptor::DrawableGroup& drawableGroupImpl = Dali::GetImplementation(group); + DrawableGroup::DrawableVector drawables = drawableGroupImpl.GetDrawables(); + for(auto& it : drawables) + { + UpdateDrawablesChanged(it, changed); + } } + else if(drawableImpl.GetType() == Drawable::Types::SHAPE) + { + Dali::CanvasRenderer::Shape& shape = static_cast(drawable); + Dali::CanvasRenderer::Gradient fillGradient = shape.GetFillGradient(); + if(DALI_UNLIKELY(fillGradient)) + { + Internal::Adaptor::Gradient& fillGradientImpl = Dali::GetImplementation(fillGradient); + fillGradientImpl.SetChanged(changed); + } - if(mTvgRoot->push(std::unique_ptr(pDrawable)) != tvg::Result::Success) + Dali::CanvasRenderer::Gradient strokeGradient = shape.GetStrokeGradient(); + if(DALI_UNLIKELY(strokeGradient)) + { + Internal::Adaptor::Gradient& strokeGradientImpl = Dali::GetImplementation(strokeGradient); + strokeGradientImpl.SetChanged(changed); + } + } +} +#endif + +bool CanvasRendererTizen::IsCanvasChanged() const +{ +#ifdef THORVG_SUPPORT + if(mChanged) { - DALI_LOG_ERROR("Tvg push fail [%p]\n", this); + return true; + } + + for(auto& it : mDrawables) + { + if(HaveDrawablesChanged(it)) + { + return true; + } + } +#endif + return false; +} + +bool CanvasRendererTizen::Rasterize() +{ +#ifdef THORVG_SUPPORT + Mutex::ScopedLock lock(mMutex); + + if(mTvgCanvas->draw() != tvg::Result::Success) + { + DALI_LOG_ERROR("ThorVG Draw fail [%p]\n", this); return false; } - drawableImpl.SetDrawableAdded(true); - mDrawables.push_back(drawable); + mTvgCanvas->sync(); + + return true; +#else + return false; +#endif +} + +bool CanvasRendererTizen::RemoveDrawable(Dali::CanvasRenderer::Drawable& drawable) +{ +#ifdef THORVG_SUPPORT + DrawableGroup::DrawableVector::iterator it = std::find(mDrawables.begin(), mDrawables.end(), drawable); + if(it != mDrawables.end()) + { + Internal::Adaptor::Drawable& drawableImpl = GetImplementation(drawable); + drawableImpl.SetAdded(false); + + mDrawables.erase(it); + mChanged = true; + + return true; + } + +#endif + return false; +} + +bool CanvasRendererTizen::RemoveAllDrawables() +{ +#ifdef THORVG_SUPPORT + for(auto& it : mDrawables) + { + Internal::Adaptor::Drawable& drawableImpl = GetImplementation(it); + drawableImpl.SetAdded(false); + } + + mDrawables.clear(); mChanged = true; return true; @@ -224,7 +387,7 @@ bool CanvasRendererTizen::AddDrawable(Dali::CanvasRenderer::Drawable& drawable) #endif } -bool CanvasRendererTizen::SetSize(const Vector2& size) +bool CanvasRendererTizen::SetSize(Vector2 size) { if(size.width < 1.0f || size.height < 1.0f) { @@ -233,24 +396,43 @@ bool CanvasRendererTizen::SetSize(const Vector2& size) if(size != mSize) { - mSize = size; - MakeTargetBuffer(size); + mSize = size; + mChanged = true; } - mChanged = true; - return true; } -const Vector2& CanvasRendererTizen::GetSize() +Vector2 CanvasRendererTizen::GetSize() const { return mSize; } +bool CanvasRendererTizen::SetViewBox(const Vector2& viewBox) +{ + if(viewBox.width < 1.0f || viewBox.height < 1.0f) + { + return false; + } + + if(viewBox != mViewBox) + { + mViewBox = viewBox; + mChanged = true; + } + + return true; +} + +const Vector2& CanvasRendererTizen::GetViewBox() +{ + return mViewBox; +} + void CanvasRendererTizen::MakeTargetBuffer(const Vector2& size) { #ifdef THORVG_SUPPORT - mPixelBuffer = Devel::PixelBuffer::New(size.width, size.height, Dali::Pixel::RGBA8888); + mPixelBuffer = Devel::PixelBuffer::New(size.width, size.height, Dali::Pixel::BGRA8888); unsigned char* pBuffer; pBuffer = mPixelBuffer.GetBuffer(); @@ -261,12 +443,109 @@ void CanvasRendererTizen::MakeTargetBuffer(const Vector2& size) return; } - mTvgCanvas->sync(); - - mTvgCanvas->target(reinterpret_cast(pBuffer), size.width, size.width, size.height, tvg::SwCanvas::ABGR8888); + mTvgCanvas->target(reinterpret_cast(pBuffer), size.width, size.width, size.height, tvg::SwCanvas::ARGB8888); #endif } +#ifdef THORVG_SUPPORT +void CanvasRendererTizen::PushDrawableToGroup(Dali::CanvasRenderer::Drawable& drawable, tvg::Scene* parent) +{ + Internal::Adaptor::Drawable& drawableImpl = Dali::GetImplementation(drawable); + tvg::Paint* tvgDuplicatedObject = static_cast(drawableImpl.GetObject())->duplicate(); + if(!tvgDuplicatedObject) + { + DALI_LOG_ERROR("Invalid drawable object [%p]\n", this); + return; + } + Drawable::Types type = drawableImpl.GetType(); + + if(type == Drawable::Types::DRAWABLE_GROUP) + { + Dali::CanvasRenderer::DrawableGroup& group = static_cast(drawable); + Internal::Adaptor::DrawableGroup& drawableGroupImpl = Dali::GetImplementation(group); + DrawableGroup::DrawableVector drawables = drawableGroupImpl.GetDrawables(); + for(auto& it : drawables) + { + PushDrawableToGroup(it, static_cast(tvgDuplicatedObject)); + } + } + else if(type == Drawable::Types::SHAPE) + { + //FillGradient + Dali::CanvasRenderer::Shape& shape = static_cast(drawable); + Dali::CanvasRenderer::Gradient fillGradient = shape.GetFillGradient(); + if(DALI_UNLIKELY(fillGradient)) + { + Internal::Adaptor::Gradient& fillGradientImpl = Dali::GetImplementation(fillGradient); + tvg::Fill* tvgDuplicatedFillGradient = static_cast(fillGradientImpl.GetObject())->duplicate(); + if(!tvgDuplicatedFillGradient) + { + DALI_LOG_ERROR("Invalid gradient object [%p]\n", this); + return; + } + if(static_cast(tvgDuplicatedObject)->fill(std::unique_ptr(tvgDuplicatedFillGradient)) != tvg::Result::Success) + { + DALI_LOG_ERROR("Tvg gradient set fail [%p]\n", this); + return; + } + } + + //StrokeGradient + Dali::CanvasRenderer::Gradient strokeGradient = shape.GetStrokeGradient(); + if(DALI_UNLIKELY(strokeGradient)) + { + Internal::Adaptor::Gradient& strokeGradientImpl = Dali::GetImplementation(strokeGradient); + tvg::Fill* tvgDuplicatedStrokeGradient = static_cast(strokeGradientImpl.GetObject())->duplicate(); + if(!tvgDuplicatedStrokeGradient) + { + DALI_LOG_ERROR("Invalid gradient object [%p]\n", this); + return; + } + if(static_cast(tvgDuplicatedObject)->stroke(std::unique_ptr(tvgDuplicatedStrokeGradient)) != tvg::Result::Success) + { + DALI_LOG_ERROR("Tvg gradient set fail [%p]\n", this); + return; + } + } + } + + Dali::CanvasRenderer::Drawable compositeDrawable = drawableImpl.GetCompositionDrawable(); + if(DALI_UNLIKELY(compositeDrawable)) + { + Internal::Adaptor::Drawable& compositeDrawableImpl = Dali::GetImplementation(compositeDrawable); + tvg::Paint* tvgCompositeObject = static_cast(compositeDrawableImpl.GetObject()); + if(tvgCompositeObject) + { + tvg::Paint* tvgDuplicatedCompositeObject = tvgCompositeObject->duplicate(); + Drawable::Types type = compositeDrawableImpl.GetType(); + + if(type == Drawable::Types::DRAWABLE_GROUP) + { + Dali::CanvasRenderer::DrawableGroup& compositeGroup = static_cast(compositeDrawable); + Internal::Adaptor::DrawableGroup& compositeDrawableGroupImpl = Dali::GetImplementation(compositeGroup); + DrawableGroup::DrawableVector compositeDrawables = compositeDrawableGroupImpl.GetDrawables(); + for(auto& it : compositeDrawables) + { + PushDrawableToGroup(it, static_cast(tvgDuplicatedCompositeObject)); + } + } + + if(tvgDuplicatedObject->composite(std::move(std::unique_ptr(tvgDuplicatedCompositeObject)), static_cast(drawableImpl.GetCompositionType())) != tvg::Result::Success) + { + DALI_LOG_ERROR("Tvg composite fail [%p]\n", this); + return; + } + } + } + + if(parent->push(std::move(std::unique_ptr(tvgDuplicatedObject))) != tvg::Result::Success) + { + DALI_LOG_ERROR("Tvg push fail [%p]\n", this); + return; + } +} +#endif + } // namespace Adaptor } // namespace Internal