Merge "Clean up the code to build successfully on macOS" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / common / animatable-property.h
index 3108050..35daa3e 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H__
+#ifndef DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H
+#define DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -27,7 +27,7 @@
 #include <dali/public-api/object/property-input.h>
 #include <dali/public-api/object/property-types.h>
 #include <dali/internal/common/message.h>
-#include <dali/internal/common/event-to-update.h>
+#include <dali/internal/event/common/event-thread-services.h>
 #include <dali/internal/event/common/property-input-impl.h>
 #include <dali/internal/update/common/double-buffered.h>
 #include <dali/internal/update/common/property-base.h>
@@ -52,9 +52,9 @@ namespace SceneGraph
  * However if the property was only "Set" (and not "Baked"), then typically the base value and previous value will not match.
  * In this case the reset operation is equivalent to a "Bake", and the value is considered "dirty" for an additional frame.
  */
-static const unsigned int CLEAN_FLAG = 0x00; ///< Indicates that the value did not change in this, or the previous frame
-static const unsigned int BAKED_FLAG = 0x01; ///< Indicates that the value was Baked during the previous frame
-static const unsigned int SET_FLAG   = 0x02; ///< Indicates that the value was Set during the previous frame
+static const uint32_t CLEAN_FLAG = 0x00; ///< Indicates that the value did not change in this, or the previous frame
+static const uint32_t BAKED_FLAG = 0x01; ///< Indicates that the value was Baked during the previous frame
+static const uint32_t SET_FLAG   = 0x02; ///< Indicates that the value was Set during the previous frame
 
 template <class T>
 class AnimatableProperty;
@@ -77,8 +77,7 @@ public:
   /**
    * Virtual destructor.
    */
-  virtual ~AnimatablePropertyBase()
-  {}
+  ~AnimatablePropertyBase() override = default;
 
 protected: // for derived classes
 
@@ -103,7 +102,7 @@ public: // From PropertyBase
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::IsClean()
    */
-  virtual bool IsClean() const
+  bool IsClean() const override
   {
     return ( CLEAN_FLAG == mDirtyFlags );
   }
@@ -111,14 +110,14 @@ public: // From PropertyBase
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::InputInitialized()
    */
-  virtual bool InputInitialized() const
+  bool InputInitialized() const override
   {
     return true; // Animatable properties are always valid
   }
 
 protected: // so that ResetToBaseValue can set it directly
 
-  unsigned int mDirtyFlags; ///< Flag whether value changed during previous 2 frames
+  uint32_t mDirtyFlags; ///< Flag whether value changed during previous 2 frames
 
 };
 
@@ -144,14 +143,12 @@ public:
   /**
    * Virtual destructor.
    */
-  virtual ~AnimatableProperty()
-  {
-  }
+  ~AnimatableProperty() override = default;
 
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
    */
-  virtual Dali::Property::Type GetType() const
+  Dali::Property::Type GetType() const override
   {
     return Dali::PropertyTypes::Get<bool>();
   }
