#include <dali/public-api/object/type-registry.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/controls/canvas-view/canvas-view.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/internal/controls/canvas-view/canvas-view-rasterize-thread.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
}
// 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_TYPE_REGISTRATION_END()
} // anonymous namespace
: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
mCanvasRenderer(CanvasRenderer::New(viewBox)),
mTexture(),
- mChanged(false)
+ mTextureSet(),
+ mSize(viewBox),
+ mCanvasViewRasterizeThread(nullptr)
{
}
CanvasView::~CanvasView()
{
+ if(mCanvasViewRasterizeThread)
+ {
+ mCanvasViewRasterizeThread->RemoveTask(this);
+
+ CanvasViewRasterizeThread::TerminateThread(mCanvasViewRasterizeThread);
+ }
+
if(Adaptor::IsAvailable())
{
Adaptor::Get().UnregisterProcessor(*this);
new DevelControl::AccessibleImpl(actor, 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)
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(bool postProcessor)
+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;
+ }
+ }
}
- 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;
+ }
}
+ }
+ return value;
+}
- if(!mTexture || mChanged)
- {
- 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;
- }
- else
+void CanvasView::Process(bool postProcessor)
+{
+ if(mCanvasRenderer && mCanvasRenderer.IsCanvasChanged() && mSize.width > 0 && mSize.height > 0)
+ {
+ AddRasterizationTask();
+ }
+}
+
+void CanvasView::AddRasterizationTask()
+{
+ CanvasRendererRasterizingTaskPtr newTask = new CanvasRendererRasterizingTask(this, mCanvasRenderer);
+
+ if(!mCanvasViewRasterizeThread)
+ {
+ mCanvasViewRasterizeThread = new CanvasViewRasterizeThread();
+ mCanvasViewRasterizeThread->RasterizationCompletedSignal().Connect(this, &CanvasView::ApplyRasterizedImage);
+ mCanvasViewRasterizeThread->Start();
+ }
+
+ if(mCanvasRenderer.Commit())
+ {
+ mCanvasViewRasterizeThread->AddTask(newTask);
+ }
+}
+
+void CanvasView::ApplyRasterizedImage(PixelData rasterizedPixelData)
+{
+ if(rasterizedPixelData)
+ {
+ auto rasterizedPixelDataWidth = rasterizedPixelData.GetWidth();
+ auto rasterizedPixelDataHeight = rasterizedPixelData.GetHeight();
+
+ if(rasterizedPixelDataWidth > 0 && rasterizedPixelDataHeight > 0)
{
- //Update texture
- mTexture.Upload(pixelData);
+ if(!mTexture || mTexture.GetWidth() != rasterizedPixelDataWidth || mTexture.GetHeight() != rasterizedPixelDataHeight)
+ {
+ mTexture = Texture::New(TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, rasterizedPixelDataWidth, rasterizedPixelDataHeight);
+ mTexture.Upload(rasterizedPixelData);
+
+ if(!mTextureSet)
+ {
+ mTextureSet = TextureSet::New();
+ Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
+ Shader shader = Shader::New(SHADER_CANVAS_VIEW_VERT, SHADER_CANVAS_VIEW_FRAG);
+ Renderer renderer = Renderer::New(geometry, shader);
+ renderer.SetTextures(mTextureSet);
+ renderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true);
+
+ Actor actor = Self();
+ if(actor)
+ {
+ actor.AddRenderer(renderer);
+ }
+ }
+ mTextureSet.SetTexture(0, mTexture);
+ }
+ else
+ {
+ //Update texture
+ mTexture.Upload(rasterizedPixelData);
+ }
}
}
+
+ //If there are accumulated changes to CanvasRenderer during Rasterize, Rasterize once again.
+ if(mCanvasRenderer && mCanvasRenderer.IsCanvasChanged())
+ {
+ AddRasterizationTask();
+ }
}
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;
+}
} // namespace Internal
} // namespace Toolkit
} // namespace Dali