X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Fcanvas-view%2Fcanvas-view-impl.cpp;h=282ebb44763bef3d246358ef7aed2ea90d589ab0;hp=07c77d936e8f9fe5e8a931c534efc1cf52eaa5b4;hb=HEAD;hpb=c857a82d2a092fe17e654baf70afd454143310de diff --git a/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp b/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp index 07c77d9..282ebb4 100644 --- a/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp +++ b/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 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. @@ -19,13 +19,13 @@ #include "canvas-view-impl.h" // EXTERNAL INCLUDES +#include #include #include #include #include // INTERNAL INCLUDES -#include #include #include #include @@ -45,6 +45,8 @@ BaseHandle Create() } // Setup properties, signals and actions using the type-registry. DALI_TYPE_REGISTRATION_BEGIN(Toolkit::CanvasView, Toolkit::Control, Create); +DALI_PROPERTY_REGISTRATION(Toolkit, CanvasView, "viewBox", VECTOR2, VIEW_BOX) +DALI_PROPERTY_REGISTRATION(Toolkit, CanvasView, "synchronousLoading", BOOLEAN, SYNCHRONOUS_LOADING) DALI_TYPE_REGISTRATION_END() } // anonymous namespace @@ -54,7 +56,9 @@ CanvasView::CanvasView(const Vector2& viewBox) : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)), mCanvasRenderer(CanvasRenderer::New(viewBox)), mTexture(), - mChanged(false) + mTextureSet(), + mSize(viewBox), + mIsSynchronous(true) { } @@ -62,7 +66,9 @@ CanvasView::~CanvasView() { if(Adaptor::IsAvailable()) { - Adaptor::Get().UnregisterProcessor(*this); + Dali::AsyncTaskManager::Get().RemoveTask(mRasterizingTask); + mRasterizingTask.Reset(); + Adaptor::Get().UnregisterProcessor(*this, true); } } @@ -86,25 +92,19 @@ void CanvasView::OnInitialize() // CanvasView can relayout in the OnImageReady, alternative to a signal would be to have a upcall from the Control to CanvasView Dali::Toolkit::Control handle(GetOwner()); - DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) { - return std::unique_ptr( - new DevelControl::AccessibleImpl(actor, Dali::Accessibility::Role::IMAGE)); - }); + Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE); - Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true); - - Adaptor::Get().RegisterProcessor(*this); + Adaptor::Get().RegisterProcessor(*this, true); } void CanvasView::OnRelayout(const Vector2& size, RelayoutContainer& container) { if(!mCanvasRenderer || - mCanvasRenderer.GetSize() == size || !mCanvasRenderer.SetSize(size)) { return; } - mChanged = true; + mSize = size; } void CanvasView::OnSizeSet(const Vector3& targetSize) @@ -112,58 +112,131 @@ void CanvasView::OnSizeSet(const Vector3& targetSize) Control::OnSizeSet(targetSize); if(!mCanvasRenderer || - mCanvasRenderer.GetSize() == Vector2(targetSize) || !mCanvasRenderer.SetSize(Vector2(targetSize))) { return; } - mChanged = true; + mSize.width = targetSize.width; + mSize.height = targetSize.height; } -void CanvasView::Process() +void CanvasView::SetProperty(BaseObject* object, Property::Index propertyIndex, const Property::Value& value) { - if(!mCanvasRenderer) + Toolkit::CanvasView canvasView = Toolkit::CanvasView::DownCast(Dali::BaseHandle(object)); + if(canvasView) { - return; + CanvasView& canvasViewImpl(GetImpl(canvasView)); + + switch(propertyIndex) + { + case Toolkit::CanvasView::Property::VIEW_BOX: + { + Vector2 valueVector2; + if(value.Get(valueVector2)) + { + canvasViewImpl.SetViewBox(valueVector2); + } + break; + } + case Toolkit::CanvasView::Property::SYNCHRONOUS_LOADING: + { + bool isSynchronous; + if(value.Get(isSynchronous)) + { + canvasViewImpl.SetSynchronous(isSynchronous); + } + break; + } + } } - Commit(); } -void CanvasView::Commit() +Property::Value CanvasView::GetProperty(BaseObject* object, Property::Index propertyIndex) { - if(mCanvasRenderer && mCanvasRenderer.Commit()) + Property::Value value; + + Toolkit::CanvasView canvasView = Toolkit::CanvasView::DownCast(Dali::BaseHandle(object)); + + if(canvasView) { - Devel::PixelBuffer pixbuf = mCanvasRenderer.GetPixelBuffer(); - auto width = pixbuf.GetWidth(); - auto height = pixbuf.GetHeight(); + CanvasView& canvasViewImpl(GetImpl(canvasView)); - Dali::PixelData pixelData = Devel::PixelBuffer::Convert(pixbuf); - if(!pixelData) + switch(propertyIndex) { - return; + case Toolkit::CanvasView::Property::VIEW_BOX: + { + value = canvasViewImpl.GetViewBox(); + break; + } + case Toolkit::CanvasView::Property::SYNCHRONOUS_LOADING: + { + value = canvasViewImpl.IsSynchronous(); + break; + } } + } + return value; +} + +void CanvasView::Process(bool postProcessor) +{ + if(mCanvasRenderer && mCanvasRenderer.IsCanvasChanged() && mSize.width > 0 && mSize.height > 0) + { + AddRasterizationTask(); + } +} + +void CanvasView::AddRasterizationTask() +{ + mRasterizingTask = new CanvasRendererRasterizingTask(mCanvasRenderer, MakeCallback(this, &CanvasView::ApplyRasterizedImage)); - if(!mTexture || mChanged) + if(mCanvasRenderer.Commit()) + { + if(mIsSynchronous) { - mTexture = Texture::New(TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, width, height); - mTexture.Upload(pixelData); - TextureSet textureSet = TextureSet::New(); - textureSet.SetTexture(0, mTexture); - Geometry geometry = VisualFactoryCache::CreateQuadGeometry(); - Shader shader = Shader::New(SHADER_CANVAS_VIEW_VERT, SHADER_CANVAS_VIEW_FRAG); - Renderer renderer = Renderer::New(geometry, shader); - renderer.SetTextures(textureSet); - renderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true); - - Self().AddRenderer(renderer); - mChanged = false; + mRasterizingTask->Process(); + ApplyRasterizedImage(mRasterizingTask); + mRasterizingTask.Reset(); // We don't need it anymore. } else { - //Update texture - mTexture.Upload(pixelData); + AsyncTaskManager::Get().AddTask(mRasterizingTask); + } + } +} + +void CanvasView::ApplyRasterizedImage(CanvasRendererRasterizingTaskPtr task) +{ + if(task->IsRasterized()) + { + Texture rasterizedTexture = task->GetRasterizedTexture(); + if(rasterizedTexture && rasterizedTexture.GetWidth() != 0 && rasterizedTexture.GetHeight() != 0) + { + if(!mTextureSet) + { + std::string fragmentShader = SHADER_CANVAS_VIEW_FRAG.data(); + DevelTexture::ApplyNativeFragmentShader(rasterizedTexture, fragmentShader); + + mTextureSet = TextureSet::New(); + Geometry geometry = VisualFactoryCache::CreateQuadGeometry(); + Shader shader = Shader::New(SHADER_CANVAS_VIEW_VERT, fragmentShader, Shader::Hint::NONE, "CANVAS_VIEW"); + Renderer renderer = Renderer::New(geometry, shader); + + renderer.SetTextures(mTextureSet); + renderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true); + Self().AddRenderer(renderer); + } + mTextureSet.SetTexture(0, rasterizedTexture); } } + + mRasterizingTask.Reset(); // We don't need it anymore + + //If there are accumulated changes to CanvasRenderer during Rasterize, Rasterize once again. + if(!mIsSynchronous && mCanvasRenderer && mCanvasRenderer.IsCanvasChanged()) + { + AddRasterizationTask(); + } } bool CanvasView::AddDrawable(Dali::CanvasRenderer::Drawable& drawable) @@ -174,6 +247,53 @@ bool CanvasView::AddDrawable(Dali::CanvasRenderer::Drawable& drawable) } return false; } + +bool CanvasView::RemoveDrawable(Dali::CanvasRenderer::Drawable& drawable) +{ + if(mCanvasRenderer && mCanvasRenderer.RemoveDrawable(drawable)) + { + return true; + } + return false; +} + +bool CanvasView::RemoveAllDrawables() +{ + if(mCanvasRenderer && mCanvasRenderer.RemoveAllDrawables()) + { + return true; + } + return false; +} + +bool CanvasView::SetViewBox(const Vector2& viewBox) +{ + if(mCanvasRenderer && mCanvasRenderer.SetViewBox(viewBox)) + { + return true; + } + return false; +} + +const Vector2& CanvasView::GetViewBox() +{ + if(mCanvasRenderer) + { + return mCanvasRenderer.GetViewBox(); + } + return Vector2::ZERO; +} + +void CanvasView::SetSynchronous(const bool isSynchronous) +{ + mIsSynchronous = isSynchronous; +} + +const bool CanvasView::IsSynchronous() +{ + return mIsSynchronous; +} + } // namespace Internal } // namespace Toolkit } // namespace Dali