@@ -159,7 +156,7 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
     if (CLEAN_FLAG != mDirtyFlags)
     {
@@ -172,7 +169,7 @@ public:
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::GetBoolean()
    */
-  virtual const bool& GetBoolean( BufferIndex bufferIndex ) const
+  const bool& GetBoolean( BufferIndex bufferIndex ) const override
   {
     return mValue[ bufferIndex ];
   }
@@ -205,7 +202,7 @@ public:
     // false + false does not change value, true + false does not either
     if( delta && !mValue[bufferIndex] )
     {
-      mValue[bufferIndex] += delta;
+      mValue[bufferIndex] = delta;
 
       OnSet();
     }
@@ -214,7 +211,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  bool& Get(size_t bufferIndex)
+  bool& Get( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -222,7 +219,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const bool& Get(size_t bufferIndex) const
+  const bool& Get( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -232,7 +229,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  bool& operator[](size_t bufferIndex)
+  bool& operator[]( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -242,7 +239,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const bool& operator[](size_t bufferIndex) const
+  const bool& operator[]( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -254,11 +251,14 @@ public:
    */
   void Bake(BufferIndex bufferIndex, bool value)
   {
-    // check if the value actually changed to avoid dirtying nodes unnecessarily
-    if( mValue[bufferIndex] != value )
+    // bake has to check the base value as current buffer value can be correct by constraint or something else
+    if( mBaseValue != value )
     {
-      mValue[bufferIndex] = value;
       mBaseValue = value;
+      // It's ok to bake both buffers as render is performed in same thread as update. Reading from event side
+      // has never been atomically safe.
+      mValue[bufferIndex] = value;
+      mValue[1-bufferIndex] = value;
 
       OnBake();
     }
@@ -271,7 +271,7 @@ public:
    */
   void BakeRelative(BufferIndex bufferIndex, bool delta)
   {
-    mValue[bufferIndex] += delta;
+    mValue[bufferIndex] = mValue[bufferIndex] || delta;
     mBaseValue = mValue[bufferIndex];
 
     OnBake();
@@ -292,6 +292,186 @@ private:
 
 };
 
+
+/**
+ * An integer animatable property of a scene-graph object.
+ */
+template <>
+class AnimatableProperty<int> : public AnimatablePropertyBase
+{
+public:
+
+  /**
+   * Create an animatable property.
+   * @param [in] initialValue The initial value of the property.
+   */
+  AnimatableProperty( int initialValue )
+  : mValue( initialValue ),
+    mBaseValue( initialValue )
+  {
+  }
+
+  /**
+   * Virtual destructor.
+   */
+  ~AnimatableProperty() override = default;
+
+  /**
+   * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
+   */
+  Dali::Property::Type GetType() const override
+  {
+    return Dali::PropertyTypes::Get<int>();
+  }
+
+  /**
+   * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
+   */
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
+  {
+    if (CLEAN_FLAG != mDirtyFlags)
+    {
+      mValue[updateBufferIndex] = mBaseValue;
+
+      mDirtyFlags = ( mDirtyFlags >> 1 );
+    }
+  }
+
+  /**
+   * @copydoc Dali::Internal::PropertyInputImpl::GetInteger()
+   */
+  const int& GetInteger( BufferIndex bufferIndex ) const override
+  {
+    return mValue[ bufferIndex ];
+  }
+
+  /**
+   * Set the property value. This will only persist for the current frame; the property
+   * will be reset with the base value, at the beginning of the next frame.
+   * @param[in] bufferIndex The buffer to write.
+   * @param[in] value The new property value.
+   */
+  void Set(BufferIndex bufferIndex, int value)
+  {
+    mValue[bufferIndex] = value;
+
+    OnSet();
+  }
+
+  /**
+   * Change the property value by a relative amount.
+   * @param[in] bufferIndex The buffer to write.
+   * @param[in] delta The property will change by this amount.
+   */
+  void SetRelative(BufferIndex bufferIndex, int delta)
+  {
+    mValue[bufferIndex] = mValue[bufferIndex] + delta;
+
+    OnSet();
+  }
+
+  /**
+   * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
+   */
+  int& Get( BufferIndex bufferIndex )
+  {
+    return mValue[bufferIndex];
+  }
+
+  /**
+   * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
+   */
+  const int& Get( BufferIndex bufferIndex ) const
+  {
+    return mValue[bufferIndex];
+  }
+
+  /**
+   * Retrieve the property value.
+   * @param[in] bufferIndex The buffer to read.
+   * @return The property value.
+   */
+  int& operator[]( BufferIndex bufferIndex )
+  {
+    return mValue[bufferIndex];
+  }
+
+  /**
+   * Retrieve the property value.
+   * @param[in] bufferIndex The buffer to read.
+   * @return The property value.
+   */
+  const int& operator[]( BufferIndex bufferIndex ) const
+  {
+    return mValue[bufferIndex];
+  }
+
+  /**
+   * Set both the property value & base value.
+   * @param[in] bufferIndex The buffer to write for the property value.
+   * @param[in] value The new property value.
+   */
+  void Bake(BufferIndex bufferIndex, int value)
+  {
+    mValue[bufferIndex] = value;
+    mValue[1-bufferIndex] = value;
+    mBaseValue = mValue[bufferIndex];
+
+    OnBake();
+  }
+
+  /**
+   * Change the property value & base value by a relative amount.
+   * @param[in] bufferIndex The buffer to write for the local property value.
+   * @param[in] delta The property will change by this amount.
+   */
+  void BakeRelative(BufferIndex bufferIndex, int delta)
+  {
+    mValue[bufferIndex] = mValue[bufferIndex] + delta;
+    mBaseValue = mValue[bufferIndex];
+
+    OnBake();
+  }
+
+  /**
+   * Sets both double-buffered values & the base value.
+   * This should only be used when the owning object has not been connected to the scene-graph.
+   * @param[in] value The new property value.
+   */
+  void SetInitial(const int& value)
+  {
+    mValue[0]  = value;
+    mValue[1]  = mValue[0];
+    mBaseValue = mValue[0];
+  }
+
+  /**
+   * Change both double-buffered values & the base value by a relative amount.
+   * This should only be used when the owning object has not been connected to the scene-graph.
+   * @param[in] delta The property will change by this amount.
+   */
+  void SetInitialRelative(const int& delta)
+  {
+    mValue[0] = mValue[0] + delta;
+    mValue[1] = mValue[0];
+    mBaseValue = mValue[0];
+  }
+
+private:
+
+  // Undefined
+  AnimatableProperty(const AnimatableProperty& property);
+
+  // Undefined
+  AnimatableProperty& operator=(const AnimatableProperty& rhs);
+
+private:
+
+  DoubleBuffered<int> mValue; ///< The double-buffered property value
+  int mBaseValue;             ///< Reset to this base value at the beginning of each frame
+
+};
+
 /**
  * An float animatable property of a scene-graph object.
  */
@@ -313,14 +493,12 @@ public:
   /**
    * Virtual destructor.
    */
-  virtual ~AnimatableProperty()
-  {
-  }
+  ~AnimatableProperty() override = default;
 
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
    */
-  virtual Dali::Property::Type GetType() const
+  Dali::Property::Type GetType() const override
   {
     return Dali::PropertyTypes::Get<float>();
   }
@@ -328,7 +506,7 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
     if (CLEAN_FLAG != mDirtyFlags)
     {
@@ -341,7 +519,7 @@ public:
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::GetFloat()
    */
-  virtual const float& GetFloat( BufferIndex bufferIndex ) const
+  const float& GetFloat( BufferIndex bufferIndex ) const override
   {
     return mValue[ bufferIndex ];
   }
@@ -374,7 +552,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  float& Get(size_t bufferIndex)
+  float& Get( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -382,7 +560,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const float& Get(size_t bufferIndex) const
+  const float& Get( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -392,7 +570,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  float& operator[](size_t bufferIndex)
+  float& operator[]( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -402,7 +580,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const float& operator[](size_t bufferIndex) const
+  const float& operator[]( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -414,7 +592,10 @@ public:
    */
   void Bake(BufferIndex bufferIndex, float value)
   {
+    // It's ok to bake both buffers as render is performed in same thread as update. Reading from event side
+    // has never been atomically safe.
     mValue[bufferIndex] = value;
+    mValue[1-bufferIndex] = value;
     mBaseValue = mValue[bufferIndex];
 
     OnBake();
@@ -469,7 +650,6 @@ private:
 
   DoubleBuffered<float> mValue; ///< The double-buffered property value
   float mBaseValue;             ///< Reset to this base value at the beginning of each frame
-
 };
 
 /**
@@ -493,14 +673,12 @@ public:
   /**
    * Virtual destructor.
    */
-  virtual ~AnimatableProperty()
-  {
-  }
+  ~AnimatableProperty() override = default;
 
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
    */
-  virtual Dali::Property::Type GetType() const
+  Dali::Property::Type GetType() const override
   {
     return Dali::PropertyTypes::Get<Vector2>();
   }
@@ -508,7 +686,7 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
     if (CLEAN_FLAG != mDirtyFlags)
     {
@@ -521,7 +699,7 @@ public:
   /**
    * @copydoc Dali::PropertyInput::GetVector2()
    */
-  virtual const Vector2& GetVector2( BufferIndex bufferIndex ) const
+  const Vector2& GetVector2( BufferIndex bufferIndex ) const override
   {
     return mValue[ bufferIndex ];
   }
@@ -540,6 +718,32 @@ public:
   }
 
   /**
+   * Set the property value. This will only persist for the current frame; the property
+   * will be reset with the base value, at the beginning of the next frame.
+   * @param[in] bufferIndex The buffer to write.
+   * @param[in] value The new X value.
+   */
+  void SetX(BufferIndex bufferIndex, float value)
+  {
+    mValue[bufferIndex].x = value;
+
+    OnSet();
+  }
+
+  /**
+   * Set the property value. This will only persist for the current frame; the property
+   * will be reset with the base value, at the beginning of the next frame.
+   * @param[in] bufferIndex The buffer to write.
+   * @param[in] value The new Y value.
+   */
+  void SetY(BufferIndex bufferIndex, float value)
+  {
+    mValue[bufferIndex].y = value;
+
+    OnSet();
+  }
+
+  /**
    * Change the property value by a relative amount.
    * @param[in] bufferIndex The buffer to write.
    * @param[in] delta The property will change by this amount.
@@ -552,9 +756,33 @@ public:
   }
 
   /**
+   * Change the X value by a relative amount.
+   * @param[in] bufferIndex The buffer to write.
+   * @param[in] delta The X value will change by this amount.
+   */
+  void SetXRelative(BufferIndex bufferIndex, float delta)
+  {
+    mValue[bufferIndex].x += delta;
+
+    OnSet();
+  }
+
+  /**
+   * Change the Y value by a relative amount.
+   * @param[in] bufferIndex The buffer to write.
+   * @param[in] delta The Y value will change by this amount.
+   */
+  void SetYRelative(BufferIndex bufferIndex, float delta)
+  {
+    mValue[bufferIndex].y += delta;
+
+    OnSet();
+  }
+
+  /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Vector2& Get(size_t bufferIndex)
+  Vector2& Get( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -562,7 +790,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Vector2& Get(size_t bufferIndex) const
+  const Vector2& Get( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -572,7 +800,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  Vector2& operator[](size_t bufferIndex)
+  Vector2& operator[]( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -582,7 +810,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const Vector2& operator[](size_t bufferIndex) const
+  const Vector2& operator[]( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -594,13 +822,44 @@ public:
    */
   void Bake(BufferIndex bufferIndex, const Vector2& value)
   {
+    // It's ok to bake both buffers as render is performed in same thread as update. Reading from event side
+    // has never been atomically safe.
     mValue[bufferIndex] = value;
+    mValue[1-bufferIndex] = value;
     mBaseValue = value;
 
     OnBake();
   }
 
   /**
+   * Set both the X value & base X value.
+   * @param[in] bufferIndex The buffer to write for the property value.
+   * @param[in] value The new property value.
+   */
+  void BakeX(BufferIndex bufferIndex, float value)
+  {
+    mValue[bufferIndex].x = value;
+    mValue[1-bufferIndex].x = value;
+    mBaseValue.x = value;
+
+    OnBake();
+  }
+
+  /**
+   * Set both the Y value & base Y value.
+   * @param[in] bufferIndex The buffer to write for the property value.
+   * @param[in] value The new property value.
+   */
+  void BakeY(BufferIndex bufferIndex, float value)
+  {
+    mValue[bufferIndex].y = value;
+    mValue[1-bufferIndex].y = value;
+    mBaseValue.y = value;
+
+    OnBake();
+  }
+
+  /**
    * Change the property value & base value by a relative amount.
    * @param[in] bufferIndex The buffer to write for the local property value.
    * @param[in] delta The property will change by this amount.
@@ -613,6 +872,32 @@ public:
     OnBake();
   }
 
+  /**
+   * Change the X value & base X value by a relative amount.
+   * @param[in] bufferIndex The buffer to write for the local property value.
+   * @param[in] delta The X value will change by this amount.
+   */
+  void BakeXRelative(BufferIndex bufferIndex, float delta)
+  {
+    mValue[bufferIndex].x += delta;
+    mBaseValue.x = mValue[bufferIndex].x;
+
+    OnBake();
+  }
+
+  /**
+   * Change the Y value & base Y value by a relative amount.
+   * @param[in] bufferIndex The buffer to write for the local property value.
+   * @param[in] delta The Y value will change by this amount.
+   */
+  void BakeYRelative(BufferIndex bufferIndex, float delta)
+  {
+    mValue[bufferIndex].y += delta;
+    mBaseValue.y = mValue[bufferIndex].y;
+
+    OnBake();
+  }
+
 private:
 
   // Undefined
@@ -638,6 +923,15 @@ public:
 
   /**
    * Create an animatable property.
+   */
+  AnimatableProperty()
+  : mValue(),
+    mBaseValue()
+  {
+  }
+
+  /**
+   * Create an animatable property.
    * @param [in] initialValue The initial value of the property.
    */
   AnimatableProperty( const Vector3& initialValue )
@@ -649,14 +943,12 @@ public:
   /**
    * Virtual destructor.
    */
-  virtual ~AnimatableProperty()
-  {
-  }
+  ~AnimatableProperty() override = default;
 
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
    */
-  virtual Dali::Property::Type GetType() const
+  Dali::Property::Type GetType() const override
   {
     return Dali::PropertyTypes::Get<Vector3>();
   }
@@ -664,7 +956,7 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
     if (CLEAN_FLAG != mDirtyFlags)
     {
@@ -677,7 +969,7 @@ public:
   /**
    * @copydoc Dali::PropertyInput::GetVector3()
    */
-  virtual const Vector3& GetVector3( BufferIndex bufferIndex ) const
+  const Vector3& GetVector3( BufferIndex bufferIndex ) const override
   {
     return mValue[ bufferIndex ];
   }
@@ -785,7 +1077,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Vector3& Get(size_t bufferIndex)
+  Vector3& Get( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -793,7 +1085,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Vector3& Get(size_t bufferIndex) const
+  const Vector3& Get( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -803,7 +1095,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  Vector3& operator[](size_t bufferIndex)
+  Vector3& operator[]( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -813,7 +1105,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const Vector3& operator[](size_t bufferIndex) const
+  const Vector3& operator[]( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -826,6 +1118,7 @@ public:
   void Bake(BufferIndex bufferIndex, const Vector3& value)
   {
     mValue[bufferIndex] = value;
+    mValue[1-bufferIndex] = value;
     mBaseValue = value;
 
     OnBake();
@@ -839,6 +1132,7 @@ public:
   void BakeX(BufferIndex bufferIndex, float value)
   {
     mValue[bufferIndex].x = value;
+    mValue[1-bufferIndex].x = value;
     mBaseValue.x = value;
 
     OnBake();
@@ -852,6 +1146,7 @@ public:
   void BakeY(BufferIndex bufferIndex, float value)
   {
     mValue[bufferIndex].y = value;
+    mValue[1-bufferIndex].y = value;
     mBaseValue.y = value;
 
     OnBake();
@@ -865,6 +1160,7 @@ public:
   void BakeZ(BufferIndex bufferIndex, float value)
   {
     mValue[bufferIndex].z = value;
+    mValue[1-bufferIndex].z = value;
     mBaseValue.z = value;
 
     OnBake();
@@ -971,14 +1267,12 @@ public:
   /**
    * Virtual destructor.
    */
-  virtual ~AnimatableProperty()
-  {
-  }
+  ~AnimatableProperty() override = default;
 
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
    */
-  virtual Dali::Property::Type GetType() const
+  Dali::Property::Type GetType() const override
   {
     return Dali::PropertyTypes::Get<Vector4>();
   }
@@ -986,7 +1280,7 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
     if (CLEAN_FLAG != mDirtyFlags)
     {
@@ -999,7 +1293,7 @@ public:
   /**
    * @copydoc Dali::PropertyInput::GetVector4()
    */
-  virtual const Vector4& GetVector4( BufferIndex bufferIndex ) const
+  const Vector4& GetVector4( BufferIndex bufferIndex ) const override
   {
     return mValue[ bufferIndex ];
   }
@@ -1132,7 +1426,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Vector4& Get(size_t bufferIndex)
+  Vector4& Get( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -1140,7 +1434,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Vector4& Get(size_t bufferIndex) const
+  const Vector4& Get( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -1150,7 +1444,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  Vector4& operator[](size_t bufferIndex)
+  Vector4& operator[]( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -1160,7 +1454,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const Vector4& operator[](size_t bufferIndex) const
+  const Vector4& operator[]( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -1173,6 +1467,7 @@ public:
   void Bake(BufferIndex bufferIndex, const Vector4& value)
   {
     mValue[bufferIndex] = value;
+    mValue[1-bufferIndex] = value;
     mBaseValue = mValue[bufferIndex];
 
     OnBake();
@@ -1186,6 +1481,7 @@ public:
   void BakeX(BufferIndex bufferIndex, float value)
   {
     mValue[bufferIndex].x = value;
+    mValue[1-bufferIndex].x = value;
     mBaseValue.x = mValue[bufferIndex].x;
 
     OnBake();
@@ -1199,6 +1495,7 @@ public:
   void BakeY(BufferIndex bufferIndex, float value)
   {
     mValue[bufferIndex].y = value;
+    mValue[1-bufferIndex].y = value;
     mBaseValue.y = mValue[bufferIndex].y;
 
     OnBake();
@@ -1212,6 +1509,7 @@ public:
   void BakeZ(BufferIndex bufferIndex, float value)
   {
     mValue[bufferIndex].z = value;
+    mValue[1-bufferIndex].z = value;
     mBaseValue.z = mValue[bufferIndex].z;
 
     OnBake();
@@ -1225,6 +1523,7 @@ public:
   void BakeW(BufferIndex bufferIndex, float value)
   {
     mValue[bufferIndex].w = value;
+    mValue[1-bufferIndex].w = value;
     mBaseValue.w = mValue[bufferIndex].w;
 
     OnBake();
@@ -1331,6 +1630,15 @@ public:
 
   /**
    * Create an animatable property.
+   */
+  AnimatableProperty()
+  : mValue(),
+    mBaseValue()
+  {
+  }
+
+  /**
+   * Create an animatable property.
    * @param [in] initialValue The initial value of the property.
    */
   AnimatableProperty( const Quaternion& initialValue )
@@ -1342,14 +1650,12 @@ public:
   /**
    * Virtual destructor.
    */
-  virtual ~AnimatableProperty()
-  {
-  }
+  ~AnimatableProperty() override = default;
 
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
    */
-  virtual Dali::Property::Type GetType() const
+  Dali::Property::Type GetType() const override
   {
     return Dali::PropertyTypes::Get<Quaternion>();
   }
@@ -1357,7 +1663,7 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
     if (CLEAN_FLAG != mDirtyFlags)
     {
@@ -1370,7 +1676,7 @@ public:
   /**
    * @copydoc Dali::PropertyInput::GetQuaternion()
    */
-  virtual const Quaternion& GetQuaternion( BufferIndex bufferIndex ) const
+  const Quaternion& GetQuaternion( BufferIndex bufferIndex ) const override
   {
     return mValue[ bufferIndex ];
   }
@@ -1403,7 +1709,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Quaternion& Get(size_t bufferIndex)
+  Quaternion& Get( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -1411,7 +1717,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Quaternion& Get(size_t bufferIndex) const
+  const Quaternion& Get( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -1421,7 +1727,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  Quaternion& operator[](size_t bufferIndex)
+  Quaternion& operator[]( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -1431,7 +1737,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const Quaternion& operator[](size_t bufferIndex) const
+  const Quaternion& operator[]( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -1443,7 +1749,10 @@ public:
    */
   void Bake(BufferIndex bufferIndex, const Quaternion& value)
   {
+    // It's ok to bake both buffers as render is performed in same thread as update. Reading from event side
+    // has never been atomically safe.
     mValue[bufferIndex] = value;
+    mValue[1-bufferIndex] = value;
     mBaseValue = value;
 
     OnBake();
@@ -1498,14 +1807,12 @@ public:
   /**
    * Virtual destructor.
    */
-  virtual ~AnimatableProperty()
-  {
-  }
+  ~AnimatableProperty() override = default;
 
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
    */
-  virtual Dali::Property::Type GetType() const
+  Dali::Property::Type GetType() const override
   {
     return Dali::PropertyTypes::Get<Matrix>();
   }
@@ -1513,7 +1820,7 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
     if (CLEAN_FLAG != mDirtyFlags)
     {
@@ -1526,7 +1833,7 @@ public:
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix()
    */
-  virtual const Matrix& GetMatrix( BufferIndex bufferIndex ) const
+  const Matrix& GetMatrix( BufferIndex bufferIndex ) const override
   {
     return mValue[ bufferIndex ];
   }
@@ -1561,7 +1868,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Matrix& Get(size_t bufferIndex)
+  Matrix& Get( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -1569,7 +1876,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Matrix& Get(size_t bufferIndex) const
+  const Matrix& Get( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -1579,7 +1886,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  Matrix& operator[](size_t bufferIndex)
+  Matrix& operator[]( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -1589,7 +1896,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const Matrix& operator[](size_t bufferIndex) const
+  const Matrix& operator[]( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -1601,7 +1908,10 @@ public:
    */
   void Bake(BufferIndex bufferIndex, const Matrix& value)
   {
+    // It's ok to bake both buffers as render is performed in same thread as update. Reading from event side
+    // has never been atomically safe.
     mValue[bufferIndex] = value;
+    mValue[1-bufferIndex] = value;
     mBaseValue = mValue[bufferIndex];
 
     OnBake();
@@ -1658,14 +1968,12 @@ public:
   /**
    * Virtual destructor.
    */
-  virtual ~AnimatableProperty()
-  {
-  }
+  ~AnimatableProperty() override = default;
 
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::GetType()
    */
-  virtual Dali::Property::Type GetType() const
+  Dali::Property::Type GetType() const override
   {
     return Dali::PropertyTypes::Get<Matrix3>();
   }
@@ -1673,7 +1981,7 @@ public:
   /**
    * @copydoc Dali::Internal::SceneGraph::PropertyBase::ResetToBaseValue()
    */
-  virtual void ResetToBaseValue(BufferIndex updateBufferIndex)
+  void ResetToBaseValue(BufferIndex updateBufferIndex) override
   {
     if (CLEAN_FLAG != mDirtyFlags)
     {
@@ -1686,7 +1994,7 @@ public:
   /**
    * @copydoc Dali::Internal::PropertyInputImpl::GetMatrix3()
    */
-  virtual const Matrix3& GetMatrix3( BufferIndex bufferIndex ) const
+  const Matrix3& GetMatrix3( BufferIndex bufferIndex ) const override
   {
     return mValue[ bufferIndex ];
   }
@@ -1719,7 +2027,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  Matrix3& Get(size_t bufferIndex)
+  Matrix3& Get( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -1727,7 +2035,7 @@ public:
   /**
    * @copydoc Dali::SceneGraph::AnimatableProperty::Get()
    */
-  const Matrix3& Get(size_t bufferIndex) const
+  const Matrix3& Get( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -1737,7 +2045,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  Matrix3& operator[](size_t bufferIndex)
+  Matrix3& operator[]( BufferIndex bufferIndex )
   {
     return mValue[bufferIndex];
   }
@@ -1747,7 +2055,7 @@ public:
    * @param[in] bufferIndex The buffer to read.
    * @return The property value.
    */
-  const Matrix3& operator[](size_t bufferIndex) const
+  const Matrix3& operator[]( BufferIndex bufferIndex ) const
   {
     return mValue[bufferIndex];
   }
@@ -1759,7 +2067,10 @@ public:
    */
   void Bake(BufferIndex bufferIndex, const Matrix3& value)
   {
+    // It's ok to bake both buffers as render is performed in same thread as update. Reading from event side
+    // has never been atomically safe.
     mValue[bufferIndex] = value;
+    mValue[1-bufferIndex] = value;
     mBaseValue = mValue[bufferIndex];
 
     OnBake();
@@ -1800,14 +2111,14 @@ private:
 // Messages for AnimatableProperty<T>
 
 template <class T>
-void BakeMessage( EventToUpdate& eventToUpdate,
+void BakeMessage( EventThreadServices& eventThreadServices,
                   const SceneGraph::AnimatableProperty<T>& property,
                   typename ParameterType< T >::PassingType newValue )
 {
-  typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, T > LocalType;
+  using LocalType = MessageDoubleBuffered1<SceneGraph::AnimatableProperty<T>, T>;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &property,
@@ -1816,14 +2127,14 @@ void BakeMessage( EventToUpdate& eventToUpdate,
 }
 
 template <class T>
-void BakeRelativeMessage( EventToUpdate& eventToUpdate,
+void BakeRelativeMessage( EventThreadServices& eventThreadServices,
                           const SceneGraph::AnimatableProperty<T>& property,
                           const T& delta )
 {
-  typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, const T& > LocalType;
+  using LocalType = MessageDoubleBuffered1<SceneGraph::AnimatableProperty<T>, const T&>;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &property,
@@ -1832,14 +2143,14 @@ void BakeRelativeMessage( EventToUpdate& eventToUpdate,
 }
 
 template <class T>
-void SetXComponentMessage( EventToUpdate& eventToUpdate,
+void SetXComponentMessage( EventThreadServices& eventThreadServices,
                            const SceneGraph::AnimatableProperty<T>& property,
                            typename ParameterType< float >::PassingType newValue )
 {
-  typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
+  using LocalType = MessageDoubleBuffered1<SceneGraph::AnimatableProperty<T>, float>;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &property,
@@ -1848,14 +2159,14 @@ void SetXComponentMessage( EventToUpdate& eventToUpdate,
 }
 
 template <class T>
-void SetYComponentMessage( EventToUpdate& eventToUpdate,
+void SetYComponentMessage( EventThreadServices& eventThreadServices,
                            const SceneGraph::AnimatableProperty<T>& property,
                            typename ParameterType< float >::PassingType newValue )
 {
-  typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
+  using LocalType = MessageDoubleBuffered1<SceneGraph::AnimatableProperty<T>, float>;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &property,
@@ -1864,14 +2175,14 @@ void SetYComponentMessage( EventToUpdate& eventToUpdate,
 }
 
 template <class T>
-void SetZComponentMessage( EventToUpdate& eventToUpdate,
+void SetZComponentMessage( EventThreadServices& eventThreadServices,
                            const SceneGraph::AnimatableProperty<T>& property,
                            typename ParameterType< float >::PassingType newValue )
 {
-  typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
+  using LocalType = MessageDoubleBuffered1<SceneGraph::AnimatableProperty<T>, float>;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &property,
@@ -1880,14 +2191,14 @@ void SetZComponentMessage( EventToUpdate& eventToUpdate,
 }
 
 template <class T>
-void SetWComponentMessage( EventToUpdate& eventToUpdate,
+void SetWComponentMessage( EventThreadServices& eventThreadServices,
                            const SceneGraph::AnimatableProperty<T>& property,
                            typename ParameterType< float >::PassingType newValue )
 {
-  typedef MessageDoubleBuffered1< SceneGraph::AnimatableProperty<T>, float > LocalType;
+  using LocalType = MessageDoubleBuffered1<SceneGraph::AnimatableProperty<T>, float>;
 
   // Reserve some memory inside the message queue
-  unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &property,
@@ -1899,4 +2210,4 @@ void SetWComponentMessage( EventToUpdate& eventToUpdate,
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_ANIMATABLE_PROPERTY_H