Implements CanvasView control 98/250398/42
authorJunsuChoi <jsuya.choi@samsung.com>
Thu, 24 Dec 2020 06:59:30 +0000 (15:59 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Fri, 19 Mar 2021 06:58:26 +0000 (15:58 +0900)
Control for drawing Vector Primitives.
CanvasView can draw a shape in its internal buffer
by adding a Dali::CanvasRenderer::Shape object and calling Commit().
Dali::CanvasRenderer::Shape is a command list based on Path.
Fill and Stroke properties can be set using setters and getters.
Dali::CanvasRenderer::Drawable is a parent class of Dali::CanvasRenderer::Shape and
it has common class of classes to be added later (Scene, etc.).

Note:
Currently, the CanvasView's buffer is using PixelData.
This buffer strategy will be changed to tbmBuffer in the future.

[API List]
class CanvasView : public control
  New
  AddDrawable

Change-Id: I50ade6fb981e72f3e4ccc1ec34cd82de784a7bd4

12 files changed:
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-canvas-renderer.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp [new file with mode: 0644]
dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp [new file with mode: 0644]
dali-toolkit/devel-api/controls/canvas-view/canvas-view.h [new file with mode: 0644]
dali-toolkit/devel-api/file.list
dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/graphics/shaders/canvas-view.frag [new file with mode: 0644]
dali-toolkit/internal/graphics/shaders/canvas-view.vert [new file with mode: 0644]
doc/dali-toolkit-doc.h

index ea6c3fc..1b8e5f7 100755 (executable)
@@ -14,6 +14,7 @@ SET(TC_SOURCES
   utc-Dali-BloomView.cpp
   utc-Dali-BubbleEmitter.cpp
   utc-Dali-Builder.cpp
+  utc-Dali-CanvasView.cpp
   utc-Dali-CheckBoxButton.cpp
   utc-Dali-ConfirmationPopup.cpp
   utc-Dali-CubeTransitionEffect.cpp
@@ -77,6 +78,7 @@ SET(TC_SOURCES
 SET(TEST_HARNESS_SOURCES
   dali-toolkit-test-utils/toolkit-adaptor.cpp
   dali-toolkit-test-utils/toolkit-application.cpp
+  dali-toolkit-test-utils/toolkit-canvas-renderer.cpp
   dali-toolkit-test-utils/toolkit-clipboard.cpp
   dali-toolkit-test-utils/toolkit-clipboard-event-notifier.cpp
   dali-toolkit-test-utils/toolkit-event-thread-callback.cpp
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-canvas-renderer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-canvas-renderer.cpp
new file mode 100644 (file)
index 0000000..0d6b87e
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/devel-api/adaptor-framework/canvas-renderer.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer-drawable.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/rendering/renderer.h>
+#include <toolkit-application.h>
+#include <toolkit-event-thread-callback.h>
+#include <memory>
+#include <cstring>
+#include <sys/stat.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+class CanvasRenderer: public Dali::BaseObject
+{
+public:
+  CanvasRenderer( const Vector2& size )
+  : mPixelBuffer( Devel::PixelBuffer::New(size.width, size.height, Dali::Pixel::RGBA8888) ),
+    mSize(size)
+  {
+  }
+
+  ~CanvasRenderer()
+  {
+  }
+
+  bool Commit()
+  {
+     return true;
+  }
+
+  bool AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
+  {
+    if (!drawable)
+    {
+      return false;
+    }
+    return true;
+  }
+
+  Devel::PixelBuffer GetPixelBuffer()
+  {
+    return mPixelBuffer;
+  }
+
+
+  bool SetSize(const Vector2& size)
+  {
+    mSize = size;
+    // For negative test
+    if ( size.width == -999 && size.height == -999 )
+    {
+      return false;
+    }
+    return true;
+  }
+
+  const Vector2& GetSize()
+  {
+    mSize = Vector2(200, 200);
+    return mSize;
+  }
+
+
+public:
+   Devel::PixelBuffer mPixelBuffer;
+   Vector2 mSize;
+};
+
+inline CanvasRenderer& GetImplementation( Dali::CanvasRenderer& renderer )
+{
+  DALI_ASSERT_ALWAYS( renderer && "CanvasRenderer handle is empty." );
+  BaseObject& handle = renderer.GetBaseObject();
+  return static_cast< Internal::Adaptor::CanvasRenderer& >( handle );
+}
+
+inline const CanvasRenderer& GetImplementation( const Dali::CanvasRenderer& renderer )
+{
+  DALI_ASSERT_ALWAYS( renderer && "CanvasRenderer handle is empty." );
+  const BaseObject& handle = renderer.GetBaseObject();
+  return static_cast< const Internal::Adaptor::CanvasRenderer& >( handle );
+}
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+
+/********************************************************************************/
+/*********************************  PUBLIC CLASS  *******************************/
+/********************************************************************************/
+
+CanvasRenderer CanvasRenderer::New( const Vector2& size )
+{
+  Internal::Adaptor::CanvasRenderer* imageRenderer = new Internal::Adaptor::CanvasRenderer(size);
+
+  return CanvasRenderer( imageRenderer );
+}
+
+CanvasRenderer::CanvasRenderer()
+{
+}
+
+CanvasRenderer::~CanvasRenderer()
+{
+}
+
+CanvasRenderer::CanvasRenderer( Internal::Adaptor::CanvasRenderer* internal )
+: BaseHandle( internal )
+{
+}
+
+bool CanvasRenderer::Commit()
+{
+  return Internal::Adaptor::GetImplementation(*this).Commit();
+}
+
+Devel::PixelBuffer CanvasRenderer::GetPixelBuffer()
+{
+  return Internal::Adaptor::GetImplementation(*this).GetPixelBuffer();
+}
+
+bool CanvasRenderer::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
+{
+  return Internal::Adaptor::GetImplementation(*this).AddDrawable(drawable);
+}
+
+bool CanvasRenderer::SetSize(const Vector2& size)
+{
+  return Internal::Adaptor::GetImplementation(*this).SetSize(size);
+}
+
+const Vector2& CanvasRenderer::GetSize()
+{
+  return Internal::Adaptor::GetImplementation(*this).GetSize();
+}
+
+
+} // namespace Dali
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp
new file mode 100644 (file)
index 0000000..1c5128e
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <test-application.h>
+#include <dali-toolkit/devel-api/controls/canvas-view/canvas-view.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer-shape.h>
+
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+
+} // namespace
+
+void utc_dali_toolkit_canvasview_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_canvasview_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliCanvasViewConstructorP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView;
+
+  DALI_TEST_CHECK( !canvasView );
+  END_TEST;
+}
+
+int UtcDaliCanvasViewMoveAssignment(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100, 100));
+
+  CanvasView moved = std::move( canvasView );
+  DALI_TEST_CHECK( moved );
+  DALI_TEST_EQUALS( 1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION );
+  DALI_TEST_CHECK( !canvasView );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewAssignmentConstructorP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100, 100));
+
+  CanvasView copy( canvasView );
+  DALI_TEST_CHECK( copy );
+
+  DALI_TEST_CHECK( canvasView == copy );
+  END_TEST;
+}
+
+int UtcDaliCanvasViewAssignmentOperatorP(void)
+{
+  ToolkitTestApplication application;
+  const CanvasView canvasView = CanvasView::New(Vector2(100, 100));
+
+  CanvasView assign;
+  DALI_TEST_CHECK( !assign );
+
+  assign = canvasView ;
+  DALI_TEST_CHECK( assign == canvasView);
+  END_TEST;
+}
+
+int UtcDaliCanvasViewNewP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100, 100));
+
+  DALI_TEST_CHECK( canvasView );
+  END_TEST;
+}
+
+int UtcDaliCanvasViewDownCastP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+
+  BaseHandle object(canvasView);
+
+  CanvasView canvasView2 = CanvasView::DownCast( object );
+  DALI_TEST_CHECK(canvasView2);
+
+  CanvasView canvasView3 = DownCast< CanvasView >(object);
+  DALI_TEST_CHECK(canvasView3);
+  END_TEST;
+}
+
+int UtcDaliCanvasViewDownCastN(void)
+{
+  ToolkitTestApplication application;
+  BaseHandle unInitializedObject;
+
+  CanvasView canvasView1 = CanvasView::DownCast( unInitializedObject );
+  DALI_TEST_CHECK( !canvasView1 );
+
+  CanvasView canvasView2 = DownCast< CanvasView >( unInitializedObject );
+  DALI_TEST_CHECK( !canvasView2 );
+  END_TEST;
+}
+
+int UtcDaliCanvasViewAddP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  Dali::CanvasRenderer::Shape shape = Dali::CanvasRenderer::Shape::New();
+
+  shape.AddRect(Rect<float>(10, 10, 10, 10), Vector2(0, 0));
+
+  canvasView.AddDrawable(shape);
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewAddN(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  Dali::CanvasRenderer::Shape shape;
+
+  canvasView.AddDrawable(shape);
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewChangeSizeP(void)
+{
+  ToolkitTestApplication application;
+
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  application.GetScene().Add(canvasView);
+  application.SendNotification();
+  application.Render();
+
+  canvasView.SetProperty(Actor::Property::SIZE, Vector2(300, 300));
+
+  application.SendNotification();
+  application.Render();
+
+  Property::Value pv = canvasView.GetProperty(Actor::Property::SIZE);
+  Vector3 v3;
+  pv.Get(v3);
+  DALI_TEST_EQUALS( v3, Vector3(300, 300, 0), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewSizeN(void)
+{
+  ToolkitTestApplication application;
+
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  application.GetScene().Add(canvasView);
+  application.SendNotification();
+  application.Render();
+
+  canvasView.SetProperty(Actor::Property::SIZE, Vector2(-999, -999));
+
+  application.SendNotification();
+  application.Render();
+
+  Property::Value pv = canvasView.GetProperty(Actor::Property::SIZE);
+  Vector3 v3;
+  pv.Get(v3);
+  DALI_TEST_EQUALS( v3, Vector3(-999, -999, 0), TEST_LOCATION );
+
+  END_TEST;
+}
diff --git a/dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp b/dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp
new file mode 100644 (file)
index 0000000..d6ebc63
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/devel-api/controls/canvas-view/canvas-view.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+CanvasView::CanvasView()
+{
+}
+
+CanvasView::CanvasView(const CanvasView& canvasView)
+: Control(canvasView)
+{
+}
+
+CanvasView::CanvasView(CanvasView&& rhs) = default;
+
+CanvasView& CanvasView::operator=(const CanvasView& rhs)
+{
+  if(&rhs != this)
+  {
+    Control::operator=(rhs);
+  }
+  return *this;
+}
+
+CanvasView& CanvasView::operator=(CanvasView&& rhs) = default;
+
+CanvasView::~CanvasView()
+{
+}
+
+CanvasView CanvasView::New(const Vector2& viewBox)
+{
+  CanvasView canvasView = Internal::CanvasView::New(viewBox);
+  return canvasView;
+}
+
+CanvasView CanvasView::DownCast(BaseHandle handle)
+{
+  return Control::DownCast<CanvasView, Internal::CanvasView>(handle);
+}
+
+void CanvasView::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
+{
+  Dali::Toolkit::GetImpl(*this).AddDrawable(drawable);
+}
+
+CanvasView::CanvasView(Internal::CanvasView& implementation)
+: Control(implementation)
+{
+}
+
+CanvasView::CanvasView(Dali::Internal::CustomActor* internal)
+: Control(internal)
+{
+  VerifyCustomActorPointer<Internal::CanvasView>(internal);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/controls/canvas-view/canvas-view.h b/dali-toolkit/devel-api/controls/canvas-view/canvas-view.h
new file mode 100644 (file)
index 0000000..9e59722
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef DALI_TOOLKIT_CANVAS_VIEW_H
+#define DALI_TOOLKIT_CANVAS_VIEW_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/canvas-renderer-drawable.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer-shape.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal DALI_INTERNAL
+{
+class CanvasView;
+}
+/**
+ * @addtogroup dali_toolkit_controls_canvas_view
+ * @{
+ */
+
+/**
+ * @brief CanvasView is a class for displaying an vector primitives.
+ *
+ * @code
+ *    auto myCanvasView = CanvasView::New( viewBox ) ); //The viewBox is the size of viewbox of CanvasView.
+ *
+ *    //Create shape and set properties.
+ *    auto shape = Dali::CanvasRenderer::Shape::New();
+ *    shape.AddRect( 0, 0, 10, 10, 0, 0 );
+ *    shape.SetFillColor( Vector4( 1.0, 1.0, 1.0, 1.0 ) );
+ *    myCanvasView.AddDrawable( shape );
+ * @endcode
+ *
+ *
+ */
+class DALI_TOOLKIT_API CanvasView : public Control
+{
+public:
+  /**
+   * @brief Creates an uninitialized CanvasView.
+   */
+  CanvasView();
+
+  /**
+   * @brief Creates an initialized CanvasView
+   *
+   * @param [in] viewBox The width and height.
+   * @return A handle to a newly allocated CanvasView
+   */
+  static CanvasView New(const Vector2& viewBox);
+
+  /**
+   * @brief Destructor.
+   *
+   * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   */
+  ~CanvasView();
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] canvasView CanvasView to copy. The copied CanvasView will point at the same implementation
+   */
+  CanvasView(const CanvasView& canvasView);
+
+  /**
+   * @brief Move constructor
+   *
+   * @param[in] rhs A reference to the moved handle
+   */
+  CanvasView(CanvasView&& rhs);
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] canvasView The CanvasView to assign from
+   * @return The updated CanvasView
+   */
+  CanvasView& operator=(const CanvasView& canvasView);
+
+  /**
+   * @brief Move assignment
+   *
+   * @param[in] rhs A reference to the moved handle
+   * @return A reference to this
+   */
+  CanvasView& operator=(CanvasView&& rhs);
+
+  /**
+   * @brief Downcasts a handle to CanvasView handle.
+   *
+   * If handle points to a CanvasView, the downcast produces valid handle.
+   * If not, the returned handle is left uninitialized.
+   *
+   * @param[in] handle Handle to an object
+   * @return Handle to a CanvasView or an uninitialized handle
+   */
+  static CanvasView DownCast(BaseHandle handle);
+
+  /**
+   * @brief Add drawable object to the CanvasView.
+   * This method is similar to registration. The added shape is drawn on the inner canvas.
+   */
+  void AddDrawable(Dali::CanvasRenderer::Drawable& drawable);
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief Creates a handle using the Toolkit::Internal implementation.
+   *
+   * @param[in] implementation The CanvasView implementation
+   */
+  DALI_INTERNAL CanvasView(Internal::CanvasView& implementation);
+
+  /**
+   * @brief Allows the creation of this CanvasView from an Internal::CustomActor pointer.
+   *
+   * @param[in] internal A pointer to the internal CustomActor
+   */
+  DALI_INTERNAL CanvasView(Dali::Internal::CustomActor* internal);
+  /// @endcond
+};
+
+/**
+ * @}
+ */
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_CANVAS_VIEW_H
index 0e1ec7d..e94ebe7 100755 (executable)
@@ -10,6 +10,7 @@ SET( devel_api_src_files
   ${devel_api_src_dir}/builder/json-parser.cpp
   ${devel_api_src_dir}/builder/tree-node.cpp
   ${devel_api_src_dir}/controls/accessible-impl.cpp
+  ${devel_api_src_dir}/controls/canvas-view/canvas-view.cpp
   ${devel_api_src_dir}/controls/control-devel.cpp
   ${devel_api_src_dir}/controls/control-wrapper.cpp
   ${devel_api_src_dir}/controls/control-wrapper-impl.cpp
@@ -83,6 +84,7 @@ SET( devel_api_accessibility-manager_header_files
 
 SET( devel_api_controls_header_files
   ${devel_api_src_dir}/controls/accessible-impl.h
+  ${devel_api_src_dir}/controls/canvas-view/canvas-view.h
   ${devel_api_src_dir}/controls/control-depth-index-ranges.h
   ${devel_api_src_dir}/controls/control-devel.h
   ${devel_api_src_dir}/controls/control-wrapper.h
diff --git a/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp b/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp
new file mode 100644 (file)
index 0000000..07c77d9
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "canvas-view-impl.h"
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/scripting/scripting.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#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/control/control-data-impl.h>
+#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+namespace
+{
+BaseHandle Create()
+{
+  return BaseHandle();
+}
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN(Toolkit::CanvasView, Toolkit::Control, Create);
+DALI_TYPE_REGISTRATION_END()
+} // anonymous namespace
+
+using namespace Dali;
+
+CanvasView::CanvasView(const Vector2& viewBox)
+: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
+  mCanvasRenderer(CanvasRenderer::New(viewBox)),
+  mTexture(),
+  mChanged(false)
+{
+}
+
+CanvasView::~CanvasView()
+{
+  if(Adaptor::IsAvailable())
+  {
+    Adaptor::Get().UnregisterProcessor(*this);
+  }
+}
+
+Toolkit::CanvasView CanvasView::New(const Vector2& viewBox)
+{
+  CanvasView* impl = new CanvasView(viewBox);
+
+  Toolkit::CanvasView handle = Toolkit::CanvasView(*impl);
+
+  // Second-phase init of the implementation
+  // This can only be done after the CustomActor connection has been made...
+  impl->Initialize();
+
+  return handle;
+}
+
+/////////////////////////////////////////////////////////////
+
+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<Dali::Accessibility::Accessible>(
+      new DevelControl::AccessibleImpl(actor, Dali::Accessibility::Role::IMAGE));
+  });
+
+  Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
+
+  Adaptor::Get().RegisterProcessor(*this);
+}
+
+void CanvasView::OnRelayout(const Vector2& size, RelayoutContainer& container)
+{
+  if(!mCanvasRenderer ||
+     mCanvasRenderer.GetSize() == size ||
+     !mCanvasRenderer.SetSize(size))
+  {
+    return;
+  }
+  mChanged = true;
+}
+
+void CanvasView::OnSizeSet(const Vector3& targetSize)
+{
+  Control::OnSizeSet(targetSize);
+
+  if(!mCanvasRenderer ||
+     mCanvasRenderer.GetSize() == Vector2(targetSize) ||
+     !mCanvasRenderer.SetSize(Vector2(targetSize)))
+  {
+    return;
+  }
+  mChanged = true;
+}
+
+void CanvasView::Process()
+{
+  if(!mCanvasRenderer)
+  {
+    return;
+  }
+  Commit();
+}
+
+void CanvasView::Commit()
+{
+  if(mCanvasRenderer && mCanvasRenderer.Commit())
+  {
+    Devel::PixelBuffer pixbuf = mCanvasRenderer.GetPixelBuffer();
+    auto               width  = pixbuf.GetWidth();
+    auto               height = pixbuf.GetHeight();
+
+    Dali::PixelData pixelData = Devel::PixelBuffer::Convert(pixbuf);
+    if(!pixelData)
+    {
+      return;
+    }
+
+    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
+    {
+      //Update texture
+      mTexture.Upload(pixelData);
+    }
+  }
+}
+
+bool CanvasView::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
+{
+  if(mCanvasRenderer && mCanvasRenderer.AddDrawable(drawable))
+  {
+    return true;
+  }
+  return false;
+}
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h b/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h
new file mode 100644 (file)
index 0000000..bc5c708
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef DALI_TOOLKIT_INTERNAL_CANVAS_VIEW_H
+#define DALI_TOOLKIT_INTERNAL_CANVAS_VIEW_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/canvas-renderer-drawable.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer-shape.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
+#include <dali/integration-api/processor-interface.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/canvas-view/canvas-view.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+class CanvasView;
+
+namespace Internal
+{
+class CanvasView : public Control, public Integration::Processor
+{
+public:
+  /**
+   * Construct a new CanvasView.
+   */
+  CanvasView(const Vector2& viewBox);
+
+  /**
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~CanvasView();
+
+public:
+  /**
+   * Create a new CanvasView.
+   * @return A smart-pointer to the newly allocated CanvasView.
+   */
+  static Toolkit::CanvasView New(const Vector2& viewBox);
+
+  /**
+   * @copydoc Toolkit::Control::CanvasView::AddDrawable
+   */
+  bool AddDrawable(Dali::CanvasRenderer::Drawable& drawable);
+
+private: // From Control
+  /**
+   * @copydoc Control::OnRelayout
+   */
+  void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
+
+  /**
+   * @copydoc Toolkit::Control::OnSizeSet()
+   */
+  void OnSizeSet(const Vector3& targetSize) override;
+
+  /**
+   * @copydoc Toolkit::Control::OnInitialize
+   */
+  void OnInitialize() override;
+
+protected: // Implementation of Processor
+  /**
+   * @copydoc Dali::Integration::Processor::Process()
+   */
+  void Process() override;
+
+private:
+  /**
+   * @brief Draw drawables added to CanvasView on inner canvas.
+   * Then make that buffer into a texture and add it to renderer.
+   */
+  void Commit();
+
+private:
+  CanvasView(const CanvasView&) = delete;
+  CanvasView& operator=(const CanvasView&) = delete;
+
+private:
+  CanvasRenderer mCanvasRenderer;
+  Dali::Texture  mTexture;
+  bool           mChanged;
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+inline Toolkit::Internal::CanvasView& GetImpl(Toolkit::CanvasView& obj)
+{
+  DALI_ASSERT_ALWAYS(obj);
+  Dali::RefObject& handle = obj.GetImplementation();
+  return static_cast<Toolkit::Internal::CanvasView&>(handle);
+}
+
+inline const Toolkit::Internal::CanvasView& GetImpl(const Toolkit::CanvasView& obj)
+{
+  DALI_ASSERT_ALWAYS(obj);
+  const Dali::RefObject& handle = obj.GetImplementation();
+  return static_cast<const Toolkit::Internal::CanvasView&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_CANVAS_VIEW_H
index c26fc7c..1fd9511 100644 (file)
@@ -61,6 +61,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/controls/buttons/push-button-impl.cpp
    ${toolkit_src_dir}/controls/buttons/radio-button-impl.cpp
    ${toolkit_src_dir}/controls/buttons/toggle-button-impl.cpp
+   ${toolkit_src_dir}/controls/canvas-view/canvas-view-impl.cpp
    ${toolkit_src_dir}/controls/control/control-data-impl.cpp
    ${toolkit_src_dir}/controls/control/control-debug.cpp
    ${toolkit_src_dir}/controls/control/control-renderers.cpp
diff --git a/dali-toolkit/internal/graphics/shaders/canvas-view.frag b/dali-toolkit/internal/graphics/shaders/canvas-view.frag
new file mode 100644 (file)
index 0000000..e122bca
--- /dev/null
@@ -0,0 +1,8 @@
+uniform lowp vec4 uColor;
+varying mediump vec2 vTexCoord;
+uniform sampler2D sTexture;
+
+void main()
+{
+  gl_FragColor = texture2D(sTexture, vTexCoord) * uColor;
+}
diff --git a/dali-toolkit/internal/graphics/shaders/canvas-view.vert b/dali-toolkit/internal/graphics/shaders/canvas-view.vert
new file mode 100644 (file)
index 0000000..6988993
--- /dev/null
@@ -0,0 +1,10 @@
+attribute mediump vec2 aPosition;
+varying mediump vec2 vTexCoord;
+uniform highp mat4 uMvpMatrix;
+uniform highp vec3 uSize;
+
+void main()
+{
+  gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);
+  vTexCoord = aPosition + vec2(0.5);
+}
index 5765d9c..ce364eb 100755 (executable)
  *     @defgroup dali_toolkit_controls_buttons Buttons
  *     @brief Button is a small object on UI that you can press.
 
+ *     @defgroup dali_toolkit_controls_canvas_view CanvasView
+ *     @brief CanvasView is a class for displaying an vector primitives.
+ *
  *     @defgroup dali_toolkit_controls_gaussian_blur_view Gaussian Blur View
  *     @brief GaussianBlurView provides a render process that blurs an image.